Merge "Add callback to notify frozen RecentTasks"
diff --git a/Android.bp b/Android.bp
index 77f4d11..594126f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -162,6 +162,14 @@
}
filegroup {
+ name: "framework-telephony-common-sources",
+ srcs: [
+ "telephony/common/**/*.java",
+ ],
+ path: "telephony/common",
+}
+
+filegroup {
name: "framework-wifi-sources",
srcs: [
"wifi/java/**/*.java",
@@ -189,6 +197,7 @@
":framework-rs-sources",
":framework-sax-sources",
":framework-telecomm-sources",
+ ":framework-telephony-common-sources",
":framework-telephony-sources",
":framework-wifi-sources",
":PacProcessor-aidl-sources",
@@ -814,6 +823,7 @@
"opengl/java",
"sax/java",
"telecomm/java",
+ "telephony/common",
"telephony/java",
"wifi/java",
"lowpan/java",
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 6a909c0..f7a2858 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -254,6 +254,7 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/DefaultContainerService)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/CaptivePortalLogin)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/ext.jar)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java/com/google/android/mms)
# ******************************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
# ******************************************************************
diff --git a/apct-tests/perftests/core/Android.mk b/apct-tests/perftests/core/Android.mk
index 3f87a1c..968478c 100644
--- a/apct-tests/perftests/core/Android.mk
+++ b/apct-tests/perftests/core/Android.mk
@@ -9,8 +9,11 @@
src/android/os/ISomeService.aidl
LOCAL_STATIC_JAVA_LIBRARIES := \
+ androidx.appcompat_appcompat \
androidx.test.rules \
androidx.annotation_annotation \
+ apct-perftests-overlay-apps \
+ apct-perftests-resources-manager-apps \
apct-perftests-utils \
guava
@@ -25,5 +28,6 @@
LOCAL_ASSET_DIR := $(TOP)/external/google-fonts/dancing-script
LOCAL_COMPATIBILITY_SUITE += device-tests
+LOCAL_CERTIFICATE := platform
-include $(BUILD_PACKAGE)
+include $(BUILD_PACKAGE)
\ No newline at end of file
diff --git a/apct-tests/perftests/core/AndroidManifest.xml b/apct-tests/perftests/core/AndroidManifest.xml
index a564a4d..525975d 100644
--- a/apct-tests/perftests/core/AndroidManifest.xml
+++ b/apct-tests/perftests/core/AndroidManifest.xml
@@ -5,8 +5,11 @@
<permission android:name="com.android.perftests.core.TestPermission" />
<uses-permission android:name="com.android.perftests.core.TestPermission" />
- <uses-permission
- android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" />
+ <uses-permission android:name="android.permission.DELETE_PACKAGES" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/apct-tests/perftests/core/apps/overlay/Android.bp b/apct-tests/perftests/core/apps/overlay/Android.bp
new file mode 100644
index 0000000..7bee30e
--- /dev/null
+++ b/apct-tests/perftests/core/apps/overlay/Android.bp
@@ -0,0 +1,188 @@
+// Copyright (C) 2019 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.
+
+android_test_helper_app {
+ name: "Overlay0",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay0",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay1",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay1",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay2",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay2",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay3",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay3",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay4",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay4",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay5",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay5",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay6",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay6",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay7",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay7",
+ ]
+}
+android_test_helper_app {
+ name: "Overlay8",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay8",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay9",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay9",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay0",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large0",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay1",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large1",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay2",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large2",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay3",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large3",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay4",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large4",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay5",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large5",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay6",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large6",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay7",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large7",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay8",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large8",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay9",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large9",
+ ]
+}
+
+java_library {
+ name: "apct-perftests-overlay-apps",
+ java_resources: [
+ ":Overlay0",
+ ":Overlay1",
+ ":Overlay2",
+ ":Overlay3",
+ ":Overlay4",
+ ":Overlay5",
+ ":Overlay6",
+ ":Overlay7",
+ ":Overlay8",
+ ":Overlay9",
+ ":LargeOverlay0",
+ ":LargeOverlay1",
+ ":LargeOverlay2",
+ ":LargeOverlay3",
+ ":LargeOverlay4",
+ ":LargeOverlay5",
+ ":LargeOverlay6",
+ ":LargeOverlay7",
+ ":LargeOverlay8",
+ ":LargeOverlay9",
+ ],
+}
\ No newline at end of file
diff --git a/apct-tests/perftests/core/apps/overlay/AndroidManifest.xml b/apct-tests/perftests/core/apps/overlay/AndroidManifest.xml
new file mode 100644
index 0000000..52f5a89
--- /dev/null
+++ b/apct-tests/perftests/core/apps/overlay/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.perftests.overlay">
+ <application android:hasCode="false" />
+ <uses-sdk android:targetSdkVersion="29" />
+ <overlay android:targetPackage="com.android.perftests.core" android:targetName="TestResources"/>
+</manifest>
\ No newline at end of file
diff --git a/apct-tests/perftests/core/apps/overlay/res/values/values.xml b/apct-tests/perftests/core/apps/overlay/res/values/values.xml
new file mode 100644
index 0000000..a1a8d83
--- /dev/null
+++ b/apct-tests/perftests/core/apps/overlay/res/values/values.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string name="short_text">B</string>
+</resources>
diff --git a/apct-tests/perftests/core/apps/overlay/res_large/values/values.xml b/apct-tests/perftests/core/apps/overlay/res_large/values/values.xml
new file mode 100644
index 0000000..e741446
--- /dev/null
+++ b/apct-tests/perftests/core/apps/overlay/res_large/values/values.xml
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string name="short_text000">B</string>
+ <string name="short_text001">B</string>
+ <string name="short_text002">B</string>
+ <string name="short_text003">B</string>
+ <string name="short_text004">B</string>
+ <string name="short_text005">B</string>
+ <string name="short_text006">B</string>
+ <string name="short_text007">B</string>
+ <string name="short_text008">B</string>
+ <string name="short_text009">B</string>
+ <string name="short_text010">B</string>
+ <string name="short_text011">B</string>
+ <string name="short_text012">B</string>
+ <string name="short_text013">B</string>
+ <string name="short_text014">B</string>
+ <string name="short_text015">B</string>
+ <string name="short_text016">B</string>
+ <string name="short_text017">B</string>
+ <string name="short_text018">B</string>
+ <string name="short_text019">B</string>
+ <string name="short_text020">B</string>
+ <string name="short_text021">B</string>
+ <string name="short_text022">B</string>
+ <string name="short_text023">B</string>
+ <string name="short_text024">B</string>
+ <string name="short_text025">B</string>
+ <string name="short_text026">B</string>
+ <string name="short_text027">B</string>
+ <string name="short_text028">B</string>
+ <string name="short_text029">B</string>
+ <string name="short_text030">B</string>
+ <string name="short_text031">B</string>
+ <string name="short_text032">B</string>
+ <string name="short_text033">B</string>
+ <string name="short_text034">B</string>
+ <string name="short_text035">B</string>
+ <string name="short_text036">B</string>
+ <string name="short_text037">B</string>
+ <string name="short_text038">B</string>
+ <string name="short_text039">B</string>
+ <string name="short_text040">B</string>
+ <string name="short_text041">B</string>
+ <string name="short_text042">B</string>
+ <string name="short_text043">B</string>
+ <string name="short_text044">B</string>
+ <string name="short_text045">B</string>
+ <string name="short_text046">B</string>
+ <string name="short_text047">B</string>
+ <string name="short_text048">B</string>
+ <string name="short_text049">B</string>
+ <string name="short_text050">B</string>
+ <string name="short_text051">B</string>
+ <string name="short_text052">B</string>
+ <string name="short_text053">B</string>
+ <string name="short_text054">B</string>
+ <string name="short_text055">B</string>
+ <string name="short_text056">B</string>
+ <string name="short_text057">B</string>
+ <string name="short_text058">B</string>
+ <string name="short_text059">B</string>
+ <string name="short_text060">B</string>
+ <string name="short_text061">B</string>
+ <string name="short_text062">B</string>
+ <string name="short_text063">B</string>
+ <string name="short_text064">B</string>
+ <string name="short_text065">B</string>
+ <string name="short_text066">B</string>
+ <string name="short_text067">B</string>
+ <string name="short_text068">B</string>
+ <string name="short_text069">B</string>
+ <string name="short_text070">B</string>
+ <string name="short_text071">B</string>
+ <string name="short_text072">B</string>
+ <string name="short_text073">B</string>
+ <string name="short_text074">B</string>
+ <string name="short_text075">B</string>
+ <string name="short_text076">B</string>
+ <string name="short_text077">B</string>
+ <string name="short_text078">B</string>
+ <string name="short_text079">B</string>
+ <string name="short_text080">B</string>
+ <string name="short_text081">B</string>
+ <string name="short_text082">B</string>
+ <string name="short_text083">B</string>
+ <string name="short_text084">B</string>
+ <string name="short_text085">B</string>
+ <string name="short_text086">B</string>
+ <string name="short_text087">B</string>
+ <string name="short_text088">B</string>
+ <string name="short_text089">B</string>
+ <string name="short_text090">B</string>
+ <string name="short_text091">B</string>
+ <string name="short_text092">B</string>
+ <string name="short_text093">B</string>
+ <string name="short_text094">B</string>
+ <string name="short_text095">B</string>
+ <string name="short_text096">B</string>
+ <string name="short_text097">B</string>
+ <string name="short_text098">B</string>
+ <string name="short_text099">B</string>
+ <string name="short_text100">B</string>
+ <string name="short_text101">B</string>
+ <string name="short_text102">B</string>
+ <string name="short_text103">B</string>
+ <string name="short_text104">B</string>
+ <string name="short_text105">B</string>
+ <string name="short_text106">B</string>
+ <string name="short_text107">B</string>
+ <string name="short_text108">B</string>
+ <string name="short_text109">B</string>
+ <string name="short_text110">B</string>
+ <string name="short_text111">B</string>
+ <string name="short_text112">B</string>
+ <string name="short_text113">B</string>
+ <string name="short_text114">B</string>
+ <string name="short_text115">B</string>
+ <string name="short_text116">B</string>
+ <string name="short_text117">B</string>
+ <string name="short_text118">B</string>
+ <string name="short_text119">B</string>
+ <string name="short_text120">B</string>
+ <string name="short_text121">B</string>
+ <string name="short_text122">B</string>
+ <string name="short_text123">B</string>
+ <string name="short_text124">B</string>
+ <string name="short_text125">B</string>
+ <string name="short_text126">B</string>
+ <string name="short_text127">B</string>
+ <string name="short_text128">B</string>
+ <string name="short_text129">B</string>
+ <string name="short_text130">B</string>
+ <string name="short_text131">B</string>
+ <string name="short_text132">B</string>
+ <string name="short_text133">B</string>
+ <string name="short_text134">B</string>
+ <string name="short_text135">B</string>
+ <string name="short_text136">B</string>
+ <string name="short_text137">B</string>
+ <string name="short_text138">B</string>
+ <string name="short_text139">B</string>
+ <string name="short_text140">B</string>
+ <string name="short_text141">B</string>
+ <string name="short_text142">B</string>
+ <string name="short_text143">B</string>
+ <string name="short_text144">B</string>
+ <string name="short_text145">B</string>
+ <string name="short_text146">B</string>
+ <string name="short_text147">B</string>
+ <string name="short_text148">B</string>
+ <string name="short_text149">B</string>
+ <string name="short_text150">B</string>
+ <string name="short_text151">B</string>
+ <string name="short_text152">B</string>
+ <string name="short_text153">B</string>
+ <string name="short_text154">B</string>
+ <string name="short_text155">B</string>
+ <string name="short_text156">B</string>
+ <string name="short_text157">B</string>
+ <string name="short_text158">B</string>
+ <string name="short_text159">B</string>
+ <string name="short_text160">B</string>
+ <string name="short_text161">B</string>
+ <string name="short_text162">B</string>
+ <string name="short_text163">B</string>
+ <string name="short_text164">B</string>
+ <string name="short_text165">B</string>
+ <string name="short_text166">B</string>
+ <string name="short_text167">B</string>
+ <string name="short_text168">B</string>
+ <string name="short_text169">B</string>
+ <string name="short_text170">B</string>
+ <string name="short_text171">B</string>
+ <string name="short_text172">B</string>
+ <string name="short_text173">B</string>
+ <string name="short_text174">B</string>
+ <string name="short_text175">B</string>
+ <string name="short_text176">B</string>
+ <string name="short_text177">B</string>
+ <string name="short_text178">B</string>
+ <string name="short_text179">B</string>
+ <string name="short_text180">B</string>
+ <string name="short_text181">B</string>
+ <string name="short_text182">B</string>
+ <string name="short_text183">B</string>
+ <string name="short_text184">B</string>
+ <string name="short_text185">B</string>
+ <string name="short_text186">B</string>
+ <string name="short_text187">B</string>
+ <string name="short_text188">B</string>
+ <string name="short_text189">B</string>
+ <string name="short_text190">B</string>
+ <string name="short_text191">B</string>
+ <string name="short_text192">B</string>
+ <string name="short_text193">B</string>
+ <string name="short_text194">B</string>
+ <string name="short_text195">B</string>
+ <string name="short_text196">B</string>
+ <string name="short_text197">B</string>
+ <string name="short_text198">B</string>
+ <string name="short_text199">B</string>
+ <string name="short_text200">B</string>
+ <string name="short_text201">B</string>
+ <string name="short_text202">B</string>
+ <string name="short_text203">B</string>
+ <string name="short_text204">B</string>
+ <string name="short_text205">B</string>
+ <string name="short_text206">B</string>
+ <string name="short_text207">B</string>
+ <string name="short_text208">B</string>
+ <string name="short_text209">B</string>
+ <string name="short_text210">B</string>
+ <string name="short_text211">B</string>
+ <string name="short_text212">B</string>
+ <string name="short_text213">B</string>
+ <string name="short_text214">B</string>
+ <string name="short_text215">B</string>
+ <string name="short_text216">B</string>
+ <string name="short_text217">B</string>
+ <string name="short_text218">B</string>
+ <string name="short_text219">B</string>
+ <string name="short_text220">B</string>
+ <string name="short_text221">B</string>
+ <string name="short_text222">B</string>
+ <string name="short_text223">B</string>
+ <string name="short_text224">B</string>
+ <string name="short_text225">B</string>
+ <string name="short_text226">B</string>
+ <string name="short_text227">B</string>
+ <string name="short_text228">B</string>
+ <string name="short_text229">B</string>
+ <string name="short_text230">B</string>
+ <string name="short_text231">B</string>
+ <string name="short_text232">B</string>
+ <string name="short_text233">B</string>
+ <string name="short_text234">B</string>
+ <string name="short_text235">B</string>
+ <string name="short_text236">B</string>
+ <string name="short_text237">B</string>
+ <string name="short_text238">B</string>
+ <string name="short_text239">B</string>
+ <string name="short_text240">B</string>
+ <string name="short_text241">B</string>
+ <string name="short_text242">B</string>
+ <string name="short_text243">B</string>
+ <string name="short_text244">B</string>
+ <string name="short_text245">B</string>
+ <string name="short_text246">B</string>
+ <string name="short_text247">B</string>
+ <string name="short_text248">B</string>
+ <string name="short_text249">B</string>
+ <string name="short_text250">B</string>
+ <string name="short_text251">B</string>
+ <string name="short_text252">B</string>
+ <string name="short_text253">B</string>
+ <string name="short_text254">B</string>
+ <string name="short_text255">B</string>
+</resources>
diff --git a/apct-tests/perftests/core/apps/reources_manager/Android.bp b/apct-tests/perftests/core/apps/reources_manager/Android.bp
new file mode 100644
index 0000000..4516132
--- /dev/null
+++ b/apct-tests/perftests/core/apps/reources_manager/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2019 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.
+
+android_test_helper_app {
+ name: "LargeResourcesCompressed",
+ static_libs: [ "androidx.appcompat_appcompat" ],
+}
+
+genrule {
+ name: "LargeResourcesUncompressed",
+ srcs: [ ":LargeResourcesCompressed" ],
+ out: ["LargeResourcesUncompressed.apk"],
+ cmd: "cp $(in) $(out) && unzip -o $(out) resources.arsc"
+ + " && zip $(out) resources.arsc"
+}
+
+java_library {
+ name: "apct-perftests-resources-manager-apps",
+ java_resources: [
+ ":LargeResourcesCompressed",
+ ":LargeResourcesUncompressed",
+ ],
+}
\ No newline at end of file
diff --git a/apct-tests/perftests/core/apps/reources_manager/AndroidManifest.xml b/apct-tests/perftests/core/apps/reources_manager/AndroidManifest.xml
new file mode 100644
index 0000000..adb4e40
--- /dev/null
+++ b/apct-tests/perftests/core/apps/reources_manager/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="fake.android">
+ <application android:hasCode="false" />
+ <uses-sdk android:targetSdkVersion="29" />
+</manifest>
\ No newline at end of file
diff --git a/apct-tests/perftests/core/res/color/color_state_list.xml b/apct-tests/perftests/core/res/color/color_state_list.xml
new file mode 100644
index 0000000..142e47a
--- /dev/null
+++ b/apct-tests/perftests/core/res/color/color_state_list.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true"
+ android:color="#000000" />
+ <item android:state_pressed="true"
+ android:state_enabled="false"
+ android:color="#212121" />
+ <item android:state_enabled="false"
+ android:color="#414141" />
+ <item android:color="#616161" />
+</selector>
\ No newline at end of file
diff --git a/apct-tests/perftests/core/res/values/overlayable.xml b/apct-tests/perftests/core/res/values/overlayable.xml
new file mode 100644
index 0000000..70cedd7
--- /dev/null
+++ b/apct-tests/perftests/core/res/values/overlayable.xml
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <overlayable name="TestResources">
+ <policy type="public">
+ <item type="string" name="short_text" />
+ <item type="string" name="short_text000" />
+ <item type="string" name="short_text001" />
+ <item type="string" name="short_text002" />
+ <item type="string" name="short_text003" />
+ <item type="string" name="short_text004" />
+ <item type="string" name="short_text005" />
+ <item type="string" name="short_text006" />
+ <item type="string" name="short_text007" />
+ <item type="string" name="short_text008" />
+ <item type="string" name="short_text009" />
+ <item type="string" name="short_text010" />
+ <item type="string" name="short_text011" />
+ <item type="string" name="short_text012" />
+ <item type="string" name="short_text013" />
+ <item type="string" name="short_text014" />
+ <item type="string" name="short_text015" />
+ <item type="string" name="short_text016" />
+ <item type="string" name="short_text017" />
+ <item type="string" name="short_text018" />
+ <item type="string" name="short_text019" />
+ <item type="string" name="short_text020" />
+ <item type="string" name="short_text021" />
+ <item type="string" name="short_text022" />
+ <item type="string" name="short_text023" />
+ <item type="string" name="short_text024" />
+ <item type="string" name="short_text025" />
+ <item type="string" name="short_text026" />
+ <item type="string" name="short_text027" />
+ <item type="string" name="short_text028" />
+ <item type="string" name="short_text029" />
+ <item type="string" name="short_text030" />
+ <item type="string" name="short_text031" />
+ <item type="string" name="short_text032" />
+ <item type="string" name="short_text033" />
+ <item type="string" name="short_text034" />
+ <item type="string" name="short_text035" />
+ <item type="string" name="short_text036" />
+ <item type="string" name="short_text037" />
+ <item type="string" name="short_text038" />
+ <item type="string" name="short_text039" />
+ <item type="string" name="short_text040" />
+ <item type="string" name="short_text041" />
+ <item type="string" name="short_text042" />
+ <item type="string" name="short_text043" />
+ <item type="string" name="short_text044" />
+ <item type="string" name="short_text045" />
+ <item type="string" name="short_text046" />
+ <item type="string" name="short_text047" />
+ <item type="string" name="short_text048" />
+ <item type="string" name="short_text049" />
+ <item type="string" name="short_text050" />
+ <item type="string" name="short_text051" />
+ <item type="string" name="short_text052" />
+ <item type="string" name="short_text053" />
+ <item type="string" name="short_text054" />
+ <item type="string" name="short_text055" />
+ <item type="string" name="short_text056" />
+ <item type="string" name="short_text057" />
+ <item type="string" name="short_text058" />
+ <item type="string" name="short_text059" />
+ <item type="string" name="short_text060" />
+ <item type="string" name="short_text061" />
+ <item type="string" name="short_text062" />
+ <item type="string" name="short_text063" />
+ <item type="string" name="short_text064" />
+ <item type="string" name="short_text065" />
+ <item type="string" name="short_text066" />
+ <item type="string" name="short_text067" />
+ <item type="string" name="short_text068" />
+ <item type="string" name="short_text069" />
+ <item type="string" name="short_text070" />
+ <item type="string" name="short_text071" />
+ <item type="string" name="short_text072" />
+ <item type="string" name="short_text073" />
+ <item type="string" name="short_text074" />
+ <item type="string" name="short_text075" />
+ <item type="string" name="short_text076" />
+ <item type="string" name="short_text077" />
+ <item type="string" name="short_text078" />
+ <item type="string" name="short_text079" />
+ <item type="string" name="short_text080" />
+ <item type="string" name="short_text081" />
+ <item type="string" name="short_text082" />
+ <item type="string" name="short_text083" />
+ <item type="string" name="short_text084" />
+ <item type="string" name="short_text085" />
+ <item type="string" name="short_text086" />
+ <item type="string" name="short_text087" />
+ <item type="string" name="short_text088" />
+ <item type="string" name="short_text089" />
+ <item type="string" name="short_text090" />
+ <item type="string" name="short_text091" />
+ <item type="string" name="short_text092" />
+ <item type="string" name="short_text093" />
+ <item type="string" name="short_text094" />
+ <item type="string" name="short_text095" />
+ <item type="string" name="short_text096" />
+ <item type="string" name="short_text097" />
+ <item type="string" name="short_text098" />
+ <item type="string" name="short_text099" />
+ <item type="string" name="short_text100" />
+ <item type="string" name="short_text101" />
+ <item type="string" name="short_text102" />
+ <item type="string" name="short_text103" />
+ <item type="string" name="short_text104" />
+ <item type="string" name="short_text105" />
+ <item type="string" name="short_text106" />
+ <item type="string" name="short_text107" />
+ <item type="string" name="short_text108" />
+ <item type="string" name="short_text109" />
+ <item type="string" name="short_text110" />
+ <item type="string" name="short_text111" />
+ <item type="string" name="short_text112" />
+ <item type="string" name="short_text113" />
+ <item type="string" name="short_text114" />
+ <item type="string" name="short_text115" />
+ <item type="string" name="short_text116" />
+ <item type="string" name="short_text117" />
+ <item type="string" name="short_text118" />
+ <item type="string" name="short_text119" />
+ <item type="string" name="short_text120" />
+ <item type="string" name="short_text121" />
+ <item type="string" name="short_text122" />
+ <item type="string" name="short_text123" />
+ <item type="string" name="short_text124" />
+ <item type="string" name="short_text125" />
+ <item type="string" name="short_text126" />
+ <item type="string" name="short_text127" />
+ <item type="string" name="short_text128" />
+ <item type="string" name="short_text129" />
+ <item type="string" name="short_text130" />
+ <item type="string" name="short_text131" />
+ <item type="string" name="short_text132" />
+ <item type="string" name="short_text133" />
+ <item type="string" name="short_text134" />
+ <item type="string" name="short_text135" />
+ <item type="string" name="short_text136" />
+ <item type="string" name="short_text137" />
+ <item type="string" name="short_text138" />
+ <item type="string" name="short_text139" />
+ <item type="string" name="short_text140" />
+ <item type="string" name="short_text141" />
+ <item type="string" name="short_text142" />
+ <item type="string" name="short_text143" />
+ <item type="string" name="short_text144" />
+ <item type="string" name="short_text145" />
+ <item type="string" name="short_text146" />
+ <item type="string" name="short_text147" />
+ <item type="string" name="short_text148" />
+ <item type="string" name="short_text149" />
+ <item type="string" name="short_text150" />
+ <item type="string" name="short_text151" />
+ <item type="string" name="short_text152" />
+ <item type="string" name="short_text153" />
+ <item type="string" name="short_text154" />
+ <item type="string" name="short_text155" />
+ <item type="string" name="short_text156" />
+ <item type="string" name="short_text157" />
+ <item type="string" name="short_text158" />
+ <item type="string" name="short_text159" />
+ <item type="string" name="short_text160" />
+ <item type="string" name="short_text161" />
+ <item type="string" name="short_text162" />
+ <item type="string" name="short_text163" />
+ <item type="string" name="short_text164" />
+ <item type="string" name="short_text165" />
+ <item type="string" name="short_text166" />
+ <item type="string" name="short_text167" />
+ <item type="string" name="short_text168" />
+ <item type="string" name="short_text169" />
+ <item type="string" name="short_text170" />
+ <item type="string" name="short_text171" />
+ <item type="string" name="short_text172" />
+ <item type="string" name="short_text173" />
+ <item type="string" name="short_text174" />
+ <item type="string" name="short_text175" />
+ <item type="string" name="short_text176" />
+ <item type="string" name="short_text177" />
+ <item type="string" name="short_text178" />
+ <item type="string" name="short_text179" />
+ <item type="string" name="short_text180" />
+ <item type="string" name="short_text181" />
+ <item type="string" name="short_text182" />
+ <item type="string" name="short_text183" />
+ <item type="string" name="short_text184" />
+ <item type="string" name="short_text185" />
+ <item type="string" name="short_text186" />
+ <item type="string" name="short_text187" />
+ <item type="string" name="short_text188" />
+ <item type="string" name="short_text189" />
+ <item type="string" name="short_text190" />
+ <item type="string" name="short_text191" />
+ <item type="string" name="short_text192" />
+ <item type="string" name="short_text193" />
+ <item type="string" name="short_text194" />
+ <item type="string" name="short_text195" />
+ <item type="string" name="short_text196" />
+ <item type="string" name="short_text197" />
+ <item type="string" name="short_text198" />
+ <item type="string" name="short_text199" />
+ <item type="string" name="short_text200" />
+ <item type="string" name="short_text201" />
+ <item type="string" name="short_text202" />
+ <item type="string" name="short_text203" />
+ <item type="string" name="short_text204" />
+ <item type="string" name="short_text205" />
+ <item type="string" name="short_text206" />
+ <item type="string" name="short_text207" />
+ <item type="string" name="short_text208" />
+ <item type="string" name="short_text209" />
+ <item type="string" name="short_text210" />
+ <item type="string" name="short_text211" />
+ <item type="string" name="short_text212" />
+ <item type="string" name="short_text213" />
+ <item type="string" name="short_text214" />
+ <item type="string" name="short_text215" />
+ <item type="string" name="short_text216" />
+ <item type="string" name="short_text217" />
+ <item type="string" name="short_text218" />
+ <item type="string" name="short_text219" />
+ <item type="string" name="short_text220" />
+ <item type="string" name="short_text221" />
+ <item type="string" name="short_text222" />
+ <item type="string" name="short_text223" />
+ <item type="string" name="short_text224" />
+ <item type="string" name="short_text225" />
+ <item type="string" name="short_text226" />
+ <item type="string" name="short_text227" />
+ <item type="string" name="short_text228" />
+ <item type="string" name="short_text229" />
+ <item type="string" name="short_text230" />
+ <item type="string" name="short_text231" />
+ <item type="string" name="short_text232" />
+ <item type="string" name="short_text233" />
+ <item type="string" name="short_text234" />
+ <item type="string" name="short_text235" />
+ <item type="string" name="short_text236" />
+ <item type="string" name="short_text237" />
+ <item type="string" name="short_text238" />
+ <item type="string" name="short_text239" />
+ <item type="string" name="short_text240" />
+ <item type="string" name="short_text241" />
+ <item type="string" name="short_text242" />
+ <item type="string" name="short_text243" />
+ <item type="string" name="short_text244" />
+ <item type="string" name="short_text245" />
+ <item type="string" name="short_text246" />
+ <item type="string" name="short_text247" />
+ <item type="string" name="short_text248" />
+ <item type="string" name="short_text249" />
+ <item type="string" name="short_text250" />
+ <item type="string" name="short_text251" />
+ <item type="string" name="short_text252" />
+ <item type="string" name="short_text253" />
+ <item type="string" name="short_text254" />
+ <item type="string" name="short_text255" />
+ </policy>
+ </overlayable>
+</resources>
diff --git a/apct-tests/perftests/core/res/values/strings.xml b/apct-tests/perftests/core/res/values/strings.xml
deleted file mode 100644
index 7ab325f..0000000
--- a/apct-tests/perftests/core/res/values/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2016 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="long_text">text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text typo text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text </string>
- <string name="short_text">text text</string>
-</resources>
diff --git a/apct-tests/perftests/core/res/values/values.xml b/apct-tests/perftests/core/res/values/values.xml
new file mode 100644
index 0000000..aad42ba
--- /dev/null
+++ b/apct-tests/perftests/core/res/values/values.xml
@@ -0,0 +1,368 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2016 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="long_text">text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text typo text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text </string>
+
+ <plurals name="plurals_text">
+ <item quantity="one">1 text</item>
+ <item quantity="other"><xliff:g id="count" example="3">%d</xliff:g> texts</item>
+ </plurals>
+
+ <string-array name="strings">
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ </string-array>
+
+ <integer-array name="ints">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ </integer-array>
+
+ <color name="white">#ffffff</color>
+
+ <integer name="forty_two">42</integer>
+
+ <string name="short_text">text text</string>
+ <string name="short_text000">B</string>
+ <string name="short_text001">B</string>
+ <string name="short_text002">B</string>
+ <string name="short_text003">B</string>
+ <string name="short_text004">B</string>
+ <string name="short_text005">B</string>
+ <string name="short_text006">B</string>
+ <string name="short_text007">B</string>
+ <string name="short_text008">B</string>
+ <string name="short_text009">B</string>
+ <string name="short_text010">B</string>
+ <string name="short_text011">B</string>
+ <string name="short_text012">B</string>
+ <string name="short_text013">B</string>
+ <string name="short_text014">B</string>
+ <string name="short_text015">B</string>
+ <string name="short_text016">B</string>
+ <string name="short_text017">B</string>
+ <string name="short_text018">B</string>
+ <string name="short_text019">B</string>
+ <string name="short_text020">B</string>
+ <string name="short_text021">B</string>
+ <string name="short_text022">B</string>
+ <string name="short_text023">B</string>
+ <string name="short_text024">B</string>
+ <string name="short_text025">B</string>
+ <string name="short_text026">B</string>
+ <string name="short_text027">B</string>
+ <string name="short_text028">B</string>
+ <string name="short_text029">B</string>
+ <string name="short_text030">B</string>
+ <string name="short_text031">B</string>
+ <string name="short_text032">B</string>
+ <string name="short_text033">B</string>
+ <string name="short_text034">B</string>
+ <string name="short_text035">B</string>
+ <string name="short_text036">B</string>
+ <string name="short_text037">B</string>
+ <string name="short_text038">B</string>
+ <string name="short_text039">B</string>
+ <string name="short_text040">B</string>
+ <string name="short_text041">B</string>
+ <string name="short_text042">B</string>
+ <string name="short_text043">B</string>
+ <string name="short_text044">B</string>
+ <string name="short_text045">B</string>
+ <string name="short_text046">B</string>
+ <string name="short_text047">B</string>
+ <string name="short_text048">B</string>
+ <string name="short_text049">B</string>
+ <string name="short_text050">B</string>
+ <string name="short_text051">B</string>
+ <string name="short_text052">B</string>
+ <string name="short_text053">B</string>
+ <string name="short_text054">B</string>
+ <string name="short_text055">B</string>
+ <string name="short_text056">B</string>
+ <string name="short_text057">B</string>
+ <string name="short_text058">B</string>
+ <string name="short_text059">B</string>
+ <string name="short_text060">B</string>
+ <string name="short_text061">B</string>
+ <string name="short_text062">B</string>
+ <string name="short_text063">B</string>
+ <string name="short_text064">B</string>
+ <string name="short_text065">B</string>
+ <string name="short_text066">B</string>
+ <string name="short_text067">B</string>
+ <string name="short_text068">B</string>
+ <string name="short_text069">B</string>
+ <string name="short_text070">B</string>
+ <string name="short_text071">B</string>
+ <string name="short_text072">B</string>
+ <string name="short_text073">B</string>
+ <string name="short_text074">B</string>
+ <string name="short_text075">B</string>
+ <string name="short_text076">B</string>
+ <string name="short_text077">B</string>
+ <string name="short_text078">B</string>
+ <string name="short_text079">B</string>
+ <string name="short_text080">B</string>
+ <string name="short_text081">B</string>
+ <string name="short_text082">B</string>
+ <string name="short_text083">B</string>
+ <string name="short_text084">B</string>
+ <string name="short_text085">B</string>
+ <string name="short_text086">B</string>
+ <string name="short_text087">B</string>
+ <string name="short_text088">B</string>
+ <string name="short_text089">B</string>
+ <string name="short_text090">B</string>
+ <string name="short_text091">B</string>
+ <string name="short_text092">B</string>
+ <string name="short_text093">B</string>
+ <string name="short_text094">B</string>
+ <string name="short_text095">B</string>
+ <string name="short_text096">B</string>
+ <string name="short_text097">B</string>
+ <string name="short_text098">B</string>
+ <string name="short_text099">B</string>
+ <string name="short_text100">B</string>
+ <string name="short_text101">B</string>
+ <string name="short_text102">B</string>
+ <string name="short_text103">B</string>
+ <string name="short_text104">B</string>
+ <string name="short_text105">B</string>
+ <string name="short_text106">B</string>
+ <string name="short_text107">B</string>
+ <string name="short_text108">B</string>
+ <string name="short_text109">B</string>
+ <string name="short_text110">B</string>
+ <string name="short_text111">B</string>
+ <string name="short_text112">B</string>
+ <string name="short_text113">B</string>
+ <string name="short_text114">B</string>
+ <string name="short_text115">B</string>
+ <string name="short_text116">B</string>
+ <string name="short_text117">B</string>
+ <string name="short_text118">B</string>
+ <string name="short_text119">B</string>
+ <string name="short_text120">B</string>
+ <string name="short_text121">B</string>
+ <string name="short_text122">B</string>
+ <string name="short_text123">B</string>
+ <string name="short_text124">B</string>
+ <string name="short_text125">B</string>
+ <string name="short_text126">B</string>
+ <string name="short_text127">B</string>
+ <string name="short_text128">B</string>
+ <string name="short_text129">B</string>
+ <string name="short_text130">B</string>
+ <string name="short_text131">B</string>
+ <string name="short_text132">B</string>
+ <string name="short_text133">B</string>
+ <string name="short_text134">B</string>
+ <string name="short_text135">B</string>
+ <string name="short_text136">B</string>
+ <string name="short_text137">B</string>
+ <string name="short_text138">B</string>
+ <string name="short_text139">B</string>
+ <string name="short_text140">B</string>
+ <string name="short_text141">B</string>
+ <string name="short_text142">B</string>
+ <string name="short_text143">B</string>
+ <string name="short_text144">B</string>
+ <string name="short_text145">B</string>
+ <string name="short_text146">B</string>
+ <string name="short_text147">B</string>
+ <string name="short_text148">B</string>
+ <string name="short_text149">B</string>
+ <string name="short_text150">B</string>
+ <string name="short_text151">B</string>
+ <string name="short_text152">B</string>
+ <string name="short_text153">B</string>
+ <string name="short_text154">B</string>
+ <string name="short_text155">B</string>
+ <string name="short_text156">B</string>
+ <string name="short_text157">B</string>
+ <string name="short_text158">B</string>
+ <string name="short_text159">B</string>
+ <string name="short_text160">B</string>
+ <string name="short_text161">B</string>
+ <string name="short_text162">B</string>
+ <string name="short_text163">B</string>
+ <string name="short_text164">B</string>
+ <string name="short_text165">B</string>
+ <string name="short_text166">B</string>
+ <string name="short_text167">B</string>
+ <string name="short_text168">B</string>
+ <string name="short_text169">B</string>
+ <string name="short_text170">B</string>
+ <string name="short_text171">B</string>
+ <string name="short_text172">B</string>
+ <string name="short_text173">B</string>
+ <string name="short_text174">B</string>
+ <string name="short_text175">B</string>
+ <string name="short_text176">B</string>
+ <string name="short_text177">B</string>
+ <string name="short_text178">B</string>
+ <string name="short_text179">B</string>
+ <string name="short_text180">B</string>
+ <string name="short_text181">B</string>
+ <string name="short_text182">B</string>
+ <string name="short_text183">B</string>
+ <string name="short_text184">B</string>
+ <string name="short_text185">B</string>
+ <string name="short_text186">B</string>
+ <string name="short_text187">B</string>
+ <string name="short_text188">B</string>
+ <string name="short_text189">B</string>
+ <string name="short_text190">B</string>
+ <string name="short_text191">B</string>
+ <string name="short_text192">B</string>
+ <string name="short_text193">B</string>
+ <string name="short_text194">B</string>
+ <string name="short_text195">B</string>
+ <string name="short_text196">B</string>
+ <string name="short_text197">B</string>
+ <string name="short_text198">B</string>
+ <string name="short_text199">B</string>
+ <string name="short_text200">B</string>
+ <string name="short_text201">B</string>
+ <string name="short_text202">B</string>
+ <string name="short_text203">B</string>
+ <string name="short_text204">B</string>
+ <string name="short_text205">B</string>
+ <string name="short_text206">B</string>
+ <string name="short_text207">B</string>
+ <string name="short_text208">B</string>
+ <string name="short_text209">B</string>
+ <string name="short_text210">B</string>
+ <string name="short_text211">B</string>
+ <string name="short_text212">B</string>
+ <string name="short_text213">B</string>
+ <string name="short_text214">B</string>
+ <string name="short_text215">B</string>
+ <string name="short_text216">B</string>
+ <string name="short_text217">B</string>
+ <string name="short_text218">B</string>
+ <string name="short_text219">B</string>
+ <string name="short_text220">B</string>
+ <string name="short_text221">B</string>
+ <string name="short_text222">B</string>
+ <string name="short_text223">B</string>
+ <string name="short_text224">B</string>
+ <string name="short_text225">B</string>
+ <string name="short_text226">B</string>
+ <string name="short_text227">B</string>
+ <string name="short_text228">B</string>
+ <string name="short_text229">B</string>
+ <string name="short_text230">B</string>
+ <string name="short_text231">B</string>
+ <string name="short_text232">B</string>
+ <string name="short_text233">B</string>
+ <string name="short_text234">B</string>
+ <string name="short_text235">B</string>
+ <string name="short_text236">B</string>
+ <string name="short_text237">B</string>
+ <string name="short_text238">B</string>
+ <string name="short_text239">B</string>
+ <string name="short_text240">B</string>
+ <string name="short_text241">B</string>
+ <string name="short_text242">B</string>
+ <string name="short_text243">B</string>
+ <string name="short_text244">B</string>
+ <string name="short_text245">B</string>
+ <string name="short_text246">B</string>
+ <string name="short_text247">B</string>
+ <string name="short_text248">B</string>
+ <string name="short_text249">B</string>
+ <string name="short_text250">B</string>
+ <string name="short_text251">B</string>
+ <string name="short_text252">B</string>
+ <string name="short_text253">B</string>
+ <string name="short_text254">B</string>
+ <string name="short_text255">B</string>
+</resources>
diff --git a/apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java b/apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java
new file mode 100644
index 0000000..fcb13a8
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2019 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 android.app;
+
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.content.om.OverlayManager;
+import android.os.UserHandle;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.perftests.utils.TestPackageInstaller;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+
+import com.android.perftests.core.R;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmarks for {@link android.content.om.OverlayManager}.
+ */
+@LargeTest
+public class OverlayManagerPerfTest {
+ private static final int OVERLAY_PKG_COUNT = 10;
+ private static Context sContext;
+ private static OverlayManager sOverlayManager;
+ private static Executor sExecutor;
+ private static ArrayList<TestPackageInstaller.InstalledPackage> sSmallOverlays =
+ new ArrayList<>();
+ private static ArrayList<TestPackageInstaller.InstalledPackage> sLargeOverlays =
+ new ArrayList<>();
+
+ @Rule
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @BeforeClass
+ public static void classSetUp() throws Exception {
+ sContext = InstrumentationRegistry.getTargetContext();
+ sOverlayManager = new OverlayManager(sContext);
+ sExecutor = (command) -> new Thread(command).start();
+
+ // Install all of the test overlays.
+ TestPackageInstaller installer = new TestPackageInstaller(sContext);
+ for (int i = 0; i < OVERLAY_PKG_COUNT; i++) {
+ sSmallOverlays.add(installer.installPackage("Overlay" + i +".apk"));
+ sLargeOverlays.add(installer.installPackage("LargeOverlay" + i +".apk"));
+ }
+ }
+
+ @AfterClass
+ public static void classTearDown() throws Exception {
+ for (TestPackageInstaller.InstalledPackage overlay : sSmallOverlays) {
+ overlay.uninstall();
+ }
+
+ for (TestPackageInstaller.InstalledPackage overlay : sLargeOverlays) {
+ overlay.uninstall();
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ // Disable all test overlays after each test.
+ for (TestPackageInstaller.InstalledPackage overlay : sSmallOverlays) {
+ assertSetEnabled(sContext, overlay.getPackageName(), false);
+ }
+
+ for (TestPackageInstaller.InstalledPackage overlay : sLargeOverlays) {
+ assertSetEnabled(sContext, overlay.getPackageName(), false);
+ }
+ }
+
+ /**
+ * Enables the overlay and waits for the APK path change sto be propagated to the context
+ * AssetManager.
+ */
+ private void assertSetEnabled(Context context, String overlayPackage, boolean eanabled)
+ throws Exception {
+ sOverlayManager.setEnabled(overlayPackage, true, UserHandle.SYSTEM);
+
+ // Wait for the overlay changes to propagate
+ FutureTask<Boolean> task = new FutureTask<>(() -> {
+ while (true) {
+ for (String path : context.getAssets().getApkPaths()) {
+ if (eanabled == path.contains(overlayPackage)) {
+ return true;
+ }
+ }
+ }
+ });
+
+ sExecutor.execute(task);
+ assertTrue("Failed to load overlay " + overlayPackage,
+ task.get(20, TimeUnit.SECONDS));
+ }
+
+ @Test
+ public void setEnabledWarmCache() throws Exception {
+ String packageName = sSmallOverlays.get(0).getPackageName();
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ assertSetEnabled(sContext, packageName, true);
+
+ // Disable the overlay for the next iteration of the test
+ state.pauseTiming();
+ assertSetEnabled(sContext, packageName, false);
+ state.resumeTiming();
+ }
+ }
+
+ @Test
+ public void setEnabledColdCacheSmallOverlay() throws Exception {
+ String packageName = sSmallOverlays.get(0).getPackageName();
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ assertSetEnabled(sContext, packageName, true);
+
+ // Disable the overlay and remove the idmap for the next iteration of the test
+ state.pauseTiming();
+ assertSetEnabled(sContext, packageName, false);
+ sOverlayManager.invalidateCachesForOverlay(packageName, UserHandle.SYSTEM);
+ state.resumeTiming();
+ }
+ }
+
+ @Test
+ public void setEnabledColdCacheLargeOverlay() throws Exception {
+ String packageName = sLargeOverlays.get(0).getPackageName();
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ assertSetEnabled(sContext, packageName, true);
+
+ // Disable the overlay and remove the idmap for the next iteration of the test
+ state.pauseTiming();
+ assertSetEnabled(sContext, packageName, false);
+ sOverlayManager.invalidateCachesForOverlay(packageName, UserHandle.SYSTEM);
+ state.resumeTiming();
+ }
+ }
+
+ @Test
+ public void setEnabledDisable() throws Exception {
+ String packageName = sSmallOverlays.get(0).getPackageName();
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ assertSetEnabled(sContext, packageName, true);
+ state.resumeTiming();
+
+ assertSetEnabled(sContext, packageName, false);
+ }
+ }
+
+ @Test
+ public void getStringOneSmallOverlay() throws Exception {
+ String packageName = sSmallOverlays.get(0).getPackageName();
+ assertSetEnabled(sContext, packageName, true);
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ sContext.getString(R.string.short_text);
+ }
+
+ assertSetEnabled(sContext, packageName, false);
+ }
+
+ @Test
+ public void getStringOneLargeOverlay() throws Exception {
+ String packageName = sLargeOverlays.get(0).getPackageName();
+ assertSetEnabled(sContext, packageName, true);
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int resId = R.string.short_text000; resId < R.string.short_text255; resId++) {
+ sContext.getString(resId);
+ }
+ }
+
+ assertSetEnabled(sContext, packageName, false);
+ }
+
+ @Test
+ public void getStringTenOverlays() throws Exception {
+ // Enable all test overlays
+ for (TestPackageInstaller.InstalledPackage overlay : sSmallOverlays) {
+ assertSetEnabled(sContext, overlay.getPackageName(), true);
+ }
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ sContext.getString(R.string.short_text);
+ }
+ }
+
+ @Test
+ public void getStringLargeTenOverlays() throws Exception {
+ // Enable all test overlays
+ for (TestPackageInstaller.InstalledPackage overlay : sLargeOverlays) {
+ assertSetEnabled(sContext, overlay.getPackageName(), true);
+ }
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int resId = R.string.short_text000; resId < R.string.short_text255; resId++) {
+ sContext.getString(resId);
+ }
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java
new file mode 100644
index 0000000..2955d2c
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.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 android.app;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.view.Display;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Benchmarks for {@link android.app.ResourcesManager}.
+ */
+@LargeTest
+public class ResourcesManagerPerfTest {
+ private static Context sContext;
+ private static File sResourcesCompressed;
+ private static File sResourcesUncompressed;
+
+ @Rule
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ sContext = InstrumentationRegistry.getTargetContext();
+ sResourcesCompressed = copyApkToTemp("LargeResourcesCompressed.apk",
+ "LargeResourcesCompressed.apk");
+ sResourcesUncompressed = copyApkToTemp("LargeResourcesUncompressed.apk",
+ "LargeResourcesUncompressed.apk");
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ Assert.assertTrue(sResourcesCompressed.delete());
+ Assert.assertTrue(sResourcesUncompressed.delete());
+ }
+
+ private static File copyApkToTemp(String inputFileName, String fileName) throws Exception {
+ File file = File.createTempFile(fileName, null, sContext.getCacheDir());
+ try (OutputStream tempOutputStream = new FileOutputStream(file);
+ InputStream is = sContext.getResources().getAssets().openNonAsset(inputFileName)) {
+ byte[] buffer = new byte[4096];
+ int n;
+ while ((n = is.read(buffer)) >= 0) {
+ tempOutputStream.write(buffer, 0, n);
+ }
+ tempOutputStream.flush();
+ }
+ return file;
+ }
+
+ private void getResourcesForPath(String path) {
+ ResourcesManager.getInstance().getResources(null, path, null, null, null,
+ Display.DEFAULT_DISPLAY, null, sContext.getResources().getCompatibilityInfo(),
+ null);
+ }
+
+ @Test
+ public void getResourcesCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ getResourcesForPath(sResourcesCompressed.getPath());
+ while (state.keepRunning()) {
+ getResourcesForPath(sResourcesCompressed.getPath());
+ }
+ }
+
+ @Test
+ public void getResourcesCompressedUncached() {
+ ResourcesManager resourcesManager = ResourcesManager.getInstance();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ resourcesManager.invalidatePath(sResourcesCompressed.getPath());
+ state.resumeTiming();
+
+ getResourcesForPath(sResourcesCompressed.getPath());
+ }
+ }
+
+ @Test
+ public void getResourcesUncompressedUncached() {
+ ResourcesManager resourcesManager = ResourcesManager.getInstance();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ resourcesManager.invalidatePath(sResourcesUncompressed.getPath());
+ state.resumeTiming();
+
+ getResourcesForPath(sResourcesUncompressed.getPath());
+ }
+ }
+
+ @Test
+ public void applyConfigurationToResourcesLocked() {
+ ResourcesManager resourcesManager = ResourcesManager.getInstance();
+ Configuration c = new Configuration(resourcesManager.getConfiguration());
+ c.uiMode = Configuration.UI_MODE_TYPE_WATCH;
+
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ resourcesManager.applyConfigurationToResources(c, null);
+
+ // Alternate configurations to ensure the set configuration is different each iteration
+ if (c.uiMode == Configuration.UI_MODE_TYPE_WATCH) {
+ c.uiMode = Configuration.UI_MODE_TYPE_TELEVISION;
+ } else {
+ c.uiMode = Configuration.UI_MODE_TYPE_WATCH;
+ }
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java
index c3e43ee..7216244 100644
--- a/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java
+++ b/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java
@@ -18,15 +18,18 @@
import static org.junit.Assert.fail;
-import android.content.res.AssetManager;
+import android.content.Context;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
+import android.util.TypedValue;
+import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
-import org.junit.After;
+import com.android.perftests.core.R;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -43,36 +46,123 @@
@Rule
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
- private AssetManager mAsset;
private Resources mRes;
- private int mTextId;
- private int mColorId;
- private int mIntegerId;
- private int mLayoutId;
-
@Before
public void setUp() {
- mAsset = new AssetManager();
- mAsset.addAssetPath("/system/framework/framework-res.apk");
- mRes = new Resources(mAsset, null, null);
-
- mTextId = mRes.getIdentifier("cancel", "string", "android");
- mColorId = mRes.getIdentifier("transparent", "color", "android");
- mIntegerId = mRes.getIdentifier("config_shortAnimTime", "integer", "android");
- mLayoutId = mRes.getIdentifier("two_line_list_item", "layout", "android");
+ Context context = InstrumentationRegistry.getTargetContext();
+ mRes = context.getResources();
}
- @After
- public void tearDown() {
- mAsset.close();
+ @Test
+ public void getValue() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ TypedValue value = new TypedValue();
+ while (state.keepRunning()) {
+ mRes.getValue(R.integer.forty_two, value, false /* resolve_refs */);
+ }
+ }
+
+ @Test
+ public void getFrameworkValue() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ TypedValue value = new TypedValue();
+ while (state.keepRunning()) {
+ mRes.getValue(com.android.internal.R.integer.autofill_max_visible_datasets, value,
+ false /* resolve_refs */);
+ }
+ }
+
+ @Test
+ public void getValueString() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ TypedValue value = new TypedValue();
+ while (state.keepRunning()) {
+ mRes.getValue(R.string.long_text, value, false /* resolve_refs */);
+ }
+ }
+
+ @Test
+ public void getFrameworkStringValue() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ TypedValue value = new TypedValue();
+ while (state.keepRunning()) {
+ mRes.getValue(com.android.internal.R.string.cancel, value, false /* resolve_refs */);
+ }
+ }
+
+ @Test
+ public void getValueManyConfigurations() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ TypedValue value = new TypedValue();
+ while (state.keepRunning()) {
+ mRes.getValue(com.android.internal.R.string.mmcc_illegal_me, value,
+ false /* resolve_refs */);
+ }
}
@Test
public void getText() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- mRes.getText(mTextId);
+ mRes.getText(R.string.long_text);
+ }
+ }
+
+
+ @Test
+ public void getFont() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getFont(R.font.samplefont);
+ }
+ }
+
+ @Test
+ public void getString() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getString(R.string.long_text);
+ }
+ }
+
+ @Test
+ public void getQuantityString() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getQuantityString(R.plurals.plurals_text, 5);
+ }
+ }
+
+ @Test
+ public void getQuantityText() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getQuantityText(R.plurals.plurals_text, 5);
+ }
+ }
+
+ @Test
+ public void getTextArray() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getTextArray(R.array.strings);
+ }
+ }
+
+ @Test
+ public void getStringArray() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getStringArray(R.array.strings);
+ }
+ }
+
+ @Test
+ public void getIntegerArray() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getIntArray(R.array.ints);
}
}
@@ -80,15 +170,23 @@
public void getColor() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- mRes.getColor(mColorId, null);
+ mRes.getColor(R.color.white, null);
}
}
@Test
- public void getInteger() {
+ public void getColorStateList() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- mRes.getInteger(mIntegerId);
+ mRes.getColorStateList(R.color.color_state_list, null);
+ }
+ }
+
+ @Test
+ public void getVectorDrawable() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getDrawable(R.drawable.vector_drawable01, null);
}
}
@@ -96,7 +194,7 @@
public void getLayoutAndTravese() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- try (XmlResourceParser parser = mRes.getLayout(mLayoutId)) {
+ try (XmlResourceParser parser = mRes.getLayout(R.layout.test_relative_layout)) {
while (parser.next() != XmlPullParser.END_DOCUMENT) {
// Walk the entire tree
}
@@ -105,4 +203,23 @@
}
}
}
-}
+
+ @Test
+ public void getLayoutAndTraverseInvalidateCaches() {
+ mRes.flushLayoutCache();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ try (XmlResourceParser parser = mRes.getLayout(R.layout.test_relative_layout)) {
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ // Walk the entire tree
+ }
+ } catch (IOException | XmlPullParserException exception) {
+ fail("Parsing of the layout failed. Something is really broken");
+ }
+
+ state.pauseTiming();
+ mRes.flushLayoutCache();
+ state.resumeTiming();
+ }
+ }
+}
\ No newline at end of file
diff --git a/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
index 1b07572..6123e69 100644
--- a/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
+++ b/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
@@ -16,13 +16,19 @@
package android.app;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
import android.content.res.Resources;
+import android.os.UserHandle;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
+import android.view.Display;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -35,13 +41,69 @@
@Rule
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+ private Context mContext;
+ private int mThemeResId;
private Resources.Theme mTheme;
@Before
- public void setUp() {
- Context context = InstrumentationRegistry.getTargetContext();
- mTheme = context.getTheme();
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getTargetContext();
+ mThemeResId = com.android.perftests.core.R.style.Base_V7_Theme_AppCompat;
+ mTheme = mContext.getResources().newTheme();
+ mTheme.applyStyle(mThemeResId, true /* force */);
+ }
+ @Test
+ public void applyStyle() {
+ Resources.Theme destTheme = mContext.getResources().newTheme();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ destTheme.applyStyle(mThemeResId, true /* force */);
+ }
+ }
+
+ @Test
+ public void rebase() {
+ Resources.Theme destTheme = mContext.getResources().newTheme();
+ destTheme.applyStyle(mThemeResId, true /* force */);
+ destTheme.applyStyle(android.R.style.Theme_Material, true /* force */);
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ destTheme.rebase();
+ }
+ }
+
+ @Test
+ public void setToSameAssetManager() {
+ Resources.Theme destTheme = mContext.getResources().newTheme();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ destTheme.setTo(mTheme);
+ }
+ }
+
+ @Test
+ public void setToDifferentAssetManager() throws Exception {
+ // Create a new Resources object with the same asset paths but a different AssetManager
+ PackageManager packageManager = mContext.getApplicationContext().getPackageManager();
+ ApplicationInfo ai = packageManager.getApplicationInfo(mContext.getPackageName(),
+ UserHandle.myUserId());
+
+ ResourcesManager resourcesManager = ResourcesManager.getInstance();
+ Configuration c = resourcesManager.getConfiguration();
+ c.orientation = (c.orientation == Configuration.ORIENTATION_PORTRAIT)
+ ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
+
+ Resources destResources = resourcesManager.getResources(null, ai.sourceDir,
+ ai.splitSourceDirs, ai.resourceDirs, ai.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
+ c, mContext.getResources().getCompatibilityInfo(), null);
+ Assert.assertNotEquals(destResources.getAssets(), mContext.getAssets());
+
+ Resources.Theme destTheme = destResources.newTheme();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ destTheme.setTo(mTheme);
+ }
}
@Test
@@ -51,5 +113,4 @@
mTheme.obtainStyledAttributes(android.R.style.Theme_Material, android.R.styleable.View);
}
}
-
-}
+}
\ No newline at end of file
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/TestPackageInstaller.java b/apct-tests/perftests/utils/src/android/perftests/utils/TestPackageInstaller.java
new file mode 100644
index 0000000..a433d80
--- /dev/null
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/TestPackageInstaller.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2019 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 android.perftests.utils;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.PackageInstaller;
+import android.content.res.Resources;
+import android.util.Log;
+
+import org.junit.Assert;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Installs packages included within the assets directory.
+ */
+public class TestPackageInstaller {
+ private static final String LOG_TAG = "TestPackageInstaller";
+ private static final String BROADCAST_ACTION =
+ "com.android.perftests.core.ACTION_INSTALL_COMMIT";
+
+ private final Context mContext;
+ public TestPackageInstaller(Context context) {
+ mContext = context;
+ }
+
+
+
+ /**
+ * Installs an APK located at the specified path in the assets directory.
+ **/
+ public InstalledPackage installPackage(String resourceName) throws IOException,
+ InterruptedException {
+ Log.d(LOG_TAG, "Installing resource APK '" + resourceName + "'");
+ LocalBroadcastReceiver intentSender = new LocalBroadcastReceiver(mContext);
+
+ // Initialize the package install session.
+ PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
+ PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
+ PackageInstaller.SessionParams.MODE_FULL_INSTALL);
+ params.setInstallAsInstantApp(false);
+ int sessionId = packageInstaller.createSession(params);
+ PackageInstaller.Session session = packageInstaller.openSession(sessionId);
+
+ // Copy the apk to the install session.
+ try (OutputStream os = session.openWrite("TestPackageInstaller", 0, -1);
+ InputStream is = mContext.getResources().getAssets().openNonAsset(resourceName)) {
+ if (is == null) {
+ throw new IOException("Resource " + resourceName + " not found");
+ }
+ byte[] buffer = new byte[4096];
+ int n;
+ while ((n = is.read(buffer)) >= 0) {
+ os.write(buffer, 0, n);
+ }
+ }
+
+ session.commit(intentSender.getIntentSender(sessionId));
+ session.close();
+
+ // Retrieve the results of the installation.
+ Intent intent = intentSender.getIntentSenderResult();
+ int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS,
+ PackageInstaller.STATUS_FAILURE);
+ Assert.assertEquals(PackageInstaller.STATUS_SUCCESS, status);
+ String packageName = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME);
+ return new InstalledPackage(sessionId, packageName);
+ }
+
+ public class InstalledPackage {
+ private int mSessionId;
+ private String mPackageName;
+
+ private InstalledPackage(int sessionId, String packageName) {
+ mSessionId = sessionId;
+ mPackageName = packageName;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public void uninstall() throws Exception {
+ Log.d(LOG_TAG, "Uninstalling package '" + mPackageName + "'");
+ LocalBroadcastReceiver intentSender = new LocalBroadcastReceiver(mContext);
+ PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
+ packageInstaller.uninstall(mPackageName, intentSender.getIntentSender(mSessionId));
+ int status = intentSender.getIntentSenderResult()
+ .getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE);
+ Assert.assertEquals(PackageInstaller.STATUS_SUCCESS, status);
+ }
+ }
+
+ private class LocalBroadcastReceiver extends BroadcastReceiver {
+ private final BlockingQueue<Intent> mIntentSenderResults = new LinkedBlockingQueue<>();
+ private final Context mContext;
+
+ private LocalBroadcastReceiver(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mIntentSenderResults.add(intent);
+ }
+
+ IntentSender getIntentSender(int sessionId) {
+ String action = BROADCAST_ACTION + "." + sessionId;
+ IntentFilter filter = new IntentFilter(action);
+ mContext.registerReceiver(this, filter);
+
+ Intent intent = new Intent(action);
+ PendingIntent pending = PendingIntent.getBroadcast(mContext, sessionId, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ return pending.getIntentSender();
+ }
+
+ Intent getIntentSenderResult() throws InterruptedException {
+ return mIntentSenderResults.take();
+ }
+ }
+}
diff --git a/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
index a807eb1..5b14056 100644
--- a/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
+++ b/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
@@ -36,7 +36,7 @@
SystemServiceRegistry.registerCachedService(
Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class,
(context, b) -> new DeviceIdleManager(
- context.getOuterContext(), IDeviceIdleController.Stub.asInterface(b)));
+ context, IDeviceIdleController.Stub.asInterface(b)));
PowerManager.setIsIgnoringBatteryOptimizationsCallback((packageName) -> {
// No need for synchronization on sIDeviceIdleController; worst case
// we just initialize it twice.
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
new file mode 100644
index 0000000..3cfb080
--- /dev/null
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
@@ -0,0 +1,112 @@
+package com.android.server.usage;
+
+import android.app.usage.AppStandbyInfo;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManager.StandbyBuckets;
+import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
+import android.content.Context;
+import android.os.Looper;
+
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.Set;
+
+public interface AppStandbyInternal {
+ /**
+ * TODO AppStandbyController should probably be a binder service, and then we shouldn't need
+ * this method.
+ */
+ static AppStandbyInternal newAppStandbyController(ClassLoader loader, Context context,
+ Looper looper) {
+ try {
+ final Class<?> clazz = Class.forName("com.android.server.usage.AppStandbyController",
+ true, loader);
+ final Constructor<?> ctor = clazz.getConstructor(Context.class, Looper.class);
+ return (AppStandbyInternal) ctor.newInstance(context, looper);
+ } catch (NoSuchMethodException | InstantiationException
+ | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
+ throw new RuntimeException("Unable to instantiate AppStandbyController!", e);
+ }
+ }
+
+ void onBootPhase(int phase);
+
+ boolean isParoledOrCharging();
+
+ void postCheckIdleStates(int userId);
+
+ /**
+ * We send a different message to check idle states once, otherwise we would end up
+ * scheduling a series of repeating checkIdleStates each time we fired off one.
+ */
+ void postOneTimeCheckIdleStates();
+
+ void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId);
+
+ void setLastJobRunTime(String packageName, int userId, long elapsedRealtime);
+
+ long getTimeSinceLastJobRun(String packageName, int userId);
+
+ void onUserRemoved(int userId);
+
+ void addListener(AppIdleStateChangeListener listener);
+
+ void removeListener(AppIdleStateChangeListener listener);
+
+ int getAppId(String packageName);
+
+ boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime,
+ boolean shouldObfuscateInstantApps);
+
+ /**
+ * Checks if an app has been idle for a while and filters out apps that are excluded.
+ * It returns false if the current system state allows all apps to be considered active.
+ * This happens if the device is plugged in or temporarily allowed to make exceptions.
+ * Called by interface impls.
+ */
+ boolean isAppIdleFiltered(String packageName, int appId, int userId,
+ long elapsedRealtime);
+
+ int[] getIdleUidsForUser(int userId);
+
+ void setAppIdleAsync(String packageName, boolean idle, int userId);
+
+ @StandbyBuckets
+ int getAppStandbyBucket(String packageName, int userId,
+ long elapsedRealtime, boolean shouldObfuscateInstantApps);
+
+ List<AppStandbyInfo> getAppStandbyBuckets(int userId);
+
+ void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
+ int reason, long elapsedRealtime, boolean resetTimeout);
+
+ void addActiveDeviceAdmin(String adminPkg, int userId);
+
+ void setActiveAdminApps(Set<String> adminPkgs, int userId);
+
+ void onAdminDataAvailable();
+
+ void clearCarrierPrivilegedApps();
+
+ void flushToDisk(int userId);
+
+ void flushDurationsToDisk();
+
+ void initializeDefaultsForSystemApps(int userId);
+
+ void postReportContentProviderUsage(String name, String packageName, int userId);
+
+ void postReportSyncScheduled(String packageName, int userId, boolean exempted);
+
+ void postReportExemptedSyncStart(String packageName, int userId);
+
+ void dumpUser(IndentingPrintWriter idpw, int userId, String pkg);
+
+ void dumpState(String[] args, PrintWriter pw);
+
+ boolean isAppIdleEnabled();
+}
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
similarity index 100%
rename from services/usage/java/com/android/server/usage/AppIdleHistory.java
rename to apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
similarity index 95%
rename from services/usage/java/com/android/server/usage/AppStandbyController.java
rename to apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 75e8fb5..df5d6ae 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -120,9 +120,9 @@
* Manages the standby state of an app, listening to various events.
*
* Unit test:
- atest ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+ atest com.android.server.usage.AppStandbyControllerTests
*/
-public class AppStandbyController {
+public class AppStandbyController implements AppStandbyInternal {
private static final String TAG = "AppStandbyController";
static final boolean DEBUG = false;
@@ -247,7 +247,7 @@
/** The length of time phone must be charging before considered stable enough to run jobs */
long mStableChargingThresholdMillis;
- volatile boolean mAppIdleEnabled;
+ private volatile boolean mAppIdleEnabled;
boolean mAppIdleTempParoled;
boolean mCharging;
boolean mChargingStable;
@@ -320,7 +320,7 @@
}
}
- AppStandbyController(Context context, Looper looper) {
+ public AppStandbyController(Context context, Looper looper) {
this(new Injector(context, looper));
}
@@ -351,6 +351,7 @@
null, mHandler);
}
+ @VisibleForTesting
void setAppIdleEnabled(boolean enabled) {
synchronized (mAppIdleLock) {
if (mAppIdleEnabled != enabled) {
@@ -363,6 +364,12 @@
}
}
+ @Override
+ public boolean isAppIdleEnabled() {
+ return mAppIdleEnabled;
+ }
+
+ @Override
public void onBootPhase(int phase) {
mInjector.onBootPhase(phase);
if (phase == PHASE_SYSTEM_SERVICES_READY) {
@@ -400,7 +407,7 @@
}
}
- void reportContentProviderUsage(String authority, String providerPkgName, int userId) {
+ private void reportContentProviderUsage(String authority, String providerPkgName, int userId) {
if (!mAppIdleEnabled) return;
// Get sync adapters for the authority
@@ -432,7 +439,7 @@
}
}
- void reportExemptedSyncScheduled(String packageName, int userId) {
+ private void reportExemptedSyncScheduled(String packageName, int userId) {
if (!mAppIdleEnabled) return;
final int bucketToPromote;
@@ -463,7 +470,7 @@
}
}
- void reportUnexemptedSyncScheduled(String packageName, int userId) {
+ private void reportUnexemptedSyncScheduled(String packageName, int userId) {
if (!mAppIdleEnabled) return;
final long elapsedRealtime = mInjector.elapsedRealtime();
@@ -482,7 +489,7 @@
}
}
- void reportExemptedSyncStart(String packageName, int userId) {
+ private void reportExemptedSyncStart(String packageName, int userId) {
if (!mAppIdleEnabled) return;
final long elapsedRealtime = mInjector.elapsedRealtime();
@@ -497,6 +504,7 @@
}
}
+ @VisibleForTesting
void setChargingState(boolean charging) {
synchronized (mAppIdleLock) {
if (mCharging != charging) {
@@ -517,7 +525,7 @@
}
}
- void updateChargingStableState() {
+ private void updateChargingStableState() {
synchronized (mAppIdleLock) {
if (mChargingStable != mCharging) {
if (DEBUG) Slog.d(TAG, "Setting mChargingStable to " + mCharging);
@@ -527,8 +535,7 @@
}
}
- /** Paroled here means temporary pardon from being inactive */
- void setAppIdleParoled(boolean paroled) {
+ private void setAppIdleParoled(boolean paroled) {
synchronized (mAppIdleLock) {
final long now = mInjector.currentTimeMillis();
if (mAppIdleTempParoled != paroled) {
@@ -545,7 +552,8 @@
}
}
- boolean isParoledOrCharging() {
+ @Override
+ public boolean isParoledOrCharging() {
if (!mAppIdleEnabled) return true;
synchronized (mAppIdleLock) {
// Only consider stable charging when determining charge state.
@@ -583,15 +591,13 @@
mHandler.sendEmptyMessage(MSG_PAROLE_STATE_CHANGED);
}
- void postCheckIdleStates(int userId) {
+ @Override
+ public void postCheckIdleStates(int userId) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0));
}
- /**
- * We send a different message to check idle states once, otherwise we would end up
- * scheduling a series of repeating checkIdleStates each time we fired off one.
- */
- void postOneTimeCheckIdleStates() {
+ @Override
+ public void postOneTimeCheckIdleStates() {
if (mInjector.getBootPhase() < PHASE_SYSTEM_SERVICES_READY) {
// Not booted yet; wait for it!
mPendingOneTimeCheckIdleStates = true;
@@ -601,10 +607,7 @@
}
}
- /**
- * Check all running users' or specified user's apps to see if they enter an idle state.
- * @return Returns whether checking should continue periodically.
- */
+ @VisibleForTesting
boolean checkIdleStates(int checkUserId) {
if (!mAppIdleEnabled) {
return false;
@@ -776,19 +779,15 @@
* @return the bucket for the app, based on time since last used
*/
@GuardedBy("mAppIdleLock")
- @StandbyBuckets int getBucketForLocked(String packageName, int userId,
+ @StandbyBuckets
+ private int getBucketForLocked(String packageName, int userId,
long elapsedRealtime) {
int bucketIndex = mAppIdleHistory.getThresholdIndex(packageName, userId,
elapsedRealtime, mAppStandbyScreenThresholds, mAppStandbyElapsedThresholds);
return THRESHOLD_BUCKETS[bucketIndex];
}
- /**
- * Check if it's been a while since last parole and let idle apps do some work.
- * If network is not available, delay parole until it is available up until the end of the
- * parole window. Force the parole to be set if end of the parole window is reached.
- */
- void checkParoleTimeout() {
+ private void checkParoleTimeout() {
boolean setParoled = false;
boolean waitForNetwork = false;
NetworkInfo activeNetwork = mConnectivityManager.getActiveNetworkInfo();
@@ -845,7 +844,7 @@
}
}
- void onDeviceIdleModeChanged() {
+ private void onDeviceIdleModeChanged() {
final boolean deviceIdle = mPowerManager.isDeviceIdleMode();
if (DEBUG) Slog.i(TAG, "DeviceIdleMode changed to " + deviceIdle);
boolean paroled = false;
@@ -869,7 +868,8 @@
setAppIdleParoled(paroled);
}
- void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId) {
+ @Override
+ public void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId) {
if (!mAppIdleEnabled) return;
synchronized (mAppIdleLock) {
// TODO: Ideally this should call isAppIdleFiltered() to avoid calling back
@@ -950,14 +950,7 @@
}
}
- /**
- * Forces the app's beginIdleTime and lastUsedTime to reflect idle or active. If idle,
- * then it rolls back the beginIdleTime and lastUsedTime to a point in time that's behind
- * the threshold for idle.
- *
- * This method is always called from the handler thread, so not much synchronization is
- * required.
- */
+ @VisibleForTesting
void forceIdleState(String packageName, int userId, boolean idle) {
if (!mAppIdleEnabled) return;
@@ -983,12 +976,14 @@
}
}
+ @Override
public void setLastJobRunTime(String packageName, int userId, long elapsedRealtime) {
synchronized (mAppIdleLock) {
mAppIdleHistory.setLastJobRunTime(packageName, userId, elapsedRealtime);
}
}
+ @Override
public long getTimeSinceLastJobRun(String packageName, int userId) {
final long elapsedRealtime = mInjector.elapsedRealtime();
synchronized (mAppIdleLock) {
@@ -996,6 +991,7 @@
}
}
+ @Override
public void onUserRemoved(int userId) {
synchronized (mAppIdleLock) {
mAppIdleHistory.onUserRemoved(userId);
@@ -1011,7 +1007,8 @@
}
}
- void addListener(AppIdleStateChangeListener listener) {
+ @Override
+ public void addListener(AppIdleStateChangeListener listener) {
synchronized (mPackageAccessListeners) {
if (!mPackageAccessListeners.contains(listener)) {
mPackageAccessListeners.add(listener);
@@ -1019,13 +1016,15 @@
}
}
- void removeListener(AppIdleStateChangeListener listener) {
+ @Override
+ public void removeListener(AppIdleStateChangeListener listener) {
synchronized (mPackageAccessListeners) {
mPackageAccessListeners.remove(listener);
}
}
- int getAppId(String packageName) {
+ @Override
+ public int getAppId(String packageName) {
try {
ApplicationInfo ai = mPackageManager.getApplicationInfo(packageName,
PackageManager.MATCH_ANY_USER
@@ -1036,7 +1035,8 @@
}
}
- boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime,
+ @Override
+ public boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime,
boolean shouldObfuscateInstantApps) {
if (isParoledOrCharging()) {
return false;
@@ -1048,8 +1048,7 @@
return isAppIdleFiltered(packageName, getAppId(packageName), userId, elapsedRealtime);
}
- /** Returns true if this app should be whitelisted for some reason, to never go into standby */
- boolean isAppSpecial(String packageName, int appId, int userId) {
+ private boolean isAppSpecial(String packageName, int appId, int userId) {
if (packageName == null) return false;
// If not enabled at all, of course nobody is ever idle.
if (!mAppIdleEnabled) {
@@ -1102,13 +1101,8 @@
return false;
}
- /**
- * Checks if an app has been idle for a while and filters out apps that are excluded.
- * It returns false if the current system state allows all apps to be considered active.
- * This happens if the device is plugged in or temporarily allowed to make exceptions.
- * Called by interface impls.
- */
- boolean isAppIdleFiltered(String packageName, int appId, int userId,
+ @Override
+ public boolean isAppIdleFiltered(String packageName, int appId, int userId,
long elapsedRealtime) {
if (isAppSpecial(packageName, appId, userId)) {
return false;
@@ -1117,7 +1111,8 @@
}
}
- int[] getIdleUidsForUser(int userId) {
+ @Override
+ public int[] getIdleUidsForUser(int userId) {
if (!mAppIdleEnabled) {
return new int[0];
}
@@ -1181,13 +1176,15 @@
return res;
}
- void setAppIdleAsync(String packageName, boolean idle, int userId) {
+ @Override
+ public void setAppIdleAsync(String packageName, boolean idle, int userId) {
if (packageName == null || !mAppIdleEnabled) return;
mHandler.obtainMessage(MSG_FORCE_IDLE_STATE, userId, idle ? 1 : 0, packageName)
.sendToTarget();
}
+ @Override
@StandbyBuckets public int getAppStandbyBucket(String packageName, int userId,
long elapsedRealtime, boolean shouldObfuscateInstantApps) {
if (!mAppIdleEnabled || (shouldObfuscateInstantApps
@@ -1200,18 +1197,21 @@
}
}
+ @Override
public List<AppStandbyInfo> getAppStandbyBuckets(int userId) {
synchronized (mAppIdleLock) {
return mAppIdleHistory.getAppStandbyBuckets(userId, mAppIdleEnabled);
}
}
+ @VisibleForTesting
void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
int reason, long elapsedRealtime) {
setAppStandbyBucket(packageName, userId, newBucket, reason, elapsedRealtime, false);
}
- void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
+ @Override
+ public void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
int reason, long elapsedRealtime, boolean resetTimeout) {
synchronized (mAppIdleLock) {
// If the package is not installed, don't allow the bucket to be set.
@@ -1279,6 +1279,7 @@
}
}
+ @Override
public void addActiveDeviceAdmin(String adminPkg, int userId) {
synchronized (mActiveAdminApps) {
Set<String> adminPkgs = mActiveAdminApps.get(userId);
@@ -1290,6 +1291,7 @@
}
}
+ @Override
public void setActiveAdminApps(Set<String> adminPkgs, int userId) {
synchronized (mActiveAdminApps) {
if (adminPkgs == null) {
@@ -1300,6 +1302,7 @@
}
}
+ @Override
public void onAdminDataAvailable() {
mAdminDataAvailableLatch.countDown();
}
@@ -1314,6 +1317,7 @@
}
}
+ @VisibleForTesting
Set<String> getActiveAdminAppsForTest(int userId) {
synchronized (mActiveAdminApps) {
return mActiveAdminApps.get(userId);
@@ -1342,7 +1346,8 @@
}
}
- void clearCarrierPrivilegedApps() {
+ @Override
+ public void clearCarrierPrivilegedApps() {
if (DEBUG) {
Slog.i(TAG, "Clearing carrier privileged apps list");
}
@@ -1368,7 +1373,7 @@
return packageName != null && packageName.equals(activeScorer);
}
- void informListeners(String packageName, int userId, int bucket, int reason,
+ private void informListeners(String packageName, int userId, int bucket, int reason,
boolean userInteraction) {
final boolean idle = bucket >= STANDBY_BUCKET_RARE;
synchronized (mPackageAccessListeners) {
@@ -1381,7 +1386,7 @@
}
}
- void informParoleStateChanged() {
+ private void informParoleStateChanged() {
final boolean paroled = isParoledOrCharging();
synchronized (mPackageAccessListeners) {
for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
@@ -1390,13 +1395,15 @@
}
}
- void flushToDisk(int userId) {
+ @Override
+ public void flushToDisk(int userId) {
synchronized (mAppIdleLock) {
mAppIdleHistory.writeAppIdleTimes(userId);
}
}
- void flushDurationsToDisk() {
+ @Override
+ public void flushDurationsToDisk() {
// Persist elapsed and screen on time. If this fails for whatever reason, the apps will be
// considered not-idle, which is the safest outcome in such an event.
synchronized (mAppIdleLock) {
@@ -1404,10 +1411,11 @@
}
}
- boolean isDisplayOn() {
+ private boolean isDisplayOn() {
return mInjector.isDefaultDisplayOn();
}
+ @VisibleForTesting
void clearAppIdleForPackage(String packageName, int userId) {
synchronized (mAppIdleLock) {
mAppIdleHistory.clearUsage(packageName, userId);
@@ -1431,7 +1439,8 @@
}
}
- void initializeDefaultsForSystemApps(int userId) {
+ @Override
+ public void initializeDefaultsForSystemApps(int userId) {
if (!mSystemServicesReady) {
// Do it later, since SettingsProvider wasn't queried yet for app_standby_enabled
mPendingInitializeDefaults = true;
@@ -1461,7 +1470,8 @@
}
}
- void postReportContentProviderUsage(String name, String packageName, int userId) {
+ @Override
+ public void postReportContentProviderUsage(String name, String packageName, int userId) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = name;
args.arg2 = packageName;
@@ -1470,23 +1480,27 @@
.sendToTarget();
}
- void postReportSyncScheduled(String packageName, int userId, boolean exempted) {
+ @Override
+ public void postReportSyncScheduled(String packageName, int userId, boolean exempted) {
mHandler.obtainMessage(MSG_REPORT_SYNC_SCHEDULED, userId, exempted ? 1 : 0, packageName)
.sendToTarget();
}
- void postReportExemptedSyncStart(String packageName, int userId) {
+ @Override
+ public void postReportExemptedSyncStart(String packageName, int userId) {
mHandler.obtainMessage(MSG_REPORT_EXEMPTED_SYNC_START, userId, 0, packageName)
.sendToTarget();
}
- void dumpUser(IndentingPrintWriter idpw, int userId, String pkg) {
+ @Override
+ public void dumpUser(IndentingPrintWriter idpw, int userId, String pkg) {
synchronized (mAppIdleLock) {
mAppIdleHistory.dump(idpw, userId, pkg);
}
}
- void dumpState(String[] args, PrintWriter pw) {
+ @Override
+ public void dumpState(String[] args, PrintWriter pw) {
synchronized (mAppIdleLock) {
pw.println("Carrier privileged apps (have=" + mHaveCarrierPrivilegedApps
+ "): " + mCarrierPrivilegedApps);
diff --git a/apex/statsd/OWNERS b/apex/statsd/OWNERS
new file mode 100644
index 0000000..bed9600
--- /dev/null
+++ b/apex/statsd/OWNERS
@@ -0,0 +1,9 @@
+jeffreyhuang@google.com
+joeo@google.com
+jtnguyen@google.com
+muhammadq@google.com
+ruchirr@google.com
+singhtejinder@google.com
+tsaichristine@google.com
+yaochen@google.com
+yro@google.com
\ No newline at end of file
diff --git a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
index 1d3ac6a..1a10753 100644
--- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java
@@ -2079,9 +2079,6 @@
HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
TimeUnit.MILLISECONDS);
- StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.APP_OPS, elapsedNanos,
- wallClockNanos);
-
for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
final int uid = uidOps.getUid();
@@ -2089,6 +2086,9 @@
final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
final AppOpsManager.HistoricalOp op = packageOps.getOpAt(opIdx);
+ StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.APP_OPS,
+ elapsedNanos, wallClockNanos);
+
e.writeInt(uid);
e.writeString(packageOps.getPackageName());
e.writeInt(op.getOpCode());
diff --git a/api/current.txt b/api/current.txt
index 231495f..47cfe3c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8,7 +8,6 @@
public static final class Manifest.permission {
ctor public Manifest.permission();
field public static final String ACCEPT_HANDOVER = "android.permission.ACCEPT_HANDOVER";
- field public static final String ACCESSIBILITY_SHORTCUT_TARGET = "android.permission.ACCESSIBILITY_SHORTCUT_TARGET";
field public static final String ACCESS_BACKGROUND_LOCATION = "android.permission.ACCESS_BACKGROUND_LOCATION";
field public static final String ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES";
field public static final String ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION";
@@ -2834,6 +2833,7 @@
method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
method @NonNull public final android.accessibilityservice.AccessibilityService.SoftKeyboardController getSoftKeyboardController();
method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
+ method @NonNull public final android.util.SparseArray<java.util.List<android.view.accessibility.AccessibilityWindowInfo>> getWindowsOnAllDisplays();
method public abstract void onAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
method public final android.os.IBinder onBind(android.content.Intent);
method @Deprecated protected boolean onGesture(int);
@@ -6363,6 +6363,7 @@
method public android.view.WindowAnimationFrameStats getWindowAnimationFrameStats();
method public android.view.WindowContentFrameStats getWindowContentFrameStats(int);
method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
+ method @NonNull public android.util.SparseArray<java.util.List<android.view.accessibility.AccessibilityWindowInfo>> getWindowsOnAllDisplays();
method public void grantRuntimePermission(String, String);
method public void grantRuntimePermissionAsUser(String, String, android.os.UserHandle);
method public boolean injectInputEvent(android.view.InputEvent, boolean);
@@ -9678,6 +9679,7 @@
field public static final String QUERY_ARG_SORT_COLLATION = "android:query-arg-sort-collation";
field public static final String QUERY_ARG_SORT_COLUMNS = "android:query-arg-sort-columns";
field public static final String QUERY_ARG_SORT_DIRECTION = "android:query-arg-sort-direction";
+ field public static final String QUERY_ARG_SORT_LOCALE = "android:query-arg-sort-locale";
field public static final String QUERY_ARG_SQL_SELECTION = "android:query-arg-sql-selection";
field public static final String QUERY_ARG_SQL_SELECTION_ARGS = "android:query-arg-sql-selection-args";
field public static final String QUERY_ARG_SQL_SORT_ORDER = "android:query-arg-sql-sort-order";
@@ -10414,6 +10416,7 @@
field public static final String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND";
field @Deprecated public static final String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED";
field public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
+ field public static final String CATEGORY_ACCESSIBILITY_SHORTCUT_TARGET = "android.intent.category.ACCESSIBILITY_SHORTCUT_TARGET";
field public static final String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE";
field public static final String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER";
field public static final String CATEGORY_APP_CALCULATOR = "android.intent.category.APP_CALCULATOR";
@@ -11908,6 +11911,7 @@
field public static final int SIGNATURE_NO_MATCH = -3; // 0xfffffffd
field public static final int SIGNATURE_SECOND_NOT_SIGNED = -2; // 0xfffffffe
field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc
+ field public static final int SYNCHRONOUS = 2; // 0x2
field public static final int VERIFICATION_ALLOW = 1; // 0x1
field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff
@@ -23133,10 +23137,10 @@
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, @NonNull android.location.Criteria, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener);
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull String, long, float, @NonNull android.app.PendingIntent);
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, @NonNull android.location.Criteria, @NonNull android.app.PendingIntent);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.app.PendingIntent);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.app.PendingIntent);
+ method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.app.PendingIntent);
+ method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.app.PendingIntent);
method public boolean sendExtraCommand(@NonNull String, @NonNull String, @Nullable android.os.Bundle);
method public void setTestProviderEnabled(@NonNull String, boolean);
method public void setTestProviderLocation(@NonNull String, @NonNull android.location.Location);
@@ -23964,6 +23968,7 @@
ctor public ExifInterface(@NonNull String) throws java.io.IOException;
ctor public ExifInterface(@NonNull java.io.FileDescriptor) throws java.io.IOException;
ctor public ExifInterface(@NonNull java.io.InputStream) throws java.io.IOException;
+ method @NonNull public static android.media.ExifInterface fromStandalone(@NonNull java.io.InputStream) throws java.io.IOException;
method public double getAltitude(double);
method @Nullable public String getAttribute(@NonNull String);
method @Nullable public byte[] getAttributeBytes(@NonNull String);
@@ -40799,6 +40804,7 @@
field public static final String EXTRA_KEY_ALIAS = "android.security.extra.KEY_ALIAS";
field public static final String EXTRA_NAME = "name";
field public static final String EXTRA_PKCS12 = "PKCS12";
+ field public static final String KEY_ALIAS_SELECTION_DENIED = "alias-selection-denied-ef829e15-210a-409d-96c9-ee684fc41972";
}
public interface KeyChainAliasCallback {
@@ -43171,6 +43177,7 @@
field public static final String EXTRA_SILENT_RINGING_REQUESTED = "android.telecom.extra.SILENT_RINGING_REQUESTED";
field public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS = "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS";
field public static final int STATE_ACTIVE = 4; // 0x4
+ field public static final int STATE_AUDIO_PROCESSING = 12; // 0xc
field public static final int STATE_CONNECTING = 9; // 0x9
field public static final int STATE_DIALING = 1; // 0x1
field public static final int STATE_DISCONNECTED = 7; // 0x7
@@ -43180,6 +43187,7 @@
field public static final int STATE_PULLING_CALL = 11; // 0xb
field public static final int STATE_RINGING = 2; // 0x2
field public static final int STATE_SELECT_PHONE_ACCOUNT = 8; // 0x8
+ field public static final int STATE_SIMULATED_RINGING = 13; // 0xd
}
public abstract static class Call.Callback {
@@ -45175,6 +45183,7 @@
method public void updateAvailableNetworks(@NonNull java.util.List<android.telephony.AvailableNetworkInfo>, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
field public static final String ACTION_CARRIER_MESSAGING_CLIENT_SERVICE = "android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE";
field public static final String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
+ field public static final String ACTION_MULTI_SIM_CONFIG_CHANGED = "android.telephony.action.MULTI_SIM_CONFIG_CHANGED";
field public static final String ACTION_NETWORK_COUNTRY_CHANGED = "android.telephony.action.NETWORK_COUNTRY_CHANGED";
field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -45215,6 +45224,7 @@
field public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT";
field public static final String EXTRA_NETWORK_COUNTRY = "android.telephony.extra.NETWORK_COUNTRY";
field public static final String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT";
+ field public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED = "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED";
field public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telephony.extra.PHONE_ACCOUNT_HANDLE";
field public static final String EXTRA_SPECIFIC_CARRIER_ID = "android.telephony.extra.SPECIFIC_CARRIER_ID";
field public static final String EXTRA_SPECIFIC_CARRIER_NAME = "android.telephony.extra.SPECIFIC_CARRIER_NAME";
@@ -57407,7 +57417,7 @@
method public boolean onPrivateIMECommand(String, android.os.Bundle);
method public void onRestoreInstanceState(android.os.Parcelable);
method public android.os.Parcelable onSaveInstanceState();
- method protected void onSelectionChanged(int, int);
+ method @CallSuper protected void onSelectionChanged(int, int);
method protected void onTextChanged(CharSequence, int, int, int);
method public boolean onTextContextMenuItem(int);
method public void removeTextChangedListener(android.text.TextWatcher);
diff --git a/api/system-current.txt b/api/system-current.txt
index 7dfe90f..fc48845 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24,6 +24,7 @@
field public static final String BACKUP = "android.permission.BACKUP";
field public static final String BIND_ATTENTION_SERVICE = "android.permission.BIND_ATTENTION_SERVICE";
field public static final String BIND_AUGMENTED_AUTOFILL_SERVICE = "android.permission.BIND_AUGMENTED_AUTOFILL_SERVICE";
+ field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE";
field @Deprecated public static final String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final String BIND_CONTENT_CAPTURE_SERVICE = "android.permission.BIND_CONTENT_CAPTURE_SERVICE";
field public static final String BIND_CONTENT_SUGGESTIONS_SERVICE = "android.permission.BIND_CONTENT_SUGGESTIONS_SERVICE";
@@ -3431,9 +3432,9 @@
method public boolean isProviderEnabledForUser(@NonNull String, @NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public boolean isProviderPackage(@NonNull String);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean registerGnssBatchedLocationCallback(long, boolean, @NonNull android.location.BatchedLocationCallback, @Nullable android.os.Handler);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.app.PendingIntent);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackage(@Nullable String);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackageEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
@@ -5519,7 +5520,7 @@
public class UpdateEngine {
ctor public UpdateEngine();
method public void applyPayload(String, long, long, String[]);
- method public void applyPayload(@NonNull java.io.FileDescriptor, long, long, @NonNull String[]);
+ method public void applyPayload(@NonNull android.os.ParcelFileDescriptor, long, long, @NonNull String[]);
method public boolean bind(android.os.UpdateEngineCallback, android.os.Handler);
method public boolean bind(android.os.UpdateEngineCallback);
method public void cancel();
@@ -6361,6 +6362,7 @@
method public android.os.IBinder onBind(android.content.Intent);
method @Nullable public float[][] onCalculateScores(@NonNull java.util.List<android.view.autofill.AutofillValue>, @NonNull java.util.List<java.lang.String>, @NonNull java.util.List<java.lang.String>, @Nullable String, @Nullable android.os.Bundle, @Nullable java.util.Map, @Nullable java.util.Map);
method @Deprecated @Nullable public float[][] onGetScores(@Nullable String, @Nullable android.os.Bundle, @NonNull java.util.List<android.view.autofill.AutofillValue>, @NonNull java.util.List<java.lang.String>);
+ field public static final String REQUIRED_ALGORITHM_CREDIT_CARD = "CREDIT_CARD";
field public static final String REQUIRED_ALGORITHM_EDIT_DISTANCE = "EDIT_DISTANCE";
field public static final String REQUIRED_ALGORITHM_EXACT_MATCH = "EXACT_MATCH";
field public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillFieldClassificationService";
@@ -6967,6 +6969,8 @@
public final class Call {
method @Deprecated public void addListener(android.telecom.Call.Listener);
+ method public void enterBackgroundAudioProcessing();
+ method public void exitBackgroundAudioProcessing(boolean);
method @Deprecated public void removeListener(android.telecom.Call.Listener);
field @Deprecated public static final int STATE_PRE_DIAL_WAIT = 8; // 0x8
}
@@ -6975,6 +6979,10 @@
ctor @Deprecated public Call.Listener();
}
+ public static class CallScreeningService.CallResponse.Builder {
+ method public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallFurther(boolean);
+ }
+
public abstract class Conference extends android.telecom.Conferenceable {
method @Deprecated public final android.telecom.AudioState getAudioState();
method @Deprecated public final long getConnectTimeMillis();
@@ -7297,6 +7305,14 @@
method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int);
}
+ public abstract class CellBroadcastService extends android.app.Service {
+ ctor public CellBroadcastService();
+ method @CallSuper public android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onCdmaCellBroadcastSms(int, byte[]);
+ method public abstract void onGsmCellBroadcastSms(int, byte[]);
+ field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
+ }
+
public final class DataFailCause {
field public static final int ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219; // 0x8ab
field public static final int ACCESS_BLOCK = 2087; // 0x827
@@ -7869,8 +7885,8 @@
field public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 134217728; // 0x8000000
- field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_CALL_EMERGENCY_NUMBER = 268435456; // 0x10000000
- field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_SMS_EMERGENCY_NUMBER = 536870912; // 0x20000000
+ field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
+ field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
@@ -8239,7 +8255,7 @@
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping();
method public static long getMaxNumberVerificationTimeoutMillis();
- method @NonNull public String getNetworkCountryIso(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getNetworkCountryIso(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmask();
method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState();
method public int getSimApplicationState();
diff --git a/api/test-current.txt b/api/test-current.txt
index ee631be..70837a8 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5,6 +5,7 @@
field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS";
field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS";
+ field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE";
field public static final String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE";
field public static final String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE";
field public static final String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
@@ -1093,9 +1094,9 @@
method @NonNull public String[] getBackgroundThrottlingWhitelist();
method @NonNull public String[] getIgnoreSettingsWhitelist();
method @NonNull public java.util.List<android.location.LocationRequest> getTestProviderCurrentRequests(String);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.app.PendingIntent);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
}
@@ -2033,10 +2034,18 @@
public final class UserHandle implements android.os.Parcelable {
method public static int getAppId(int);
method public int getIdentifier();
+ method public static int getUid(int, int);
+ method public static int getUserId(int);
method public static boolean isApp(int);
+ method public static int myUserId();
+ method public static android.os.UserHandle of(int);
field @NonNull public static final android.os.UserHandle ALL;
field @NonNull public static final android.os.UserHandle CURRENT;
+ field public static final int MIN_SECONDARY_USER_ID = 10; // 0xa
field @NonNull public static final android.os.UserHandle SYSTEM;
+ field public static final int USER_ALL = -1; // 0xffffffff
+ field public static final int USER_NULL = -10000; // 0xffffd8f0
+ field public static final int USER_SYSTEM = 0; // 0x0
}
public class UserManager {
@@ -2404,7 +2413,6 @@
field public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS = "location_access_check_delay_millis";
field public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS = "location_access_check_interval_millis";
field public static final String NOTIFICATION_BADGING = "notification_badging";
- field @Deprecated public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
field @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds";
field public static final String USER_SETUP_COMPLETE = "user_setup_complete";
field public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
@@ -2481,6 +2489,7 @@
public abstract class AutofillFieldClassificationService extends android.app.Service {
ctor public AutofillFieldClassificationService();
method public android.os.IBinder onBind(android.content.Intent);
+ field public static final String REQUIRED_ALGORITHM_CREDIT_CARD = "CREDIT_CARD";
field public static final String REQUIRED_ALGORITHM_EDIT_DISTANCE = "EDIT_DISTANCE";
field public static final String REQUIRED_ALGORITHM_EXACT_MATCH = "EXACT_MATCH";
field public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillFieldClassificationService";
@@ -2771,10 +2780,19 @@
package android.telecom {
+ public final class Call {
+ method public void enterBackgroundAudioProcessing();
+ method public void exitBackgroundAudioProcessing(boolean);
+ }
+
public final class CallAudioState implements android.os.Parcelable {
ctor public CallAudioState(boolean, int, int, @Nullable android.bluetooth.BluetoothDevice, @NonNull java.util.Collection<android.bluetooth.BluetoothDevice>);
}
+ public static class CallScreeningService.CallResponse.Builder {
+ method public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallFurther(boolean);
+ }
+
public abstract class Conference extends android.telecom.Conferenceable {
method public android.telecom.Connection getPrimaryConnection();
}
@@ -2891,8 +2909,10 @@
}
public class PhoneStateListener {
- field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_CALL_EMERGENCY_NUMBER = 268435456; // 0x10000000
- field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_SMS_EMERGENCY_NUMBER = 536870912; // 0x20000000
+ method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+ method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
+ field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
+ field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
}
public class ServiceState implements android.os.Parcelable {
@@ -2919,7 +2939,7 @@
method public int checkCarrierPrivilegesForPackage(String);
method public int getCarrierIdListVersion();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag();
- method @NonNull public String getNetworkCountryIso(int);
+ method @NonNull @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNetworkCountryIso(int);
method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile();
method @Deprecated public void setCarrierTestOverride(String, String, String, String, String, String, String);
@@ -2933,6 +2953,14 @@
}
+package android.telephony.emergency {
+
+ public final class EmergencyNumber implements java.lang.Comparable<android.telephony.emergency.EmergencyNumber> android.os.Parcelable {
+ field public static final int EMERGENCY_NUMBER_SOURCE_TEST = 32; // 0x20
+ }
+
+}
+
package android.telephony.mbms {
public static class DownloadRequest.Builder {
@@ -3355,6 +3383,7 @@
public class WindowlessViewRoot {
ctor public WindowlessViewRoot(android.content.Context, android.view.Display, android.view.SurfaceControl);
method public void addView(android.view.View, android.view.WindowManager.LayoutParams);
+ method public void relayout(android.view.WindowManager.LayoutParams);
}
}
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index 053b7bc..d0530f2 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -178,6 +178,17 @@
continue;
}
+ // Note that conditional property enablement/exclusion only applies if
+ // the attribute is present. In its absence, all overlays are presumed enabled.
+ if (!overlay_info->requiredSystemPropertyName.empty()
+ && !overlay_info->requiredSystemPropertyValue.empty()) {
+ // if property set & equal to value, then include overlay - otherwise skip
+ if (android::base::GetProperty(overlay_info->requiredSystemPropertyName, "")
+ != overlay_info->requiredSystemPropertyValue) {
+ continue;
+ }
+ }
+
std::vector<std::string> fulfilled_policies;
if (!override_policies.empty()) {
fulfilled_policies = override_policies;
diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h
index 8797a78..9a0c2ab 100644
--- a/cmds/idmap2/include/idmap2/ResourceUtils.h
+++ b/cmds/idmap2/include/idmap2/ResourceUtils.h
@@ -30,6 +30,8 @@
struct OverlayManifestInfo {
std::string target_package; // NOLINT(misc-non-private-member-variables-in-classes)
std::string target_name; // NOLINT(misc-non-private-member-variables-in-classes)
+ std::string requiredSystemPropertyName; // NOLINT(misc-non-private-member-variables-in-classes)
+ std::string requiredSystemPropertyValue; // NOLINT(misc-non-private-member-variables-in-classes)
bool is_static; // NOLINT(misc-non-private-member-variables-in-classes)
int priority = -1; // NOLINT(misc-non-private-member-variables-in-classes)
};
diff --git a/cmds/idmap2/libidmap2/ResourceUtils.cpp b/cmds/idmap2/libidmap2/ResourceUtils.cpp
index 71ba3f0..dce83e3 100644
--- a/cmds/idmap2/libidmap2/ResourceUtils.cpp
+++ b/cmds/idmap2/libidmap2/ResourceUtils.cpp
@@ -103,6 +103,16 @@
info.priority = std::stoi(iter->second);
}
+ iter = tag->find("requiredSystemPropertyName");
+ if (iter != tag->end()) {
+ info.requiredSystemPropertyName = iter->second;
+ }
+
+ iter = tag->find("requiredSystemPropertyValue");
+ if (iter != tag->end()) {
+ info.requiredSystemPropertyValue = iter->second;
+ }
+
return info;
}
diff --git a/cmds/locksettings/TEST_MAPPING b/cmds/locksettings/TEST_MAPPING
index c1cba5f..56f5cc0 100644
--- a/cmds/locksettings/TEST_MAPPING
+++ b/cmds/locksettings/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit": [
+ "presubmit-devicepolicy": [
{
"name": "CtsDevicePolicyManagerTestCases",
"options": [
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index c79b0ca..cb27325 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -138,6 +138,7 @@
"libprotoutil",
"libservices",
"libstatslog",
+ "libstatssocket",
"libsysutils",
"libtimestats_proto",
"libutils",
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index f0db1b0..3d002d2 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -248,19 +248,6 @@
FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation);
- FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationCondition);
-
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition);
-
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondition);
- FRIEND_TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationCondition);
-
FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
diff --git a/cmds/statsd/src/external/GpuStatsPuller.cpp b/cmds/statsd/src/external/GpuStatsPuller.cpp
index bbdb540..d38b87f 100644
--- a/cmds/statsd/src/external/GpuStatsPuller.cpp
+++ b/cmds/statsd/src/external/GpuStatsPuller.cpp
@@ -92,9 +92,15 @@
android::util::GPU_STATS_APP_INFO, getWallClockNs(), getElapsedRealtimeNs());
if (!event->write(info.appPackageName)) return false;
if (!event->write((int64_t)info.driverVersionCode)) return false;
- if (!event->write(int64VectorToProtoByteString(info.glDriverLoadingTime))) return false;
- if (!event->write(int64VectorToProtoByteString(info.vkDriverLoadingTime))) return false;
- if (!event->write(int64VectorToProtoByteString(info.angleDriverLoadingTime))) return false;
+ if (!event->writeBytes(int64VectorToProtoByteString(info.glDriverLoadingTime))) {
+ return false;
+ }
+ if (!event->writeBytes(int64VectorToProtoByteString(info.vkDriverLoadingTime))) {
+ return false;
+ }
+ if (!event->writeBytes(int64VectorToProtoByteString(info.angleDriverLoadingTime))) {
+ return false;
+ }
if (!event->write(info.cpuVulkanInUse)) return false;
if (!event->write(info.falsePrerotation)) return false;
event->init();
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 0ade531..fd19c9d 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -332,6 +332,13 @@
return false;
}
+bool LogEvent::writeBytes(const string& value) {
+ if (mContext) {
+ return android_log_write_char_array(mContext, value.c_str(), value.length()) >= 0;
+ }
+ return false;
+}
+
bool LogEvent::writeKeyValuePairs(int32_t uid,
const std::map<int32_t, int32_t>& int_map,
const std::map<int32_t, int64_t>& long_map,
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 531ce29..f1f45a2 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -21,9 +21,9 @@
#include <android/frameworks/stats/1.0/types.h>
#include <android/os/StatsLogEventWrapper.h>
#include <android/util/ProtoOutputStream.h>
-#include <log/log_event_list.h>
#include <log/log_read.h>
#include <private/android_logger.h>
+#include <stats_event_list.h>
#include <utils/Errors.h>
#include <string>
@@ -157,6 +157,7 @@
bool write(float value);
bool write(const std::vector<AttributionNodeInternal>& nodes);
bool write(const AttributionNodeInternal& node);
+ bool writeBytes(const std::string& value);
bool writeKeyValuePairs(int32_t uid,
const std::map<int32_t, int32_t>& int_map,
const std::map<int32_t, int64_t>& long_map,
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 42132ee..7d446a9 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -53,6 +53,8 @@
if (gStatsService != nullptr) {
gStatsService->Terminate();
}
+ ALOGW("statsd terminated on receiving signal %d.", sig);
+ exit(1);
}
void registerSigHandler()
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index 504ee22..0743480 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -582,7 +582,7 @@
event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS);
event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW);
event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS);
- event1.write(extension_str);
+ event1.writeBytes(extension_str);
event1.init();
ProtoOutputStream proto;
@@ -621,7 +621,7 @@
event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS);
event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW);
event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS);
- event1.write(extension_str);
+ event1.writeBytes(extension_str);
event1.init();
ProtoOutputStream proto;
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index 76ee9a6..460b9e0 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -1199,87 +1199,66 @@
ConfigKey cfgKey1(uid, 12341);
long timeBase1 = 1;
- sp<StatsLogProcessor> processor =
+ sp<StatsLogProcessor> processor1 =
CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
// Metric 1 is not active.
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_EQ(1, processor->mMetricsManagers.size());
- auto it = processor->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor->mMetricsManagers.end());
+ EXPECT_EQ(1, processor1->mMetricsManagers.size());
+ auto it = processor1->mMetricsManagers.find(cfgKey1);
+ EXPECT_TRUE(it != processor1->mMetricsManagers.end());
auto& metricsManager1 = it->second;
EXPECT_TRUE(metricsManager1->isActive());
- auto metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer1 = *metricIt;
- EXPECT_FALSE(metricProducer1->isActive());
+ EXPECT_EQ(metricsManager1->mAllMetricProducers.size(), 2);
+ // We assume that the index of a MetricProducer within the mAllMetricProducers
+ // array follows the order in which metrics are added to the config.
+ auto& metricProducer1_1 = metricsManager1->mAllMetricProducers[0];
+ EXPECT_EQ(metricProducer1_1->getMetricId(), metricId1);
+ EXPECT_FALSE(metricProducer1_1->isActive()); // inactive due to associated MetricActivation
- metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer2 = *metricIt;
- EXPECT_TRUE(metricProducer2->isActive());
+ auto& metricProducer1_2 = metricsManager1->mAllMetricProducers[1];
+ EXPECT_EQ(metricProducer1_2->getMetricId(), metricId2);
+ EXPECT_TRUE(metricProducer1_2->isActive());
- int i = 0;
- for (; i < metricsManager1->mAllAtomMatchers.size(); i++) {
- if (metricsManager1->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation1 = metricProducer1->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kNotActive, activation1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1->activationType);
+ EXPECT_EQ(metricProducer1_1->mEventActivationMap.size(), 2);
+ // The key in mEventActivationMap is the index of the associated atom matcher. We assume
+ // that matchers are indexed in the order that they are added to the config.
+ const auto& activation1_1_1 = metricProducer1_1->mEventActivationMap.at(0);
+ EXPECT_EQ(100 * NS_PER_SEC, activation1_1_1->ttl_ns);
+ EXPECT_EQ(0, activation1_1_1->start_ns);
+ EXPECT_EQ(kNotActive, activation1_1_1->state);
+ EXPECT_EQ(ACTIVATE_ON_BOOT, activation1_1_1->activationType);
- i = 0;
- for (; i < metricsManager1->mAllAtomMatchers.size(); i++) {
- if (metricsManager1->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation2 = metricProducer1->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2->activationType);
+ const auto& activation1_1_2 = metricProducer1_1->mEventActivationMap.at(1);
+ EXPECT_EQ(200 * NS_PER_SEC, activation1_1_2->ttl_ns);
+ EXPECT_EQ(0, activation1_1_2->start_ns);
+ EXPECT_EQ(kNotActive, activation1_1_2->state);
+ EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1_1_2->activationType);
// }}}------------------------------------------------------------------------------
// Trigger Activation 1 for Metric 1
std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")};
auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 100 + timeBase1);
- processor->OnLogEvent(event.get());
+ processor1->OnLogEvent(event.get());
// Metric 1 is not active; Activation 1 set to kActiveOnBoot
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_FALSE(metricProducer1->isActive());
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1->state);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
+ EXPECT_FALSE(metricProducer1_1->isActive());
+ EXPECT_EQ(0, activation1_1_1->start_ns);
+ EXPECT_EQ(kActiveOnBoot, activation1_1_1->state);
+ EXPECT_EQ(0, activation1_1_2->start_ns);
+ EXPECT_EQ(kNotActive, activation1_1_2->state);
- EXPECT_TRUE(metricProducer2->isActive());
+ EXPECT_TRUE(metricProducer1_2->isActive());
// }}}-----------------------------------------------------------------------------
// Simulate shutdown by saving state to disk
int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
- processor->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_FALSE(metricProducer1->isActive());
- int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC;
+ processor1->SaveActiveConfigsToDisk(shutDownTime);
+ EXPECT_FALSE(metricProducer1_1->isActive());
// Simulate device restarted state by creating new instance of StatsLogProcessor with the
// same config.
@@ -1293,55 +1272,34 @@
EXPECT_EQ(1, processor2->mMetricsManagers.size());
it = processor2->mMetricsManagers.find(cfgKey1);
EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1001 = it->second;
- EXPECT_TRUE(metricsManager1001->isActive());
+ auto& metricsManager2 = it->second;
+ EXPECT_TRUE(metricsManager2->isActive());
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1001 = *metricIt;
- EXPECT_FALSE(metricProducer1001->isActive());
+ EXPECT_EQ(metricsManager2->mAllMetricProducers.size(), 2);
+ // We assume that the index of a MetricProducer within the mAllMetricProducers
+ // array follows the order in which metrics are added to the config.
+ auto& metricProducer2_1 = metricsManager2->mAllMetricProducers[0];
+ EXPECT_EQ(metricProducer2_1->getMetricId(), metricId1);
+ EXPECT_FALSE(metricProducer2_1->isActive());
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1002 = *metricIt;
- EXPECT_TRUE(metricProducer1002->isActive());
+ auto& metricProducer2_2 = metricsManager2->mAllMetricProducers[1];
+ EXPECT_EQ(metricProducer2_2->getMetricId(), metricId2);
+ EXPECT_TRUE(metricProducer2_2->isActive());
- i = 0;
- for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) {
- if (metricsManager1001->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation1001_1 = metricProducer1001->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activation1001_1->ttl_ns);
- EXPECT_EQ(0, activation1001_1->start_ns);
- EXPECT_EQ(kNotActive, activation1001_1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1001_1->activationType);
+ EXPECT_EQ(metricProducer2_1->mEventActivationMap.size(), 2);
+ // The key in mEventActivationMap is the index of the associated atom matcher. We assume
+ // that matchers are indexed in the order that they are added to the config.
+ const auto& activation2_1_1 = metricProducer2_1->mEventActivationMap.at(0);
+ EXPECT_EQ(100 * NS_PER_SEC, activation2_1_1->ttl_ns);
+ EXPECT_EQ(0, activation2_1_1->start_ns);
+ EXPECT_EQ(kNotActive, activation2_1_1->state);
+ EXPECT_EQ(ACTIVATE_ON_BOOT, activation2_1_1->activationType);
- i = 0;
- for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) {
- if (metricsManager1001->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
-
- const auto& activation1001_2 = metricProducer1001->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activation1001_2->ttl_ns);
- EXPECT_EQ(0, activation1001_2->start_ns);
- EXPECT_EQ(kNotActive, activation1001_2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1001_2->activationType);
+ const auto& activation2_1_2 = metricProducer2_1->mEventActivationMap.at(1);
+ EXPECT_EQ(200 * NS_PER_SEC, activation2_1_2->ttl_ns);
+ EXPECT_EQ(0, activation2_1_2->start_ns);
+ EXPECT_EQ(kNotActive, activation2_1_2->state);
+ EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2_1_2->activationType);
// }}}-----------------------------------------------------------------------------------
// Load saved state from disk.
@@ -1350,13 +1308,14 @@
// Metric 1 active; Activation 1 is active, Activation 2 is not active
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns);
- EXPECT_EQ(kActive, activation1001_1->state);
- EXPECT_EQ(0, activation1001_2->start_ns);
- EXPECT_EQ(kNotActive, activation1001_2->state);
+ EXPECT_TRUE(metricProducer2_1->isActive());
+ int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC;
+ EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns);
+ EXPECT_EQ(kActive, activation2_1_1->state);
+ EXPECT_EQ(0, activation2_1_2->start_ns);
+ EXPECT_EQ(kNotActive, activation2_1_2->state);
- EXPECT_TRUE(metricProducer1002->isActive());
+ EXPECT_TRUE(metricProducer2_2->isActive());
// }}}--------------------------------------------------------------------------------
// Trigger Activation 2 for Metric 1.
@@ -1369,23 +1328,23 @@
// Metric 1 active; Activation 1 is active, Activation 2 is active
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns);
- EXPECT_EQ(kActive, activation1001_1->state);
- EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation1001_2->start_ns);
- EXPECT_EQ(kActive, activation1001_2->state);
+ EXPECT_TRUE(metricProducer2_1->isActive());
+ EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns);
+ EXPECT_EQ(kActive, activation2_1_1->state);
+ EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation2_1_2->start_ns);
+ EXPECT_EQ(kActive, activation2_1_2->state);
- EXPECT_TRUE(metricProducer1002->isActive());
+ EXPECT_TRUE(metricProducer2_2->isActive());
// }}}---------------------------------------------------------------------------
// Simulate shutdown by saving state to disk
shutDownTime = timeBase2 + 50 * NS_PER_SEC;
processor2->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_TRUE(metricProducer1002->isActive());
- ttl1 = timeBase2 + metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC - shutDownTime;
- int64_t ttl2 = screenOnEvent->GetElapsedTimestampNs() +
- metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC - shutDownTime;
+ EXPECT_TRUE(metricProducer2_1->isActive());
+ EXPECT_TRUE(metricProducer2_2->isActive());
+ ttl1 -= shutDownTime - timeBase2;
+ int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC
+ - (shutDownTime - screenOnEvent->GetElapsedTimestampNs());
// Simulate device restarted state by creating new instance of StatsLogProcessor with the
// same config.
@@ -1399,55 +1358,34 @@
EXPECT_EQ(1, processor3->mMetricsManagers.size());
it = processor3->mMetricsManagers.find(cfgKey1);
EXPECT_TRUE(it != processor3->mMetricsManagers.end());
- auto& metricsManagerTimeBase3 = it->second;
- EXPECT_TRUE(metricsManagerTimeBase3->isActive());
+ auto& metricsManager3 = it->second;
+ EXPECT_TRUE(metricsManager3->isActive());
- metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end());
- auto& metricProducerTimeBase3_1 = *metricIt;
- EXPECT_FALSE(metricProducerTimeBase3_1->isActive());
+ EXPECT_EQ(metricsManager3->mAllMetricProducers.size(), 2);
+ // We assume that the index of a MetricProducer within the mAllMetricProducers
+ // array follows the order in which metrics are added to the config.
+ auto& metricProducer3_1 = metricsManager3->mAllMetricProducers[0];
+ EXPECT_EQ(metricProducer3_1->getMetricId(), metricId1);
+ EXPECT_FALSE(metricProducer3_1->isActive());
- metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end());
- auto& metricProducerTimeBase3_2 = *metricIt;
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
+ auto& metricProducer3_2 = metricsManager3->mAllMetricProducers[1];
+ EXPECT_EQ(metricProducer3_2->getMetricId(), metricId2);
+ EXPECT_TRUE(metricProducer3_2->isActive());
- i = 0;
- for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activationTimeBase3_1 = metricProducerTimeBase3_1->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase3_1->ttl_ns);
- EXPECT_EQ(0, activationTimeBase3_1->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase3_1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activationTimeBase3_1->activationType);
+ EXPECT_EQ(metricProducer3_1->mEventActivationMap.size(), 2);
+ // The key in mEventActivationMap is the index of the associated atom matcher. We assume
+ // that matchers are indexed in the order that they are added to the config.
+ const auto& activation3_1_1 = metricProducer3_1->mEventActivationMap.at(0);
+ EXPECT_EQ(100 * NS_PER_SEC, activation3_1_1->ttl_ns);
+ EXPECT_EQ(0, activation3_1_1->start_ns);
+ EXPECT_EQ(kNotActive, activation3_1_1->state);
+ EXPECT_EQ(ACTIVATE_ON_BOOT, activation3_1_1->activationType);
- i = 0;
- for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
-
- const auto& activationTimeBase3_2 = metricProducerTimeBase3_1->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase3_2->ttl_ns);
- EXPECT_EQ(0, activationTimeBase3_2->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase3_2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activationTimeBase3_2->activationType);
+ const auto& activation3_1_2 = metricProducer3_1->mEventActivationMap.at(1);
+ EXPECT_EQ(200 * NS_PER_SEC, activation3_1_2->ttl_ns);
+ EXPECT_EQ(0, activation3_1_2->start_ns);
+ EXPECT_EQ(kNotActive, activation3_1_2->state);
+ EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation3_1_2->activationType);
// }}}----------------------------------------------------------------------------------
// Load saved state from disk.
@@ -1456,13 +1394,13 @@
// Metric 1 active: Activation 1 is active, Activation 2 is active
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducerTimeBase3_1->isActive());
- EXPECT_EQ(timeBase3 + ttl1 - activationTimeBase3_1->ttl_ns, activationTimeBase3_1->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_1->state);
- EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_2->state);
+ EXPECT_TRUE(metricProducer3_1->isActive());
+ EXPECT_EQ(timeBase3 + ttl1 - activation3_1_1->ttl_ns, activation3_1_1->start_ns);
+ EXPECT_EQ(kActive, activation3_1_1->state);
+ EXPECT_EQ(timeBase3 + ttl2 - activation3_1_2->ttl_ns, activation3_1_2->start_ns);
+ EXPECT_EQ(kActive, activation3_1_2->state);
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
+ EXPECT_TRUE(metricProducer3_2->isActive());
// }}}-------------------------------------------------------------------------------
@@ -1473,15 +1411,16 @@
);
processor3->OnLogEvent(screenOnEvent.get());
- // Metric 1 active; Activation 1 is not active, Activation 2 is set to active
+ // Metric 1 active; Activation 1 is inactive (above screenOnEvent causes ttl1 to expire),
+ // Activation 2 is set to active
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducerTimeBase3_1->isActive());
- EXPECT_EQ(kNotActive, activationTimeBase3_1->state);
- EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activationTimeBase3_2->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_2->state);
+ EXPECT_TRUE(metricProducer3_1->isActive());
+ EXPECT_EQ(kNotActive, activation3_1_1->state);
+ EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation3_1_2->start_ns);
+ EXPECT_EQ(kActive, activation3_1_2->state);
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
+ EXPECT_TRUE(metricProducer3_2->isActive());
// }}}---------------------------------------------------------------------------
}
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index b37ee74..c9f069d 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -78,6 +78,8 @@
private static final String COMMAND_SET_SIM_COUNT = "set-sim-count";
private static final String COMMAND_GET_SIM_CONFIG = "get-sim-config";
private static final String COMMAND_GET_MAX_PHONES = "get-max-phones";
+ private static final String COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_FILTER =
+ "set-test-emergency-phone-account-package-filter";
private ComponentName mComponent;
private String mAccountId;
@@ -91,7 +93,10 @@
+ "usage: telecom set-phone-account-enabled <COMPONENT> <ID> <USER_SN>\n"
+ "usage: telecom set-phone-account-disabled <COMPONENT> <ID> <USER_SN>\n"
+ "usage: telecom register-phone-account <COMPONENT> <ID> <USER_SN> <LABEL>\n"
- + "usage: telecom set-user-selected-outgoing-phone-account <COMPONENT> <ID> "
+ + "usage: telecom register-sim-phone-account [-e] <COMPONENT> <ID> <USER_SN>"
+ + " <LABEL>: registers a PhoneAccount with CAPABILITY_SIM_SUBSCRIPTION"
+ + " and optionally CAPABILITY_PLACE_EMERGENCY_CALLS if \"-e\" is provided\n"
+ + "usage: telecom set-user-selected-outgoing-phone-account [-e] <COMPONENT> <ID> "
+ "<USER_SN>\n"
+ "usage: telecom set-test-call-redirection-app <PACKAGE>\n"
+ "usage: telecom set-test-call-screening-app <PACKAGE>\n"
@@ -108,6 +113,7 @@
+ "usage: telecom set-sim-count <COUNT>\n"
+ "usage: telecom get-sim-config\n"
+ "usage: telecom get-max-phones\n"
+ + "usage: telecom set-emer-phone-account-filter <PACKAGE>\n"
+ "\n"
+ "telecom set-phone-account-enabled: Enables the given phone account, if it has"
+ " already been registered with Telecom.\n"
@@ -121,6 +127,8 @@
+ "telecom get-default-dialer: Displays the current default dialer.\n"
+ "\n"
+ "telecom get-system-dialer: Displays the current system dialer.\n"
+ + "telecom set-system-dialer: Set the override system dialer to the given"
+ + " component. To remove the override, send \"default\"\n"
+ "\n"
+ "telecom wait-on-handlers: Wait until all handlers finish their work.\n"
+ "\n"
@@ -131,6 +139,10 @@
+ " or \"\" for single SIM\n"
+ "\n"
+ "telecom get-max-phones: Get the max supported phones from the modem.\n"
+ + "telecom set-test-emergency-phone-account-package-filter <PACKAGE>: sets a"
+ + " package name that will be used for test emergency calls. To clear,"
+ + " send an empty package name. Real emergency calls will still be placed"
+ + " over Telephony.\n"
);
}
@@ -219,6 +231,9 @@
case COMMAND_GET_MAX_PHONES:
runGetMaxPhones();
break;
+ case COMMAND_SET_TEST_EMERGENCY_PHONE_ACCOUNT_PACKAGE_FILTER:
+ runSetEmergencyPhoneAccountPackageFilter();
+ break;
default:
Log.w(this, "onRun: unknown command: %s", command);
throw new IllegalArgumentException ("unknown command '" + command + "'");
@@ -245,19 +260,31 @@
}
private void runRegisterSimPhoneAccount() throws RemoteException {
+ boolean isEmergencyAccount = false;
+ String opt;
+ while ((opt = nextOption()) != null) {
+ switch (opt) {
+ case "-e": {
+ isEmergencyAccount = true;
+ break;
+ }
+ }
+ }
final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
final String label = nextArgRequired();
final String address = nextArgRequired();
+ int capabilities = PhoneAccount.CAPABILITY_CALL_PROVIDER
+ | PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION
+ | (isEmergencyAccount ? PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS : 0);
PhoneAccount account = PhoneAccount.builder(
handle, label)
- .setAddress(Uri.parse(address))
- .setSubscriptionAddress(Uri.parse(address))
- .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
- PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
- .setShortDescription(label)
- .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
- .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
- .build();
+ .setAddress(Uri.parse(address))
+ .setSubscriptionAddress(Uri.parse(address))
+ .setCapabilities(capabilities)
+ .setShortDescription(label)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
+ .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
+ .build();
mTelecomService.registerPhoneAccount(account);
System.out.println("Success - " + handle + " registered.");
}
@@ -309,9 +336,11 @@
}
private void runSetSystemDialer() throws RemoteException {
- final String packageName = nextArg();
- mTelecomService.setSystemDialerPackage(packageName.equals("default") ? null : packageName);
- System.out.println("Success - " + packageName + " set as override system dialer.");
+ final String flatComponentName = nextArg();
+ final ComponentName componentName = (flatComponentName.equals("default")
+ ? null : parseComponentName(flatComponentName));
+ mTelecomService.setSystemDialer(componentName);
+ System.out.println("Success - " + componentName + " set as override system dialer.");
}
private void runGetDefaultDialer() throws RemoteException {
@@ -355,6 +384,18 @@
}
}
+ private void runSetEmergencyPhoneAccountPackageFilter() throws RemoteException {
+ String packageName = mArgs.getNextArg();
+ if (TextUtils.isEmpty(packageName)) {
+ mTelecomService.setTestEmergencyPhoneAccountPackageNameFilter(null);
+ System.out.println("Success - filter cleared");
+ } else {
+ mTelecomService.setTestEmergencyPhoneAccountPackageNameFilter(packageName);
+ System.out.println("Success = filter set to " + packageName);
+ }
+
+ }
+
private PhoneAccountHandle getPhoneAccountHandleFromArgs() throws RemoteException {
if (TextUtils.isEmpty(mArgs.peekNextArg())) {
return null;
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index e1cf7c1..3cb2273 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -1182,284 +1182,4 @@
Lcom/android/server/ResettableTimeout$T;-><init>(Lcom/android/server/ResettableTimeout;)V
Lcom/google/android/gles_jni/EGLImpl;-><init>()V
Lcom/google/android/gles_jni/GLImpl;-><init>()V
-Lcom/google/android/mms/ContentType;->getAudioTypes()Ljava/util/ArrayList;
-Lcom/google/android/mms/ContentType;->getImageTypes()Ljava/util/ArrayList;
-Lcom/google/android/mms/ContentType;->getVideoTypes()Ljava/util/ArrayList;
-Lcom/google/android/mms/ContentType;->isAudioType(Ljava/lang/String;)Z
-Lcom/google/android/mms/ContentType;->isDrmType(Ljava/lang/String;)Z
-Lcom/google/android/mms/ContentType;->isImageType(Ljava/lang/String;)Z
-Lcom/google/android/mms/ContentType;->isSupportedAudioType(Ljava/lang/String;)Z
-Lcom/google/android/mms/ContentType;->isSupportedImageType(Ljava/lang/String;)Z
-Lcom/google/android/mms/ContentType;->isSupportedType(Ljava/lang/String;)Z
-Lcom/google/android/mms/ContentType;->isSupportedVideoType(Ljava/lang/String;)Z
-Lcom/google/android/mms/ContentType;->isTextType(Ljava/lang/String;)Z
-Lcom/google/android/mms/ContentType;->isVideoType(Ljava/lang/String;)Z
-Lcom/google/android/mms/InvalidHeaderValueException;-><init>(Ljava/lang/String;)V
-Lcom/google/android/mms/MmsException;-><init>()V
-Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/String;)V
-Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/String;Ljava/lang/Throwable;)V
-Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/Throwable;)V
-Lcom/google/android/mms/pdu/AcknowledgeInd;-><init>(I[B)V
-Lcom/google/android/mms/pdu/AcknowledgeInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
-Lcom/google/android/mms/pdu/AcknowledgeInd;->setReportAllowed(I)V
-Lcom/google/android/mms/pdu/AcknowledgeInd;->setTransactionId([B)V
-Lcom/google/android/mms/pdu/Base64;->decodeBase64([B)[B
-Lcom/google/android/mms/pdu/CharacterSets;->getMibEnumValue(Ljava/lang/String;)I
-Lcom/google/android/mms/pdu/CharacterSets;->getMimeName(I)Ljava/lang/String;
-Lcom/google/android/mms/pdu/DeliveryInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
-Lcom/google/android/mms/pdu/DeliveryInd;->getDate()J
-Lcom/google/android/mms/pdu/DeliveryInd;->getMessageId()[B
-Lcom/google/android/mms/pdu/DeliveryInd;->getStatus()I
-Lcom/google/android/mms/pdu/DeliveryInd;->getTo()[Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/EncodedStringValue;-><init>(I[B)V
-Lcom/google/android/mms/pdu/EncodedStringValue;-><init>(Ljava/lang/String;)V
-Lcom/google/android/mms/pdu/EncodedStringValue;-><init>([B)V
-Lcom/google/android/mms/pdu/EncodedStringValue;->appendTextString([B)V
-Lcom/google/android/mms/pdu/EncodedStringValue;->concat([Lcom/google/android/mms/pdu/EncodedStringValue;)Ljava/lang/String;
-Lcom/google/android/mms/pdu/EncodedStringValue;->copy(Lcom/google/android/mms/pdu/EncodedStringValue;)Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/EncodedStringValue;->encodeStrings([Ljava/lang/String;)[Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/EncodedStringValue;->extract(Ljava/lang/String;)[Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/EncodedStringValue;->getCharacterSet()I
-Lcom/google/android/mms/pdu/EncodedStringValue;->getString()Ljava/lang/String;
-Lcom/google/android/mms/pdu/EncodedStringValue;->getTextString()[B
-Lcom/google/android/mms/pdu/EncodedStringValue;->setCharacterSet(I)V
-Lcom/google/android/mms/pdu/EncodedStringValue;->setTextString([B)V
-Lcom/google/android/mms/pdu/GenericPdu;-><init>()V
-Lcom/google/android/mms/pdu/GenericPdu;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/GenericPdu;->getMessageType()I
-Lcom/google/android/mms/pdu/GenericPdu;->getPduHeaders()Lcom/google/android/mms/pdu/PduHeaders;
-Lcom/google/android/mms/pdu/GenericPdu;->mPduHeaders:Lcom/google/android/mms/pdu/PduHeaders;
-Lcom/google/android/mms/pdu/GenericPdu;->setFrom(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/GenericPdu;->setMessageType(I)V
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;-><init>()V
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;-><init>(Lcom/google/android/mms/pdu/PduHeaders;Lcom/google/android/mms/pdu/PduBody;)V
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;->addTo(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getBody()Lcom/google/android/mms/pdu/PduBody;
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getDate()J
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getPriority()I
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getSubject()Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getTo()[Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setBody(Lcom/google/android/mms/pdu/PduBody;)V
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setDate(J)V
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setPriority(I)V
-Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setSubject(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/NotificationInd;-><init>()V
-Lcom/google/android/mms/pdu/NotificationInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
-Lcom/google/android/mms/pdu/NotificationInd;->getContentClass()I
-Lcom/google/android/mms/pdu/NotificationInd;->getContentLocation()[B
-Lcom/google/android/mms/pdu/NotificationInd;->getDeliveryReport()I
-Lcom/google/android/mms/pdu/NotificationInd;->getExpiry()J
-Lcom/google/android/mms/pdu/NotificationInd;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/NotificationInd;->getMessageClass()[B
-Lcom/google/android/mms/pdu/NotificationInd;->getMessageSize()J
-Lcom/google/android/mms/pdu/NotificationInd;->getSubject()Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/NotificationInd;->getTransactionId()[B
-Lcom/google/android/mms/pdu/NotificationInd;->setContentClass(I)V
-Lcom/google/android/mms/pdu/NotificationInd;->setContentLocation([B)V
-Lcom/google/android/mms/pdu/NotificationInd;->setDeliveryReport(I)V
-Lcom/google/android/mms/pdu/NotificationInd;->setExpiry(J)V
-Lcom/google/android/mms/pdu/NotificationInd;->setFrom(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/NotificationInd;->setMessageClass([B)V
-Lcom/google/android/mms/pdu/NotificationInd;->setMessageSize(J)V
-Lcom/google/android/mms/pdu/NotificationInd;->setSubject(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/NotificationInd;->setTransactionId([B)V
-Lcom/google/android/mms/pdu/NotifyRespInd;-><init>(I[BI)V
-Lcom/google/android/mms/pdu/NotifyRespInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
-Lcom/google/android/mms/pdu/NotifyRespInd;->setReportAllowed(I)V
-Lcom/google/android/mms/pdu/NotifyRespInd;->setStatus(I)V
-Lcom/google/android/mms/pdu/NotifyRespInd;->setTransactionId([B)V
-Lcom/google/android/mms/pdu/PduBody;-><init>()V
-Lcom/google/android/mms/pdu/PduBody;->addPart(ILcom/google/android/mms/pdu/PduPart;)V
-Lcom/google/android/mms/pdu/PduBody;->addPart(Lcom/google/android/mms/pdu/PduPart;)Z
-Lcom/google/android/mms/pdu/PduBody;->getPart(I)Lcom/google/android/mms/pdu/PduPart;
-Lcom/google/android/mms/pdu/PduBody;->getPartByContentId(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart;
-Lcom/google/android/mms/pdu/PduBody;->getPartByContentLocation(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart;
-Lcom/google/android/mms/pdu/PduBody;->getPartByFileName(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart;
-Lcom/google/android/mms/pdu/PduBody;->getPartByName(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart;
-Lcom/google/android/mms/pdu/PduBody;->getPartIndex(Lcom/google/android/mms/pdu/PduPart;)I
-Lcom/google/android/mms/pdu/PduBody;->getPartsNum()I
-Lcom/google/android/mms/pdu/PduBody;->removePart(I)Lcom/google/android/mms/pdu/PduPart;
-Lcom/google/android/mms/pdu/PduComposer$BufferStack;->copy()V
-Lcom/google/android/mms/pdu/PduComposer$BufferStack;->mark()Lcom/google/android/mms/pdu/PduComposer$PositionMarker;
-Lcom/google/android/mms/pdu/PduComposer$BufferStack;->newbuf()V
-Lcom/google/android/mms/pdu/PduComposer$BufferStack;->pop()V
-Lcom/google/android/mms/pdu/PduComposer$PositionMarker;->getLength()I
-Lcom/google/android/mms/pdu/PduComposer;-><init>(Landroid/content/Context;Lcom/google/android/mms/pdu/GenericPdu;)V
-Lcom/google/android/mms/pdu/PduComposer;->appendEncodedString(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/PduComposer;->appendHeader(I)I
-Lcom/google/android/mms/pdu/PduComposer;->appendLongInteger(J)V
-Lcom/google/android/mms/pdu/PduComposer;->appendOctet(I)V
-Lcom/google/android/mms/pdu/PduComposer;->appendQuotedString(Ljava/lang/String;)V
-Lcom/google/android/mms/pdu/PduComposer;->appendQuotedString([B)V
-Lcom/google/android/mms/pdu/PduComposer;->appendShortInteger(I)V
-Lcom/google/android/mms/pdu/PduComposer;->appendTextString(Ljava/lang/String;)V
-Lcom/google/android/mms/pdu/PduComposer;->appendTextString([B)V
-Lcom/google/android/mms/pdu/PduComposer;->appendUintvarInteger(J)V
-Lcom/google/android/mms/pdu/PduComposer;->appendValueLength(J)V
-Lcom/google/android/mms/pdu/PduComposer;->arraycopy([BII)V
-Lcom/google/android/mms/pdu/PduComposer;->make()[B
-Lcom/google/android/mms/pdu/PduComposer;->mContentTypeMap:Ljava/util/HashMap;
-Lcom/google/android/mms/pdu/PduComposer;->mMessage:Ljava/io/ByteArrayOutputStream;
-Lcom/google/android/mms/pdu/PduComposer;->mPdu:Lcom/google/android/mms/pdu/GenericPdu;
-Lcom/google/android/mms/pdu/PduComposer;->mPduHeader:Lcom/google/android/mms/pdu/PduHeaders;
-Lcom/google/android/mms/pdu/PduComposer;->mPosition:I
-Lcom/google/android/mms/pdu/PduComposer;->mResolver:Landroid/content/ContentResolver;
-Lcom/google/android/mms/pdu/PduComposer;->mStack:Lcom/google/android/mms/pdu/PduComposer$BufferStack;
-Lcom/google/android/mms/pdu/PduContentTypes;->contentTypes:[Ljava/lang/String;
-Lcom/google/android/mms/pdu/PduHeaders;-><init>()V
-Lcom/google/android/mms/pdu/PduHeaders;->appendEncodedStringValue(Lcom/google/android/mms/pdu/EncodedStringValue;I)V
-Lcom/google/android/mms/pdu/PduHeaders;->getEncodedStringValue(I)Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/PduHeaders;->getEncodedStringValues(I)[Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/PduHeaders;->getLongInteger(I)J
-Lcom/google/android/mms/pdu/PduHeaders;->getOctet(I)I
-Lcom/google/android/mms/pdu/PduHeaders;->getTextString(I)[B
-Lcom/google/android/mms/pdu/PduHeaders;->setEncodedStringValue(Lcom/google/android/mms/pdu/EncodedStringValue;I)V
-Lcom/google/android/mms/pdu/PduHeaders;->setLongInteger(JI)V
-Lcom/google/android/mms/pdu/PduHeaders;->setOctet(II)V
-Lcom/google/android/mms/pdu/PduParser;-><init>([BZ)V
-Lcom/google/android/mms/pdu/PduParser;->checkPartPosition(Lcom/google/android/mms/pdu/PduPart;)I
-Lcom/google/android/mms/pdu/PduParser;->log(Ljava/lang/String;)V
-Lcom/google/android/mms/pdu/PduParser;->parse()Lcom/google/android/mms/pdu/GenericPdu;
-Lcom/google/android/mms/pdu/PduParser;->parseContentType(Ljava/io/ByteArrayInputStream;Ljava/util/HashMap;)[B
-Lcom/google/android/mms/pdu/PduParser;->parsePartHeaders(Ljava/io/ByteArrayInputStream;Lcom/google/android/mms/pdu/PduPart;I)Z
-Lcom/google/android/mms/pdu/PduParser;->parseShortInteger(Ljava/io/ByteArrayInputStream;)I
-Lcom/google/android/mms/pdu/PduParser;->parseUnsignedInt(Ljava/io/ByteArrayInputStream;)I
-Lcom/google/android/mms/pdu/PduParser;->parseValueLength(Ljava/io/ByteArrayInputStream;)I
-Lcom/google/android/mms/pdu/PduParser;->parseWapString(Ljava/io/ByteArrayInputStream;I)[B
-Lcom/google/android/mms/pdu/PduPart;-><init>()V
-Lcom/google/android/mms/pdu/PduPart;->generateLocation()Ljava/lang/String;
-Lcom/google/android/mms/pdu/PduPart;->getCharset()I
-Lcom/google/android/mms/pdu/PduPart;->getContentDisposition()[B
-Lcom/google/android/mms/pdu/PduPart;->getContentId()[B
-Lcom/google/android/mms/pdu/PduPart;->getContentLocation()[B
-Lcom/google/android/mms/pdu/PduPart;->getContentTransferEncoding()[B
-Lcom/google/android/mms/pdu/PduPart;->getContentType()[B
-Lcom/google/android/mms/pdu/PduPart;->getData()[B
-Lcom/google/android/mms/pdu/PduPart;->getDataLength()I
-Lcom/google/android/mms/pdu/PduPart;->getDataUri()Landroid/net/Uri;
-Lcom/google/android/mms/pdu/PduPart;->getFilename()[B
-Lcom/google/android/mms/pdu/PduPart;->getName()[B
-Lcom/google/android/mms/pdu/PduPart;->setCharset(I)V
-Lcom/google/android/mms/pdu/PduPart;->setContentDisposition([B)V
-Lcom/google/android/mms/pdu/PduPart;->setContentId([B)V
-Lcom/google/android/mms/pdu/PduPart;->setContentLocation([B)V
-Lcom/google/android/mms/pdu/PduPart;->setContentTransferEncoding([B)V
-Lcom/google/android/mms/pdu/PduPart;->setContentType([B)V
-Lcom/google/android/mms/pdu/PduPart;->setData([B)V
-Lcom/google/android/mms/pdu/PduPart;->setDataUri(Landroid/net/Uri;)V
-Lcom/google/android/mms/pdu/PduPart;->setFilename([B)V
-Lcom/google/android/mms/pdu/PduPart;->setName([B)V
-Lcom/google/android/mms/pdu/PduPersister;->ADDRESS_FIELDS:[I
-Lcom/google/android/mms/pdu/PduPersister;->CHARSET_COLUMN_NAME_MAP:Ljava/util/HashMap;
-Lcom/google/android/mms/pdu/PduPersister;->ENCODED_STRING_COLUMN_NAME_MAP:Ljava/util/HashMap;
-Lcom/google/android/mms/pdu/PduPersister;->getByteArrayFromPartColumn(Landroid/database/Cursor;I)[B
-Lcom/google/android/mms/pdu/PduPersister;->getBytes(Ljava/lang/String;)[B
-Lcom/google/android/mms/pdu/PduPersister;->getIntegerFromPartColumn(Landroid/database/Cursor;I)Ljava/lang/Integer;
-Lcom/google/android/mms/pdu/PduPersister;->getPartContentType(Lcom/google/android/mms/pdu/PduPart;)Ljava/lang/String;
-Lcom/google/android/mms/pdu/PduPersister;->getPduPersister(Landroid/content/Context;)Lcom/google/android/mms/pdu/PduPersister;
-Lcom/google/android/mms/pdu/PduPersister;->getPendingMessages(J)Landroid/database/Cursor;
-Lcom/google/android/mms/pdu/PduPersister;->load(Landroid/net/Uri;)Lcom/google/android/mms/pdu/GenericPdu;
-Lcom/google/android/mms/pdu/PduPersister;->loadRecipients(ILjava/util/HashSet;Ljava/util/HashMap;Z)V
-Lcom/google/android/mms/pdu/PduPersister;->LONG_COLUMN_NAME_MAP:Ljava/util/HashMap;
-Lcom/google/android/mms/pdu/PduPersister;->mContentResolver:Landroid/content/ContentResolver;
-Lcom/google/android/mms/pdu/PduPersister;->mContext:Landroid/content/Context;
-Lcom/google/android/mms/pdu/PduPersister;->MESSAGE_BOX_MAP:Ljava/util/HashMap;
-Lcom/google/android/mms/pdu/PduPersister;->move(Landroid/net/Uri;Landroid/net/Uri;)Landroid/net/Uri;
-Lcom/google/android/mms/pdu/PduPersister;->mTelephonyManager:Landroid/telephony/TelephonyManager;
-Lcom/google/android/mms/pdu/PduPersister;->OCTET_COLUMN_NAME_MAP:Ljava/util/HashMap;
-Lcom/google/android/mms/pdu/PduPersister;->PART_PROJECTION:[Ljava/lang/String;
-Lcom/google/android/mms/pdu/PduPersister;->PDU_CACHE_INSTANCE:Lcom/google/android/mms/util/PduCache;
-Lcom/google/android/mms/pdu/PduPersister;->persist(Lcom/google/android/mms/pdu/GenericPdu;Landroid/net/Uri;ZZLjava/util/HashMap;)Landroid/net/Uri;
-Lcom/google/android/mms/pdu/PduPersister;->persistAddress(JI[Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/PduPersister;->persistPart(Lcom/google/android/mms/pdu/PduPart;JLjava/util/HashMap;)Landroid/net/Uri;
-Lcom/google/android/mms/pdu/PduPersister;->TEXT_STRING_COLUMN_NAME_MAP:Ljava/util/HashMap;
-Lcom/google/android/mms/pdu/PduPersister;->toIsoString([B)Ljava/lang/String;
-Lcom/google/android/mms/pdu/PduPersister;->updateAddress(JI[Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/PduPersister;->updateHeaders(Landroid/net/Uri;Lcom/google/android/mms/pdu/SendReq;)V
-Lcom/google/android/mms/pdu/PduPersister;->updateParts(Landroid/net/Uri;Lcom/google/android/mms/pdu/PduBody;Ljava/util/HashMap;)V
-Lcom/google/android/mms/pdu/QuotedPrintable;->decodeQuotedPrintable([B)[B
-Lcom/google/android/mms/pdu/ReadOrigInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
-Lcom/google/android/mms/pdu/ReadOrigInd;->getMessageId()[B
-Lcom/google/android/mms/pdu/ReadOrigInd;->getReadStatus()I
-Lcom/google/android/mms/pdu/ReadRecInd;-><init>(Lcom/google/android/mms/pdu/EncodedStringValue;[BII[Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/ReadRecInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
-Lcom/google/android/mms/pdu/ReadRecInd;->getMessageId()[B
-Lcom/google/android/mms/pdu/ReadRecInd;->setDate(J)V
-Lcom/google/android/mms/pdu/RetrieveConf;-><init>()V
-Lcom/google/android/mms/pdu/RetrieveConf;-><init>(Lcom/google/android/mms/pdu/PduHeaders;Lcom/google/android/mms/pdu/PduBody;)V
-Lcom/google/android/mms/pdu/RetrieveConf;->addCc(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/RetrieveConf;->getCc()[Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/RetrieveConf;->getContentType()[B
-Lcom/google/android/mms/pdu/RetrieveConf;->getDeliveryReport()I
-Lcom/google/android/mms/pdu/RetrieveConf;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/RetrieveConf;->getMessageClass()[B
-Lcom/google/android/mms/pdu/RetrieveConf;->getMessageId()[B
-Lcom/google/android/mms/pdu/RetrieveConf;->getReadReport()I
-Lcom/google/android/mms/pdu/RetrieveConf;->getRetrieveStatus()I
-Lcom/google/android/mms/pdu/RetrieveConf;->getRetrieveText()Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/RetrieveConf;->getTransactionId()[B
-Lcom/google/android/mms/pdu/RetrieveConf;->setContentType([B)V
-Lcom/google/android/mms/pdu/RetrieveConf;->setDeliveryReport(I)V
-Lcom/google/android/mms/pdu/RetrieveConf;->setFrom(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/RetrieveConf;->setMessageClass([B)V
-Lcom/google/android/mms/pdu/RetrieveConf;->setMessageId([B)V
-Lcom/google/android/mms/pdu/RetrieveConf;->setReadReport(I)V
-Lcom/google/android/mms/pdu/RetrieveConf;->setRetrieveStatus(I)V
-Lcom/google/android/mms/pdu/RetrieveConf;->setRetrieveText(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/RetrieveConf;->setTransactionId([B)V
-Lcom/google/android/mms/pdu/SendConf;-><init>()V
-Lcom/google/android/mms/pdu/SendConf;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
-Lcom/google/android/mms/pdu/SendConf;->getMessageId()[B
-Lcom/google/android/mms/pdu/SendConf;->getResponseStatus()I
-Lcom/google/android/mms/pdu/SendConf;->getTransactionId()[B
-Lcom/google/android/mms/pdu/SendReq;-><init>()V
-Lcom/google/android/mms/pdu/SendReq;-><init>(Lcom/google/android/mms/pdu/PduHeaders;Lcom/google/android/mms/pdu/PduBody;)V
-Lcom/google/android/mms/pdu/SendReq;->addBcc(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/SendReq;->addCc(Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/SendReq;->getBcc()[Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/SendReq;->getCc()[Lcom/google/android/mms/pdu/EncodedStringValue;
-Lcom/google/android/mms/pdu/SendReq;->getContentType()[B
-Lcom/google/android/mms/pdu/SendReq;->getDeliveryReport()I
-Lcom/google/android/mms/pdu/SendReq;->getExpiry()J
-Lcom/google/android/mms/pdu/SendReq;->getMessageClass()[B
-Lcom/google/android/mms/pdu/SendReq;->getMessageSize()J
-Lcom/google/android/mms/pdu/SendReq;->getReadReport()I
-Lcom/google/android/mms/pdu/SendReq;->getTransactionId()[B
-Lcom/google/android/mms/pdu/SendReq;->setBcc([Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/SendReq;->setCc([Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/SendReq;->setContentType([B)V
-Lcom/google/android/mms/pdu/SendReq;->setDeliveryReport(I)V
-Lcom/google/android/mms/pdu/SendReq;->setExpiry(J)V
-Lcom/google/android/mms/pdu/SendReq;->setMessageClass([B)V
-Lcom/google/android/mms/pdu/SendReq;->setMessageSize(J)V
-Lcom/google/android/mms/pdu/SendReq;->setReadReport(I)V
-Lcom/google/android/mms/pdu/SendReq;->setTo([Lcom/google/android/mms/pdu/EncodedStringValue;)V
-Lcom/google/android/mms/pdu/SendReq;->setTransactionId([B)V
-Lcom/google/android/mms/util/AbstractCache;-><init>()V
-Lcom/google/android/mms/util/AbstractCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
-Lcom/google/android/mms/util/AbstractCache;->purge(Ljava/lang/Object;)Ljava/lang/Object;
-Lcom/google/android/mms/util/AbstractCache;->purgeAll()V
-Lcom/google/android/mms/util/AbstractCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Z
-Lcom/google/android/mms/util/DownloadDrmHelper;->isDrmConvertNeeded(Ljava/lang/String;)Z
-Lcom/google/android/mms/util/DownloadDrmHelper;->modifyDrmFwLockFileExtension(Ljava/lang/String;)Ljava/lang/String;
-Lcom/google/android/mms/util/DrmConvertSession;->close(Ljava/lang/String;)I
-Lcom/google/android/mms/util/DrmConvertSession;->convert([BI)[B
-Lcom/google/android/mms/util/DrmConvertSession;->open(Landroid/content/Context;Ljava/lang/String;)Lcom/google/android/mms/util/DrmConvertSession;
-Lcom/google/android/mms/util/PduCache;-><init>()V
-Lcom/google/android/mms/util/PduCache;->getInstance()Lcom/google/android/mms/util/PduCache;
-Lcom/google/android/mms/util/PduCache;->isUpdating(Landroid/net/Uri;)Z
-Lcom/google/android/mms/util/PduCache;->purge(Landroid/net/Uri;)Lcom/google/android/mms/util/PduCacheEntry;
-Lcom/google/android/mms/util/PduCache;->purge(Ljava/lang/Object;)Ljava/lang/Object;
-Lcom/google/android/mms/util/PduCache;->purgeAll()V
-Lcom/google/android/mms/util/PduCacheEntry;-><init>(Lcom/google/android/mms/pdu/GenericPdu;IJ)V
-Lcom/google/android/mms/util/PduCacheEntry;->getMessageBox()I
-Lcom/google/android/mms/util/PduCacheEntry;->getPdu()Lcom/google/android/mms/pdu/GenericPdu;
-Lcom/google/android/mms/util/PduCacheEntry;->getThreadId()J
-Lcom/google/android/mms/util/SqliteWrapper;->checkSQLiteException(Landroid/content/Context;Landroid/database/sqlite/SQLiteException;)V
-Lcom/google/android/mms/util/SqliteWrapper;->delete(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;[Ljava/lang/String;)I
-Lcom/google/android/mms/util/SqliteWrapper;->insert(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri;
-Lcom/google/android/mms/util/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
-Lcom/google/android/mms/util/SqliteWrapper;->requery(Landroid/content/Context;Landroid/database/Cursor;)Z
-Lcom/google/android/mms/util/SqliteWrapper;->update(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
-Lcom/google/android/mms/pdu/PduParser;->$assertionsDisabled:Z
Lcom/google/android/util/AbstractMessageParser$Token$Type;->values()[Lcom/google/android/util/AbstractMessageParser$Token$Type;
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index d3c274f..4603f08 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -605,7 +605,7 @@
}
/**
- * Gets the windows on the screen. This method returns only the windows
+ * Gets the windows on the screen of the default display. This method returns only the windows
* that a sighted user can interact with, as opposed to all windows.
* For example, if there is a modal dialog shown and the user cannot touch
* anything behind it, then only the modal window will be reported
@@ -632,6 +632,34 @@
}
/**
+ * Gets the windows on the screen of all displays. This method returns only the windows
+ * that a sighted user can interact with, as opposed to all windows.
+ * For example, if there is a modal dialog shown and the user cannot touch
+ * anything behind it, then only the modal window will be reported
+ * (assuming it is the top one). For convenience the returned windows
+ * are ordered in a descending layer order, which is the windows that
+ * are on top are reported first. Since the user can always
+ * interact with the window that has input focus by typing, the focused
+ * window is always returned (even if covered by a modal window).
+ * <p>
+ * <strong>Note:</strong> In order to access the windows your service has
+ * to declare the capability to retrieve window content by setting the
+ * {@link android.R.styleable#AccessibilityService_canRetrieveWindowContent}
+ * property in its meta-data. For details refer to {@link #SERVICE_META_DATA}.
+ * Also the service has to opt-in to retrieve the interactive windows by
+ * setting the {@link AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS}
+ * flag.
+ * </p>
+ *
+ * @return The windows of all displays if there are windows and the service is can retrieve
+ * them, otherwise an empty list. The key of SparseArray is display ID.
+ */
+ @NonNull
+ public final SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
+ return AccessibilityInteractionClient.getInstance().getWindowsOnAllDisplays(mConnectionId);
+ }
+
+ /**
* Gets the root node in the currently active window if this service
* can retrieve window content. The active window is the one that the user
* is currently touching or the window with input focus, if the user is not
diff --git a/core/java/android/accessibilityservice/AccessibilityShortcutInfo.java b/core/java/android/accessibilityservice/AccessibilityShortcutInfo.java
new file mode 100644
index 0000000..f4cadfd
--- /dev/null
+++ b/core/java/android/accessibilityservice/AccessibilityShortcutInfo.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2019 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 android.accessibilityservice;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.util.AttributeSet;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * Activities of interest to users with accessibility needs may request to be targets of the
+ * accessibility shortcut. These activities must handle the
+ * {@link Intent#ACTION_MAIN} intent with category
+ * {@link Intent#CATEGORY_ACCESSIBILITY_SHORTCUT_TARGET}, which will be dispatched by the system
+ * when the user activates the shortcut when it is configured to point at this target.
+ *
+ * @see Intent#CATEGORY_ACCESSIBILITY_SHORTCUT_TARGET
+ *
+ * @hide
+ */
+public final class AccessibilityShortcutInfo {
+ private static final String TAG_ACCESSIBILITY_SHORTCUT = "accessibility-shortcut-target";
+
+ /**
+ * Name under which an activity component of the accessibility shortcut publishes information
+ * about itself. This meta-data must reference an XML resource containing an
+ * <code><accessibility-shortcut-target></code> tag.
+ */
+ public static final String META_DATA = "android.accessibilityshortcut.target";
+
+ /**
+ * The component name of the accessibility shortcut target.
+ */
+ private final ComponentName mComponentName;
+
+ /**
+ * The activity info of the accessibility shortcut target.
+ */
+ private final ActivityInfo mActivityInfo;
+
+ /**
+ * Resource id of the summary of the accessibility shortcut target.
+ */
+ private final int mSummaryResId;
+
+ /**
+ * Resource id of the description of the accessibility shortcut target.
+ */
+ private final int mDescriptionResId;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param context Context for accessing resources.
+ * @param activityInfo The activity info.
+ * @throws XmlPullParserException If a XML parsing error occurs.
+ * @throws IOException If a XML parsing error occurs.
+ */
+ public AccessibilityShortcutInfo(@NonNull Context context, @NonNull ActivityInfo activityInfo)
+ throws XmlPullParserException, IOException {
+ final PackageManager packageManager = context.getPackageManager();
+ mComponentName = activityInfo.getComponentName();
+ mActivityInfo = activityInfo;
+
+ try (XmlResourceParser parser = mActivityInfo.loadXmlMetaData(
+ packageManager, META_DATA)) {
+ if (parser == null) {
+ throw new XmlPullParserException("Meta-data "
+ + TAG_ACCESSIBILITY_SHORTCUT + " does not exist");
+ }
+
+ int type = 0;
+ while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
+ type = parser.next();
+ }
+
+ final String nodeName = parser.getName();
+ if (!TAG_ACCESSIBILITY_SHORTCUT.equals(nodeName)) {
+ throw new XmlPullParserException("Meta-data does not start with"
+ + TAG_ACCESSIBILITY_SHORTCUT + " tag");
+ }
+
+ final AttributeSet allAttributes = Xml.asAttributeSet(parser);
+ final Resources resources = packageManager.getResourcesForApplication(
+ mActivityInfo.applicationInfo);
+ final TypedArray asAttributes = resources.obtainAttributes(allAttributes,
+ com.android.internal.R.styleable.AccessibilityShortcutTarget);
+
+ // Gets description
+ mDescriptionResId = asAttributes.getResourceId(
+ com.android.internal.R.styleable.AccessibilityShortcutTarget_description, 0);
+ // Gets summary
+ mSummaryResId = asAttributes.getResourceId(
+ com.android.internal.R.styleable.AccessibilityShortcutTarget_summary, 0);
+ asAttributes.recycle();
+
+ if (mDescriptionResId == 0 || mSummaryResId == 0) {
+ throw new XmlPullParserException("No description or summary in meta-data");
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new XmlPullParserException("Unable to create context for: "
+ + mActivityInfo.packageName);
+ }
+ }
+
+ /**
+ * The {@link ActivityInfo} of accessibility shortcut target.
+ *
+ * @return The activity info.
+ */
+ @NonNull
+ public ActivityInfo getActivityInfo() {
+ return mActivityInfo;
+ }
+
+ /**
+ * The localized summary of the accessibility shortcut target.
+ *
+ * @return The localized summary if available, and {@code null} if a summary
+ * has not been provided.
+ */
+ @Nullable
+ public String loadSummary(@NonNull PackageManager packageManager) {
+ return loadResourceString(packageManager, mActivityInfo, mSummaryResId);
+ }
+
+ /**
+ * The localized description of the accessibility shortcut target.
+ *
+ * @return The localized description.
+ */
+ @Nullable
+ public String loadDescription(@NonNull PackageManager packageManager) {
+ return loadResourceString(packageManager, mActivityInfo, mDescriptionResId);
+ }
+
+ /**
+ * Gets string resource by the given activity and resource id.
+ */
+ @Nullable
+ private String loadResourceString(@NonNull PackageManager packageManager,
+ @NonNull ActivityInfo activityInfo, int resId) {
+ if (resId == 0) {
+ return null;
+ }
+ final CharSequence text = packageManager.getText(activityInfo.packageName,
+ resId, activityInfo.applicationInfo);
+ if (text != null) {
+ return text.toString().trim();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return 31 * 1 + ((mComponentName == null) ? 0 : mComponentName.hashCode());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final AccessibilityShortcutInfo other = (AccessibilityShortcutInfo) obj;
+ if (mComponentName == null) {
+ if (other.mComponentName != null) {
+ return false;
+ }
+ } else if (!mComponentName.equals(other.mComponentName)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("AccessibilityShortcutInfo[");
+ stringBuilder.append("activityInfo: ").append(mActivityInfo);
+ stringBuilder.append("]");
+ return stringBuilder.toString();
+ }
+}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 1ca07dd..4841781 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -60,7 +60,7 @@
AccessibilityWindowInfo getWindow(int windowId);
- List<AccessibilityWindowInfo> getWindows();
+ AccessibilityWindowInfo.WindowListSparseArray getWindows();
AccessibilityServiceInfo getServiceInfo();
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index cf36032..03300e4 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -76,7 +76,6 @@
import android.os.RemoteException;
import android.os.ServiceManager.ServiceNotFoundException;
import android.os.StrictMode;
-import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.text.Selection;
@@ -7866,13 +7865,10 @@
mFragments.dispatchStart();
mFragments.reportLoaderStart();
+ // Warn app developers if the dynamic linker logged anything during startup.
boolean isAppDebuggable =
(mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
-
- // This property is set for all non-user builds except final release
- boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1;
-
- if (isAppDebuggable || isDlwarningEnabled) {
+ if (isAppDebuggable) {
String dlwarning = getDlWarning();
if (dlwarning != null) {
String appName = getApplicationInfo().loadLabel(getPackageManager())
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index e891828..b56c00e 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -29,6 +29,7 @@
import android.content.Intent;
import android.graphics.Insets;
import android.graphics.Matrix;
+import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
@@ -101,6 +102,8 @@
private Insets mForwardedInsets;
+ private float mCornerRadius;
+
public ActivityView(Context context) {
this(context, null /* attrs */);
}
@@ -204,6 +207,45 @@
}
/**
+ * @hide
+ */
+ public float getCornerRadius() {
+ return mSurfaceView.getCornerRadius();
+ }
+
+ /**
+ * Control whether the surface is clipped to the same bounds as the View. If true, then
+ * the bounds set by {@link #setSurfaceClipBounds(Rect)} are applied to the surface as
+ * window-crop.
+ *
+ * @param clippingEnabled whether to enable surface clipping
+ * @hide
+ */
+ public void setSurfaceClippingEnabled(boolean clippingEnabled) {
+ mSurfaceView.setEnableSurfaceClipping(clippingEnabled);
+ }
+
+ /**
+ * Sets an area on the contained surface to which it will be clipped
+ * when it is drawn. Setting the value to null will remove the clip bounds
+ * and the surface will draw normally, using its full bounds.
+ *
+ * @param clipBounds The rectangular area, in the local coordinates of
+ * this view, to which future drawing operations will be clipped.
+ * @hide
+ */
+ public void setSurfaceClipBounds(Rect clipBounds) {
+ mSurfaceView.setClipBounds(clipBounds);
+ }
+
+ /**
+ * @hide
+ */
+ public boolean getSurfaceClipBounds(Rect outRect) {
+ return mSurfaceView.getClipBounds(outRect);
+ }
+
+ /**
* Launch a new activity into this container.
* <p>Activity resolved by the provided {@link Intent} must have
* {@link android.R.attr#resizeableActivity} attribute set to {@code true} in order to be
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 9b667a1..b1565ab 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -87,12 +87,6 @@
"android.app.action.CONFIRM_FRP_CREDENTIAL";
/**
- * @hide
- */
- public static final String EXTRA_BIOMETRIC_PROMPT_BUNDLE =
- "android.app.extra.BIOMETRIC_PROMPT_BUNDLE";
-
- /**
* A CharSequence dialog title to show to the user when used with a
* {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
* @hide
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 40cb29f..cb9ebac 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -191,6 +192,17 @@
}
}
Log.i(TAG, "Invalidated " + count + " asset managers that referenced " + path);
+
+ for (int i = mCachedApkAssets.size() - 1; i >= 0; i--) {
+ final ApkKey key = mCachedApkAssets.keyAt(i);
+ if (key.path.equals(path)) {
+ WeakReference<ApkAssets> apkAssetsRef = mCachedApkAssets.remove(key);
+ if (apkAssetsRef != null && apkAssetsRef.get() != null) {
+ apkAssetsRef.get().close();
+ }
+ mCachedApkAssets.remove(key);
+ }
+ }
}
}
@@ -1000,6 +1012,14 @@
}
}
+ @TestApi
+ public final boolean applyConfigurationToResources(@NonNull Configuration config,
+ @Nullable CompatibilityInfo compat) {
+ synchronized(this) {
+ return applyConfigurationToResourcesLocked(config, compat);
+ }
+ }
+
public final boolean applyConfigurationToResourcesLocked(@NonNull Configuration config,
@Nullable CompatibilityInfo compat) {
try {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 0499337..e81dc1c 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -1343,13 +1343,13 @@
* @hide
*/
public static <T> void registerCachedService(String serviceName, Class<T> serviceWrapperClass,
- BiFunction<ContextImpl, IBinder, T> serviceFetcher) {
+ BiFunction<Context, IBinder, T> serviceFetcher) {
registerService(serviceName, serviceWrapperClass,
new CachedServiceFetcher<T>() {
@Override
public T createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(serviceName);
- return serviceFetcher.apply(ctx, b);
+ return serviceFetcher.apply(ctx.getOuterContext(), b);
}});
}
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index fd93450..13d566c 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -42,6 +42,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Log;
+import android.util.SparseArray;
import android.view.Display;
import android.view.InputEvent;
import android.view.KeyEvent;
@@ -535,7 +536,7 @@
}
/**
- * Gets the windows on the screen. This method returns only the windows
+ * Gets the windows on the screen of the default display. This method returns only the windows
* that a sighted user can interact with, as opposed to all windows.
* For example, if there is a modal dialog shown and the user cannot touch
* anything behind it, then only the modal window will be reported
@@ -562,6 +563,35 @@
}
/**
+ * Gets the windows on the screen of all displays. This method returns only the windows
+ * that a sighted user can interact with, as opposed to all windows.
+ * For example, if there is a modal dialog shown and the user cannot touch
+ * anything behind it, then only the modal window will be reported
+ * (assuming it is the top one). For convenience the returned windows
+ * are ordered in a descending layer order, which is the windows that
+ * are higher in the Z-order are reported first.
+ * <p>
+ * <strong>Note:</strong> In order to access the windows you have to opt-in
+ * to retrieve the interactive windows by setting the
+ * {@link AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS} flag.
+ * </p>
+ *
+ * @return The windows of all displays if there are windows and the service is can retrieve
+ * them, otherwise an empty list. The key of SparseArray is display ID.
+ */
+ @NonNull
+ public SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
+ final int connectionId;
+ synchronized (mLock) {
+ throwIfNotConnectedLocked();
+ connectionId = mConnectionId;
+ }
+ // Calling out without a lock held.
+ return AccessibilityInteractionClient.getInstance()
+ .getWindowsOnAllDisplays(connectionId);
+ }
+
+ /**
* Gets the root {@link AccessibilityNodeInfo} in the active window.
*
* @return The root info.
diff --git a/core/java/android/app/admin/DelegatedAdminReceiver.java b/core/java/android/app/admin/DelegatedAdminReceiver.java
index f66de8d..25b8eab 100644
--- a/core/java/android/app/admin/DelegatedAdminReceiver.java
+++ b/core/java/android/app/admin/DelegatedAdminReceiver.java
@@ -63,6 +63,10 @@
* Allows this receiver to select the alias for a private key and certificate pair for
* authentication. If this method returns null, the default {@link android.app.Activity} will
* be shown that lets the user pick a private key and certificate pair.
+ * If this method returns {@link KeyChain#KEY_ALIAS_SELECTION_DENIED},
+ * the default {@link android.app.Activity} will not be shown and the user will not be allowed
+ * to pick anything. And the app, that called {@link KeyChain#choosePrivateKeyAlias}, will
+ * receive {@code null} back.
*
* <p> This callback is only applicable if the delegated app has
* {@link DevicePolicyManager#DELEGATION_CERT_SELECTION} capability. Additionally, it must
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 0c500da..d175a66 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -791,6 +791,10 @@
* Allows this receiver to select the alias for a private key and certificate pair for
* authentication. If this method returns null, the default {@link android.app.Activity} will be
* shown that lets the user pick a private key and certificate pair.
+ * If this method returns {@link KeyChain#KEY_ALIAS_SELECTION_DENIED},
+ * the default {@link android.app.Activity} will not be shown and the user will not be allowed
+ * to pick anything. And the app, that called {@link KeyChain#choosePrivateKeyAlias}, will
+ * receive {@code null} back.
*
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index f9e710e..80c5b17 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -684,8 +684,9 @@
static final int FLAGS_HAS_EXTRAS = 0x00400000;
static final int FLAGS_HAS_ID = 0x00200000;
static final int FLAGS_HAS_CHILDREN = 0x00100000;
- static final int FLAGS_HAS_URL = 0x00080000;
+ static final int FLAGS_HAS_URL_DOMAIN = 0x00080000;
static final int FLAGS_HAS_INPUT_TYPE = 0x00040000;
+ static final int FLAGS_HAS_URL_SCHEME = 0x00020000;
static final int FLAGS_HAS_LOCALE_LIST = 0x00010000;
static final int FLAGS_ALL_CONTROL = 0xfff00000;
@@ -829,8 +830,10 @@
if ((flags&FLAGS_HAS_INPUT_TYPE) != 0) {
mInputType = in.readInt();
}
- if ((flags&FLAGS_HAS_URL) != 0) {
+ if ((flags&FLAGS_HAS_URL_SCHEME) != 0) {
mWebScheme = in.readString();
+ }
+ if ((flags&FLAGS_HAS_URL_DOMAIN) != 0) {
mWebDomain = in.readString();
}
if ((flags&FLAGS_HAS_LOCALE_LIST) != 0) {
@@ -891,8 +894,11 @@
if (mInputType != 0) {
flags |= FLAGS_HAS_INPUT_TYPE;
}
- if (mWebScheme != null || mWebDomain != null) {
- flags |= FLAGS_HAS_URL;
+ if (mWebScheme != null) {
+ flags |= FLAGS_HAS_URL_SCHEME;
+ }
+ if (mWebDomain != null) {
+ flags |= FLAGS_HAS_URL_DOMAIN;
}
if (mLocaleList != null) {
flags |= FLAGS_HAS_LOCALE_LIST;
@@ -1055,8 +1061,10 @@
if ((flags&FLAGS_HAS_INPUT_TYPE) != 0) {
out.writeInt(mInputType);
}
- if ((flags&FLAGS_HAS_URL) != 0) {
+ if ((flags & FLAGS_HAS_URL_SCHEME) != 0) {
out.writeString(mWebScheme);
+ }
+ if ((flags&FLAGS_HAS_URL_DOMAIN) != 0) {
out.writeString(mWebDomain);
}
if ((flags&FLAGS_HAS_LOCALE_LIST) != 0) {
@@ -1431,13 +1439,18 @@
public void setWebDomain(@Nullable String domain) {
if (domain == null) return;
- final Uri uri = Uri.parse(domain);
+ Uri uri = Uri.parse(domain);
if (uri == null) {
// Cannot log domain because it could contain PII;
Log.w(TAG, "Failed to parse web domain");
return;
}
+
mWebScheme = uri.getScheme();
+ if (mWebScheme == null) {
+ uri = Uri.parse("http://" + domain);
+ }
+
mWebDomain = uri.getHost();
}
diff --git a/core/java/android/app/role/IRoleManager.aidl b/core/java/android/app/role/IRoleManager.aidl
index d8cea28..6d790b3 100644
--- a/core/java/android/app/role/IRoleManager.aidl
+++ b/core/java/android/app/role/IRoleManager.aidl
@@ -19,7 +19,6 @@
import android.app.role.IOnRoleHoldersChangedListener;
import android.os.Bundle;
import android.os.RemoteCallback;
-import android.telephony.IFinancialSmsCallback;
/**
* @hide
@@ -55,9 +54,4 @@
List<String> getHeldRolesFromController(in String packageName);
String getDefaultSmsPackage(int userId);
-
- /**
- * Get filtered SMS messages for financial app.
- */
- void getSmsMessagesForFinancialApp(in String callingPkg, in Bundle params, in IFinancialSmsCallback callback);
}
diff --git a/core/java/android/app/usage/AppStandbyInfo.java b/core/java/android/app/usage/AppStandbyInfo.java
index ebdbf83..c283702 100644
--- a/core/java/android/app/usage/AppStandbyInfo.java
+++ b/core/java/android/app/usage/AppStandbyInfo.java
@@ -22,6 +22,10 @@
/**
* A pair of {package, bucket} to denote the app standby bucket for a given package.
* Used as a vehicle of data across the binder IPC.
+ *
+ * Note we're not moving this class to the jobscheduler apex, because it's consumed by
+ * UsageStatsManager, which is not updatable anyway, so making this updatable isn't really
+ * beneficial.
* @hide
*/
public final class AppStandbyInfo implements Parcelable {
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 1f48393..7c279fe 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -265,6 +265,7 @@
* @see #QUERY_ARG_SORT_COLUMNS
* @see #QUERY_ARG_SORT_DIRECTION
* @see #QUERY_ARG_SORT_COLLATION
+ * @see #QUERY_ARG_SORT_LOCALE
*/
public static final String QUERY_ARG_SQL_SELECTION = "android:query-arg-sql-selection";
@@ -282,6 +283,7 @@
* @see #QUERY_ARG_SORT_COLUMNS
* @see #QUERY_ARG_SORT_DIRECTION
* @see #QUERY_ARG_SORT_COLLATION
+ * @see #QUERY_ARG_SORT_LOCALE
*/
public static final String QUERY_ARG_SQL_SELECTION_ARGS =
"android:query-arg-sql-selection-args";
@@ -297,6 +299,7 @@
* @see #QUERY_ARG_SORT_COLUMNS
* @see #QUERY_ARG_SORT_DIRECTION
* @see #QUERY_ARG_SORT_COLLATION
+ * @see #QUERY_ARG_SORT_LOCALE
*/
public static final String QUERY_ARG_SQL_SORT_ORDER = "android:query-arg-sql-sort-order";
@@ -351,20 +354,22 @@
/**
* Allows client to specify a hint to the provider declaring which collation
- * to use when sorting text values.
- *
- * <p>Providers may support custom collators. When specifying a custom collator
+ * to use when sorting values.
+ * <p>
+ * Providers may support custom collators. When specifying a custom collator
* the value is determined by the Provider.
- *
- * <li>{@link ContentProvider} implementations: When preparing data in
- * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)}, if sort collation
- * is reflected in the returned Cursor, it is strongly recommended that
- * {@link #QUERY_ARG_SORT_COLLATION} then be included in the array of honored arguments
- * reflected in {@link Cursor} extras {@link Bundle} under {@link #EXTRA_HONORED_ARGS}.
- *
- * <li>When querying a provider, where no QUERY_ARG_SQL* otherwise exists in the
- * arguments {@link Bundle}, the Content framework will attempt to synthesize
- * a QUERY_ARG_SQL* argument using the corresponding QUERY_ARG_SORT* values.
+ * <p>
+ * {@link ContentProvider} implementations: When preparing data in
+ * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)},
+ * if sort collation is reflected in the returned Cursor, it is strongly
+ * recommended that {@link #QUERY_ARG_SORT_COLLATION} then be included in
+ * the array of honored arguments reflected in {@link Cursor} extras
+ * {@link Bundle} under {@link #EXTRA_HONORED_ARGS}.
+ * <p>
+ * When querying a provider, where no QUERY_ARG_SQL* otherwise exists in the
+ * arguments {@link Bundle}, the Content framework will attempt to
+ * synthesize a QUERY_ARG_SQL* argument using the corresponding
+ * QUERY_ARG_SORT* values.
*
* @see java.text.Collator#PRIMARY
* @see java.text.Collator#SECONDARY
@@ -374,6 +379,28 @@
public static final String QUERY_ARG_SORT_COLLATION = "android:query-arg-sort-collation";
/**
+ * Allows client to specify a hint to the provider declaring which locale to
+ * use when sorting values.
+ * <p>
+ * The value is defined as a RFC 3066 locale ID followed by an optional
+ * keyword list, which is the locale format used to configure ICU through
+ * classes like {@link android.icu.util.ULocale}. This supports requesting
+ * advanced sorting options, such as {@code de@collation=phonebook},
+ * {@code zh@collation=pinyin}, etc.
+ * <p>
+ * {@link ContentProvider} implementations: When preparing data in
+ * {@link ContentProvider#query(Uri, String[], Bundle, CancellationSignal)},
+ * if sort locale is reflected in the returned Cursor, it is strongly
+ * recommended that {@link #QUERY_ARG_SORT_LOCALE} then be included in the
+ * array of honored arguments reflected in {@link Cursor} extras
+ * {@link Bundle} under {@link #EXTRA_HONORED_ARGS}.
+ *
+ * @see java.util.Locale#Locale(String)
+ * @see android.icu.util.ULocale#ULocale(String)
+ */
+ public static final String QUERY_ARG_SORT_LOCALE = "android:query-arg-sort-locale";
+
+ /**
* Allows provider to report back to client which query keys are honored in a Cursor.
*
* <p>Key identifying a {@code String[]} containing all QUERY_ARG_SORT* arguments
@@ -386,6 +413,7 @@
* @see #QUERY_ARG_SORT_COLUMNS
* @see #QUERY_ARG_SORT_DIRECTION
* @see #QUERY_ARG_SORT_COLLATION
+ * @see #QUERY_ARG_SORT_LOCALE
*/
public static final String EXTRA_HONORED_ARGS = "android.content.extra.HONORED_ARGS";
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 802c1a0a..08817e0 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3301,7 +3301,7 @@
* <dt> {@link #VIBRATOR_SERVICE} ("vibrator")
* <dd> A {@link android.os.Vibrator} for interacting with the vibrator
* hardware.
- * <dt> {@link #CONNECTIVITY_SERVICE} ("connection")
+ * <dt> {@link #CONNECTIVITY_SERVICE} ("connectivity")
* <dd> A {@link android.net.ConnectivityManager ConnectivityManager} for
* handling management of network connections.
* <dt> {@link #IPSEC_SERVICE} ("ipsec")
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 39ddc82..efb1c6a 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -4654,6 +4654,59 @@
*/
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_VR_HOME = "android.intent.category.VR_HOME";
+
+ /**
+ * The accessibility shortcut is a global gesture for users with disabilities to trigger an
+ * important for them accessibility feature to help developers determine whether they want to
+ * make their activity a shortcut target.
+ * <p>
+ * An activity of interest to users with accessibility needs may request to be the target of
+ * the accessibility shortcut. It handles intent {@link #ACTION_MAIN} with this category,
+ * which will be dispatched by the system when the user activates the shortcut when it is
+ * configured to point at this target.
+ * </p>
+ * <p>
+ * An activity declared itself to be a target of the shortcut in AndroidManifest.xml. It must
+ * also do two things:
+ * <ul>
+ * <ol>
+ * Specify that it handles the <code>android.intent.action.MAIN</code>
+ * {@link android.content.Intent}
+ * with category <code>android.intent.category.ACCESSIBILITY_SHORTCUT_TARGET</code>.
+ * </ol>
+ * <ol>
+ * Provide a meta-data entry <code>android.accessibilityshortcut.target</code> in the
+ * manifest when declaring the activity.
+ * </ol>
+ * </ul>
+ * If either of these items is missing, the system will ignore the accessibility shortcut
+ * target. Following is an example declaration:
+ * </p>
+ * <pre>
+ * <activity android:name=".MainActivity"
+ * . . .
+ * <intent-filter>
+ * <action android:name="android.intent.action.MAIN" />
+ * <category android:name="android.intent.category.ACCESSIBILITY_SHORTCUT_TARGET" />
+ * </intent-filter>
+ * <meta-data android:name="android.accessibilityshortcut.target"
+ * android:resource="@xml/accessibilityshortcut" />
+ * </activity>
+ * </pre>
+ * <p> This is a sample XML file configuring a accessibility shortcut target: </p>
+ * <pre>
+ * <accessibility-shortcut-target
+ * android:description="@string/shortcut_target_description"
+ * android:summary="@string/shortcut_target_summary" />
+ * </pre>
+ * <p>
+ * Both description and summary are necessary. The system will ignore the accessibility
+ * shortcut target if they are missing.
+ * </p>
+ */
+ @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+ public static final String CATEGORY_ACCESSIBILITY_SHORTCUT_TARGET =
+ "android.intent.category.ACCESSIBILITY_SHORTCUT_TARGET";
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Application launch intent categories (see addCategory()).
diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java
index e24512a..c3daad1 100644
--- a/core/java/android/content/PermissionChecker.java
+++ b/core/java/android/content/PermissionChecker.java
@@ -16,8 +16,6 @@
package android.content;
-import static android.app.AppOpsManager.strOpToOp;
-
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -52,6 +50,19 @@
* permission model for which the user had disabled the "permission"
* which is achieved by disallowing the corresponding app op.
* </p>
+ * <p>
+ * This class has two types of methods and you should be careful which
+ * type to call based on whether permission protected data is being
+ * passed to the app or you are just checking whether the app holds a
+ * permission. The reason is that a permission check requires checking
+ * the runtime permission and if it is granted checking the corresponding
+ * app op as for apps not supporting the runtime mode we never revoke
+ * permissions but disable app ops. Since there are two types of app op
+ * checks, one that does not leave a record an action was performed and
+ * another the does, one needs to call the preflight flavor of the checks
+ * named xxxForPreflight only if no private data is being delivered but
+ * a permission check is what is needed and the xxxForDataDelivery where
+ * the permission check is right before private data delivery.
*
* @hide
*/
@@ -65,6 +76,9 @@
/** Permission result: The permission is denied because the app op is not allowed. */
public static final int PERMISSION_DENIED_APP_OP = PackageManager.PERMISSION_DENIED - 1;
+ /** Constant when the PID for which we check permissions is unknown. */
+ public static final int PID_UNKNOWN = -1;
+
/** @hide */
@IntDef({PERMISSION_GRANTED,
PERMISSION_DENIED,
@@ -77,33 +91,297 @@
}
/**
- * @deprecated Use {@link #checkPermission(Context, String, int, int, String, String)} instead
+ * Checks whether a given package in a UID and PID has a given permission
+ * and whether the app op that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * point where you will deliver the permission protected data to clients.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use {@link #checkPermissionForPreflight(Context, String, int, int, String)}
+ * to determine if the app has or may have location permission (if app has only foreground
+ * location the grant state depends on the app's fg/gb state) and this check will not
+ * leave a trace that permission protected data was delivered. When you are about to
+ * deliver the location data to a registered listener you should use this method which
+ * will evaluate the permission access based on the current fg/bg state of the app and
+ * leave a record that the data was accessed.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @param pid The process id for which to check. Use {@link #PID_UNKNOWN} if the PID
+ * is not known.
+ * @param uid The uid for which to check.
+ * @param packageName The package name for which to check. If null the
+ * the first package for the calling UID will be used.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ * @param message A message describing the reason the permission was checked
+ *
+ * @see #checkPermissionForPreflight(Context, String, int, int, String)
*/
- @Deprecated
@PermissionResult
- public static int checkPermission(@NonNull Context context, @NonNull String permission,
- int pid, int uid, @Nullable String packageName) {
- return checkPermission(context, permission, pid, uid, packageName, null);
+ public static int checkPermissionForDataDelivery(@NonNull Context context,
+ @NonNull String permission, int pid, int uid, @Nullable String packageName,
+ @Nullable String message) {
+ return checkPermissionCommon(context, permission, pid, uid, packageName, message,
+ true /*forDataDelivery*/);
}
/**
* Checks whether a given package in a UID and PID has a given permission
* and whether the app op that corresponds to this permission is allowed.
*
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * preflight point where you will not deliver the permission protected data
+ * to clients but schedule permission data delivery, apps register listeners,
+ * etc.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use this method to determine if the app has or may have location
+ * permission (if app has only foreground location the grant state depends on the app's
+ * fg/gb state) and this check will not leave a trace that permission protected data
+ * was delivered. When you are about to deliver the location data to a registered
+ * listener you should use {@link #checkPermissionForDataDelivery(Context, String,
+ * int, int, String, String)} which will evaluate the permission access based on the current
+ * fg/bg state of the app and leave a record that the data was accessed.
+ *
* @param context Context for accessing resources.
* @param permission The permission to check.
* @param pid The process id for which to check.
* @param uid The uid for which to check.
* @param packageName The package name for which to check. If null the
* the first package for the calling UID will be used.
- * @param message A message describing the reason the permission was checked
- *
* @return The permission check result which is either {@link #PERMISSION_GRANTED}
* or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ *
+ * @see #checkPermissionForDataDelivery(Context, String, int, int, String, String)
*/
@PermissionResult
- public static int checkPermission(@NonNull Context context, @NonNull String permission,
- int pid, int uid, @Nullable String packageName, @Nullable String message) {
+ public static int checkPermissionForPreflight(@NonNull Context context,
+ @NonNull String permission, int pid, int uid, @Nullable String packageName) {
+ return checkPermissionCommon(context, permission, pid, uid, packageName, null /*message*/,
+ false /*forDataDelivery*/);
+ }
+
+ /**
+ * Checks whether your app has a given permission and whether the app op
+ * that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * point where you will deliver the permission protected data to clients.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use {@link #checkSelfPermissionForPreflight(Context, String)}
+ * to determine if the app has or may have location permission (if app has only foreground
+ * location the grant state depends on the app's fg/gb state) and this check will not
+ * leave a trace that permission protected data was delivered. When you are about to
+ * deliver the location data to a registered listener you should use this method
+ * which will evaluate the permission access based on the current fg/bg state of the
+ * app and leave a record that the data was accessed.
+ *
+ * <p>This API assumes the the {@link Binder#getCallingUid()} is the same as
+ * {@link Process#myUid()}.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ * @param message A message describing the reason the permission was checked
+ *
+ * @see #checkSelfPermissionForPreflight(Context, String)
+ */
+ @PermissionResult
+ public static int checkSelfPermissionForDataDelivery(@NonNull Context context,
+ @NonNull String permission, @Nullable String message) {
+ return checkPermissionForDataDelivery(context, permission, Process.myPid(),
+ Process.myUid(), context.getPackageName(), message);
+ }
+
+ /**
+ * Checks whether your app has a given permission and whether the app op
+ * that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * preflight point where you will not deliver the permission protected data
+ * to clients but schedule permission data delivery, apps register listeners,
+ * etc.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use this method to determine if the app has or may have location
+ * permission (if app has only foreground location the grant state depends on the
+ * app's fg/gb state) and this check will not leave a trace that permission protected
+ * data was delivered. When you are about to deliver the location data to a registered
+ * listener you should use this method which will evaluate the permission access based
+ * on the current fg/bg state of the app and leave a record that the data was accessed.
+ *
+ * <p>This API assumes the the {@link Binder#getCallingUid()} is the same as
+ * {@link Process#myUid()}.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ *
+ * @see #checkSelfPermissionForDataDelivery(Context, String, String)
+ */
+ @PermissionResult
+ public static int checkSelfPermissionForPreflight(@NonNull Context context,
+ @NonNull String permission) {
+ return checkPermissionForPreflight(context, permission, Process.myPid(),
+ Process.myUid(), context.getPackageName());
+ }
+
+ /**
+ * Checks whether the IPC you are handling has a given permission and whether
+ * the app op that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * point where you will deliver the permission protected data to clients.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use {@link #checkCallingPermissionForPreflight(Context, String, String)}
+ * to determine if the app has or may have location permission (if app has only foreground
+ * location the grant state depends on the app's fg/gb state) and this check will not
+ * leave a trace that permission protected data was delivered. When you are about to
+ * deliver the location data to a registered listener you should use this method which
+ * will evaluate the permission access based on the current fg/bg state of the app and
+ * leave a record that the data was accessed.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @param packageName The package name making the IPC. If null the
+ * the first package for the calling UID will be used.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ * @param message A message describing the reason the permission was checked
+ *
+ * @see #checkCallingPermissionForPreflight(Context, String, String)
+ */
+ @PermissionResult
+ public static int checkCallingPermissionForDataDelivery(@NonNull Context context,
+ @NonNull String permission, @Nullable String packageName, @Nullable String message) {
+ if (Binder.getCallingPid() == Process.myPid()) {
+ return PERMISSION_DENIED;
+ }
+ return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(),
+ Binder.getCallingUid(), packageName, message);
+ }
+
+ /**
+ * Checks whether the IPC you are handling has a given permission and whether
+ * the app op that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * preflight point where you will not deliver the permission protected data
+ * to clients but schedule permission data delivery, apps register listeners,
+ * etc.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use this method to determine if the app has or may have location
+ * permission (if app has only foreground location the grant state depends on the app's
+ * fg/gb state) and this check will not leave a trace that permission protected data
+ * was delivered. When you are about to deliver the location data to a registered
+ * listener you should use {@link #checkCallingOrSelfPermissionForDataDelivery(Context,
+ * String, String)} which will evaluate the permission access based on the current fg/bg state
+ * of the app and leave a record that the data was accessed.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @param packageName The package name making the IPC. If null the
+ * the first package for the calling UID will be used.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ *
+ * @see #checkCallingPermissionForDataDelivery(Context, String, String, String)
+ */
+ @PermissionResult
+ public static int checkCallingPermissionForPreflight(@NonNull Context context,
+ @NonNull String permission, @Nullable String packageName) {
+ if (Binder.getCallingPid() == Process.myPid()) {
+ return PERMISSION_DENIED;
+ }
+ return checkPermissionForPreflight(context, permission, Binder.getCallingPid(),
+ Binder.getCallingUid(), packageName);
+ }
+
+ /**
+ * Checks whether the IPC you are handling or your app has a given permission
+ * and whether the app op that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * point where you will deliver the permission protected data to clients.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use {@link #checkCallingOrSelfPermissionForPreflight(Context, String)}
+ * to determine if the app has or may have location permission (if app has only foreground
+ * location the grant state depends on the app's fg/gb state) and this check will not
+ * leave a trace that permission protected data was delivered. When you are about to
+ * deliver the location data to a registered listener you should use this method which
+ * will evaluate the permission access based on the current fg/bg state of the app and
+ * leave a record that the data was accessed.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ * @param message A message describing the reason the permission was checked
+ *
+ * @see #checkCallingOrSelfPermissionForPreflight(Context, String)
+ */
+ @PermissionResult
+ public static int checkCallingOrSelfPermissionForDataDelivery(@NonNull Context context,
+ @NonNull String permission, @Nullable String message) {
+ String packageName = (Binder.getCallingPid() == Process.myPid())
+ ? context.getPackageName() : null;
+ return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(),
+ Binder.getCallingUid(), packageName, message);
+ }
+
+ /**
+ * Checks whether the IPC you are handling or your app has a given permission
+ * and whether the app op that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * preflight point where you will not deliver the permission protected data
+ * to clients but schedule permission data delivery, apps register listeners,
+ * etc.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use this method to determine if the app has or may have location
+ * permission (if app has only foreground location the grant state depends on the
+ * app's fg/gb state) and this check will not leave a trace that permission protected
+ * data was delivered. When you are about to deliver the location data to a registered
+ * listener you should use {@link #checkCallingOrSelfPermissionForDataDelivery(Context,
+ * String, String)} which will evaluate the permission access based on the current fg/bg state
+ * of the app and leave a record that the data was accessed.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ *
+ * @see #checkCallingOrSelfPermissionForDataDelivery(Context, String, String)
+ */
+ @PermissionResult
+ public static int checkCallingOrSelfPermissionForPreflight(@NonNull Context context,
+ @NonNull String permission) {
+ String packageName = (Binder.getCallingPid() == Process.myPid())
+ ? context.getPackageName() : null;
+ return checkPermissionForPreflight(context, permission, Binder.getCallingPid(),
+ Binder.getCallingUid(), packageName);
+ }
+
+ private static int checkPermissionCommon(@NonNull Context context, @NonNull String permission,
+ int pid, int uid, @Nullable String packageName, @Nullable String message,
+ boolean forDataDelivery) {
if (context.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_DENIED) {
return PERMISSION_DENIED;
}
@@ -122,93 +400,18 @@
packageName = packageNames[0];
}
- if (appOpsManager.noteProxyOpNoThrow(strOpToOp(op), packageName, uid, message)
- != AppOpsManager.MODE_ALLOWED) {
- return PERMISSION_DENIED_APP_OP;
+ if (forDataDelivery) {
+ if (appOpsManager.noteProxyOpNoThrow(op, packageName, uid, message)
+ != AppOpsManager.MODE_ALLOWED) {
+ return PERMISSION_DENIED_APP_OP;
+ }
+ } else {
+ final int mode = appOpsManager.unsafeCheckOpRawNoThrow(op, uid, packageName);
+ if (mode != AppOpsManager.MODE_ALLOWED && mode != AppOpsManager.MODE_FOREGROUND) {
+ return PERMISSION_DENIED_APP_OP;
+ }
}
return PERMISSION_GRANTED;
}
-
- /**
- * Checks whether your app has a given permission and whether the app op
- * that corresponds to this permission is allowed.
- *
- * <p>This API assumes the the {@link Binder#getCallingUid()} is the same as
- * {@link Process#myUid()}.
- *
- * @param context Context for accessing resources.
- * @param permission The permission to check.
- * @return The permission check result which is either {@link #PERMISSION_GRANTED}
- * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
- */
- @PermissionResult
- public static int checkSelfPermission(@NonNull Context context,
- @NonNull String permission) {
- return checkPermission(context, permission, Process.myPid(),
- Process.myUid(), context.getPackageName(), null /* self access */);
- }
-
- /**
- * @deprecated Use {@link #checkCallingPermission(Context, String, String, String)} instead
- */
- @Deprecated
- @PermissionResult
- public static int checkCallingPermission(@NonNull Context context,
- @NonNull String permission, @Nullable String packageName) {
- return checkCallingPermission(context, permission, packageName, null);
- }
-
- /**
- * Checks whether the IPC you are handling has a given permission and whether
- * the app op that corresponds to this permission is allowed.
- *
- * @param context Context for accessing resources.
- * @param permission The permission to check.
- * @param packageName The package name making the IPC. If null the
- * the first package for the calling UID will be used.
- * @param message A message describing the reason the permission was checked
- *
- * @return The permission check result which is either {@link #PERMISSION_GRANTED}
- * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
- */
- @PermissionResult
- public static int checkCallingPermission(@NonNull Context context,
- @NonNull String permission, @Nullable String packageName, @Nullable String message) {
- if (Binder.getCallingPid() == Process.myPid()) {
- return PERMISSION_DENIED;
- }
- return checkPermission(context, permission, Binder.getCallingPid(),
- Binder.getCallingUid(), packageName, message);
- }
-
- /**
- * @deprecated Use {@link #checkCallingOrSelfPermission(Context, String, String)} instead
- */
- @Deprecated
- @PermissionResult
- public static int checkCallingOrSelfPermission(@NonNull Context context,
- @NonNull String permission) {
- return checkCallingOrSelfPermission(context, permission, null);
- }
-
- /**
- * Checks whether the IPC you are handling or your app has a given permission
- * and whether the app op that corresponds to this permission is allowed.
- *
- * @param context Context for accessing resources.
- * @param permission The permission to check.
- * @param message A message describing the reason the permission was checked
- *
- * @return The permission check result which is either {@link #PERMISSION_GRANTED}
- * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
- */
- @PermissionResult
- public static int checkCallingOrSelfPermission(@NonNull Context context,
- @NonNull String permission, @Nullable String message) {
- String packageName = (Binder.getCallingPid() == Process.myPid())
- ? context.getPackageName() : null;
- return checkPermission(context, permission, Binder.getCallingPid(),
- Binder.getCallingUid(), packageName, message);
- }
-}
+}
\ No newline at end of file
diff --git a/core/java/android/content/om/IOverlayManager.aidl b/core/java/android/content/om/IOverlayManager.aidl
index 43a4fe5..3d7e3be 100644
--- a/core/java/android/content/om/IOverlayManager.aidl
+++ b/core/java/android/content/om/IOverlayManager.aidl
@@ -157,4 +157,10 @@
* Returns the list of default overlay packages, or an empty array if there are none.
*/
String[] getDefaultOverlayPackages();
+
+ /**
+ * Invalidates and removes the idmap for an overlay,
+ * @param packageName The name of the overlay package whose idmap should be deleted.
+ */
+ void invalidateCachesForOverlay(in String packageName, in int userIs);
}
diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java
index f2716fe..853e818 100644
--- a/core/java/android/content/om/OverlayManager.java
+++ b/core/java/android/content/om/OverlayManager.java
@@ -21,6 +21,7 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -163,4 +164,28 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Returns information about all overlays for the given target package for
+ * the specified user. The returned list is ordered according to the
+ * overlay priority with the highest priority at the end of the list.
+ *
+ * @param targetPackageName The name of the target package.
+ * @param user The user to get the OverlayInfos for.
+ *
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(anyOf = {
+ "android.permission.INTERACT_ACROSS_USERS",
+ })
+ @NonNull
+ public void invalidateCachesForOverlay(@NonNull final String targetPackageName,
+ @NonNull UserHandle user) {
+ try {
+ mService.invalidateCachesForOverlay(targetPackageName, user.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 1099d8b..69ce3bd 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -101,19 +101,6 @@
* <p>
* The ApiDemos project contains examples of using this API:
* <code>ApiDemos/src/com/example/android/apis/content/InstallApk*.java</code>.
- * <p>
- * On Android Q or above, an app installed notification will be posted
- * by system after a new app is installed.
- * To customize installer's notification icon, you should declare the following in the manifest
- * <application> as follows: </p>
- * <pre>
- * <meta-data android:name="com.android.packageinstaller.notification.smallIcon"
- * android:resource="@drawable/installer_notification_icon"/>
- * </pre>
- * <pre>
- * <meta-data android:name="com.android.packageinstaller.notification.color"
- * android:resource="@color/installer_notification_color"/>
- * </pre>
*/
public class PackageInstaller {
private static final String TAG = "PackageInstaller";
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index fafb56d..fd14d23 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -917,8 +917,9 @@
public static final int INSTALL_DRY_RUN = 0x00800000;
/** @hide */
- @IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = {
- DONT_KILL_APP
+ @IntDef(flag = true, value = {
+ DONT_KILL_APP,
+ SYNCHRONOUS
})
@Retention(RetentionPolicy.SOURCE)
public @interface EnabledFlags {}
@@ -931,6 +932,14 @@
*/
public static final int DONT_KILL_APP = 0x00000001;
+ /**
+ * Flag parameter for
+ * {@link #setComponentEnabledSetting(android.content.ComponentName, int, int)} to indicate
+ * that the given user's package restrictions state will be serialised to disk after the
+ * component state has been updated.
+ */
+ public static final int SYNCHRONOUS = 0x00000002;
+
/** @hide */
@IntDef(prefix = { "INSTALL_REASON_" }, value = {
INSTALL_REASON_UNKNOWN,
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index df652f1..9f0bade 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -187,6 +187,18 @@
@UnsupportedAppUsage
public boolean guestToRemove;
+ /**
+ * This is used to optimize the creation of an user, i.e. OEMs might choose to pre-create a
+ * number of users at the first boot, so the actual creation later is faster.
+ *
+ * <p>A {@code preCreated} user is not a real user yet, so it should not show up on regular
+ * user operations (other than user creation per se).
+ *
+ * <p>Once the pre-created is used to create a "real" user later on, {@code preCreate} is set to
+ * {@code false}.
+ */
+ public boolean preCreated;
+
@UnsupportedAppUsage
public UserInfo(int id, String name, int flags) {
this(id, name, null, flags);
@@ -214,6 +226,13 @@
@UnsupportedAppUsage
public boolean isGuest() {
+ return isGuest(flags);
+ }
+
+ /**
+ * Checks if the flag denotes a guest user.
+ */
+ public static boolean isGuest(@UserInfoFlag int flags) {
return (flags & FLAG_GUEST) == FLAG_GUEST;
}
@@ -224,6 +243,13 @@
@UnsupportedAppUsage
public boolean isManagedProfile() {
+ return isManagedProfile(flags);
+ }
+
+ /**
+ * Checks if the flag denotes a managed profile.
+ */
+ public static boolean isManagedProfile(@UserInfoFlag int flags) {
return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE;
}
@@ -315,6 +341,7 @@
lastLoggedInTime = orig.lastLoggedInTime;
lastLoggedInFingerprint = orig.lastLoggedInFingerprint;
partial = orig.partial;
+ preCreated = orig.preCreated;
profileGroupId = orig.profileGroupId;
restrictedProfileParentId = orig.restrictedProfileParentId;
guestToRemove = orig.guestToRemove;
@@ -339,6 +366,8 @@
return "UserInfo[id=" + id
+ ", name=" + name
+ ", flags=" + flagsToString(flags)
+ + (preCreated ? " (pre-created)" : "")
+ + (partial ? " (partial)" : "")
+ "]";
}
@@ -362,9 +391,10 @@
dest.writeLong(creationTime);
dest.writeLong(lastLoggedInTime);
dest.writeString(lastLoggedInFingerprint);
- dest.writeInt(partial ? 1 : 0);
+ dest.writeBoolean(partial);
+ dest.writeBoolean(preCreated);
dest.writeInt(profileGroupId);
- dest.writeInt(guestToRemove ? 1 : 0);
+ dest.writeBoolean(guestToRemove);
dest.writeInt(restrictedProfileParentId);
dest.writeInt(profileBadge);
}
@@ -389,9 +419,10 @@
creationTime = source.readLong();
lastLoggedInTime = source.readLong();
lastLoggedInFingerprint = source.readString();
- partial = source.readInt() != 0;
+ partial = source.readBoolean();
+ preCreated = source.readBoolean();
profileGroupId = source.readInt();
- guestToRemove = source.readInt() != 0;
+ guestToRemove = source.readBoolean();
restrictedProfileParentId = source.readInt();
profileBadge = source.readInt();
}
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
index 69462ab..a35ad56 100644
--- a/core/java/android/content/res/ApkAssets.java
+++ b/core/java/android/content/res/ApkAssets.java
@@ -188,7 +188,7 @@
/**
* Closes this class and the contained {@link #mStringBlock}.
*/
- public void close() throws Throwable {
+ public void close() {
synchronized (this) {
if (mOpen) {
mOpen = false;
diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java
index b7bc822..2ae1932 100644
--- a/core/java/android/content/res/StringBlock.java
+++ b/core/java/android/content/res/StringBlock.java
@@ -175,7 +175,7 @@
}
}
- public void close() throws Throwable {
+ public void close() {
synchronized (this) {
if (mOpen) {
mOpen = false;
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/core/java/android/hardware/biometrics/Authenticator.java
similarity index 62%
copy from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
copy to core/java/android/hardware/biometrics/Authenticator.java
index 8b35852..6d7e748 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/core/java/android/hardware/biometrics/Authenticator.java
@@ -17,10 +17,19 @@
package android.hardware.biometrics;
/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
+ * Type of authenticators defined on a granularity that the BiometricManager / BiometricPrompt
+ * supports.
* @hide
*/
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+public class Authenticator {
+
+ /**
+ * Device credential, e.g. Pin/Pattern/Password.
+ */
+ public static final int TYPE_CREDENTIAL = 1 << 0;
+ /**
+ * Encompasses all biometrics on the device, e.g. Fingerprint/Iris/Face.
+ */
+ public static final int TYPE_BIOMETRIC = 1 << 1;
+
+}
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index d8110f3..cbe8a05 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -201,55 +201,5 @@
}
}
- /**
- * TODO(b/123378871): Remove when moved.
- * @hide
- */
- @RequiresPermission(USE_BIOMETRIC_INTERNAL)
- public void onConfirmDeviceCredentialSuccess() {
- if (mService != null) {
- try {
- mService.onConfirmDeviceCredentialSuccess();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- } else {
- Slog.w(TAG, "onConfirmDeviceCredentialSuccess(): Service not connected");
- }
- }
-
- /**
- * TODO(b/123378871): Remove when moved.
- * @hide
- */
- @RequiresPermission(USE_BIOMETRIC_INTERNAL)
- public void onConfirmDeviceCredentialError(int error, String message) {
- if (mService != null) {
- try {
- mService.onConfirmDeviceCredentialError(error, message);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- } else {
- Slog.w(TAG, "onConfirmDeviceCredentialError(): Service not connected");
- }
- }
-
- /**
- * TODO(b/123378871): Remove when moved.
- * @hide
- */
- @RequiresPermission(USE_BIOMETRIC_INTERNAL)
- public void registerCancellationCallback(IBiometricConfirmDeviceCredentialCallback callback) {
- if (mService != null) {
- try {
- mService.registerCancellationCallback(callback);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- } else {
- Slog.w(TAG, "registerCancellationCallback(): Service not connected");
- }
- }
}
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index fb6b231..cf86e251 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -69,24 +69,21 @@
/**
* @hide
*/
- public static final String KEY_POSITIVE_TEXT = "positive_text";
- /**
- * @hide
- */
public static final String KEY_NEGATIVE_TEXT = "negative_text";
/**
* @hide
*/
public static final String KEY_REQUIRE_CONFIRMATION = "require_confirmation";
/**
+ * This is deprecated. Internally we should use {@link #KEY_AUTHENTICATORS_ALLOWED}
* @hide
*/
public static final String KEY_ALLOW_DEVICE_CREDENTIAL = "allow_device_credential";
/**
+ * If this key is set, we will ignore {@link #KEY_ALLOW_DEVICE_CREDENTIAL}
* @hide
*/
- public static final String KEY_FROM_CONFIRM_DEVICE_CREDENTIAL
- = "from_confirm_device_credential";
+ public static final String KEY_AUTHENTICATORS_ALLOWED = "authenticators_allowed";
/**
* Error/help message will show for this amount of time.
@@ -100,7 +97,7 @@
/**
* @hide
*/
- public static final int DISMISSED_REASON_CONFIRMED = 1;
+ public static final int DISMISSED_REASON_BIOMETRIC_CONFIRMED = 1;
/**
* Dialog is done animating away after user clicked on the button set via
@@ -119,7 +116,7 @@
* Authenticated, confirmation not required. Dialog animated away.
* @hide
*/
- public static final int DISMISSED_REASON_CONFIRM_NOT_REQUIRED = 4;
+ public static final int DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED = 4;
/**
* Error message shown on SystemUI. When BiometricService receives this, the UI is already
@@ -134,6 +131,11 @@
*/
public static final int DISMISSED_REASON_SERVER_REQUESTED = 6;
+ /**
+ * @hide
+ */
+ public static final int DISMISSED_REASON_CREDENTIAL_CONFIRMED = 7;
+
private static class ButtonInfo {
Executor executor;
DialogInterface.OnClickListener listener;
@@ -203,30 +205,6 @@
}
/**
- * Optional: Set the text for the positive button. If not set, the positive button
- * will not show.
- * @param text
- * @return
- * @hide
- */
- @NonNull public Builder setPositiveButton(@NonNull CharSequence text,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull DialogInterface.OnClickListener listener) {
- if (TextUtils.isEmpty(text)) {
- throw new IllegalArgumentException("Text must be set and non-empty");
- }
- if (executor == null) {
- throw new IllegalArgumentException("Executor must not be null");
- }
- if (listener == null) {
- throw new IllegalArgumentException("Listener must not be null");
- }
- mBundle.putCharSequence(KEY_POSITIVE_TEXT, text);
- mPositiveButtonInfo = new ButtonInfo(executor, listener);
- return this;
- }
-
- /**
* Required: Set the text for the negative button. This would typically be used as a
* "Cancel" button, but may be also used to show an alternative method for authentication,
* such as screen that asks for a backup password.
@@ -298,17 +276,6 @@
}
/**
- * TODO(123378871): Remove when moved.
- * @return
- * @hide
- */
- @RequiresPermission(USE_BIOMETRIC_INTERNAL)
- @NonNull public Builder setFromConfirmDeviceCredential() {
- mBundle.putBoolean(KEY_FROM_CONFIRM_DEVICE_CREDENTIAL, true);
- return this;
- }
-
- /**
* Creates a {@link BiometricPrompt}.
* @return a {@link BiometricPrompt}
* @throws IllegalArgumentException if any of the required fields are not set.
@@ -317,15 +284,19 @@
final CharSequence title = mBundle.getCharSequence(KEY_TITLE);
final CharSequence negative = mBundle.getCharSequence(KEY_NEGATIVE_TEXT);
final boolean useDefaultTitle = mBundle.getBoolean(KEY_USE_DEFAULT_TITLE);
- final boolean enableFallback = mBundle.getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL);
+ final boolean allowCredential = mBundle.getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL);
+ final Object authenticatorsAllowed = mBundle.get(KEY_AUTHENTICATORS_ALLOWED);
if (TextUtils.isEmpty(title) && !useDefaultTitle) {
throw new IllegalArgumentException("Title must be set and non-empty");
- } else if (TextUtils.isEmpty(negative) && !enableFallback) {
+ } else if (TextUtils.isEmpty(negative) && !allowCredential) {
throw new IllegalArgumentException("Negative text must be set and non-empty");
- } else if (!TextUtils.isEmpty(negative) && enableFallback) {
+ } else if (!TextUtils.isEmpty(negative) && allowCredential) {
throw new IllegalArgumentException("Can't have both negative button behavior"
+ " and device credential enabled");
+ } else if (authenticatorsAllowed != null && allowCredential) {
+ throw new IllegalArgumentException("setAuthenticatorsAllowed and"
+ + " setDeviceCredentialAllowed should not be used simultaneously");
}
return new BiometricPrompt(mContext, mBundle, mPositiveButtonInfo, mNegativeButtonInfo);
}
@@ -384,7 +355,7 @@
@Override
public void onDialogDismissed(int reason) throws RemoteException {
// Check the reason and invoke OnClickListener(s) if necessary
- if (reason == DISMISSED_REASON_CONFIRMED) {
+ if (reason == DISMISSED_REASON_BIOMETRIC_CONFIRMED) {
mPositiveButtonInfo.executor.execute(() -> {
mPositiveButtonInfo.listener.onClick(null, DialogInterface.BUTTON_POSITIVE);
});
@@ -532,8 +503,7 @@
public void authenticateUser(@NonNull CancellationSignal cancel,
@NonNull @CallbackExecutor Executor executor,
@NonNull AuthenticationCallback callback,
- int userId,
- IBiometricConfirmDeviceCredentialCallback confirmDeviceCredentialCallback) {
+ int userId) {
if (cancel == null) {
throw new IllegalArgumentException("Must supply a cancellation signal");
}
@@ -543,8 +513,7 @@
if (callback == null) {
throw new IllegalArgumentException("Must supply a callback");
}
- authenticateInternal(null /* crypto */, cancel, executor, callback, userId,
- confirmDeviceCredentialCallback);
+ authenticateInternal(null /* crypto */, cancel, executor, callback, userId);
}
/**
@@ -595,8 +564,7 @@
if (mBundle.getBoolean(KEY_ALLOW_DEVICE_CREDENTIAL)) {
throw new IllegalArgumentException("Device credential not supported with crypto");
}
- authenticateInternal(crypto, cancel, executor, callback, mContext.getUserId(),
- null /* confirmDeviceCredentialCallback */);
+ authenticateInternal(crypto, cancel, executor, callback, mContext.getUserId());
}
/**
@@ -638,8 +606,7 @@
if (callback == null) {
throw new IllegalArgumentException("Must supply a callback");
}
- authenticateInternal(null /* crypto */, cancel, executor, callback, mContext.getUserId(),
- null /* confirmDeviceCredentialCallback */);
+ authenticateInternal(null /* crypto */, cancel, executor, callback, mContext.getUserId());
}
private void cancelAuthentication() {
@@ -656,8 +623,7 @@
@NonNull CancellationSignal cancel,
@NonNull @CallbackExecutor Executor executor,
@NonNull AuthenticationCallback callback,
- int userId,
- IBiometricConfirmDeviceCredentialCallback confirmDeviceCredentialCallback) {
+ int userId) {
try {
if (cancel.isCanceled()) {
Log.w(TAG, "Authentication already canceled");
@@ -672,7 +638,7 @@
final long sessionId = crypto != null ? crypto.getOpId() : 0;
if (BiometricManager.hasBiometrics(mContext)) {
mService.authenticate(mToken, sessionId, userId, mBiometricServiceReceiver,
- mContext.getOpPackageName(), mBundle, confirmDeviceCredentialCallback);
+ mContext.getOpPackageName(), mBundle);
} else {
mExecutor.execute(() -> {
callback.onAuthenticationError(BiometricPrompt.BIOMETRIC_ERROR_HW_NOT_PRESENT,
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index f0a0b2f..6a3bf38 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -17,7 +17,6 @@
package android.hardware.biometrics;
import android.os.Bundle;
-import android.hardware.biometrics.IBiometricConfirmDeviceCredentialCallback;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.biometrics.IBiometricServiceReceiver;
@@ -31,10 +30,8 @@
interface IBiometricService {
// Requests authentication. The service choose the appropriate biometric to use, and show
// the corresponding BiometricDialog.
- // TODO(b/123378871): Remove callback when moved.
void authenticate(IBinder token, long sessionId, int userId,
- IBiometricServiceReceiver receiver, String opPackageName, in Bundle bundle,
- IBiometricConfirmDeviceCredentialCallback callback);
+ IBiometricServiceReceiver receiver, String opPackageName, in Bundle bundle);
// Cancel authentication for the given sessionId
void cancelAuthentication(IBinder token, String opPackageName);
@@ -57,16 +54,4 @@
// Reset the lockout when user authenticates with strong auth (e.g. PIN, pattern or password)
void resetLockout(in byte [] token);
-
- // TODO(b/123378871): Remove when moved.
- // CDCA needs to send results to BiometricService if it was invoked using BiometricPrompt's
- // setAllowDeviceCredential method, since there's no way for us to intercept onActivityResult.
- // CDCA is launched from BiometricService (startActivityAsUser) instead of *ForResult.
- void onConfirmDeviceCredentialSuccess();
- // TODO(b/123378871): Remove when moved.
- void onConfirmDeviceCredentialError(int error, String message);
- // TODO(b/123378871): Remove when moved.
- // When ConfirmLock* is invoked from BiometricPrompt, it needs to register a callback so that
- // it can receive the cancellation signal.
- void registerCancellationCallback(IBiometricConfirmDeviceCredentialCallback callback);
}
diff --git a/core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl b/core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl
index ca6114e..66b6e89 100644
--- a/core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl
@@ -38,4 +38,6 @@
void onDialogDismissed(int reason);
// Notifies that the user has pressed the "try again" button on SystemUI
void onTryAgainPressed();
+ // Notifies that the user has pressed the "use password" button on SystemUI
+ void onDeviceCredentialPressed();
}
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 0daf30f25..638d81b 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -76,6 +76,9 @@
// Registers a tablet mode change listener
void registerTabletModeChangedListener(ITabletModeChangedListener listener);
+ // Queries whether the device's microphone is muted by switch
+ int isMicMuted();
+
// Input device vibrator control.
void vibrate(int deviceId, in long[] pattern, int repeat, IBinder token);
void cancelVibrate(int deviceId, IBinder token);
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 2a59be2..0c0f248 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -520,6 +520,22 @@
}
/**
+ * Queries whether the device's microphone is muted
+ *
+ * @return The mic mute switch state which is one of {@link #SWITCH_STATE_UNKNOWN},
+ * {@link #SWITCH_STATE_OFF} or {@link #SWITCH_STATE_ON}.
+ * @hide
+ */
+ @SwitchState
+ public int isMicMuted() {
+ try {
+ return mIm.isMicMuted();
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Gets information about all supported keyboard layouts.
* <p>
* The input manager consults the built-in keyboard layouts as well
diff --git a/core/java/android/hardware/location/ContextHubClientCallback.java b/core/java/android/hardware/location/ContextHubClientCallback.java
index cc2fe65..20fa753 100644
--- a/core/java/android/hardware/location/ContextHubClientCallback.java
+++ b/core/java/android/hardware/location/ContextHubClientCallback.java
@@ -66,7 +66,9 @@
public void onNanoAppAborted(ContextHubClient client, long nanoAppId, int abortCode) {}
/**
- * Callback invoked when a nanoapp is loaded at the attached Context Hub.
+ * Callback invoked when a nanoapp is dynamically loaded at the attached Context Hub through
+ * the {@link android.hardware.location.ContextHubManager}. This callback is not invoked for a
+ * nanoapp that is loaded internally by CHRE (e.g. nanoapps that are preloaded by the system).
*
* @param client the client that is associated with this callback
* @param nanoAppId the ID of the nanoapp that had been loaded
@@ -74,7 +76,8 @@
public void onNanoAppLoaded(ContextHubClient client, long nanoAppId) {}
/**
- * Callback invoked when a nanoapp is unloaded from the attached Context Hub.
+ * Callback invoked when a nanoapp is dynamically unloaded from the attached Context Hub through
+ * the {@link android.hardware.location.ContextHubManager}.
*
* @param client the client that is associated with this callback
* @param nanoAppId the ID of the nanoapp that had been unloaded
@@ -82,7 +85,8 @@
public void onNanoAppUnloaded(ContextHubClient client, long nanoAppId) {}
/**
- * Callback invoked when a nanoapp is enabled at the attached Context Hub.
+ * Callback invoked when a nanoapp is dynamically enabled at the attached Context Hub through
+ * the {@link android.hardware.location.ContextHubManager}.
*
* @param client the client that is associated with this callback
* @param nanoAppId the ID of the nanoapp that had been enabled
@@ -90,7 +94,8 @@
public void onNanoAppEnabled(ContextHubClient client, long nanoAppId) {}
/**
- * Callback invoked when a nanoapp is disabled at the attached Context Hub.
+ * Callback invoked when a nanoapp is dynamically disabled at the attached Context Hub through
+ * the {@link android.hardware.location.ContextHubManager}.
*
* @param client the client that is associated with this callback
* @param nanoAppId the ID of the nanoapp that had been disabled
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index 08c9eea..11f4ffb 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -60,6 +60,9 @@
private final int mClass;
private final int mSubclass;
private final int mProtocol;
+ private final boolean mHasAudioPlayback;
+ private final boolean mHasAudioCapture;
+ private final boolean mHasMidi;
/** All interfaces on the device. Initialized on first call to getInterfaceList */
@UnsupportedAppUsage
@@ -73,7 +76,8 @@
private UsbDevice(@NonNull String name, int vendorId, int productId, int Class, int subClass,
int protocol, @Nullable String manufacturerName, @Nullable String productName,
@NonNull String version, @NonNull UsbConfiguration[] configurations,
- @NonNull IUsbSerialReader serialNumberReader) {
+ @NonNull IUsbSerialReader serialNumberReader,
+ boolean hasAudioPlayback, boolean hasAudioCapture, boolean hasMidi) {
mName = Preconditions.checkNotNull(name);
mVendorId = vendorId;
mProductId = productId;
@@ -85,6 +89,9 @@
mVersion = Preconditions.checkStringNotEmpty(version);
mConfigurations = Preconditions.checkArrayElementsNotNull(configurations, "configurations");
mSerialNumberReader = Preconditions.checkNotNull(serialNumberReader);
+ mHasAudioPlayback = hasAudioPlayback;
+ mHasAudioCapture = hasAudioCapture;
+ mHasMidi = hasMidi;
// Make sure the binder belongs to the system
if (ActivityThread.isSystem()) {
@@ -214,6 +221,21 @@
return mConfigurations.length;
}
+ /** @hide */
+ public boolean getHasAudioPlayback() {
+ return mHasAudioPlayback;
+ }
+
+ /** @hide */
+ public boolean getHasAudioCapture() {
+ return mHasAudioCapture;
+ }
+
+ /** @hide */
+ public boolean getHasMidi() {
+ return mHasMidi;
+ }
+
/**
* Returns the {@link UsbConfiguration} at the given index.
*
@@ -286,12 +308,15 @@
@Override
public String toString() {
- StringBuilder builder = new StringBuilder("UsbDevice[mName=" + mName +
- ",mVendorId=" + mVendorId + ",mProductId=" + mProductId +
- ",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol +
- ",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName +
- ",mVersion=" + mVersion + ",mSerialNumberReader=" + mSerialNumberReader
- + ",mConfigurations=[");
+ StringBuilder builder = new StringBuilder("UsbDevice[mName=" + mName
+ + ",mVendorId=" + mVendorId + ",mProductId=" + mProductId
+ + ",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol
+ + ",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName
+ + ",mVersion=" + mVersion + ",mSerialNumberReader=" + mSerialNumberReader
+ + ", mHasAudioPlayback=" + mHasAudioPlayback
+ + ", mHasAudioCapture=" + mHasAudioCapture
+ + ", mHasMidi=" + mHasMidi
+ + ", mConfigurations=[");
for (int i = 0; i < mConfigurations.length; i++) {
builder.append("\n");
builder.append(mConfigurations[i].toString());
@@ -316,9 +341,15 @@
IUsbSerialReader.Stub.asInterface(in.readStrongBinder());
UsbConfiguration[] configurations = in.readParcelableArray(
UsbConfiguration.class.getClassLoader(), UsbConfiguration.class);
+ // Capabilities
+ boolean hasAudioPlayback = in.readInt() == 1;
+ boolean hasAudioCapture = in.readInt() == 1;
+ boolean hasMidi = in.readInt() == 1;
+
UsbDevice device = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol,
- manufacturerName, productName, version, configurations,
- serialNumberReader);
+ manufacturerName, productName, version, configurations, serialNumberReader,
+ hasAudioPlayback, hasAudioCapture, hasMidi);
+
return device;
}
@@ -343,7 +374,10 @@
parcel.writeString(mVersion);
parcel.writeStrongBinder(mSerialNumberReader.asBinder());
parcel.writeParcelableArray(mConfigurations, 0);
- }
+ parcel.writeInt(mHasAudioPlayback ? 1 : 0);
+ parcel.writeInt(mHasAudioCapture ? 1 : 0);
+ parcel.writeInt(mHasMidi ? 1 : 0);
+ }
public static int getDeviceId(String name) {
return native_get_device_id(name);
@@ -370,6 +404,9 @@
private final @Nullable String mProductName;
private final @NonNull String mVersion;
private final @NonNull UsbConfiguration[] mConfigurations;
+ private final boolean mHasAudioPlayback;
+ private final boolean mHasAudioCapture;
+ private final boolean mHasMidi;
// Temporary storage for serial number. Serial number reader need to be wrapped in a
// IUsbSerialReader as they might be used as PII.
@@ -378,7 +415,8 @@
public Builder(@NonNull String name, int vendorId, int productId, int Class, int subClass,
int protocol, @Nullable String manufacturerName, @Nullable String productName,
@NonNull String version, @NonNull UsbConfiguration[] configurations,
- @Nullable String serialNumber) {
+ @Nullable String serialNumber,
+ boolean hasAudioPlayback, boolean hasAudioCapture, boolean hasMidi) {
mName = Preconditions.checkNotNull(name);
mVendorId = vendorId;
mProductId = productId;
@@ -390,6 +428,9 @@
mVersion = Preconditions.checkStringNotEmpty(version);
mConfigurations = configurations;
this.serialNumber = serialNumber;
+ mHasAudioPlayback = hasAudioPlayback;
+ mHasAudioCapture = hasAudioCapture;
+ mHasMidi = hasMidi;
}
/**
@@ -401,7 +442,8 @@
*/
public UsbDevice build(@NonNull IUsbSerialReader serialReader) {
return new UsbDevice(mName, mVendorId, mProductId, mClass, mSubclass, mProtocol,
- mManufacturerName, mProductName, mVersion, mConfigurations, serialReader);
+ mManufacturerName, mProductName, mVersion, mConfigurations, serialReader,
+ mHasAudioPlayback, mHasAudioCapture, mHasMidi);
}
}
}
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 3cc2819..bc32df4 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -278,11 +278,13 @@
/** @hide */
public static final int OTHER_DALVIK_OTHER_ACCOUNTING = 22;
/** @hide */
- public static final int OTHER_DALVIK_OTHER_CODE_CACHE = 23;
+ public static final int OTHER_DALVIK_OTHER_ZYGOTE_CODE_CACHE = 23;
/** @hide */
- public static final int OTHER_DALVIK_OTHER_COMPILER_METADATA = 24;
+ public static final int OTHER_DALVIK_OTHER_APP_CODE_CACHE = 24;
/** @hide */
- public static final int OTHER_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE = 25;
+ public static final int OTHER_DALVIK_OTHER_COMPILER_METADATA = 25;
+ /** @hide */
+ public static final int OTHER_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE = 26;
/** @hide */
public static final int OTHER_DVK_STAT_DALVIK_OTHER_START =
OTHER_DALVIK_OTHER_LINEARALLOC - NUM_OTHER_STATS;
@@ -292,11 +294,11 @@
// Dex subsections (Boot vdex, App dex, and App vdex).
/** @hide */
- public static final int OTHER_DEX_BOOT_VDEX = 26;
+ public static final int OTHER_DEX_BOOT_VDEX = 27;
/** @hide */
- public static final int OTHER_DEX_APP_DEX = 27;
+ public static final int OTHER_DEX_APP_DEX = 28;
/** @hide */
- public static final int OTHER_DEX_APP_VDEX = 28;
+ public static final int OTHER_DEX_APP_VDEX = 29;
/** @hide */
public static final int OTHER_DVK_STAT_DEX_START = OTHER_DEX_BOOT_VDEX - NUM_OTHER_STATS;
/** @hide */
@@ -304,9 +306,9 @@
// Art subsections (App image, boot image).
/** @hide */
- public static final int OTHER_ART_APP = 29;
+ public static final int OTHER_ART_APP = 30;
/** @hide */
- public static final int OTHER_ART_BOOT = 30;
+ public static final int OTHER_ART_BOOT = 31;
/** @hide */
public static final int OTHER_DVK_STAT_ART_START = OTHER_ART_APP - NUM_OTHER_STATS;
/** @hide */
@@ -314,7 +316,7 @@
/** @hide */
@UnsupportedAppUsage
- public static final int NUM_DVK_STATS = 14;
+ public static final int NUM_DVK_STATS = OTHER_ART_BOOT + 1 - OTHER_DALVIK_NORMAL;
/** @hide */
public static final int NUM_CATEGORIES = 9;
@@ -540,7 +542,8 @@
case OTHER_DALVIK_NON_MOVING: return ".NonMoving";
case OTHER_DALVIK_OTHER_LINEARALLOC: return ".LinearAlloc";
case OTHER_DALVIK_OTHER_ACCOUNTING: return ".GC";
- case OTHER_DALVIK_OTHER_CODE_CACHE: return ".JITCache";
+ case OTHER_DALVIK_OTHER_ZYGOTE_CODE_CACHE: return ".ZygoteJIT";
+ case OTHER_DALVIK_OTHER_APP_CODE_CACHE: return ".AppJIT";
case OTHER_DALVIK_OTHER_COMPILER_METADATA: return ".CompilerMetadata";
case OTHER_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE: return ".IndirectRef";
case OTHER_DEX_BOOT_VDEX: return ".Boot vdex";
@@ -722,7 +725,9 @@
+ getOtherPrivate(OTHER_APK)
+ getOtherPrivate(OTHER_TTF)
+ getOtherPrivate(OTHER_DEX)
- + getOtherPrivate(OTHER_OAT);
+ + getOtherPrivate(OTHER_OAT)
+ + getOtherPrivate(OTHER_DALVIK_OTHER_ZYGOTE_CODE_CACHE)
+ + getOtherPrivate(OTHER_DALVIK_OTHER_APP_CODE_CACHE);
}
/**
@@ -813,7 +818,9 @@
+ getOtherRss(OTHER_APK)
+ getOtherRss(OTHER_TTF)
+ getOtherRss(OTHER_DEX)
- + getOtherRss(OTHER_OAT);
+ + getOtherRss(OTHER_OAT)
+ + getOtherRss(OTHER_DALVIK_OTHER_ZYGOTE_CODE_CACHE)
+ + getOtherRss(OTHER_DALVIK_OTHER_APP_CODE_CACHE);
}
/**
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 63641e5..c30491a 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -41,6 +41,7 @@
*/
UserInfo createUser(in String name, int flags);
+ UserInfo preCreateUser(int flags);
UserInfo createProfileForUser(in String name, int flags, int userHandle,
in String[] disallowedPackages);
UserInfo createRestrictedProfile(String name, int parentUserHandle);
@@ -53,7 +54,7 @@
void setUserIcon(int userHandle, in Bitmap icon);
ParcelFileDescriptor getUserIcon(int userHandle);
UserInfo getPrimaryUser();
- List<UserInfo> getUsers(boolean excludeDying);
+ List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated);
List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
int[] getProfileIds(int userId, boolean enabledOnly);
boolean canAddMoreManagedProfiles(int userHandle, boolean allowedToRemoveOne);
@@ -92,6 +93,7 @@
boolean someUserHasSeedAccount(in String accountName, in String accountType);
boolean isManagedProfile(int userId);
boolean isDemoUser(int userId);
+ boolean isPreCreated(int userId);
UserInfo createProfileForUserEvenWhenDisallowed(in String name, int flags, int userHandle,
in String[] disallowedPackages);
boolean isUserUnlockingOrUnlocked(int userId);
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index b568f15..e371df0 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -1,2 +1,4 @@
# Zygote
per-file ZygoteProcess.java = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
+
+per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index dd5e20e..a9ddffe 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -22,8 +22,6 @@
import android.os.IUpdateEngineCallback;
import android.os.RemoteException;
-import java.io.FileDescriptor;
-
/**
* UpdateEngine handles calls to the update engine which takes care of A/B OTA
* updates. It wraps up the update engine Binder APIs and exposes them as
@@ -315,16 +313,16 @@
}
/**
- * Applies the payload passed as file descriptor {@code fd} instead of
+ * Applies the payload passed as ParcelFileDescriptor {@code pfd} instead of
* using the {@code file://} scheme.
*
* <p>See {@link #applyPayload(String)} for {@code offset}, {@code size} and
* {@code headerKeyValuePairs} parameters.
*/
- public void applyPayload(@NonNull FileDescriptor fd, long offset, long size,
+ public void applyPayload(@NonNull ParcelFileDescriptor pfd, long offset, long size,
@NonNull String[] headerKeyValuePairs) {
try {
- mUpdateEngine.applyPayloadFd(fd, offset, size, headerKeyValuePairs);
+ mUpdateEngine.applyPayloadFd(pfd, offset, size, headerKeyValuePairs);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 0754dc7..3558fcd 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -39,6 +39,7 @@
/** @hide A user id to indicate all users on the device */
@UnsupportedAppUsage
+ @TestApi
public static final @UserIdInt int USER_ALL = -1;
/** @hide A user handle to indicate all users on the device */
@@ -69,8 +70,11 @@
/** @hide An undefined user id */
@UnsupportedAppUsage
+ @TestApi
public static final @UserIdInt int USER_NULL = -10000;
+ private static final @NonNull UserHandle NULL = new UserHandle(USER_NULL);
+
/**
* @hide A user id constant to indicate the "owner" user of the device
* @deprecated Consider using either {@link UserHandle#USER_SYSTEM} constant or
@@ -91,6 +95,7 @@
/** @hide A user id constant to indicate the "system" user of the device */
@UnsupportedAppUsage
+ @TestApi
public static final @UserIdInt int USER_SYSTEM = 0;
/** @hide A user serial constant to indicate the "system" user of the device */
@@ -110,6 +115,27 @@
public static final boolean MU_ENABLED = true;
/** @hide */
+ @TestApi
+ public static final int MIN_SECONDARY_USER_ID = 10;
+
+ /**
+ * Arbitrary user handle cache size. We use the cache even when {@link #MU_ENABLED} is false
+ * anyway, so we can always assume in CTS that UserHandle.of(10) returns a cached instance
+ * even on non-multiuser devices.
+ */
+ private static final int NUM_CACHED_USERS = 4;
+
+ private static final UserHandle[] CACHED_USER_INFOS = new UserHandle[NUM_CACHED_USERS];
+
+ static {
+ // Not lazily initializing the cache, so that we can share them across processes.
+ // (We'll create them in zygote.)
+ for (int i = 0; i < CACHED_USER_INFOS.length; i++) {
+ CACHED_USER_INFOS[i] = new UserHandle(MIN_SECONDARY_USER_ID + i);
+ }
+ }
+
+ /** @hide */
@UnsupportedAppUsage
public static final int ERR_GID = -1;
/** @hide */
@@ -209,6 +235,7 @@
* @hide
*/
@UnsupportedAppUsage
+ @TestApi
public static @UserIdInt int getUserId(int uid) {
if (MU_ENABLED) {
return uid / PER_USER_RANGE;
@@ -229,9 +256,31 @@
}
/** @hide */
+ @TestApi
@SystemApi
public static UserHandle of(@UserIdInt int userId) {
- return userId == USER_SYSTEM ? SYSTEM : new UserHandle(userId);
+ if (userId == USER_SYSTEM) {
+ return SYSTEM; // Most common.
+ }
+ // These are sequential; so use a switch. Maybe they'll be optimized to a table lookup.
+ switch (userId) {
+ case USER_ALL:
+ return ALL;
+
+ case USER_CURRENT:
+ return CURRENT;
+
+ case USER_CURRENT_OR_SELF:
+ return CURRENT_OR_SELF;
+ }
+ if (userId >= MIN_SECONDARY_USER_ID
+ && userId < (MIN_SECONDARY_USER_ID + CACHED_USER_INFOS.length)) {
+ return CACHED_USER_INFOS[userId - MIN_SECONDARY_USER_ID];
+ }
+ if (userId == USER_NULL) { // Not common.
+ return NULL;
+ }
+ return new UserHandle(userId);
}
/**
@@ -239,6 +288,7 @@
* @hide
*/
@UnsupportedAppUsage
+ @TestApi
public static int getUid(@UserIdInt int userId, @AppIdInt int appId) {
if (MU_ENABLED) {
return userId * PER_USER_RANGE + (appId % PER_USER_RANGE);
@@ -404,6 +454,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public static @UserIdInt int myUserId() {
return getUserId(Process.myUid());
}
@@ -513,7 +564,9 @@
public static final @android.annotation.NonNull Parcelable.Creator<UserHandle> CREATOR
= new Parcelable.Creator<UserHandle>() {
public UserHandle createFromParcel(Parcel in) {
- return new UserHandle(in);
+ // Try to avoid allocation; use of() here. Keep this and the constructor below
+ // in sync.
+ return UserHandle.of(in.readInt());
}
public UserHandle[] newArray(int size) {
@@ -532,6 +585,6 @@
* positioned at the location in the buffer where it was written.
*/
public UserHandle(Parcel in) {
- mHandle = in.readInt();
+ mHandle = in.readInt(); // Keep this and createFromParcel() in sync.
}
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index af574da..3296f11 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -37,6 +37,7 @@
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.UserInfo;
+import android.content.pm.UserInfo.UserInfoFlag;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -2013,18 +2014,20 @@
/**
* Creates a user with the specified name and options. For non-admin users, default user
- * restrictions are going to be applied.
- * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+ * restrictions will be applied.
+ *
+ * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
*
* @param name the user's name
- * @param flags flags that identify the type of user and other properties.
+ * @param flags UserInfo flags that identify the type of user and other properties.
* @see UserInfo
*
- * @return the UserInfo object for the created user, or null if the user could not be created.
+ * @return the UserInfo object for the created user, or {@code null} if the user could not be
+ * created.
* @hide
*/
@UnsupportedAppUsage
- public UserInfo createUser(String name, int flags) {
+ public @Nullable UserInfo createUser(@Nullable String name, @UserInfoFlag int flags) {
UserInfo user = null;
try {
user = mService.createUser(name, flags);
@@ -2041,6 +2044,36 @@
}
/**
+ * Pre-creates a user with the specified name and options. For non-admin users, default user
+ * restrictions will be applied.
+ *
+ * <p>This method can be used by OEMs to "warm" up the user creation by pre-creating some users
+ * at the first boot, so they when the "real" user is created (for example,
+ * by {@link #createUser(String, int)} or {@link #createGuest(Context, String)}), it takes
+ * less time.
+ *
+ * <p>Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+ *
+ * @param flags UserInfo flags that identify the type of user and other properties.
+ * @see UserInfo
+ *
+ * @return the UserInfo object for the created user, or {@code null} if the user could not be
+ * created.
+ *
+ * @throw {@link IllegalArgumentException} if {@code flags} contains
+ * {@link UserInfo#FLAG_MANAGED_PROFILE}.
+ *
+ * @hide
+ */
+ public @Nullable UserInfo preCreateUser(@UserInfoFlag int flags) {
+ try {
+ return mService.preCreateUser(flags);
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Creates a guest user and configures it.
* @param context an application context
* @param name the name to set for the user
@@ -2356,15 +2389,26 @@
/**
* Returns information for all users on this device, including ones marked for deletion.
* To retrieve only users that are alive, use {@link #getUsers(boolean)}.
- * <p>
- * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+ *
* @return the list of users that exist on the device.
* @hide
*/
@UnsupportedAppUsage
+ @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
public List<UserInfo> getUsers() {
+ return getUsers(/* excludeDying= */ false);
+ }
+
+ /**
+ * Returns information for all users on this device, based on the filtering parameters.
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+ public List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying,
+ boolean excludePreCreated) {
try {
- return mService.getUsers(false);
+ return mService.getUsers(excludePartial, excludeDying, excludePreCreated);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -2380,16 +2424,12 @@
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
public long[] getSerialNumbersOfUsers(boolean excludeDying) {
- try {
- List<UserInfo> users = mService.getUsers(excludeDying);
- long[] result = new long[users.size()];
- for (int i = 0; i < result.length; i++) {
- result[i] = users.get(i).serialNumber;
- }
- return result;
- } catch (RemoteException re) {
- throw re.rethrowFromSystemServer();
+ List<UserInfo> users = getUsers(excludeDying);
+ long[] result = new long[users.size()];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = users.get(i).serialNumber;
}
+ return result;
}
/**
@@ -2773,11 +2813,8 @@
*/
@UnsupportedAppUsage
public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
- try {
- return mService.getUsers(excludeDying);
- } catch (RemoteException re) {
- throw re.rethrowFromSystemServer();
- }
+ return getUsers(/*excludePartial= */ true, excludeDying,
+ /* excludePreCreated= */ true);
}
/**
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 9a3a7ce..907eae8 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -758,6 +758,7 @@
ZygoteState state = openZygoteSocketIfNeeded(abi);
state.mZygoteOutputWriter.write("1\n--boot-completed\n");
state.mZygoteOutputWriter.flush();
+ state.mZygoteInputStream.readInt();
}
} catch (Exception ex) {
throw new RuntimeException("Failed to inform zygote of boot_completed", ex);
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 351462f..2d8af83 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1580,7 +1580,14 @@
/** {@hide} */
public static boolean hasAdoptable() {
- return SystemProperties.getBoolean(PROP_HAS_ADOPTABLE, false);
+ switch (SystemProperties.get(PROP_ADOPTABLE)) {
+ case "force_on":
+ return true;
+ case "force_off":
+ return false;
+ default:
+ return SystemProperties.getBoolean(PROP_HAS_ADOPTABLE, false);
+ }
}
/**
diff --git a/core/java/android/os/telephony/TelephonyRegistryManager.java b/core/java/android/os/telephony/TelephonyRegistryManager.java
index 459c414..1332331 100644
--- a/core/java/android/os/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/os/telephony/TelephonyRegistryManager.java
@@ -21,23 +21,24 @@
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.telephony.Annotation.ApnType;
+import android.telephony.Annotation.CallState;
+import android.telephony.Annotation.DataActivityType;
+import android.telephony.Annotation.DataFailureCause;
+import android.telephony.Annotation.DataState;
+import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.PreciseCallStates;
+import android.telephony.Annotation.RadioPowerState;
+import android.telephony.Annotation.SimActivationState;
+import android.telephony.Annotation.SrvccState;
import android.telephony.CallQuality;
import android.telephony.CellInfo;
-import android.telephony.DataFailCause;
import android.telephony.DisconnectCause;
import android.telephony.PhoneCapability;
-import android.telephony.PreciseCallState.State;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
-import android.telephony.TelephonyManager.CallState;
-import android.telephony.TelephonyManager.DataActivityType;
-import android.telephony.TelephonyManager.DataState;
-import android.telephony.TelephonyManager.NetworkType;
-import android.telephony.TelephonyManager.RadioPowerState;
-import android.telephony.TelephonyManager.SimActivationState;
import android.telephony.data.ApnSetting;
-import android.telephony.data.ApnSetting.ApnType;
import android.telephony.ims.ImsReasonInfo;
import com.android.internal.telephony.ITelephonyRegistry;
import java.util.List;
@@ -410,7 +411,7 @@
* @hide
*/
public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, String apnType,
- String apn, @DataFailCause.FailCause int failCause) {
+ String apn, @DataFailureCause int failCause) {
try {
sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause);
} catch (RemoteException ex) {
@@ -427,7 +428,7 @@
*
* @hide
*/
- public void notifySrvccStateChanged(int subId, @TelephonyManager.SrvccState int state) {
+ public void notifySrvccStateChanged(int subId, @SrvccState int state) {
try {
sRegistry.notifySrvccStateChanged(subId, state);
} catch (RemoteException ex) {
@@ -464,8 +465,10 @@
*
* @hide
*/
- public void notifyPreciseCallState(int subId, int slotIndex, @State int ringCallPreciseState,
- @State int foregroundCallPreciseState, @State int backgroundCallPreciseState) {
+ public void notifyPreciseCallState(int subId, int slotIndex,
+ @PreciseCallStates int ringCallPreciseState,
+ @PreciseCallStates int foregroundCallPreciseState,
+ @PreciseCallStates int backgroundCallPreciseState) {
try {
sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState,
foregroundCallPreciseState, backgroundCallPreciseState);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3c26df3..e4e8bf7 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7908,16 +7908,6 @@
public static final String NOTIFICATION_BADGING = "notification_badging";
/**
- * Whether the notification bubbles are globally enabled
- * The value is boolean (1 or 0).
- * @hide
- * @deprecated use {@link Global#NOTIFICATION_BUBBLES} instead.
- */
- @TestApi
- @Deprecated
- public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
-
- /**
* Whether notifications are dismissed by a right-to-left swipe (instead of a left-to-right
* swipe).
*
diff --git a/core/java/android/service/autofill/AutofillFieldClassificationService.java b/core/java/android/service/autofill/AutofillFieldClassificationService.java
index 320dcec6..28842a7 100644
--- a/core/java/android/service/autofill/AutofillFieldClassificationService.java
+++ b/core/java/android/service/autofill/AutofillFieldClassificationService.java
@@ -93,6 +93,13 @@
*/
public static final String REQUIRED_ALGORITHM_EXACT_MATCH = "EXACT_MATCH";
+ /**
+ * Field classification algorithm that compares a credit card string to known last four digits.
+ *
+ * <p>Service implementation must provide this algorithm.</p>
+ */
+ public static final String REQUIRED_ALGORITHM_CREDIT_CARD = "CREDIT_CARD";
+
/** {@hide} **/
public static final String EXTRA_SCORES = "scores";
diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java
index 70dfef5..dfc5c82 100644
--- a/core/java/android/speech/RecognitionService.java
+++ b/core/java/android/speech/RecognitionService.java
@@ -170,13 +170,23 @@
* Checks whether the caller has sufficient permissions
*
* @param listener to send the error message to in case of error
+ * @param forDataDelivery If the permission check is for delivering the sensitive data.
* @return {@code true} if the caller has enough permissions, {@code false} otherwise
*/
- private boolean checkPermissions(IRecognitionListener listener) {
+ private boolean checkPermissions(IRecognitionListener listener, boolean forDataDelivery) {
if (DBG) Log.d(TAG, "checkPermissions");
- if (PermissionChecker.checkCallingOrSelfPermission(this,
- android.Manifest.permission.RECORD_AUDIO) == PermissionChecker.PERMISSION_GRANTED) {
- return true;
+ if (forDataDelivery) {
+ if (PermissionChecker.checkCallingOrSelfPermissionForDataDelivery(this,
+ android.Manifest.permission.RECORD_AUDIO, null /*message*/)
+ == PermissionChecker.PERMISSION_GRANTED) {
+ return true;
+ }
+ } else {
+ if (PermissionChecker.checkCallingOrSelfPermissionForPreflight(this,
+ android.Manifest.permission.RECORD_AUDIO)
+ == PermissionChecker.PERMISSION_GRANTED) {
+ return true;
+ }
}
try {
Log.e(TAG, "call for recognition service without RECORD_AUDIO permissions");
@@ -342,7 +352,7 @@
public void startListening(Intent recognizerIntent, IRecognitionListener listener) {
if (DBG) Log.d(TAG, "startListening called by:" + listener.asBinder());
final RecognitionService service = mServiceRef.get();
- if (service != null && service.checkPermissions(listener)) {
+ if (service != null && service.checkPermissions(listener, true /*forDataDelivery*/)) {
service.mHandler.sendMessage(Message.obtain(service.mHandler,
MSG_START_LISTENING, service.new StartListeningArgs(
recognizerIntent, listener, Binder.getCallingUid())));
@@ -353,7 +363,7 @@
public void stopListening(IRecognitionListener listener) {
if (DBG) Log.d(TAG, "stopListening called by:" + listener.asBinder());
final RecognitionService service = mServiceRef.get();
- if (service != null && service.checkPermissions(listener)) {
+ if (service != null && service.checkPermissions(listener, false /*forDataDelivery*/)) {
service.mHandler.sendMessage(Message.obtain(service.mHandler,
MSG_STOP_LISTENING, listener));
}
@@ -363,7 +373,7 @@
public void cancel(IRecognitionListener listener) {
if (DBG) Log.d(TAG, "cancel called by:" + listener.asBinder());
final RecognitionService service = mServiceRef.get();
- if (service != null && service.checkPermissions(listener)) {
+ if (service != null && service.checkPermissions(listener, false /*forDataDelivery*/)) {
service.mHandler.sendMessage(Message.obtain(service.mHandler,
MSG_CANCEL, listener));
}
diff --git a/core/java/android/util/OWNERS b/core/java/android/util/OWNERS
index 98297fb..8f3d9f6 100644
--- a/core/java/android/util/OWNERS
+++ b/core/java/android/util/OWNERS
@@ -1,3 +1,3 @@
per-file FeatureFlagUtils.java = sbasi@google.com
-per-file FeatureFlagUtils.java = zhfan@google.com
+per-file FeatureFlagUtils.java = tmfang@google.com
per-file FeatureFlagUtils.java = asapperstein@google.com
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index f34f9e6..4b872d3 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -73,6 +73,14 @@
*/
void insetsControlChanged(in InsetsState insetsState, in InsetsSourceControl[] activeControls);
+ /**
+ * Called when a set of insets source window should be shown by policy.
+ *
+ * @param types internal inset types (WindowInsets.Type.InsetType) to show
+ * @param fromIme true if this request originated from IME (InputMethodService).
+ */
+ void showInsets(int types, boolean fromIme);
+
void moved(int newX, int newY);
void dispatchAppVisibility(boolean visible);
void dispatchGetNewSurface();
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 49e8800..35cfe9e 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -644,4 +644,16 @@
* Enables/disables SurfaceFlinger layer tracing.
*/
void setLayerTracing(boolean enabled);
+
+ /**
+ * Mirrors a specified display. The root of the mirrored hierarchy will be stored in
+ * outSurfaceControl.
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ *
+ * @param displayId The id of the display to mirror
+ * @param outSurfaceControl The SurfaceControl for the root of the mirrored hierarchy.
+ *
+ * @return true if the display was successfully mirrored.
+ */
+ boolean mirrorDisplay(int displayId, out SurfaceControl outSurfaceControl);
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index c798d85..5a8636d 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -224,7 +224,7 @@
show(types, false /* fromIme */);
}
- private void show(@InsetType int types, boolean fromIme) {
+ void show(@InsetType int types, boolean fromIme) {
// TODO: Support a ResultReceiver for IME.
// TODO(b/123718661): Make show() work for multi-session IME.
int typesReady = 0;
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 6639fbf..b685cf0 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -91,7 +91,7 @@
boolean captureSecureLayers);
private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder displayToken,
long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects);
-
+ private static native long nativeMirrorSurface(long mirrorOfObject);
private static native long nativeCreateTransaction();
private static native long nativeGetNativeTransactionFinalizer();
private static native void nativeApplyTransaction(long transactionObj, boolean sync);
@@ -2034,6 +2034,28 @@
return nativeSetDisplayBrightness(displayToken, brightness);
}
+ /**
+ * Creates a mirrored hierarchy for the mirrorOf {@link SurfaceControl}
+ *
+ * Real Hierarchy Mirror
+ * SC (value that's returned)
+ * |
+ * A A'
+ * | |
+ * B B'
+ *
+ * @param mirrorOf The root of the hierarchy that should be mirrored.
+ * @return A SurfaceControl that's the parent of the root of the mirrored hierarchy.
+ *
+ * @hide
+ */
+ public static SurfaceControl mirrorSurface(SurfaceControl mirrorOf) {
+ long nativeObj = nativeMirrorSurface(mirrorOf.mNativeObject);
+ SurfaceControl sc = new SurfaceControl();
+ sc.assignNativeObject(nativeObj);
+ return sc;
+ }
+
/**
* An atomic set of changes to a set of SurfaceControl.
*/
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 06ff568..a858300 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -167,6 +167,7 @@
boolean mUseAlpha = false;
float mSurfaceAlpha = 1f;
+ boolean mClipSurfaceToBounds;
@UnsupportedAppUsage
boolean mHaveFrame = false;
@@ -555,9 +556,52 @@
super.dispatchDraw(canvas);
}
+ /**
+ * Control whether the surface is clipped to the same bounds as the View. If true, then
+ * the bounds set by {@link #setClipBounds(Rect)} are applied to the surface as window-crop.
+ *
+ * @param enabled whether to enable surface clipping
+ * @hide
+ */
+ public void setEnableSurfaceClipping(boolean enabled) {
+ mClipSurfaceToBounds = enabled;
+ invalidate();
+ }
+
+ @Override
+ public void setClipBounds(Rect clipBounds) {
+ super.setClipBounds(clipBounds);
+
+ if (!mClipSurfaceToBounds) {
+ return;
+ }
+
+ // When cornerRadius is non-zero, a draw() is required to update
+ // the viewport (rounding the corners of the clipBounds).
+ if (mCornerRadius > 0f && !isAboveParent()) {
+ invalidate();
+ }
+
+ if (mSurfaceControl != null) {
+ if (mClipBounds != null) {
+ mTmpRect.set(mClipBounds);
+ } else {
+ mTmpRect.set(0, 0, mSurfaceWidth, mSurfaceHeight);
+ }
+ SyncRtSurfaceTransactionApplier applier = new SyncRtSurfaceTransactionApplier(this);
+ applier.scheduleApply(
+ new SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(mSurfaceControl)
+ .withWindowCrop(mTmpRect)
+ .build());
+ }
+ }
+
private void clearSurfaceViewPort(Canvas canvas) {
if (mCornerRadius > 0f) {
canvas.getClipBounds(mTmpRect);
+ if (mClipSurfaceToBounds && mClipBounds != null) {
+ mTmpRect.intersect(mClipBounds);
+ }
canvas.drawRoundRect(mTmpRect.left, mTmpRect.top, mTmpRect.right, mTmpRect.bottom,
mCornerRadius, mCornerRadius, mRoundedViewportPaint);
} else {
@@ -583,6 +627,16 @@
}
/**
+ * Returns the corner radius for the SurfaceView.
+
+ * @return the radius of the corners in pixels
+ * @hide
+ */
+ public float getCornerRadius() {
+ return mCornerRadius;
+ }
+
+ /**
* Control whether the surface view's surface is placed on top of another
* regular surface view in the window (but still behind the window itself).
* This is typically used to place overlays on top of an underlying media
@@ -840,7 +894,11 @@
// crop the buffer to the surface size since the buffer producer may
// use SCALING_MODE_SCALE and submit a larger size than the surface
// size.
- mSurfaceControl.setWindowCrop(mSurfaceWidth, mSurfaceHeight);
+ if (mClipSurfaceToBounds && mClipBounds != null) {
+ mSurfaceControl.setWindowCrop(mClipBounds);
+ } else {
+ mSurfaceControl.setWindowCrop(mSurfaceWidth, mSurfaceHeight);
+ }
}
mSurfaceControl.setCornerRadius(mCornerRadius);
if (sizeChanged && !creating) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 3756a7d..fedd6fb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -91,6 +91,7 @@
import android.view.View.AttachInfo;
import android.view.View.FocusDirection;
import android.view.View.MeasureSpec;
+import android.view.WindowInsets.Type.InsetType;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -4528,6 +4529,8 @@
private static final int MSG_INSETS_CONTROL_CHANGED = 31;
private static final int MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED = 32;
private static final int MSG_LOCATION_IN_PARENT_DISPLAY_CHANGED = 33;
+ private static final int MSG_SHOW_INSETS = 34;
+
final class ViewRootHandler extends Handler {
@Override
@@ -4591,6 +4594,8 @@
return "MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED";
case MSG_LOCATION_IN_PARENT_DISPLAY_CHANGED:
return "MSG_LOCATION_IN_PARENT_DISPLAY_CHANGED";
+ case MSG_SHOW_INSETS:
+ return "MSG_SHOW_INSETS";
}
return super.getMessageName(message);
}
@@ -4705,6 +4710,10 @@
mInsetsController.onStateChanged((InsetsState) args.arg1);
break;
}
+ case MSG_SHOW_INSETS: {
+ mInsetsController.show(msg.arg1, msg.arg2 == 1);
+ break;
+ }
case MSG_WINDOW_MOVED:
if (mAdded) {
final int w = mWinFrame.width();
@@ -7484,6 +7493,10 @@
mHandler.obtainMessage(MSG_INSETS_CONTROL_CHANGED, args).sendToTarget();
}
+ private void showInsets(@InsetType int types, boolean fromIme) {
+ mHandler.obtainMessage(MSG_SHOW_INSETS, types, fromIme ? 1 : 0).sendToTarget();
+ }
+
public void dispatchMoved(int newX, int newY) {
if (DEBUG_LAYOUT) Log.v(mTag, "Window moved " + this + ": newX=" + newX + " newY=" + newY);
if (mTranslator != null) {
@@ -8599,6 +8612,14 @@
}
@Override
+ public void showInsets(@InsetType int types, boolean fromIme) {
+ final ViewRootImpl viewAncestor = mViewAncestor.get();
+ if (viewAncestor != null) {
+ viewAncestor.showInsets(types, fromIme);
+ }
+ }
+
+ @Override
public void moved(int newX, int newY) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
diff --git a/core/java/android/view/WindowlessViewRoot.java b/core/java/android/view/WindowlessViewRoot.java
index b76e1fa..c2500b8 100644
--- a/core/java/android/view/WindowlessViewRoot.java
+++ b/core/java/android/view/WindowlessViewRoot.java
@@ -41,4 +41,12 @@
public void addView(View view, WindowManager.LayoutParams attrs) {
mViewRoot.setView(view, attrs, null);
}
+
+ public void relayout(WindowManager.LayoutParams attrs) {
+ mViewRoot.setLayoutParams(attrs, false);
+ mViewRoot.setReportNextDraw();
+ mWm.setCompletionCallback(mViewRoot.mWindow.asBinder(), (SurfaceControl.Transaction t) -> {
+ t.apply();
+ });
+ }
}
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 430fb6d..f4f7d0b 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -39,11 +39,27 @@
class WindowlessWindowManager implements IWindowSession {
private final static String TAG = "WindowlessWindowManager";
+ private class State {
+ SurfaceControl mSurfaceControl;
+ WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
+ State(SurfaceControl sc, WindowManager.LayoutParams p) {
+ mSurfaceControl = sc;
+ mParams.copyFrom(p);
+ }
+ };
/**
* Used to store SurfaceControl we've built for clients to
* reconfigure them if relayout is called.
*/
- final HashMap<IBinder, SurfaceControl> mScForWindow = new HashMap<IBinder, SurfaceControl>();
+ final HashMap<IBinder, State> mStateForWindow = new HashMap<IBinder, State>();
+
+ public interface ResizeCompleteCallback {
+ public void finished(SurfaceControl.Transaction completion);
+ }
+
+ final HashMap<IBinder, ResizeCompleteCallback> mResizeCompletionForWindow =
+ new HashMap<IBinder, ResizeCompleteCallback>();
+
final SurfaceSession mSurfaceSession = new SurfaceSession();
final SurfaceControl mRootSurface;
final Configuration mConfiguration;
@@ -58,6 +74,19 @@
mRealWm = WindowManagerGlobal.getWindowSession();
}
+ /**
+ * Utility API.
+ */
+ void setCompletionCallback(IBinder window, ResizeCompleteCallback callback) {
+ if (mResizeCompletionForWindow.get(window) != null) {
+ Log.w(TAG, "Unsupported overlapping resizes");
+ }
+ mResizeCompletionForWindow.put(window, callback);
+ }
+
+ /**
+ * IWindowSession implementation.
+ */
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets,
Rect outStableInsets, Rect outOutsets,
@@ -68,7 +97,7 @@
.setName(attrs.getTitle().toString());
final SurfaceControl sc = b.build();
synchronized (this) {
- mScForWindow.put(window.asBinder(), sc);
+ mStateForWindow.put(window.asBinder(), new State(sc, attrs));
}
if ((attrs.inputFeatures &
@@ -104,34 +133,40 @@
}
@Override
- public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
+ public int relayout(IWindow window, int seq, WindowManager.LayoutParams inAttrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets,
Rect outStableInsets, Rect outsets, Rect outBackdropFrame,
DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
- SurfaceControl sc = null;
+ State state = null;
synchronized (this) {
- sc = mScForWindow.get(window.asBinder());
+ state = mStateForWindow.get(window.asBinder());
}
- if (sc == null) {
+ if (state == null) {
throw new IllegalArgumentException(
"Invalid window token (never added or removed already)");
}
+ SurfaceControl sc = state.mSurfaceControl;
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ if (inAttrs != null) {
+ state.mParams.copyFrom(inAttrs);
+ }
+ WindowManager.LayoutParams attrs = state.mParams;
+
final Rect surfaceInsets = attrs.surfaceInsets;
int width = surfaceInsets != null ?
- requestedWidth + surfaceInsets.left + surfaceInsets.right : requestedWidth;
+ attrs.width + surfaceInsets.left + surfaceInsets.right : attrs.width;
int height = surfaceInsets != null ?
- requestedHeight + surfaceInsets.top + surfaceInsets.bottom : requestedHeight;
+ attrs.height + surfaceInsets.top + surfaceInsets.bottom : attrs.height;
t.show(sc)
.setBufferSize(sc, width, height)
.setOpaque(sc, isOpaque(attrs))
.apply();
outSurfaceControl.copyFrom(sc);
- outFrame.set(0, 0, requestedWidth, requestedHeight);
+ outFrame.set(0, 0, attrs.width, attrs.height);
mergedConfiguration.setConfiguration(mConfiguration, mConfiguration);
@@ -165,6 +200,17 @@
@Override
public void finishDrawing(android.view.IWindow window,
android.view.SurfaceControl.Transaction postDrawTransaction) {
+ synchronized (this) {
+ final ResizeCompleteCallback c =
+ mResizeCompletionForWindow.get(window.asBinder());
+ if (c == null) {
+ // No one wanted the callback, but it wasn't necessarily unexpected.
+ postDrawTransaction.apply();
+ return;
+ }
+ c.finished(postDrawTransaction);
+ mResizeCompletionForWindow.remove(window.asBinder());
+ }
}
@Override
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index d9fa9f2..bb10ef1 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -259,23 +259,38 @@
}
/**
- * Gets the info for all windows.
+ * Gets the info for all windows of the default display.
*
* @param connectionId The id of a connection for interacting with the system.
* @return The {@link AccessibilityWindowInfo} list.
*/
public List<AccessibilityWindowInfo> getWindows(int connectionId) {
+ final SparseArray<List<AccessibilityWindowInfo>> windows =
+ getWindowsOnAllDisplays(connectionId);
+ if (windows.size() > 0) {
+ return windows.valueAt(Display.DEFAULT_DISPLAY);
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * Gets the info for all windows of all displays.
+ *
+ * @param connectionId The id of a connection for interacting with the system.
+ * @return The SparseArray of {@link AccessibilityWindowInfo} list.
+ * The key of SparseArray is display ID.
+ */
+ public SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays(int connectionId) {
try {
IAccessibilityServiceConnection connection = getConnection(connectionId);
if (connection != null) {
- SparseArray<List<AccessibilityWindowInfo>> allWindows =
+ SparseArray<List<AccessibilityWindowInfo>> windows =
sAccessibilityCache.getWindowsOnAllDisplays();
- List<AccessibilityWindowInfo> windows;
- if (allWindows != null) {
+ if (windows != null) {
if (DEBUG) {
Log.i(LOG_TAG, "Windows cache hit");
}
- return allWindows.valueAt(Display.DEFAULT_DISPLAY);
+ return windows;
}
if (DEBUG) {
Log.i(LOG_TAG, "Windows cache miss");
@@ -287,9 +302,7 @@
Binder.restoreCallingIdentity(identityToken);
}
if (windows != null) {
- allWindows = new SparseArray<>();
- allWindows.put(Display.DEFAULT_DISPLAY, windows);
- sAccessibilityCache.setWindowsOnAllDisplays(allWindows);
+ sAccessibilityCache.setWindowsOnAllDisplays(windows);
return windows;
}
} else {
@@ -298,9 +311,11 @@
}
}
} catch (RemoteException re) {
- Log.e(LOG_TAG, "Error while calling remote getWindows", re);
+ Log.e(LOG_TAG, "Error while calling remote getWindowsOnAllDisplays", re);
}
- return Collections.emptyList();
+
+ final SparseArray<List<AccessibilityWindowInfo>> emptyWindows = new SparseArray<>();
+ return emptyWindows;
}
/**
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 2e9d881..0817452 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -21,6 +21,7 @@
import android.Manifest;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityServiceInfo.FeedbackType;
+import android.accessibilityservice.AccessibilityShortcutInfo;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -30,9 +31,13 @@
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
+import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.os.Binder;
@@ -56,6 +61,9 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IntPair;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -1257,6 +1265,64 @@
return null;
}
+ /**
+ * Returns the {@link AccessibilityShortcutInfo}s of the installed accessibility shortcut
+ * targets, for specific user.
+ *
+ * @param context The context of the application.
+ * @param userId The user id.
+ * @return A list with {@link AccessibilityShortcutInfo}s.
+ * @hide
+ */
+ @NonNull
+ public List<AccessibilityShortcutInfo> getInstalledAccessibilityShortcutListAsUser(
+ @NonNull Context context, @UserIdInt int userId) {
+ final List<AccessibilityShortcutInfo> shortcutInfos = new ArrayList<>();
+ final int flags = PackageManager.GET_ACTIVITIES
+ | PackageManager.GET_META_DATA
+ | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+ final Intent actionMain = new Intent(Intent.ACTION_MAIN);
+ actionMain.addCategory(Intent.CATEGORY_ACCESSIBILITY_SHORTCUT_TARGET);
+
+ final PackageManager packageManager = context.getPackageManager();
+ final List<ResolveInfo> installedShortcutList =
+ packageManager.queryIntentActivitiesAsUser(actionMain, flags, userId);
+ for (int i = 0; i < installedShortcutList.size(); i++) {
+ final AccessibilityShortcutInfo shortcutInfo =
+ getShortcutInfo(context, installedShortcutList.get(i));
+ if (shortcutInfo != null) {
+ shortcutInfos.add(shortcutInfo);
+ }
+ }
+ return shortcutInfos;
+ }
+
+ /**
+ * Returns an {@link AccessibilityShortcutInfo} according to the given {@link ResolveInfo} of
+ * an activity.
+ *
+ * @param context The context of the application.
+ * @param resolveInfo The resolve info of an activity.
+ * @return The AccessibilityShortcutInfo.
+ */
+ @Nullable
+ private AccessibilityShortcutInfo getShortcutInfo(@NonNull Context context,
+ @NonNull ResolveInfo resolveInfo) {
+ final ActivityInfo activityInfo = resolveInfo.activityInfo;
+ if (activityInfo == null || activityInfo.metaData == null
+ || activityInfo.metaData.getInt(AccessibilityShortcutInfo.META_DATA) == 0) {
+ return null;
+ }
+ try {
+ return new AccessibilityShortcutInfo(context, activityInfo);
+ } catch (XmlPullParserException | IOException exp) {
+ Log.e(LOG_TAG, "Error while initializing AccessibilityShortcutInfo", exp);
+ }
+ return null;
+ }
+
private IAccessibilityManager getServiceLocked() {
if (mService == null) {
tryConnectToServiceLocked(null);
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl b/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl
index fdb25fb..c36c4aa 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl
@@ -17,3 +17,4 @@
package android.view.accessibility;
parcelable AccessibilityWindowInfo;
+parcelable AccessibilityWindowInfo.WindowListSparseArray;
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index 6a3af34..5fa8a6e 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -26,9 +26,12 @@
import android.text.TextUtils;
import android.util.LongArray;
import android.util.Pools.SynchronizedPool;
+import android.util.SparseArray;
import android.view.Display;
import android.view.accessibility.AccessibilityEvent.WindowsChangeTypes;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
@@ -797,4 +800,49 @@
return new AccessibilityWindowInfo[size];
}
};
+
+ /**
+ * Transfers a sparsearray with lists having {@link AccessibilityWindowInfo}s across an IPC.
+ * The key of this sparsearray is display Id.
+ *
+ * @hide
+ */
+ public static final class WindowListSparseArray
+ extends SparseArray<List<AccessibilityWindowInfo>> implements Parcelable {
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ final int count = size();
+ dest.writeInt(count);
+ for (int i = 0; i < count; i++) {
+ dest.writeParcelableList(valueAt(i), 0);
+ dest.writeInt(keyAt(i));
+ }
+ }
+
+ public static final Parcelable.Creator<WindowListSparseArray> CREATOR =
+ new Parcelable.Creator<WindowListSparseArray>() {
+ public WindowListSparseArray createFromParcel(
+ Parcel source) {
+ final WindowListSparseArray array = new WindowListSparseArray();
+ final ClassLoader loader = array.getClass().getClassLoader();
+ final int count = source.readInt();
+ for (int i = 0; i < count; i++) {
+ List<AccessibilityWindowInfo> windows = new ArrayList<>();
+ source.readParcelableList(windows, loader);
+ array.put(source.readInt(), windows);
+ }
+ return array;
+ }
+
+ public WindowListSparseArray[] newArray(int size) {
+ return new WindowListSparseArray[size];
+ }
+ };
+ }
}
diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java
index fc23c54..358fdc7 100644
--- a/core/java/android/webkit/MimeTypeMap.java
+++ b/core/java/android/webkit/MimeTypeMap.java
@@ -19,7 +19,7 @@
import android.annotation.Nullable;
import android.text.TextUtils;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import java.util.regex.Pattern;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f997d68..31f5055 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -23,6 +23,7 @@
import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
import android.R;
+import android.annotation.CallSuper;
import android.annotation.CheckResult;
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
@@ -10446,10 +10447,15 @@
/**
* This method is called when the selection has changed, in case any
* subclasses would like to know.
+ * </p>
+ * <p class="note"><strong>Note:</strong> Always call the super implementation, which informs
+ * the accessibility subsystem about the selection change.
+ * </p>
*
* @param selStart The new selection start location.
* @param selEnd The new selection end location.
*/
+ @CallSuper
protected void onSelectionChanged(int selStart, int selEnd) {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
}
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index e415b41..4d8378a 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -43,11 +43,6 @@
/**
* Reports that a compatibility change is affecting an app process now.
*
- * <p>Same as {@link #reportChange(long, ApplicationInfo)}, except it receives a package name
- * instead of an {@link ApplicationInfo}
- * object, and finds an app info object based on the package name. Returns {@code true} if
- * there is no installed package by that name.
- *
* <p>Note: for changes that are gated using {@link #isChangeEnabled(long, String)},
* you do not need to call this API directly. The change will be reported for you.
*
@@ -57,6 +52,17 @@
void reportChangeByPackageName(long changeId, in String packageName);
/**
+ * Reports that a compatibility change is affecting an app process now.
+ *
+ * <p>Note: for changes that are gated using {@link #isChangeEnabled(long, int)},
+ * you do not need to call this API directly. The change will be reported for you.
+ *
+ * @param changeId The ID of the compatibility change taking effect.
+ * @param uid The UID of the app in question.
+ */
+ void reportChangeByUid(long changeId, int uid);
+
+ /**
* Query if a given compatibility change is enabled for an app process. This method should
* be called when implementing functionality on behalf of the affected app.
*
@@ -95,4 +101,28 @@
* @return {@code true} if the change is enabled for the current app.
*/
boolean isChangeEnabledByPackageName(long changeId, in String packageName);
+
+ /**
+ * Query if a given compatibility change is enabled for an app process. This method should
+ * be called when implementing functionality on behalf of the affected app.
+ *
+ * <p>Same as {@link #isChangeEnabled(long, ApplicationInfo)}, except it receives a uid
+ * instead of an {@link ApplicationInfo} object, and finds an app info object based on the
+ * uid (or objects if there's more than one package associated with the UID).
+ * Returns {@code true} if there are no installed packages for the required UID, or if the
+ * change is enabled for ALL of the installed packages associated with the provided UID. Please
+ * use a more specific API if you want a different behaviour for multi-package UIDs.
+ *
+ * <p>If this method returns {@code true}, the calling code should implement the compatibility
+ * change, resulting in differing behaviour compared to earlier releases. If this method
+ * returns {@code false}, the calling code should behave as it did in earlier releases.
+ *
+ * <p>It will also report the change as {@link #reportChange(long, int)} would, so there is
+ * no need to call that method directly.
+ *
+ * @param changeId The ID of the compatibility change in question.
+ * @param uid The UID of the app in question.
+ * @return {@code true} if the change is enabled for the current app.
+ */
+ boolean isChangeEnabledByUid(long changeId, int uid);
}
\ No newline at end of file
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 5142d3c..033e9b2 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -239,6 +239,13 @@
public static final String ASSIST_TRANSCRIPTION_MIN_DURATION =
"assist_transcription_min_duration";
+ /**
+ * (boolean) Whether or not to enable an extra section in the notification shade which
+ * filters for "people" related messages.
+ */
+ public static final String NOTIFICATIONS_USE_PEOPLE_FILTERING =
+ "notifications_use_people_filtering";
+
// Flags related to brightline falsing
/**
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 9fff447..fd3cd42 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -35,7 +35,7 @@
import dalvik.system.RuntimeHooks;
import dalvik.system.VMRuntime;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -203,13 +203,15 @@
public static void preForkInit() {
if (DEBUG) Slog.d(TAG, "Entered preForkInit.");
RuntimeInit.enableDdms();
+ // TODO(b/142019040#comment13): Decide whether to load the default instance eagerly, i.e.
+ // MimeMap.setDefault(DefaultMimeMapFactory.create());
/*
* Replace libcore's minimal default mapping between MIME types and file
* extensions with a mapping that's suitable for Android. Android's mapping
* contains many more entries that are derived from IANA registrations but
* with several customizations (extensions, overrides).
*/
- MimeMap.setDefault(DefaultMimeMapFactory.create());
+ MimeMap.setDefaultSupplier(DefaultMimeMapFactory::create);
}
@UnsupportedAppUsage
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index b3ec5f5..a14b093 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -306,6 +306,12 @@
}
private void handleBootCompleted() {
+ try {
+ mSocketOutStream.writeInt(0);
+ } catch (IOException ioe) {
+ throw new IllegalStateException("Error writing to command socket", ioe);
+ }
+
VMRuntime.bootCompleted();
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 9441825..c8ba52a 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -151,17 +151,17 @@
void showShutdownUi(boolean isReboot, String reason);
- // Used to show the dialog when BiometricService starts authentication
- void showBiometricDialog(in Bundle bundle, IBiometricServiceReceiverInternal receiver, int type,
- boolean requireConfirmation, int userId, String opPackageName);
- // Used to hide the dialog when a biometric is authenticated
+ // Used to show the authentication dialog (Biometrics, Device Credential)
+ void showAuthenticationDialog(in Bundle bundle, IBiometricServiceReceiverInternal receiver,
+ int biometricModality, boolean requireConfirmation, int userId, String opPackageName);
+ // Used to notify the authentication dialog that a biometric has been authenticated or rejected
void onBiometricAuthenticated(boolean authenticated, String failureReason);
// Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
void onBiometricHelp(String message);
// Used to set a message - the dialog will dismiss after a certain amount of time
- void onBiometricError(String error);
- // Used to hide the biometric dialog when the AuthenticationClient is stopped
- void hideBiometricDialog();
+ void onBiometricError(int errorCode, String error);
+ // Used to hide the authentication dialog, e.g. when the application cancels authentication
+ void hideAuthenticationDialog();
/**
* Notifies System UI that the display is ready to show system decorations.
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 4c3a177..a845b58 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -99,15 +99,15 @@
void showPinningEnterExitToast(boolean entering);
void showPinningEscapeToast();
- // Used to show the dialog when BiometricService starts authentication
- void showBiometricDialog(in Bundle bundle, IBiometricServiceReceiverInternal receiver, int type,
- boolean requireConfirmation, int userId, String opPackageName);
- // Used to hide the dialog when a biometric is authenticated
+ // Used to show the authentication dialog (Biometrics, Device Credential)
+ void showAuthenticationDialog(in Bundle bundle, IBiometricServiceReceiverInternal receiver,
+ int biometricModality, boolean requireConfirmation, int userId, String opPackageName);
+ // Used to notify the authentication dialog that a biometric has been authenticated or rejected
void onBiometricAuthenticated(boolean authenticated, String failureReason);
// Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
void onBiometricHelp(String message);
// Used to set a message - the dialog will dismiss after a certain amount of time
- void onBiometricError(String error);
- // Used to hide the biometric dialog when the AuthenticationClient is stopped
- void hideBiometricDialog();
+ void onBiometricError(int errorCode, String error);
+ // Used to hide the authentication dialog, e.g. when the application cancels authentication
+ void hideAuthenticationDialog();
}
diff --git a/core/java/com/android/internal/util/MimeIconUtils.java b/core/java/com/android/internal/util/MimeIconUtils.java
index 2230c31..31ea5b2 100644
--- a/core/java/com/android/internal/util/MimeIconUtils.java
+++ b/core/java/com/android/internal/util/MimeIconUtils.java
@@ -27,7 +27,7 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import java.util.Locale;
import java.util.Objects;
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/core/java/com/android/internal/util/function/DecConsumer.java
similarity index 69%
copy from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
copy to core/java/com/android/internal/util/function/DecConsumer.java
index 8b35852..0abb785 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/core/java/com/android/internal/util/function/DecConsumer.java
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package android.hardware.biometrics;
+package com.android.internal.util.function;
+
+import java.util.function.Consumer;
/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
+ * A 10-argument {@link Consumer}
+ *
* @hide
*/
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+public interface DecConsumer<A, B, C, D, E, F, G, H, I, J> {
+ void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j);
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/core/java/com/android/internal/util/function/DecFunction.java
similarity index 69%
copy from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
copy to core/java/com/android/internal/util/function/DecFunction.java
index 8b35852..59fc5e6 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/core/java/com/android/internal/util/function/DecFunction.java
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package android.hardware.biometrics;
+package com.android.internal.util.function;
+
+import java.util.function.Function;
/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
+ * A 10-argument {@link Function}
+ *
* @hide
*/
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+public interface DecFunction<A, B, C, D, E, F, G, H, I, J, R> {
+ R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j);
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/core/java/com/android/internal/util/function/DecPredicate.java
similarity index 69%
copy from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
copy to core/java/com/android/internal/util/function/DecPredicate.java
index 8b35852..975993d 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/core/java/com/android/internal/util/function/DecPredicate.java
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package android.hardware.biometrics;
+package com.android.internal.util.function;
+
+import java.util.function.Predicate;
/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
+ * A 10-argument {@link Predicate}
+ *
* @hide
*/
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+public interface DecPredicate<A, B, C, D, E, F, G, H, I, J> {
+ boolean test(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j);
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/core/java/com/android/internal/util/function/UndecConsumer.java
similarity index 69%
copy from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
copy to core/java/com/android/internal/util/function/UndecConsumer.java
index 8b35852..1a1d4ca 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/core/java/com/android/internal/util/function/UndecConsumer.java
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package android.hardware.biometrics;
+package com.android.internal.util.function;
+
+import java.util.function.Consumer;
/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
+ * A 11-argument {@link Consumer}
+ *
* @hide
*/
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+public interface UndecConsumer<A, B, C, D, E, F, G, H, I, J, K> {
+ void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k);
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/core/java/com/android/internal/util/function/UndecFunction.java
similarity index 69%
rename from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
rename to core/java/com/android/internal/util/function/UndecFunction.java
index 8b35852..5cd324c 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/core/java/com/android/internal/util/function/UndecFunction.java
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package android.hardware.biometrics;
+package com.android.internal.util.function;
+
+import java.util.function.Function;
/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
+ * A 11-argument {@link Function}
+ *
* @hide
*/
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+public interface UndecFunction<A, B, C, D, E, F, G, H, I, J, K, R> {
+ R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k);
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/core/java/com/android/internal/util/function/UndecPredicate.java
similarity index 69%
copy from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
copy to core/java/com/android/internal/util/function/UndecPredicate.java
index 8b35852..c09193e 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/core/java/com/android/internal/util/function/UndecPredicate.java
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-package android.hardware.biometrics;
+package com.android.internal.util.function;
+
+import java.util.function.Predicate;
/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
+ * A 11-argument {@link Predicate}
+ *
* @hide
*/
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+public interface UndecPredicate<A, B, C, D, E, F, G, H, I, J, K> {
+ boolean test(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k);
+}
diff --git a/core/java/com/android/internal/util/function/pooled/OmniFunction.java b/core/java/com/android/internal/util/function/pooled/OmniFunction.java
index d74e715..7a17253 100755
--- a/core/java/com/android/internal/util/function/pooled/OmniFunction.java
+++ b/core/java/com/android/internal/util/function/pooled/OmniFunction.java
@@ -18,6 +18,8 @@
import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
+import com.android.internal.util.function.DecConsumer;
+import com.android.internal.util.function.DecFunction;
import com.android.internal.util.function.HeptConsumer;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexConsumer;
@@ -32,6 +34,8 @@
import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.TriConsumer;
import com.android.internal.util.function.TriFunction;
+import com.android.internal.util.function.UndecConsumer;
+import com.android.internal.util.function.UndecFunction;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@@ -43,62 +47,65 @@
*
* @hide
*/
-abstract class OmniFunction<A, B, C, D, E, F, G, H, I, R> implements
+abstract class OmniFunction<A, B, C, D, E, F, G, H, I, J, K, R> implements
PooledFunction<A, R>, BiFunction<A, B, R>, TriFunction<A, B, C, R>,
QuadFunction<A, B, C, D, R>, QuintFunction<A, B, C, D, E, R>,
HexFunction<A, B, C, D, E, F, R>, HeptFunction<A, B, C, D, E, F, G, R>,
OctFunction<A, B, C, D, E, F, G, H, R>, NonaFunction<A, B, C, D, E, F, G, H, I, R>,
+ DecFunction<A, B, C, D, E, F, G, H, I, J, R>,
+ UndecFunction<A, B, C, D, E, F, G, H, I, J, K, R>,
PooledConsumer<A>, BiConsumer<A, B>, TriConsumer<A, B, C>, QuadConsumer<A, B, C, D>,
QuintConsumer<A, B, C, D, E>, HexConsumer<A, B, C, D, E, F>,
HeptConsumer<A, B, C, D, E, F, G>, OctConsumer<A, B, C, D, E, F, G, H>,
- NonaConsumer<A, B, C, D, E, F, G, H, I>, PooledPredicate<A>, BiPredicate<A, B>,
- PooledSupplier<R>, PooledRunnable, ThrowingRunnable, ThrowingSupplier<R>,
- PooledSupplier.OfInt, PooledSupplier.OfLong, PooledSupplier.OfDouble {
+ NonaConsumer<A, B, C, D, E, F, G, H, I>, DecConsumer<A, B, C, D, E, F, G, H, I, J>,
+ UndecConsumer<A, B, C, D, E, F, G, H, I, J, K>,
+ PooledPredicate<A>, BiPredicate<A, B>, PooledSupplier<R>, PooledRunnable, ThrowingRunnable,
+ ThrowingSupplier<R>, PooledSupplier.OfInt, PooledSupplier.OfLong, PooledSupplier.OfDouble {
- abstract R invoke(A a, B b, C c, D d, E e, F f, G g, H h, I i);
+ abstract R invoke(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k);
@Override
public R apply(A o, B o2) {
- return invoke(o, o2, null, null, null, null, null, null, null);
+ return invoke(o, o2, null, null, null, null, null, null, null, null, null);
}
@Override
public R apply(A o) {
- return invoke(o, null, null, null, null, null, null, null, null);
+ return invoke(o, null, null, null, null, null, null, null, null, null, null);
}
- public abstract <V> OmniFunction<A, B, C, D, E, F, G, H, I, V> andThen(
+ public abstract <V> OmniFunction<A, B, C, D, E, F, G, H, I, J, K, V> andThen(
Function<? super R, ? extends V> after);
- public abstract OmniFunction<A, B, C, D, E, F, G, H, I, R> negate();
+ public abstract OmniFunction<A, B, C, D, E, F, G, H, I, J, K, R> negate();
@Override
public void accept(A o, B o2) {
- invoke(o, o2, null, null, null, null, null, null, null);
+ invoke(o, o2, null, null, null, null, null, null, null, null, null);
}
@Override
public void accept(A o) {
- invoke(o, null, null, null, null, null, null, null, null);
+ invoke(o, null, null, null, null, null, null, null, null, null, null);
}
@Override
public void run() {
- invoke(null, null, null, null, null, null, null, null, null);
+ invoke(null, null, null, null, null, null, null, null, null, null, null);
}
@Override
public R get() {
- return invoke(null, null, null, null, null, null, null, null, null);
+ return invoke(null, null, null, null, null, null, null, null, null, null, null);
}
@Override
public boolean test(A o, B o2) {
- return (Boolean) invoke(o, o2, null, null, null, null, null, null, null);
+ return (Boolean) invoke(o, o2, null, null, null, null, null, null, null, null, null);
}
@Override
public boolean test(A o) {
- return (Boolean) invoke(o, null, null, null, null, null, null, null, null);
+ return (Boolean) invoke(o, null, null, null, null, null, null, null, null, null, null);
}
@Override
@@ -113,72 +120,92 @@
@Override
public R apply(A a, B b, C c) {
- return invoke(a, b, c, null, null, null, null, null, null);
+ return invoke(a, b, c, null, null, null, null, null, null, null, null);
}
@Override
public void accept(A a, B b, C c) {
- invoke(a, b, c, null, null, null, null, null, null);
+ invoke(a, b, c, null, null, null, null, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d) {
- return invoke(a, b, c, d, null, null, null, null, null);
+ return invoke(a, b, c, d, null, null, null, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e) {
- return invoke(a, b, c, d, e, null, null, null, null);
+ return invoke(a, b, c, d, e, null, null, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e, F f) {
- return invoke(a, b, c, d, e, f, null, null, null);
+ return invoke(a, b, c, d, e, f, null, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e, F f, G g) {
- return invoke(a, b, c, d, e, f, g, null, null);
+ return invoke(a, b, c, d, e, f, g, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e, F f, G g, H h) {
- return invoke(a, b, c, d, e, f, g, h, null);
+ return invoke(a, b, c, d, e, f, g, h, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i) {
- return invoke(a, b, c, d, e, f, g, h, i);
+ return invoke(a, b, c, d, e, f, g, h, i, null, null);
+ }
+
+ @Override
+ public R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) {
+ return invoke(a, b, c, d, e, f, g, h, i, j, null);
+ }
+
+ @Override
+ public R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) {
+ return invoke(a, b, c, d, e, f, g, h, i, j, k);
}
@Override
public void accept(A a, B b, C c, D d) {
- invoke(a, b, c, d, null, null, null, null, null);
+ invoke(a, b, c, d, null, null, null, null, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e) {
- invoke(a, b, c, d, e, null, null, null, null);
+ invoke(a, b, c, d, e, null, null, null, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e, F f) {
- invoke(a, b, c, d, e, f, null, null, null);
+ invoke(a, b, c, d, e, f, null, null, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e, F f, G g) {
- invoke(a, b, c, d, e, f, g, null, null);
+ invoke(a, b, c, d, e, f, g, null, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e, F f, G g, H h) {
- invoke(a, b, c, d, e, f, g, h, null);
+ invoke(a, b, c, d, e, f, g, h, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i) {
- invoke(a, b, c, d, e, f, g, h, i);
+ invoke(a, b, c, d, e, f, g, h, i, null, null);
+ }
+
+ @Override
+ public void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) {
+ invoke(a, b, c, d, e, f, g, h, i, j, null);
+ }
+
+ @Override
+ public void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) {
+ invoke(a, b, c, d, e, f, g, h, i, j, k);
}
@Override
@@ -192,5 +219,5 @@
}
@Override
- public abstract OmniFunction<A, B, C, D, E, F, G, H, I, R> recycleOnUse();
+ public abstract OmniFunction<A, B, C, D, E, F, G, H, I, J, K, R> recycleOnUse();
}
diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambda.java b/core/java/com/android/internal/util/function/pooled/PooledLambda.java
index c00932e..b9bf933 100755
--- a/core/java/com/android/internal/util/function/pooled/PooledLambda.java
+++ b/core/java/com/android/internal/util/function/pooled/PooledLambda.java
@@ -21,6 +21,8 @@
import android.os.Message;
+import com.android.internal.util.function.DecConsumer;
+import com.android.internal.util.function.DecFunction;
import com.android.internal.util.function.HeptConsumer;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexConsumer;
@@ -35,6 +37,8 @@
import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.TriConsumer;
import com.android.internal.util.function.TriFunction;
+import com.android.internal.util.function.UndecConsumer;
+import com.android.internal.util.function.UndecFunction;
import com.android.internal.util.function.pooled.PooledLambdaImpl.LambdaType.ReturnType;
import java.util.function.BiConsumer;
@@ -181,7 +185,7 @@
A arg1) {
return acquire(PooledLambdaImpl.sPool,
function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -198,7 +202,7 @@
A arg1) {
return acquire(PooledLambdaImpl.sPool,
function, 1, 0, ReturnType.BOOLEAN, arg1, null, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -215,7 +219,7 @@
A arg1) {
return acquire(PooledLambdaImpl.sPool,
function, 1, 0, ReturnType.OBJECT, arg1, null, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -246,7 +250,7 @@
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -266,7 +270,7 @@
A arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -284,7 +288,7 @@
A arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 0, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -302,7 +306,7 @@
A arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 0, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -320,7 +324,7 @@
ArgumentPlaceholder<A> arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -338,7 +342,7 @@
ArgumentPlaceholder<A> arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -356,7 +360,7 @@
ArgumentPlaceholder<A> arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -374,7 +378,7 @@
A arg1, ArgumentPlaceholder<B> arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -392,7 +396,7 @@
A arg1, ArgumentPlaceholder<B> arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -410,7 +414,7 @@
A arg1, ArgumentPlaceholder<B> arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -442,7 +446,7 @@
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -463,7 +467,7 @@
A arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -482,7 +486,7 @@
A arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 0, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -501,7 +505,7 @@
ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -520,7 +524,7 @@
ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -539,7 +543,7 @@
A arg1, ArgumentPlaceholder<B> arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -558,7 +562,7 @@
A arg1, ArgumentPlaceholder<B> arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -577,7 +581,7 @@
A arg1, B arg2, ArgumentPlaceholder<C> arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -596,7 +600,7 @@
A arg1, B arg2, ArgumentPlaceholder<C> arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -629,7 +633,7 @@
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -651,7 +655,7 @@
A arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -671,7 +675,7 @@
A arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -691,7 +695,7 @@
ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -711,7 +715,7 @@
ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -731,7 +735,7 @@
A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -751,7 +755,7 @@
A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -771,7 +775,7 @@
A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -791,7 +795,7 @@
A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -811,7 +815,7 @@
A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -831,7 +835,7 @@
A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -865,7 +869,7 @@
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -888,7 +892,7 @@
A arg1, B arg2, C arg3, D arg4, E arg5) {
return acquire(PooledLambdaImpl.sPool,
function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -909,7 +913,7 @@
function, A arg1, B arg2, C arg3, D arg4, E arg5) {
return acquire(PooledLambdaImpl.sPool,
function, 5, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -945,7 +949,7 @@
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -969,7 +973,7 @@
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
return acquire(PooledLambdaImpl.sPool,
function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
- null);
+ null, null, null);
}
/**
@@ -991,7 +995,7 @@
? extends R> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
return acquire(PooledLambdaImpl.sPool,
function, 6, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
- null);
+ null, null, null);
}
/**
@@ -1028,7 +1032,7 @@
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -1053,7 +1057,7 @@
? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
return acquire(PooledLambdaImpl.sPool,
function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
- null);
+ null, null, null);
}
/**
@@ -1077,7 +1081,7 @@
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
return acquire(PooledLambdaImpl.sPool,
function, 7, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
- null);
+ null, null, null);
}
/**
@@ -1115,7 +1119,7 @@
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -1142,7 +1146,7 @@
H arg8) {
return acquire(PooledLambdaImpl.sPool,
function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- null);
+ null, null, null);
}
/**
@@ -1167,7 +1171,7 @@
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8) {
return acquire(PooledLambdaImpl.sPool,
function, 8, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- null);
+ null, null, null);
}
/**
@@ -1207,7 +1211,7 @@
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -1235,7 +1239,7 @@
E arg5, F arg6, G arg7, H arg8, I arg9) {
return acquire(PooledLambdaImpl.sPool,
function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- arg9);
+ arg9, null, null);
}
/**
@@ -1261,7 +1265,7 @@
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9) {
return acquire(PooledLambdaImpl.sPool,
function, 9, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- arg9);
+ arg9, null, null);
}
/**
@@ -1302,7 +1306,209 @@
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- arg9);
+ arg9, null, null);
+ return Message.obtain().setCallback(callback.recycleOnUse());
+ }
+ }
+
+ /**
+ * {@link PooledRunnable} factory
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @return a {@link PooledRunnable}, equivalent to lambda:
+ * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) }
+ */
+ static <A, B, C, D, E, F, G, H, I, J> PooledRunnable obtainRunnable(
+ DecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J> function, A arg1, B arg2, C arg3,
+ D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) {
+ return acquire(PooledLambdaImpl.sPool,
+ function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+ arg9, arg10, null);
+ }
+
+ /**
+ * {@link PooledSupplier} factory
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @return a {@link PooledSupplier}, equivalent to lambda:
+ * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) }
+ */
+ static <A, B, C, D, E, F, G, H, I, J, R> PooledSupplier<R> obtainSupplier(
+ DecFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J, ? extends R> function,
+ A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) {
+ return acquire(PooledLambdaImpl.sPool,
+ function, 10, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+ arg9, arg10, null);
+ }
+
+ /**
+ * Factory of {@link Message}s that contain an
+ * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
+ * {@link Message#getCallback internal callback}.
+ *
+ * The callback is equivalent to one obtainable via
+ * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
+ *
+ * Note that using this method with {@link android.os.Handler#handleMessage}
+ * is more efficient than the alternative of {@link android.os.Handler#post}
+ * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
+ * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
+ *
+ * You may optionally set a {@link Message#what} for the message if you want to be
+ * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
+ * there's no need to do so
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
+ * arg7, arg8, arg9, arg10) } when handled
+ */
+ static <A, B, C, D, E, F, G, H, I, J> Message obtainMessage(
+ DecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J> function, A arg1, B arg2, C arg3,
+ D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) {
+ synchronized (Message.sPoolSync) {
+ PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
+ function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
+ arg8, arg9, arg10, null);
+ return Message.obtain().setCallback(callback.recycleOnUse());
+ }
+ }
+
+ /**
+ * {@link PooledRunnable} factory
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @param arg11 parameter supplied to {@code function} on call
+ * @return a {@link PooledRunnable}, equivalent to lambda:
+ * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
+ * arg11) }
+ */
+ static <A, B, C, D, E, F, G, H, I, J, K> PooledRunnable obtainRunnable(
+ UndecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J, ? super K> function, A arg1, B arg2,
+ C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11) {
+ return acquire(PooledLambdaImpl.sPool,
+ function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+ arg9, arg10, arg11);
+ }
+
+ /**
+ * {@link PooledSupplier} factory
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @param arg11 parameter supplied to {@code function} on call
+ * @return a {@link PooledSupplier}, equivalent to lambda:
+ * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
+ * arg11) }
+ */
+ static <A, B, C, D, E, F, G, H, I, J, K, R> PooledSupplier<R> obtainSupplier(
+ UndecFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J, ? super K, ? extends R> function,
+ A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10,
+ K arg11) {
+ return acquire(PooledLambdaImpl.sPool,
+ function, 11, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+ arg9, arg10, arg11);
+ }
+
+ /**
+ * Factory of {@link Message}s that contain an
+ * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
+ * {@link Message#getCallback internal callback}.
+ *
+ * The callback is equivalent to one obtainable via
+ * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
+ *
+ * Note that using this method with {@link android.os.Handler#handleMessage}
+ * is more efficient than the alternative of {@link android.os.Handler#post}
+ * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
+ * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
+ *
+ * You may optionally set a {@link Message#what} for the message if you want to be
+ * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
+ * there's no need to do so
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @param arg11 parameter supplied to {@code function} on call
+ * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
+ * arg7, arg8, arg9, arg10, arg11) } when handled
+ */
+ static <A, B, C, D, E, F, G, H, I, J, K> Message obtainMessage(
+ UndecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J, ? super K> function, A arg1, B arg2,
+ C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11) {
+ synchronized (Message.sPoolSync) {
+ PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
+ function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
+ arg8, arg9, arg10, arg11);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
index e12c031..c7502ef 100755
--- a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
+++ b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
@@ -26,6 +26,9 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.BitUtils;
import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.DecConsumer;
+import com.android.internal.util.function.DecFunction;
+import com.android.internal.util.function.DecPredicate;
import com.android.internal.util.function.HeptConsumer;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HeptPredicate;
@@ -47,6 +50,9 @@
import com.android.internal.util.function.TriConsumer;
import com.android.internal.util.function.TriFunction;
import com.android.internal.util.function.TriPredicate;
+import com.android.internal.util.function.UndecConsumer;
+import com.android.internal.util.function.UndecFunction;
+import com.android.internal.util.function.UndecPredicate;
import java.util.Arrays;
import java.util.Objects;
@@ -63,12 +69,12 @@
* @hide
*/
final class PooledLambdaImpl<R> extends OmniFunction<Object,
- Object, Object, Object, Object, Object, Object, Object, Object, R> {
+ Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, R> {
private static final boolean DEBUG = false;
private static final String LOG_TAG = "PooledLambdaImpl";
- private static final int MAX_ARGS = 9;
+ private static final int MAX_ARGS = 11;
private static final int MAX_POOL_SIZE = 50;
@@ -134,7 +140,7 @@
/**
* Bit schema:
- * AAAAAAAAABCDEEEEEEFFFFFF
+ * AAAAAAAAAAABCDEEEEEEFFFFFF
*
* Where:
* A - whether {@link #mArgs arg} at corresponding index was specified at
@@ -171,18 +177,18 @@
@Override
R invoke(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) {
+ Object a8, Object a9, Object a10, Object a11) {
checkNotRecycled();
if (DEBUG) {
Log.i(LOG_TAG, this + ".invoke("
+ commaSeparateFirstN(
- new Object[] { a1, a2, a3, a4, a5, a6, a7, a8, a9 },
+ new Object[] { a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 },
LambdaType.decodeArgCount(getFlags(MASK_EXPOSED_AS)))
+ ")");
}
final boolean notUsed = fillInArg(a1) && fillInArg(a2) && fillInArg(a3) && fillInArg(a4)
&& fillInArg(a5) && fillInArg(a6) && fillInArg(a7) && fillInArg(a8)
- && fillInArg(a9);
+ && fillInArg(a9) && fillInArg(a10) && fillInArg(a11);
int argCount = LambdaType.decodeArgCount(getFlags(MASK_FUNC_TYPE));
if (argCount != LambdaType.MASK_ARG_COUNT) {
for (int i = 0; i < argCount; i++) {
@@ -410,6 +416,48 @@
}
}
} break;
+
+ case 10: {
+ switch (returnType) {
+ case LambdaType.ReturnType.VOID: {
+ ((DecConsumer) mFunc).accept(popArg(0), popArg(1),
+ popArg(2), popArg(3), popArg(4), popArg(5),
+ popArg(6), popArg(7), popArg(8), popArg(9));
+ return null;
+ }
+ case LambdaType.ReturnType.BOOLEAN: {
+ return (R) (Object) ((DecPredicate) mFunc).test(popArg(0),
+ popArg(1), popArg(2), popArg(3), popArg(4),
+ popArg(5), popArg(6), popArg(7), popArg(8), popArg(9));
+ }
+ case LambdaType.ReturnType.OBJECT: {
+ return (R) ((DecFunction) mFunc).apply(popArg(0), popArg(1),
+ popArg(2), popArg(3), popArg(4), popArg(5),
+ popArg(6), popArg(7), popArg(8), popArg(9));
+ }
+ }
+ } break;
+
+ case 11: {
+ switch (returnType) {
+ case LambdaType.ReturnType.VOID: {
+ ((UndecConsumer) mFunc).accept(popArg(0), popArg(1),
+ popArg(2), popArg(3), popArg(4), popArg(5),
+ popArg(6), popArg(7), popArg(8), popArg(9), popArg(10));
+ return null;
+ }
+ case LambdaType.ReturnType.BOOLEAN: {
+ return (R) (Object) ((UndecPredicate) mFunc).test(popArg(0),
+ popArg(1), popArg(2), popArg(3), popArg(4),
+ popArg(5), popArg(6), popArg(7), popArg(8), popArg(9), popArg(10));
+ }
+ case LambdaType.ReturnType.OBJECT: {
+ return (R) ((UndecFunction) mFunc).apply(popArg(0), popArg(1),
+ popArg(2), popArg(3), popArg(4), popArg(5),
+ popArg(6), popArg(7), popArg(8), popArg(9), popArg(10));
+ }
+ }
+ } break;
}
throw new IllegalStateException("Unknown function type: " + LambdaType.toString(funcType));
}
@@ -475,7 +523,7 @@
*/
static <E extends PooledLambda> E acquire(Pool pool, Object func,
int fNumArgs, int numPlaceholders, int fReturnType, Object a, Object b, Object c,
- Object d, Object e, Object f, Object g, Object h, Object i) {
+ Object d, Object e, Object f, Object g, Object h, Object i, Object j, Object k) {
PooledLambdaImpl r = acquire(pool);
if (DEBUG) {
Log.i(LOG_TAG,
@@ -493,6 +541,8 @@
+ ", g = " + g
+ ", h = " + h
+ ", i = " + i
+ + ", j = " + j
+ + ", k = " + k
+ ")");
}
r.mFunc = Preconditions.checkNotNull(func);
@@ -508,6 +558,8 @@
setIfInBounds(r.mArgs, 6, g);
setIfInBounds(r.mArgs, 7, h);
setIfInBounds(r.mArgs, 8, i);
+ setIfInBounds(r.mArgs, 9, j);
+ setIfInBounds(r.mArgs, 10, k);
return (E) r;
}
@@ -564,13 +616,13 @@
@Override
public OmniFunction<Object, Object, Object, Object, Object, Object, Object, Object, Object,
- R> negate() {
+ Object, Object, R> negate() {
throw new UnsupportedOperationException();
}
@Override
public <V> OmniFunction<Object, Object, Object, Object, Object, Object, Object, Object, Object,
- V> andThen(Function<? super R, ? extends V> after) {
+ Object, Object, V> andThen(Function<? super R, ? extends V> after) {
throw new UnsupportedOperationException();
}
@@ -591,7 +643,7 @@
@Override
public OmniFunction<Object, Object, Object, Object, Object, Object, Object, Object, Object,
- R> recycleOnUse() {
+ Object, Object, R> recycleOnUse() {
if (DEBUG) Log.i(LOG_TAG, this + ".recycleOnUse()");
mFlags |= FLAG_RECYCLE_ON_USE;
return this;
@@ -683,6 +735,8 @@
case 7: return "Hept";
case 8: return "Oct";
case 9: return "Nona";
+ case 10: return "Dec";
+ case 11: return "Undec";
default: return "" + argCount + "arg";
}
}
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index cc468f4..0e078dd 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -30,6 +30,7 @@
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.PointerIcon;
+import android.view.WindowInsets.Type.InsetType;
import com.android.internal.os.IResultReceiver;
@@ -75,6 +76,10 @@
}
@Override
+ public void showInsets(@InsetType int types, boolean fromIme) throws RemoteException {
+ }
+
+ @Override
public void moved(int newX, int newY) {
}
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index f2a4f4f..9445319 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -85,7 +85,8 @@
// Dalvik other extra sections.
HEAP_DALVIK_OTHER_LINEARALLOC,
HEAP_DALVIK_OTHER_ACCOUNTING,
- HEAP_DALVIK_OTHER_CODE_CACHE,
+ HEAP_DALVIK_OTHER_ZYGOTE_CODE_CACHE,
+ HEAP_DALVIK_OTHER_APP_CODE_CACHE,
HEAP_DALVIK_OTHER_COMPILER_METADATA,
HEAP_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE,
@@ -282,9 +283,10 @@
is_swappable = true;
} else if (base::EndsWith(name, ".vdex")) {
which_heap = HEAP_DEX;
- // Handle system@framework@boot and system/framework/boot
+ // Handle system@framework@boot and system/framework/boot|apex
if ((strstr(name.c_str(), "@boot") != nullptr) ||
- (strstr(name.c_str(), "/boot"))) {
+ (strstr(name.c_str(), "/boot") != nullptr) ||
+ (strstr(name.c_str(), "/apex") != nullptr)) {
sub_heap = HEAP_DEX_BOOT_VDEX;
} else {
sub_heap = HEAP_DEX_APP_VDEX;
@@ -295,9 +297,10 @@
is_swappable = true;
} else if (base::EndsWith(name, ".art") || base::EndsWith(name, ".art]")) {
which_heap = HEAP_ART;
- // Handle system@framework@boot* and system/framework/boot*
+ // Handle system@framework@boot* and system/framework/boot|apex*
if ((strstr(name.c_str(), "@boot") != nullptr) ||
- (strstr(name.c_str(), "/boot"))) {
+ (strstr(name.c_str(), "/boot") != nullptr) ||
+ (strstr(name.c_str(), "/apex") != nullptr)) {
sub_heap = HEAP_ART_BOOT;
} else {
sub_heap = HEAP_ART_APP;
@@ -309,9 +312,18 @@
which_heap = HEAP_GL_DEV;
} else if (base::StartsWith(name, "/dev/ashmem/CursorWindow")) {
which_heap = HEAP_CURSOR;
+ } else if (base::StartsWith(name, "/dev/ashmem/jit-zygote-cache")) {
+ which_heap = HEAP_DALVIK_OTHER;
+ sub_heap = HEAP_DALVIK_OTHER_ZYGOTE_CODE_CACHE;
} else if (base::StartsWith(name, "/dev/ashmem")) {
which_heap = HEAP_ASHMEM;
}
+ } else if (base::StartsWith(name, "/memfd:jit-cache")) {
+ which_heap = HEAP_DALVIK_OTHER;
+ sub_heap = HEAP_DALVIK_OTHER_APP_CODE_CACHE;
+ } else if (base::StartsWith(name, "/memfd:jit-zygote-cache")) {
+ which_heap = HEAP_DALVIK_OTHER;
+ sub_heap = HEAP_DALVIK_OTHER_ZYGOTE_CODE_CACHE;
} else if (base::StartsWith(name, "[anon:")) {
which_heap = HEAP_UNKNOWN;
if (base::StartsWith(name, "[anon:dalvik-")) {
@@ -339,7 +351,7 @@
sub_heap = HEAP_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE;
} else if (base::StartsWith(name, "[anon:dalvik-jit-code-cache") ||
base::StartsWith(name, "[anon:dalvik-data-code-cache")) {
- sub_heap = HEAP_DALVIK_OTHER_CODE_CACHE;
+ sub_heap = HEAP_DALVIK_OTHER_APP_CODE_CACHE;
} else if (base::StartsWith(name, "[anon:dalvik-CompilerMetadata")) {
sub_heap = HEAP_DALVIK_OTHER_COMPILER_METADATA;
} else {
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 8aa6f86..3cefeea 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -191,9 +191,21 @@
return -1;
}
+static bool verifyGroup(JNIEnv* env, int grp)
+{
+ if (grp < SP_DEFAULT || grp >= SP_CNT) {
+ signalExceptionForError(env, EINVAL, grp);
+ return false;
+ }
+ return true;
+}
+
void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int tid, jint grp)
{
ALOGV("%s tid=%d grp=%" PRId32, __func__, tid, grp);
+ if (!verifyGroup(env, grp)) {
+ return;
+ }
SchedPolicy sp = (SchedPolicy) grp;
int res = set_sched_policy(tid, sp);
if (res != NO_ERROR) {
@@ -204,6 +216,9 @@
void android_os_Process_setThreadGroupAndCpuset(JNIEnv* env, jobject clazz, int tid, jint grp)
{
ALOGV("%s tid=%d grp=%" PRId32, __func__, tid, grp);
+ if (!verifyGroup(env, grp)) {
+ return;
+ }
SchedPolicy sp = (SchedPolicy) grp;
int res = set_sched_policy(tid, sp);
@@ -234,6 +249,9 @@
grp = SP_FOREGROUND;
isDefault = true;
}
+ if (!verifyGroup(env, grp)) {
+ return;
+ }
SchedPolicy sp = (SchedPolicy) grp;
if (kDebugPolicy) {
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index c380fd5..59dab0c8 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -148,7 +148,7 @@
mFdEvents = events;
int fd = mInputConsumer.getChannel()->getFd();
if (events) {
- mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL);
+ mMessageQueue->getLooper()->addFd(fd, 0, events, this, nullptr);
} else {
mMessageQueue->getLooper()->removeFd(fd);
}
@@ -169,7 +169,7 @@
if (events & ALOOPER_EVENT_INPUT) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
- status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL);
+ status_t status = consumeEvents(env, false /*consumeBatches*/, -1, nullptr);
mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
return status == OK || status == NO_MEMORY ? 1 : 0;
}
@@ -230,7 +230,7 @@
*outConsumedBatch = false;
}
- ScopedLocalRef<jobject> receiverObj(env, NULL);
+ ScopedLocalRef<jobject> receiverObj(env, nullptr);
bool skipCallbacks = false;
for (;;) {
uint32_t seq;
@@ -305,7 +305,7 @@
default:
assert(false); // InputConsumer should prevent this from ever happening
- inputEventObj = NULL;
+ inputEventObj = nullptr;
}
if (inputEventObj) {
@@ -337,13 +337,13 @@
jobject inputChannelObj, jobject messageQueueObj) {
sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
inputChannelObj);
- if (inputChannel == NULL) {
+ if (inputChannel == nullptr) {
jniThrowRuntimeException(env, "InputChannel is not initialized.");
return 0;
}
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
- if (messageQueue == NULL) {
+ if (messageQueue == nullptr) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 1ca9383..d5cd278 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -1244,6 +1244,15 @@
return reinterpret_cast<jlong>(transaction.release());
}
+static jlong nativeMirrorSurface(JNIEnv* env, jclass clazz, jlong mirrorOfObj) {
+ sp<SurfaceComposerClient> client = SurfaceComposerClient::getDefault();
+ SurfaceControl *mirrorOf = reinterpret_cast<SurfaceControl*>(mirrorOfObj);
+ sp<SurfaceControl> surface = client->mirrorSurface(mirrorOf);
+
+ surface->incStrong((void *)nativeCreate);
+ return reinterpret_cast<jlong>(surface.get());
+}
+
// ----------------------------------------------------------------------------
static const JNINativeMethod sSurfaceControlMethods[] = {
@@ -1394,6 +1403,8 @@
(void*)nativeReadTransactionFromParcel },
{"nativeWriteTransactionToParcel", "(JLandroid/os/Parcel;)V",
(void*)nativeWriteTransactionToParcel },
+ {"nativeMirrorSurface", "(J)J",
+ (void*)nativeMirrorSurface },
};
int register_android_view_SurfaceControl(JNIEnv* env)
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index d54b6b0..d01a45c 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -118,13 +118,15 @@
message ActivityRecordProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
- optional .com.android.server.wm.ConfigurationContainerProto configuration_container = 1;
+ // To be removed soon.
+ optional .com.android.server.wm.ConfigurationContainerProto configuration_container = 1 [deprecated=true];
optional .com.android.server.wm.IdentifierProto identifier = 2;
optional string state = 3;
optional bool visible = 4;
optional bool front_of_task = 5;
optional int32 proc_id = 6;
optional bool translucent = 7;
+ optional .com.android.server.wm.AppWindowTokenProto app_window_token = 8;
}
message KeyguardControllerProto {
diff --git a/core/proto/android/telecomm/enums.proto b/core/proto/android/telecomm/enums.proto
index 7a2ba62..5ca4a85 100644
--- a/core/proto/android/telecomm/enums.proto
+++ b/core/proto/android/telecomm/enums.proto
@@ -110,6 +110,24 @@
* {@link android.telecom.Connection#CAPABILITY_CAN_PULL_CALL}.
*/
PULLING = 10;
+
+ /**
+ * Indicates that an incoming call has been answered by the in-call UI, but Telephony hasn't yet
+ * set the call to active.
+ */
+ ANSWERED = 11;
+
+ /**
+ * Indicates that the call is undergoing audio processing by a different app in the background.
+ * @see android.telecom.Call#STATE_AUDIO_PROCESSING
+ */
+ AUDIO_PROCESSING = 12;
+
+ /**
+ * Indicates that the call is in a fake ringing state.
+ * @see android.telecom.Call#STATE_SIMULATED_RINGING
+ */
+ SIMULATED_RINGING = 13;
}
// Disconnect causes for a call. Primarily used by android/telecom/DisconnectCause.java
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7a0d0cb..18f8d7b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -794,6 +794,18 @@
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />
+ <!-- @SystemApi @TestApi Allows an application to forward cell broadcast messages to the cell
+ broadcast module. This is required in order to bind to the cell broadcast service, and
+ ensures that only the system can forward messages to it.
+
+ <p>Protection level: signature|privileged
+
+ @hide -->
+ <permission android:name="android.permission.BIND_CELL_BROADCAST_SERVICE"
+ android:label="@string/permlab_bindCellBroadcastService"
+ android:description="@string/permdesc_bindCellBroadcastService"
+ android:protectionLevel="signature" />
+
<!-- @SystemApi @TestApi Allows an application to read previously received cell broadcast
messages and to register a content observer to get notifications when
a cell broadcast has been received and added to the database. For
@@ -2552,19 +2564,6 @@
android:label="@string/permlab_readSyncStats"
android:protectionLevel="normal" />
- <!-- ==================================================== -->
- <!-- Permissions related to accessibility -->
- <!-- ==================================================== -->
- <eat-comment />
-
- <!-- Allows applications to define the accessibility shortcut target.
- <p>Protection level: normal
- -->
- <permission android:name="android.permission.ACCESSIBILITY_SHORTCUT_TARGET"
- android:description="@string/permdesc_accessibilityShortcutTarget"
- android:label="@string/permlab_accessibilityShortcutTarget"
- android:protectionLevel="normal" />
-
<!-- ============================================ -->
<!-- Permissions for low-level system interaction -->
<!-- ============================================ -->
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index a44b137a..dd9eafe 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Laat die program toe om SMS-boodskappe te ontvang en te verwerk. Dit beteken dat die program boodskappe wat na jou toestel gestuur is, kan monitor of uitvee, sonder dat jy dit gesien het."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ontvang teksboodskappe (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Laat die program toe om MMS-boodskappe te ontvang en te verwerk. Dit beteken dat die program boodskappe wat na jou toestel gestuur is kan monitor of uitvee, sonder dat jy dit gesien het."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lees seluitsending-boodskappe"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Laat die program toe om seluitsending-boodskappe te lees wat deur jou toestel ontvang word. Seluitsending-waarskuwings word in sommige plekke afgelewer om jou van noodsituasies te waarsku. Kwaadwillige programme mag inmeng met die prestasie of die werking van jou toestel wanneer \'n noodgeval se seluitsending ontvang word."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lees ingetekende nuus"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Laat die program toe om Moenie Steur Nie-opstelling te lees en skryf."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"begin kyk van toestemminggebruik"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Laat die houer toe om die toestemminggebruik vir \'n program te begin. Behoort nooit vir normale programme nodig te wees nie."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"toeganklikheidkortpadteiken"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Laat \'n program toe om die toeganklikheidkortpadteiken te definieer."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Stel wagwoordreëls"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Beheer die lengte en die karakters wat in skermslotwagwoorde en -PIN\'e toegelaat word."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor pogings om skerm te ontsluit"</string>
@@ -1075,7 +1081,7 @@
<string name="Midnight" msgid="5630806906897892201">"Middernag"</string>
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
- <string name="selectAll" msgid="6876518925844129331">"Kies alle"</string>
+ <string name="selectAll" msgid="6876518925844129331">"Kies alles"</string>
<string name="cut" msgid="3092569408438626261">"Sny"</string>
<string name="copy" msgid="2681946229533511987">"Kopieer"</string>
<string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"Kon nie na knipbord toe kopieer nie"</string>
@@ -1356,11 +1362,13 @@
<string name="usb_power_notification_message" msgid="4647527153291917218">"Laai tans gekoppelde toestel. Tik vir meer opsies."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analoë oudiobykomstigheid bespeur"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Die aangehegde toestel is nie met hierdie foon versoenbaar nie. Tik om meer te wete te kom."</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouting gekoppel"</string>
<string name="adb_active_notification_message" msgid="7463062450474107752">"Tik om USB-ontfouting af te skakel"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Kies om USB-ontfouting te deaktiveer."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Toetsraamwerkmodus is geaktiveer"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Voer \'n fabriekterugstelling uit om Toetsraamwerkmodus te deaktiveer."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Reekskonsole is geaktiveer"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Werkverrigting word beïnvloed. Gaan selflaaiprogram na om te deaktiveer."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vloeistof of vuilgoed in USB-poort"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-poort is outomaties gedeaktiveer. Tik om meer te wete te kom."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK om USB-poort te gebruik"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Ongekategoriseer"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Jy stel die belangrikheid van hierdie kennisgewings."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Dit is belangrik as gevolg van die mense wat betrokke is."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Laat <xliff:g id="APP">%1$s</xliff:g> toe om \'n nuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> te skep (\'n gebruiker met hierdie rekening bestaan reeds)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Laat <xliff:g id="APP">%1$s</xliff:g> toe om \'n nuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> te skep?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Voeg \'n taal by"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Streekvoorkeur"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Voer taalnaam in"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index db758e3..a007c9d 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"መተግበሪያው የኤስ.ኤም.ኤስ. መልዕክቶችን እንዲያነብ እና እንዲያካሂድ ይፈቅዳል። ይህ ማለት መተግበሪያው ወደ መሳሪያህ የተላኩ መልዕክቶችን ላንተ ሳያሳይህ ሊቆጣጠር ወይም ሊሰርዝ ይችላል።"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"የፅሁፍ መልዕክቶችን ተቀበል (ኤም.ኤም.ኤስ.)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"መተግበሪያው የኤም.ኤም.ኤስ. መልዕክቶችን እንዲያነብ እና እንዲያካሂድ ይፈቅዳል። ይህ ማለት መተግበሪያው ወደ መሳሪያህ የተላኩ መልዕክቶችን ላንተ ሳያሳይህ ሊቆጣጠር ወይም ሊሰርዝ ይችላል።"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"የህዋስ ስርጭት መልዕክቶችን አንብብ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"መሣሪያህ የህዋስ ስርጭት መልዕክቶች ሲቀበል መተግበሪያው እንዲያነበው ይፈቅድለታል። የህዋስ ስርጭት ማንቂያዎች አስቸኳይ ሁኔታዎች ሲያጋጥሙ አንዳንድ አካባቢዎች ላይ የሚላኩ ናቸው። የህዋስ ስርጭት ሲደርስ ተንኮል አዘል መተግበሪያዎች በመሣሪያህ አፈጻጸም ወይም አሰራር ላይ ጣልቃ ሊገቡ ይችላሉ።"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"የምዝገባ መግቦች አንበብ"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"መተግበሪያው የአትረብሽ ውቅረትን እንዲያነብብ እና እንዲጸፍ ይፈቅዳል።"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"የእይታ ፈቃድ መጠቀምን መጀመር"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ያዢው ለአንድ መተግበሪያ የፈቃድ አጠቃቀሙን እንዲያስጀምር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"የተደራሽነት አቋራጭ ዒላማ"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"መተግበሪያ የተደራሽነት አቋራጭ ዒላማን ለመግለጽ እንዲችል ይፈቅድለታል።"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"በማያ ገጽ መቆለፊያ የይለፍ ቃሎች እና ፒኖች ውስጥ የሚፈቀዱ ቁምፊዎችን እና ርዝመታቸውን ተቆጣጠር።"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"የማሳያ-ክፈት ሙከራዎችን ክትትል ያድርጉባቸው"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ማረሚያ ላለማንቃት ምረጥ።"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"የሙከራ ጥቅል ሁነታ ነቅቷል"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"የመሞከሪያ ጥቅል ሁነታን ለማሰናከል የፋብሪካ ዳግም ቅንብርን ይሞክሩ።"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"ተከታታይ ኮንሶል ነቅቷል"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"አፈጻጸም ተጽዕኖ አርፎበታል። ለማሰናከል፣ bootloader ን ይፈትሹ።"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"በዩኤስቢ ወደብ ውስጥ ፈሳሽ ወይም ፍርስራሽ"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"የዩኤስቢ ወደብ በራስ-ሰር ተሰናክሏል። የበለጠ ለመረዳት መታ ያድርጉ።"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"የዩኤስቢ ወደቡን መጠቀም ችግር የለውም"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"ያልተመደቡ"</string>
<string name="importance_from_user" msgid="7318955817386549931">"የእነዚህን ማሳወቂያዎች አስፈላጊነት አዘጋጅተዋል።"</string>
<string name="importance_from_person" msgid="9160133597262938296">"ይሄ በሚሳተፉ ሰዎች ምክንያት አስፈላጊ ነው።"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> በ<xliff:g id="ACCOUNT">%2$s</xliff:g> አዲስ ተጠቃሚ እንዲፈጥር ይፈቀድለት (ይህ መለያ ያለው ተጠቃሚ አስቀድሞ አለ)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> አዲስ ተጠቃሚ ከ <xliff:g id="ACCOUNT">%2$s</xliff:g> ጋር መፍጠር እንዲችል ይፍቀዱ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ቋንቋ ያክሉ"</string>
<string name="country_selection_title" msgid="2954859441620215513">"የክልል ምርጫ"</string>
<string name="search_language_hint" msgid="7042102592055108574">"የቋንቋ ስም ይተይቡ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 113a342..2e272ee 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -356,6 +356,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"للسماح للتطبيق بتلقي ومعالجة الرسائل القصيرة SMS. وهذا يعني أنه يمكن للتطبيق مراقبة الرسائل التي يتم إرسالها إلى جهازك أو حذفها بدون عرضها لك."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"تلقي رسائل نصية (رسائل وسائط متعددة)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"للسماح للتطبيق بتلقي ومعالجة رسائل الوسائط المتعددة. وهذا يعني أنه يمكن للتطبيق مراقبة الرسائل التي يتم إرسالها لجهازك أو حذفها بدون عرضها لك."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"قراءة رسائل بث الخلية"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"السماح للتطبيق بقراءة رسائل بث الخلية التي يتلقاها هذا الجهاز. يتم تسليم اشعارات بث الخلية في بعض المواقع لتحذيرك من حالات طارئة. يمكن أن تتداخل التطبيقات الضارة مع أداء أو تشغيل الجهاز عندما يتم تلقي بث خلية طارئ."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"قراءة الخلاصات المشتركة"</string>
@@ -536,7 +540,7 @@
<string name="permdesc_imagesWrite" msgid="7073662756617474375">"للسماح للتطبيق بتعديل مجموعة صورك."</string>
<string name="permlab_mediaLocation" msgid="8675148183726247864">"قراءة المواقع من مجموعة الوسائط التابعة لك"</string>
<string name="permdesc_mediaLocation" msgid="2237023389178865130">"للسماح للتطبيق بقراءة المواقع من مجموعة الوسائط التابعة لك."</string>
- <string name="biometric_dialog_default_title" msgid="881952973720613213">"التحقق من هويتك"</string>
+ <string name="biometric_dialog_default_title" msgid="881952973720613213">"إثبات هويتك"</string>
<string name="biometric_error_hw_unavailable" msgid="645781226537551036">"معدّات المقاييس الحيوية غير متاحة."</string>
<string name="biometric_error_user_canceled" msgid="2260175018114348727">"تم إلغاء المصادقة."</string>
<string name="biometric_not_recognized" msgid="5770511773560736082">"لم يتم التعرف عليها."</string>
@@ -667,6 +671,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"للسماح للتطبيق بقراءة تهيئة \"عدم الإزعاج\" وكتابتها."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"بدء استخدام إذن العرض"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"للسماح للمالك ببدء استخدام الإذن لأحد التطبيقات. ولن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"هدف اختصار أدوات تمكين الوصول"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"للسماح للتطبيق بتحديد هدف اختصار أدوات تمكين الوصول."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"للتحكم في الطول والأحرف المسموح بها في كلمات المرور وأرقام التعريف الشخصي في قفل الشاشة."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"مراقبة محاولات إلغاء قفل الشاشة"</string>
@@ -1155,7 +1161,7 @@
<string name="Midnight" msgid="5630806906897892201">"منتصف الليل"</string>
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
- <string name="selectAll" msgid="6876518925844129331">"تحديد الكل"</string>
+ <string name="selectAll" msgid="6876518925844129331">"اختيار الكل"</string>
<string name="cut" msgid="3092569408438626261">"قص"</string>
<string name="copy" msgid="2681946229533511987">"نسخ"</string>
<string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"تعذّر النسخ في الحافظة"</string>
@@ -1444,11 +1450,13 @@
<string name="usb_power_notification_message" msgid="4647527153291917218">"جارٍ شحن الجهاز المتصل. انقر لعرض خيارات أكثر."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"تم اكتشاف ملحق صوتي تناظري"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"الجهاز الذي تم توصيله بالهاتف غير متوافق معه. انقر للحصول على المزيد من المعلومات."</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"تم توصيل تصحيح أخطاء USB"</string>
- <string name="adb_active_notification_message" msgid="7463062450474107752">"انقر لإيقاف تصحيح أخطاء USB."</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"تم توصيل تصحيح أخطاء الجهاز عبر USB"</string>
+ <string name="adb_active_notification_message" msgid="7463062450474107752">"انقر لإيقاف تصحيح أخطاء الجهاز عبر USB."</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"اختيار إيقاف تصحيح أخطاء USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"تم تفعيل وضع \"مفعّل الاختبار\""</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"يمكنك إجراء إعادة ضبط على إعدادات المصنع لإيقاف وضع \"مفعِّل اختبار\"."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"وحدة التحكّم التسلسلية مفعّلة"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"الأداء متأثر. لإيقاف وحدة التحكّم، تحقّق من برنامج الإقلاع."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"السوائل والشوائب في منفذ USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"تمّ إيقاف منفذ USB تلقائيًا. انقُر لمعرفة المزيد من المعلومات."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"مسموح باستخدام منفذ USB"</string>
@@ -2026,10 +2034,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"غير مصنفة"</string>
<string name="importance_from_user" msgid="7318955817386549931">"لقد عيَّنت أهمية هذه الإشعارات."</string>
<string name="importance_from_person" msgid="9160133597262938296">"هذه الرسالة مهمة نظرًا لأهمية الأشخاص المعنيين."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"هل تسمح لتطبيق <xliff:g id="APP">%1$s</xliff:g> بإنشاء مستخدم جديد باستخدام <xliff:g id="ACCOUNT">%2$s</xliff:g> (يوجد مستخدم بهذا الحساب مسبقًا)؟"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"هل تسمح لتطبيق <xliff:g id="APP">%1$s</xliff:g> بإنشاء مستخدم جديد باستخدام <xliff:g id="ACCOUNT">%2$s</xliff:g> ؟"</string>
<string name="language_selection_title" msgid="2680677278159281088">"إضافة لغة"</string>
<string name="country_selection_title" msgid="2954859441620215513">"تفضيل المنطقة"</string>
<string name="search_language_hint" msgid="7042102592055108574">"اكتب اسم اللغة"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 00617a5..70d9713 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"এপটোক এছএমএছ বাৰ্তাবোৰ পাবলৈ আৰু প্ৰক্ৰিয়া সম্পন্ন কৰিবলৈ অনুমতি দিয়ে৷ ইয়াৰ অৰ্থ এইটোৱেই যে এপটোৱে আপোনাক বাৰ্তাবোৰ নেদেখুৱাকৈয়ে আপোনাৰ ডিভাইচলৈ পঠিওৱা বাৰ্তাবোৰ নিৰীক্ষণ কৰিব বা মচিব পাৰে৷"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"পাঠ বার্তা (এমএমএছ) বোৰ লাভ কৰক"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"এমএমএছ বার্তাবোৰ লাভ আৰু ইয়াৰ প্ৰক্ৰিয়া সম্পন্ন কৰিবলৈ এপক অনুমতি দিয়ে। ইয়াৰ অৰ্থ হৈছে এই এপে আপোনাৰ ডিভাইচলৈ প্ৰেৰণ কৰা বার্তাসমূহ আপোনাক নেদেখুৱাকৈয়ে পৰ্যবেক্ষণ আৰু মচিব পাৰে।"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"চেল সম্প্ৰচাৰৰ বার্তাবোৰ পঢ়ক"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"আপোনাৰ ডিভাইচে লাভ কৰা চেল সম্প্ৰচাৰৰ বার্তাবোৰ পঢ়িবলৈ এপক অনুমতি দিয়ে। আপোনাক জৰুৰীকালীন পৰিস্থিতিবোৰত সর্তক কৰিবলৈ চেল সম্প্ৰচাৰৰ বার্তাবোৰ প্ৰেৰণ কৰা হয়। জৰুৰীকালীন চেল সম্প্ৰচাৰ লাভ কৰাৰ সময়ত আপোনাৰ ডিভাইচৰ কাৰ্যদক্ষতা বা কাৰ্যপ্ৰণালীত ক্ষতিকাৰক এপবোৰে হস্তক্ষেপ কৰিব পাৰে।"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"আপুনি সদস্যভুক্ত হোৱা ফীডসমূহ পঢ়ক"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"অসুবিধা নিদিবৰ কনফিগাৰেশ্বনক পঢ়িবলৈ আৰু সালসলনি কৰিবলৈ এপটোক অনুমতি দিয়ে।"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"চোৱাৰ অনুমতিৰ ব্যৱহাৰ আৰম্ভ কৰক"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ধাৰকক কোনো এপৰ বাবে অনুমতিৰ ব্যৱহাৰ আৰম্ভ কৰিবলৈ দিয়ে। সাধাৰণ এপ্সমূহৰ বাবে কেতিয়াও প্ৰয়োজন হ’ব নালাগে।"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"সাধ্য সুবিধাসমূহৰ শ্বৰ্টকাট লক্ষ্য"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"সাধ্য সুবিধাসমূহৰ শ্বৰ্টকাট লক্ষ্য নির্ধাৰণ কৰিবলৈ এটা এপক অনুমতি দিয়ে।"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"পাছৱর্ডৰ নিয়ম ছেট কৰক"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"স্ক্ৰীণ লক পাছৱৰ্ড আৰু পিনৰ দৈর্ঘ্য আৰু কি কি আখৰ ব্যৱহাৰ কৰিব পাৰে তাক নিয়ন্ত্ৰণ কৰক।"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"স্ক্ৰীণ আনলক কৰা প্ৰয়াসবোৰ পৰ্যবেক্ষণ কৰিব পাৰে"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ইউএছবি ডিবাগিং অক্ষম কৰিবলৈ বাছনি কৰক।"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"টেষ্ট হাৰনেছ ম’ড সক্ষম কৰা আছে"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"টেষ্ট হাৰনেছ ম’ড অক্ষম কৰিবলৈ ফেক্টৰী ৰিছেট কৰক।"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"ক্ৰমিক কনছ’ল সক্ষম কৰা আছে"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"কাৰ্যক্ষমতা প্ৰভাৱিত হৈছে। অক্ষম কৰিবলৈ বুটল’ডাৰ পৰীক্ষা কৰক।"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ইউএছবি প’ৰ্টত তৰল বা ধূলি-মাকতি আছে"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"ইউএছবি প’ৰ্ট স্বয়ংক্ৰিয়ভাৱে অক্ষম কৰা হয়। অধিক জানিবৰ বাবে টিপক।"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ইউএছবি প’ৰ্ট ব্যৱহাৰ কৰাত সমস্যা নাই"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"শ্ৰেণীবদ্ধ নকৰা"</string>
<string name="importance_from_user" msgid="7318955817386549931">"এই জাননীবোৰৰ গুৰুত্ব আপুনি ছেট কৰব লাগিব।"</string>
<string name="importance_from_person" msgid="9160133597262938296">"এই কার্যৰ সৈতে জড়িত থকা লোকসকলক ভিত্তি কৰি এইয়া গুৰুত্বপূর্ণ বুলি বিবেচনা কৰা হৈছ।"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>ক <xliff:g id="ACCOUNT">%2$s</xliff:g>ৰ (এই একাউণ্টটোৰ এজন ব্যৱহাৰকাৰী ইতিমধ্যে আছে) জৰিয়তে এজন নতুন ব্যৱহাৰকাৰী সৃষ্টি কৰিবলৈ অনুমতি দিবনে ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>ক <xliff:g id="ACCOUNT">%2$s</xliff:g>ৰ জৰিয়তে এজন নতুন ব্যৱহাৰকাৰী সৃষ্টি কৰিবলৈ অনুমতি দিবনে?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ভাষা যোগ কৰক"</string>
<string name="country_selection_title" msgid="2954859441620215513">"অঞ্চলৰ অগ্ৰাধিকাৰ"</string>
<string name="search_language_hint" msgid="7042102592055108574">"ভাষাৰ নাম লিখক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index f79decd..5d09250 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Tətbiqə MMS mesajlarını almaq və emal etmək icazəsi verir. Bu o deməkdir ki, tətbiq sizin mesajlarınızı sizə göstərmədən monitorinq edə və ya silə bilər."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"mətn mesajlarını qəbul edir (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Tətbiqə MMS mesajlarını qəbul və emal üçün imkan verir. Bu o deməkdir ki, bu tətbiq sizə göstərmədən cihazınıza göndərilən mesajları silə bilər."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"mobil yayım mesajlarını oxuyur"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tətbiqə telefonunuz tərəfindən alınmış yayım mesajlarını oxuma icazəsi verir. Telefon yayımı bəzi məkanlarda olan fövqəladə hadisələrlə bağlı sizi xəbərdar etmək üçün qəbul edilir. Zərərli tətbiqlər təcili mobil yayım qəbul edildiyi zaman telefonunun performansına və əməliyyatına müdaxilə edə bilər."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"abunə olunmuş xəbərləri oxuyur"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Tətbiqə \"Narahat Etməyin\" konfiqurasiyasını oxumağa və yazmağa icazə verin."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"Baxış icazəsinin istifadəsinə başlayın"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Sahibinə tətbiqin icazədən istifadəsinə başlamağa imkan verir. Adi tətbiqlər üçün heç vaxt tələb edilmir."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"əlçatımlılıq qısayolunun hədəfi"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Tətbiqə əlçatımlılıq qısayolunun hədəfini müəyyən etməyə imkan verir."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Parol qaydalarını təyin edin"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Ekran kilidinin parolu və PINlərində icazə verilən uzunluq və simvollara nəzarət edin."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Ekranı kiliddən çıxarmaq üçün edilən cəhdlərə nəzarət edin"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USb debaqı deaktivasiya etməyi seçin."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Rejimi aktivdir"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Test Rejimini deaktiv etmək üçün fabrika ayarlarına sıfırlayın."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Ardıcıl konsol aktiv edildi"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Performansa təsir edir. Deaktiv etmək üçün yükləyicini yoxlayın."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB portuna maye sızıb və ya qırılıb"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB portu avtomatik deaktiv edildi. Ətraflı məlumat üçün klikləyin."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB portundan istifadə etmək üçün OK"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Kateqoriyasız"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Bildirişlərin əhəmiyyətini Siz ayarlaryırsınız."</string>
<string name="importance_from_person" msgid="9160133597262938296">"İnsanlar cəlb olunduğu üçün bu vacibdir."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> tətbiqinə <xliff:g id="ACCOUNT">%2$s</xliff:g> (artıq bu hesabı olan İstifadəçi mövcuddur) ilə yeni İstifadəçi yaratmağa icazə verilsin?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> tətbiqinə <xliff:g id="ACCOUNT">%2$s</xliff:g> ilə yeni İstifadəçi yartmağa icazə verilsin?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Dil əlavə edin"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Region seçimi"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Dil adını daxil edin"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 10dc339..5891bae 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -27,7 +27,7 @@
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
- <string name="untitled" msgid="4638956954852782576">"<Bez naslova>"</string>
+ <string name="untitled" msgid="4638956954852782576">"<Bez imena>"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nema broja telefona)"</string>
<string name="unknownName" msgid="6867811765370350269">"Nepoznato"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Glasovna pošta"</string>
@@ -347,6 +347,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Dozvoljava aplikaciji da prima i obrađuje SMS poruke. To znači da aplikacija može da nadgleda ili briše poruke koje se šalju uređaju, a da vam ih ne prikaže."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"prijem tekstualnih poruka (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Dozvoljava aplikaciji da prima i obrađuje MMS poruke. To znači da aplikacija može da nadgleda ili briše poruke koje se šalju uređaju, a da vam ih ne prikaže."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čitanje poruka info servisa"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Omogućava aplikaciji da čita poruke info servisa koje uređaj prima. Upozorenja info servisa se na nekim lokacijama primaju kao upozorenja na hitne slučajeve. Zlonamerne aplikacije mogu da utiču na učinak ili ometaju funkcionisanje uređaja kada se primi poruka info servisa o hitnom slučaju."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"čitanje prijavljenih fidova"</string>
@@ -658,6 +662,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Dozvoljava aplikaciji da čita i upisuje konfiguraciju podešavanja Ne uznemiravaj."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"početak korišćenja dozvole za pregled"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Dozvoljava vlasniku da započne korišćenje dozvole za aplikaciju. Nikada ne bi trebalo da bude potrebna za uobičajene aplikacije."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cilj prečice za pristupačnost"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Dozvoljava aplikaciji da definiše cilj prečice za pristupačnost."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Podešavanje pravila za lozinku"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontroliše dužinu i znakove dozvoljene u lozinkama i PIN-ovima za zaključavanje ekrana."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Nadgledajte pokušaje otključavanja ekrana"</string>
@@ -1383,6 +1389,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izaberite da biste onemogućili otklanjanja grešaka sa USB-a."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Omogućen je režim probnog korišćenja"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Obavite resetovanje na fabrička podešavanja da biste onemogućili režim probnog korišćenja."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serijska konzola je omogućena"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Učinak je smanjen. Da biste onemogući konzolu, proverite pokretački program."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tečnost ili nečistoća u USB portu"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port je automatski isključen. Dodirnite da biste saznali više."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Korišćenje USB porta je dozvoljeno"</string>
@@ -1924,10 +1932,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizovano"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Vi podešavate važnost ovih obaveštenja."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Ovo je važno zbog ljudi koji učestvuju."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Želite li da dozvolite da <xliff:g id="APP">%1$s</xliff:g> napravi novog korisnika sa nalogom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik sa tim nalogom već postoji)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Želite li da dozvolite da <xliff:g id="APP">%1$s</xliff:g> napravi novog korisnika sa nalogom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Dodajte jezik"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Podešavanje regiona"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Unesite naziv jezika"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index ce65bea..6fdc8f1 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -350,6 +350,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Дазваляе прыкладанням атрымліваць і апрацоўваць SMS-паведамленні. Гэта значыць, што прыкладанне можа кантраляваць або выдаляць паведамленні, адпраўленыя на прыладу, не паказваючы іх вам."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"атрыманне тэкставых паведамленняў (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Дазваляе прыкладанням атрымліваць і апрацоўваць MMS-паведамленнi. Гэта значыць, што прыкладанне можа кантраляваць або выдаляць паведамленні, адпраўленыя на прыладу, не паказваючы іх вам."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"чытаць паведамленні базавай станцыі"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Дазваляе прыкладанню чытаць паведамленні базавай станцыі, атрыманыя прыладай. Папярэджанні базавай станцыі дасылаюцца ў некаторыя месцы, каб папярэдзіць вас аб надзвычайных сітуацыях. Шкоднасныя прыкладанні могуць уплываць на прадукцыйнасць ці працу прылады пры атрыманні паведамлення базавай станцыі аб надзвычайнай сітуацыі."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"чытаць падпісаныя каналы"</string>
@@ -661,6 +665,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Дазваляе праграме чытаць і выконваць запіс у канфігурацыю рэжыму «Не турбаваць»."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"запусціць выкарыстанне дазволаў на прагляд"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Дазваляе трымальніку запусціць выкарыстанне дазволаў праграмай. Не патрэбна для звычайных праграм."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"Аб\'екты хуткага доступу да спецыяльных магчымасцей"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Праграма зможа вызначаць аб\'екты хуткага доступу да спецыяльных магчымасцей."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Устанавіць правілы паролю"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Кіраваць даўжынёй і сімваламі, дазволенымі пры ўводзе пароляў і PIN-кодаў блакіроўкі экрана."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Сачыць за спробамі разблакіроўкі экрана"</string>
@@ -1405,6 +1411,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Выберыце, каб адключыць адладку USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Тэставы рэжым уключаны"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Каб выключыць тэставы рэжым, скіньце налады да заводскіх значэнняў."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Паслядоўная кансоль уключана"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Паказчык эфектыўнасці змяніўся. Каб выключыць кансоль, праверце загрузчык."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Вадкасць або смецце ў порце USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Порт USB аўтаматычна адключаны. Каб даведацца больш, націсніце тут."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Порт USB можна выкарыстоўваць"</string>
@@ -1958,10 +1966,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Некатэгарызаванае"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Вы задалі важнасць гэтых апавяшчэнняў."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Гэта важна, бо з гэтым звязаны пэўныя людзі."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Дазволіць праграме \"<xliff:g id="APP">%1$s</xliff:g>\" стварыць новага Карыстальніка з уліковым запісам <xliff:g id="ACCOUNT">%2$s</xliff:g> (Карыстальнік з гэтым уліковым запісам ужо існуе)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Дазволіць праграме \"<xliff:g id="APP">%1$s</xliff:g>\" стварыць новага Карыстальніка з уліковым запісам <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Дадаць мову"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Параметры рэгіёна"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Увядзіце назву мовы"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 87ea6de..e5fb7e8 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Разрешава на приложението да получава и обработва SMS съобщения. Това означава, че то може да наблюдава или изтрива изпратените до устройството ви, без да ви ги покаже."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"получаване на текстови съобщения (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Разрешава на приложението да получава и обработва MMS съобщения. Това означава, че то може да наблюдава или изтрива изпратените до устройството ви, без да ви ги покаже."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"четене на съобщения с клетъчно излъчване"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Разрешава на приложението да чете съобщения с клетъчно излъчване, получени от устройството ви. Сигналите с клетъчно излъчване се получават на някои местоположения, за да ви предупредят за спешни ситуации. Злонамерените приложения могат да възпрепятстват изпълнението или работата на устройството ви при получаване на такова спешно излъчване."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"четене на емисиите с абонамент"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Предоставя на приложението достъп за четене и запис до конфигурацията на „Не безпокойте“."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"стартиране на прегледа на използваните разрешения"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Разрешава на притежателя да стартира прегледа на използваните разрешения за дадено приложение. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"цел на прекия път към функцията за достъпност"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Разрешава на приложението да определя целта на прекия път към функцията за достъпност."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Контролира дължината и разрешените знаци за паролите и ПИН кодовете за заключване на екрана."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Наблюдаване на опитите за отключване на екрана"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Режимът за тестова среда е активиран"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Възстановете фабричните настройки, за да деактивирате режима за тестова среда."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Серийната конзола е активирана"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Ефективността е засегната. За да деактивирате, проверете програмата за първоначално зареждане."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или замърсяване в USB порта"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB портът е деактивиран автоматично. Докоснете, за да научите повече."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Можете да използвате USB порта"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Некатегоризирани"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Зададохте важността на тези известия."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Това е важно заради участващите хора."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Да се разреши ли на <xliff:g id="APP">%1$s</xliff:g> да създаде нов потребител с профила <xliff:g id="ACCOUNT">%2$s</xliff:g> (вече съществува потребител с този профил)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Да се разреши ли на <xliff:g id="APP">%1$s</xliff:g> да създаде нов потребител с профила <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Добавяне на език"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Предпочитание за региона"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Въведете име на език"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index c0843ea..651ed4d 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"অ্যাপ্লিকেশানটিকে এসএমএস প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো বার্তাগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"টেক্সট মেসেজ পান (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"অ্যাপ্লিকেশানটিকে MMS মেসেজ প্রাপ্ত করার এবং প্রক্রিয়া করার অনুমতি দেয়৷ এর মানে হল অ্যাপ্লিকেশানটি আপনার ডিভাইস থেকে পাঠানো মেসেজগুলিকে পর্যবেক্ষণ করতে পারে এবং মুছতে পারে সেগুলিকে আপনাকে না দেখিয়ে৷"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"সেল সম্প্রচার মেসেজ পড়ুন"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"আপনার ডিভাইস দ্বারা প্রাপ্ত সেল সম্প্রচার পড়তে অ্যাপ্লিকেশানটিকে অনুমতি দেয়৷ কয়েকটি স্থানে আপনাকে জরুরি অবস্থার জন্য সতর্ক করতে জরুরি সতর্কতাগুলি বিতরণ করা হয়৷ যখন একটি জরুরি সেল সম্প্রচার প্রাপ্ত হয় তখন ক্ষতিকারক অ্যাপ্লিকেশানগুলি আপনার ডিভাইসের কার্য সম্পাদনা বা কার্যকলাপে প্রতিবন্ধকতার সৃষ্টি করতে পারে৷"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"গ্রাহক হিসেবে নেওয়া ফিডগুলি পড়ে"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"অ্যাপটিকে \'বিরক্ত করবে না\' কনফিগারেশন পড়া এবং লেখার অনুমতি দেয়।"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"দেখার অনুমতি কাজে লাগানো শুরু করুন"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"কোনও অ্যাপের কোনও নির্দিষ্ট অনুমতির ব্যবহার শুরু করার ক্ষেত্রে হোল্ডারকে সাহায্য করে। সাধারণ অ্যাপের জন্য এটির পরিবর্তন হওয়ার কথা নয়।"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"অ্যাক্সেসিবিলিটির শর্টকাটের টার্গেট"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"এটি একটি অ্যাপকে অ্যাক্সেসিবিলিটির শর্টকাটের টার্গেটকে ব্যাখ্যা করতে অনুমতি দেয়।"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"পাসওয়ার্ড নিয়মগুলি সেট করে"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"স্ক্রিন লক করার পাসওয়ার্ডগুলিতে অনুমতিপ্রাপ্ত অক্ষর এবং দৈর্ঘ্য নিয়ন্ত্রণ করে৷"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"স্ক্রিন আনলক করার প্রচেষ্টাগুলির উপরে নজর রাখুন"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ডিবাগিং অক্ষম করতে বেছে নিন।"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"টেস্ট হারনেস মোড চালু আছে"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"টেস্ট হারনেস মোড বন্ধ করতে ফ্যাক্টরি রিসেট করুন।"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"সিরিয়াল কনসোল চালু করা হয়েছে"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"পারফর্ম্যান্সে এর প্রভাব পড়বে। চালানো বন্ধ করতে \'বুটলোডার\' প্রোগ্রামে এটিকে চেক করে দেখুন।"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ইউএসবি পোর্টে তরল পদার্থ অথবা ধুলো কণা"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"ইউএসবি পোর্ট নিজে থেকে বন্ধ করা হবে। আরও জানতে ট্যাপ করুন।"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ইউএসবি পোর্ট ব্যবহার করা যেতে পারে"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"বিভাগ নির্ধারিত নয়"</string>
<string name="importance_from_user" msgid="7318955817386549931">"আপনি এই বিজ্ঞপ্তিগুলির গুরুত্ব সেট করেছেন।"</string>
<string name="importance_from_person" msgid="9160133597262938296">"লোকজন জড়িত থাকার কারণে এটি গুরুত্বপূর্ণ।"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g>-এ (একজন ব্যবহারকারী এই অ্যাকাউন্টে আগে থেকেই রয়েছেন) একজন নতুন ব্যবহারকারী তৈরি করার অনুমতি <xliff:g id="APP">%1$s</xliff:g>-কে দেবেন?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g>-এ একজন নতুন ব্যবহারকারী তৈরি করার অনুমতি <xliff:g id="APP">%1$s</xliff:g>-কে দেবেন?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"একটি ভাষা যোগ করুন"</string>
<string name="country_selection_title" msgid="2954859441620215513">"পছন্দের অঞ্চল"</string>
<string name="search_language_hint" msgid="7042102592055108574">"ভাষার নাম লিখুন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 0d4b12c..0695fb8 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -347,6 +347,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Omogućava aplikaciji primanje i obradu SMS poruka. Ovo znači da aplikacija može pratiti ili brisati poruke poslane na vaš uređaj, a da vam ih pritom ne prikazuje."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"primanje tekstualnih poruka (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Omogućava aplikaciji prijem i obradu MMS poruka. Ovo znači da aplikacija može pratiti ili brisati poruke poslane na vaš uređaj, a da vam ih pritom ne prikazuje."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čitanje poruka info servisa"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Omogućava aplikaciji čitanje poruka info servisa koje je primio vaš uređaj. Upozorenja koja emitira info servis se isporučuju na nekim lokacijama kako bi vas upozorila na vanredne situacije. Zlonamjerne aplikacije mogu ometati performanse ili rad vašeg uređaja kada primite informaciju o vanrednoj situaciji od info servisa."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"čitanje sadržaja na koje ste pretplaćeni"</string>
@@ -658,6 +662,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Omogućava aplikaciji da čita i upisuje konfiguraciju načina rada Ne ometaj."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"pokrenuti korištenje odobrenja za pregled"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Dozvoljava vlasniku da pokrene korištenje odobrenja za aplikaciju. Ne bi trebalo biti potrebno za obične aplikacije."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cilj prečice pristupačnosti"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Omogućava aplikaciji da definira cilj prečice pristupačnosti."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Postavljanje pravila za lozinke"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolira dužinu i znakove koji su dozvoljeni u lozinkama za zaključavanje ekrana i PIN-ovima."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Prati pokušaje otključavanja ekrana"</string>
@@ -1385,6 +1391,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da onemogućite ispravljanje grešaka koristeći USB"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Omogućen način rada okvira za testiranje"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Izvršite vraćanje na fabričke postavke da onemogućite način rada okvira za testiranje."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serijska konzola omogućena"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Izvedba je otežana. Da onemogućite, provjerite program za učitavanje operativnog sistema."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tečnost ili nečistoće u USB priključku"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB priključak je automatski onemogućen. Dodirnite da saznate više."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB priključak je sada sigurno koristiti"</string>
@@ -1926,10 +1934,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Nije kategorizirano"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Vi određujete značaj ovih obavještenja."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Ovo je značajno zbog osoba koje su uključene."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Dozvoliti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da kreira novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik s ovim računom već postoji)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Dozvoliti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da kreira novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Dodajte jezik"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Izbor regije"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Upišite ime jezika"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index d828844..8ef9a17 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Permet que l\'aplicació rebi i processi missatges SMS. Això vol dir que l\'aplicació pot controlar o suprimir missatges que s\'han enviat al teu dispositiu sense mostrar-te\'ls."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"recepció de missatges de text (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permet que l\'aplicació rebi i processi missatges MMS. Això vol dir que l\'aplicació pot controlar o suprimir missatges que s\'han enviat al teu dispositiu sense mostrar-te\'ls."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"llegir missatges de difusió mòbil"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permet que l\'aplicació llegeixi missatges de difusió mòbil rebuts pel dispositiu. Les alertes de difusió mòbil s\'entreguen en algunes ubicacions per alertar de situacions d\'emergència. És possible que les aplicacions malicioses interfereixin en el rendiment o en el funcionament del dispositiu quan es rep una difusió mòbil d\'emergència."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"llegir els feeds als quals esteu subscrit"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permet que l\'aplicació llegeixi la configuració No molestis i hi escrigui."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"comença a utilitzar el permís de visualització"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permet que un propietari comenci a utilitzar el permís amb una aplicació. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"objectiu de la drecera d\'accessibilitat"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permet a una aplicació definir l\'objectiu de la drecera d\'accessibilitat."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Definir les normes de contrasenya"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Permet controlar la longitud i el nombre de caràcters permesos a les contrasenyes i als PIN del bloqueig de pantalla."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Supervisar els intents de desbloqueig de la pantalla"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona per desactivar la depuració per USB"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"S\'ha activat el mode Agent de prova"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Si vols desactivar el mode Agent de prova, restableix les dades de fàbrica."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"S\'ha activat la consola de sèrie"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"El rendiment s\'ha vist afectat. Per desactivar-la, comprova el bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hi ha líquid o pols al port USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"El port USB es desactiva automàticament. Toca per obtenir més informació."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ja pots utilitzar el port USB"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Sense classificar"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Has definit la importància d\'aquestes notificacions."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Aquest missatge és important per les persones implicades."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Concedeixes permís a <xliff:g id="APP">%1$s</xliff:g> per crear un usuari amb el compte <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Ja hi ha un usuari amb aquest compte.)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Concedeixes permís a <xliff:g id="APP">%1$s</xliff:g> per crear un usuari amb el compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Afegeix un idioma"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferència de regió"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Nom de l\'idioma"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 2b524ae..72e7a86 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -350,6 +350,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Umožňuje aplikaci přijmout a zpracovat zprávy SMS. Znamená to, že aplikace může sledovat zprávy odeslané do vašeho zařízení nebo je smazat, aniž by se vám zobrazily."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"příjem textových zpráv (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Umožňuje aplikaci přijmout a zpracovat zprávy MMS. Znamená to, že aplikace může sledovat zprávy odeslané do vašeho zařízení nebo je smazat, aniž by se vám zobrazily."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čtení zpráv informačních služeb"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Umožňuje aplikaci číst zprávy informačních služeb přijaté ve vašem zařízení. Výstražná upozornění informačních služeb jsou v některých oblastech odesílána za účelem varování před výjimečnými událostmi. Škodlivé aplikace mohou narušit výkon či provoz vašeho zařízení během přijímání zpráv informačních služeb."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"čtení zdrojů přihlášených k odběru"</string>
@@ -661,6 +665,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Umožňuje aplikaci číst a zapisovat konfiguraci režimu Nerušit."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"zahájení zobrazení využití oprávnění"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Umožňuje přístup zahájit využití oprávnění jiné aplikace. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cíl zkratky přístupnosti"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Umožňuje aplikaci definovat cíl zkratky přístupnosti."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavit pravidla pro heslo"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Ovládání délky a znaků povolených v heslech a kódech PIN zámku obrazovky."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Sledovat pokusy o odemknutí obrazovky"</string>
@@ -1405,6 +1411,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění přes USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Režim správce testů je aktivní"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Chcete-li deaktivovat režim správce testů, restartujte zařízení do továrního nastavení."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Je zapnutá sériová konzole"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Toto má dopad na výkon. Chcete-li ji vypnout, zkontrolujte bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Kapalina nebo nečistota v portu USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB byl automaticky deaktivován. Klepnutím zobrazíte další informace."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Port USB lze bezpečně použít"</string>
@@ -1958,10 +1966,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Neklasifikováno"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Důležitost oznámení určujete vy."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Tato zpráva je důležitá kvůli lidem zapojeným do konverzace."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Povolit aplikaci <xliff:g id="APP">%1$s</xliff:g> vytvořit nového uživatele s účtem <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Uživatel s tímto účtem již existuje.)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Povolit aplikaci <xliff:g id="APP">%1$s</xliff:g> vytvořit nového uživatele s účtem <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Přidat jazyk"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferovaná oblast"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Zadejte název jazyka"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 4d57a90..88900a0 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -226,7 +226,7 @@
<string name="global_actions" product="default" msgid="2406416831541615258">"Indstillinger for telefon"</string>
<string name="global_action_lock" msgid="2844945191792119712">"Skærmlås"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"Sluk"</string>
- <string name="global_action_emergency" msgid="7112311161137421166">"Nødopkald"</string>
+ <string name="global_action_emergency" msgid="7112311161137421166">"Nødsituation"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Fejlrapport"</string>
<string name="global_action_logout" msgid="935179188218826050">"Afslut sessionen"</string>
<string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Tillader, at appen kan modtage og behandle sms-beskeder. Det betyder, at appen kan overvåge eller slette de beskeder, der sendes til din enhed, uden at vise dem til dig."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"modtage tekstbeskeder (mms)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Tillader, at appen kan modtage og behandle mms-beskeder. Det betyder, at appen kan overvåge eller slette de beskeder, der sendes til din enhed, uden at vise dem til dig."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"læse Cell Broadcast-meddelelser"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tillader, at appen læser Cell Broadcast-underretninger, der modtages af din enhed. I nogle områder sendes der Cell Broadcast-underretninger for at advare om nødsituationer. Ondsindede apps kan forstyrre ydelsen eller driften af din enhed, når der modtages en Cell Broadcast-meddelelse om en nødsituation."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"læse feeds, jeg abonnerer på"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Giver appen tilladelse til at læse og redigere konfigurationen af Forstyr ikke."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start brugen at tilladelsesvisning"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Tillader, at brugeren kan bruge en tilladelse for en app. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"mål for hjælpefunktionsgenvej"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Tillader, at en app definerer målet for en hjælpefunktionsgenvej."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Angiv regler for adgangskoder"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Tjek længden samt tilladte tegn i adgangskoder og pinkoder til skærmlåsen."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Overvåg forsøg på oplåsning af skærm"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Tilstanden Testsele er aktiveret"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Gendan fabriksindstillingerne for at deaktivere tilstanden Testsele."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Seriekonsollen er aktiveret"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Effektiviteten er påvirket. Deaktiver via bootloaderen."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Væske eller snavs i USB-porten"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten deaktiveres automatisk. Tryk for at få flere oplysninger."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-porten kan bruges"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Uden kategori"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Du angiver, hvor vigtige disse notifikationer er."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Dette er vigtigt på grund af de personer, det handler om."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en ny bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g> (der findes allerede en bruger med denne konto)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en nye bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Tilføj et sprog"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Områdeindstilling"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Angiv sprog"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 2ec70d3..6bf5404 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Ermöglicht der App, SMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an dein Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie dir anzuzeigen."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"MMS empfangen"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Ermöglicht der App, MMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an dein Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie dir anzuzeigen."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Cell Broadcast-Nachrichten lesen"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ermöglicht der App, von deinem Gerät empfangene Cell Broadcast-Nachrichten zu lesen. Cell Broadcast-Benachrichtigungen werden an einigen Standorten gesendet, um dich über Notfallsituationen zu informieren. Schädliche Apps können die Leistung oder den Betrieb deines Geräts beeinträchtigen, wenn eine Cell Broadcast-Notfallbenachrichtigung eingeht."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Abonnierte Feeds lesen"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Ermöglicht der App Lese- und Schreibzugriff auf die \"Bitte nicht stören\"-Konfiguration"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"Mit der Verwendung der Anzeigeberechtigung beginnen"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Ermöglicht dem Inhaber, die Berechtigungsnutzung für eine App zu beginnen. Sollte für normale Apps nie benötigt werden."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"Ziel der Verknüpfung für Bedienungshilfen"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Ermöglicht einer App, das Ziel der Verknüpfung für Bedienungshilfen zu definieren."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Passwortregeln festlegen"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Zulässige Länge und Zeichen für Passwörter für die Displaysperre festlegen"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Versuche zum Entsperren des Displays überwachen"</string>
@@ -1361,7 +1367,9 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB-Debugging deaktivieren: auswählen"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test-Harnischmodus aktiviert"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Setz das Gerät auf die Werkseinstellungen zurück, um den Test-Harnischmodus zu deaktivieren."</string>
- <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Flüssigkeiten oder Fremdkörper im USB-Port"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serielle Konsole aktiviert"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Leistung wird beeinflusst. Überprüfe Bootloader zum Deaktivieren."</string>
+ <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Flüssigkeit oder Fremdkörper im USB-Port"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Der USB-Port wird automatisch deaktiviert. Für weitere Informationen tippen."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-Port kann wieder verwendet werden"</string>
<string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Das Smartphone erkennt keine Flüssigkeiten oder Fremdkörper mehr."</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Unkategorisiert"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Du hast die Wichtigkeit dieser Benachrichtigungen festgelegt."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Diese Benachrichtigung ist aufgrund der beteiligten Personen wichtig."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Es gibt bereits einen Nutzer mit <xliff:g id="ACCOUNT">%2$s</xliff:g>. Möchtest du zulassen, dass <xliff:g id="APP">%1$s</xliff:g> einen neuen Nutzer mit diesem Konto erstellt?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Möchtest du zulassen, dass <xliff:g id="APP">%1$s</xliff:g> einen neuen Nutzer mit <xliff:g id="ACCOUNT">%2$s</xliff:g> erstellt?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Sprache hinzufügen"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Region auswählen"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Sprache eingeben"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 6998c0c..3570fc1 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Επιτρέπει στην εφαρμογή τη λήψη και την επεξεργασία μηνυμάτων SMS. Αυτό σημαίνει ότι η εφαρμογή θα μπορούσε να παρακολουθήσει ή να διαγράψει τα μηνύματα που αποστέλλονται στη συσκευή σας χωρίς αυτά να εμφανιστούν σε εσάς."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"λαμβάνει μηνύματα κειμένου (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Επιτρέπει στην εφαρμογή τη λήψη και την επεξεργασία μηνυμάτων MMS. Αυτό σημαίνει ότι η εφαρμογή θα μπορούσε να παρακολουθήσει ή να διαγράψει τα μηνύματα που αποστέλλονται στη συσκευή σας χωρίς αυτά να εμφανιστούν σε εσάς."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"διαβάζει μηνύματα που έχουν μεταδοθεί μέσω κινητού τηλεφώνου"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Επιτρέπει στην εφαρμογή την ανάγνωση μηνυμάτων που έχουν μεταδοθεί μέσω κινητού τηλεφώνου και έχουν ληφθεί από τη συσκευή σας. Ειδοποιήσεις που μεταδίδονται μέσω κινητού παραδίδονται σε ορισμένες τοποθεσίες για να σας προειδοποιήσουν για καταστάσεις έκτακτης ανάγκης. Κακόβουλες εφαρμογές ενδέχεται να παρεμποδίσουν την απόδοση ή τη λειτουργία της συσκευής σας κατά τη λήψη μετάδοσης μέσω κινητού σχετικά με μια επείγουσα κατάσταση."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"διαβάζει ροές δεδομένων στις οποίες έχετε εγγραφεί"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Επιτρέπει στην εφαρμογή την εγγραφή και τη σύνταξη διαμόρφωσης για τη λειτουργία \"Μην ενοχλείτε\"."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"έναρξη χρήσης άδειας προβολής"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Επιτρέπει στον κάτοχο να ξεκινήσει τη χρήση της άδειας για μια εφαρμογή. Δεν απαιτείται ποτέ για κανονικές εφαρμογές."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"στόχος συντόμευσης προσβασιμότητας"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Επιτρέπει σε μια εφαρμογή να καθορίσει τον στόχο της συντόμευσης προσβασιμότητας."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Ελέγξτε την έκταση και τους επιτρεπόμενους χαρακτήρες σε κωδικούς πρόσβασης κλειδώματος οθόνης και PIN."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Η λειτουργία περιβάλλοντος δοκιμών ενεργοποιήθηκε"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Εκτελέστε επαναφορά εργοστασιακών ρυθμίσεων για να απενεργοποιήσετε τη λειτουργία περιβάλλοντος δοκιμών."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Η σειριακή κονσόλα ενεργοποιήθηκε"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Η απόδοση επηρεάζεται. Για απενεργοποίηση, επιλέξτε το πρόγραμμα φόρτωσης εκκίνησης."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Υγρασία ή ακαθαρσίες στη θύρα USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Η θύρα USB απενεργοποιείται αυτόματα. Πατήστε για να μάθετε περισσότερα."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Αποδεκτή η χρήση της θύρας USB"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Μη κατηγοριοποιημένο"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Μπορείτε να ρυθμίσετε τη βαρύτητα αυτών των ειδοποιήσεων."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Αυτό είναι σημαντικό λόγω των ατόμων που συμμετέχουν."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Επιτρέπετε στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> να δημιουργήσει έναν νέο χρήστη με τον λογαριασμό <xliff:g id="ACCOUNT">%2$s</xliff:g> (υπάρχει ήδη χρήστης με αυτόν τον λογαριασμό);"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Επιτρέπετε στην εφαρμογή <xliff:g id="APP">%1$s</xliff:g> να δημιουργήσει έναν νέο χρήστη με τον λογαριασμό <xliff:g id="ACCOUNT">%2$s</xliff:g>;"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Προσθήκη γλώσσας"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Προτίμηση περιοχής"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Εισαγ. όνομα γλώσσας"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 7c2b329..e1d9875 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Allows the app to receive and process SMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"receive text messages (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read mobile broadcast messages"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read mobile broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency mobile broadcast is received."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start view permission usage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"accessibility shortcut target"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Allows an app to define the accessibility shortcut target."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Perform a factory reset to disable Test Harness Mode."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serial console enabled"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Performance is impacted. To disable, check bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK to use USB port"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string>
<string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string>
<string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 6da3a5f..56b54d9 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Allows the app to receive and process SMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"receive text messages (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read mobile broadcast messages"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read mobile broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency mobile broadcast is received."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start view permission usage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"accessibility shortcut target"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Allows an app to define the accessibility shortcut target."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Perform a factory reset to disable Test Harness Mode."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serial console enabled"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Performance is impacted. To disable, check bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK to use USB port"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string>
<string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string>
<string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 7c2b329..e1d9875 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Allows the app to receive and process SMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"receive text messages (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read mobile broadcast messages"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read mobile broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency mobile broadcast is received."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start view permission usage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"accessibility shortcut target"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Allows an app to define the accessibility shortcut target."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Perform a factory reset to disable Test Harness Mode."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serial console enabled"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Performance is impacted. To disable, check bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK to use USB port"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string>
<string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string>
<string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 7c2b329..e1d9875 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Allows the app to receive and process SMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"receive text messages (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means that the app could monitor or delete messages sent to your device without showing them to you."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read mobile broadcast messages"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read mobile broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency mobile broadcast is received."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start view permission usage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"accessibility shortcut target"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Allows an app to define the accessibility shortcut target."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Perform a factory reset to disable Test Harness Mode."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serial console enabled"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Performance is impacted. To disable, check bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK to use USB port"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorised"</string>
<string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string>
<string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 62f294e..c4d3157 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Allows the app to receive and process SMS messages. This means the app could monitor or delete messages sent to your device without showing them to you."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"receive text messages (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Allows the app to receive and process MMS messages. This means the app could monitor or delete messages sent to your device without showing them to you."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"read cell broadcast messages"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Allows the app to read cell broadcast messages received by your device. Cell broadcast alerts are delivered in some locations to warn you of emergency situations. Malicious apps may interfere with the performance or operation of your device when an emergency cell broadcast is received."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"read subscribed feeds"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Allows the app to read and write Do Not Disturb configuration."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start view permission usage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"accessibility shortcut target"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Allows an app to define the accessibility shortcut target."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Control the length and the characters allowed in screen lock passwords and PINs."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitor screen unlock attempts"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Select to disable USB debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Harness Mode enabled"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Perform a factory reset to disable Test Harness Mode."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serial console enabled"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Performance is impacted. To disable, check bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid or debris in USB port"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port is automatically disabled. Tap to learn more."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK to use USB port"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Uncategorized"</string>
<string name="importance_from_user" msgid="7318955817386549931">"You set the importance of these notifications."</string>
<string name="importance_from_person" msgid="9160133597262938296">"This is important because of the people involved."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> (a User with this account already exists) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Add a language"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Region preference"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Type language name"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 7346bd0..30f8ba7 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que la aplicación reciba y procese mensajes SMS, lo que significa que podría controlar o eliminar mensajes enviados al dispositivo sin mostrártelos."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"recibir mensajes de texto (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite que la aplicación reciba y procese mensajes MMS, lo que significa que podría controlar o eliminar mensajes enviados al dispositivo sin mostrártelos."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Leer mensajes de difusión móvil"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite a la aplicación leer los mensajes de difusión móvil que recibe tu dispositivo. En algunas ubicaciones, las alertas de difusión móvil se envían para informar situaciones de emergencia. Las aplicaciones maliciosas pueden afectar el rendimiento o funcionamiento de tu dispositivo cuando se recibe un un mensaje de difusión móvil de emergencia."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"leer canales suscritos"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite que la aplicación lea y modifique la configuración de la función No interrumpir."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar uso de permiso de vista"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite que el propietario inicie el uso de permisos para una app. No debería requerirse para apps normales."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"orientación del acceso directo de accesibilidad"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite que una app defina la orientación del acceso directo de accesibilidad."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer reglas de contraseña"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Controlar la longitud y los caracteres permitidos en las contraseñas y los PIN para el bloqueo de pantalla."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Supervisa los intentos para desbloquear la pantalla"</string>
@@ -1357,10 +1363,12 @@
<string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Se detectó un accesorio de audio analógico"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"El dispositivo adjunto no es compatible con este teléfono. Presiona para obtener más información."</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
- <string name="adb_active_notification_message" msgid="7463062450474107752">"Presiona para desactivar la depuración USB"</string>
+ <string name="adb_active_notification_message" msgid="7463062450474107752">"Presiona para desactivar la depuración por USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para desactivar la depuración por USB"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Se habilitó el modo de agente de prueba"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece la configuración de fábrica para inhabilitar el modo de agente de prueba."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Se habilitó la consola en serie"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Afecta el rendimiento. Para inhabilitarla, verifica bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hay líquido o suciedad en el puerto USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"El puerto USB se inhabilitó automáticamente. Presiona para obtener más información."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Se puede usar el puerto USB"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Sin categoría"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Estableciste la importancia de estas notificaciones."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Es importante debido a las personas involucradas."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"¿Quieres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario nuevo con <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Ya existe un usuario con esta cuenta)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"¿Deseas permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario nuevo con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Agregar un idioma"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferencia de región"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Nombre del idioma"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 6c1c992..15e662c 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que la aplicación reciba y procese mensajes MMS, lo que significa que podría utilizar este permiso para controlar o eliminar mensajes enviados al dispositivo sin mostrárselos al usuario."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"recibir mensajes de texto (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite que la aplicación reciba y procese mensajes MMS, lo que significa que podría utilizar este permiso para controlar o eliminar mensajes enviados al dispositivo sin mostrárselos al usuario."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"leer mensajes de difusión móvil"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que la aplicación lea mensajes de difusión móvil que haya recibido el dispositivo. Las alertas de difusión móvil se envían en algunas ubicaciones para avisar de situaciones de emergencia. Es posible que las aplicaciones malintencionadas interfieran en el rendimiento o en el funcionamiento del dispositivo si se recibe una alerta de difusión móvil de emergencia."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"leer feeds a los que está suscrito el usuario"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite que la aplicación lea y modifique la configuración de No molestar."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar uso de permiso de visualización"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite que el titular inicie el uso de permisos de una aplicación. Las aplicaciones normales no deberían necesitar nunca este permiso."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"objetivo de atajo de accesibilidad"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite que una aplicación defina el objetivo de un atajo de accesibilidad."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Controla la longitud y los caracteres permitidos en los PIN y en las contraseñas de bloqueo de pantalla."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Supervisar los intentos de desbloqueo de pantalla"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modo de agente de prueba habilitado"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece los ajustes de fábrica para inhabilitar el modo de agente de prueba."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Se ha habilitado la consola en serie"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Afecta al rendimiento. Para inhabilitarlo, comprueba el bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Se ha detectado líquido o suciedad en el puerto USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"El puerto USB se ha inhabilitado automáticamente. Toca para obtener más información."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Se puede utilizar el puerto USB"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Sin clasificar"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Tú determinas la importancia de estas notificaciones."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Esto es importante por los usuarios implicados."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"¿Permitir que <xliff:g id="APP">%1$s</xliff:g> cree otro usuario con la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g>, que ya tiene uno?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"¿Permitir que <xliff:g id="APP">%1$s</xliff:g> cree otro usuario con la cuenta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Añadir un idioma"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferencia de región"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Nombre de idioma"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 28d1203..093f7d7 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Võimaldab rakendusel vastu võtta ja töödelda SMS-sõnumeid. See tähendab, et rakendus võib jälgida või kustutada teie seadmele saadetud sõnumeid neid teile näitamata."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"võtke vastu tekstisõnumeid (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Võimaldab rakendusel vastu võtta ja töödelda multimeediumsõnumeid. See tähendab, et rakendus võib jälgida või kustutada teie seadmele saadetud sõnumeid neid teile näitamata."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"mobiilsidesõnumite lugemine"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Võimaldab rakendusel lugeda seadme vastu võetud mobiilsidesõnumeid. Mobiilsidemärguandeid edastatakse mõnes asukohas eriolukorrast teavitamiseks. Pahatahtlikud rakendused võivad segada seadme toimivust või tööd eriolukorra sõnumi vastuvõtmisel."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"loe tellitud kanaleid"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Võimaldab rakendusel lugeda ja kirjutada funktsiooni Mitte segada seadistusi."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"vaatamisloa kasutamise alustamine"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Võimaldab omanikul rakenduse puhul alustada loa kasutamist. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"juurdepääsetavuse otsetee sihtmärk"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Lubab rakendusel määrata juurdepääsetavuse otsetee sihtmärgi."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Juhitakse ekraaniluku paroolide ja PIN-koodide pikkusi ning lubatud tähemärkide seadeid."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Ekraani avamiskatsete jälgimine"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Valige USB silumise keelamiseks"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Testrakendirežiim on lubatud"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Testrakendirežiimi keelamiseks taastage tehaseseaded."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Seeriakonsool on lubatud"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"See mõjutab toimivust. Keelamiseks kontrollige käivituslaadurit."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB-pordis on vedelik või mustus"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-port on automaatselt keelatud. Puudutage lisateabe saamiseks."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-porti tohib kasutada"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Kategoriseerimata"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Teie määrasite nende märguannete tähtsuse."</string>
<string name="importance_from_person" msgid="9160133597262938296">"See on tähtis osalevate inimeste tõttu."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Kas lubada rakendusel <xliff:g id="APP">%1$s</xliff:g> luua uus kasutaja kontoga <xliff:g id="ACCOUNT">%2$s</xliff:g> (selle kontoga kasutaja on juba olemas)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Kas lubada rakendusel <xliff:g id="APP">%1$s</xliff:g> luua uus kasutaja kontoga <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Keele lisamine"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Piirkonnaeelistus"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Sisestage keele nimi"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 9460ee7..53b1a38 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -280,37 +280,37 @@
<string name="managed_profile_label" msgid="8947929265267690522">"Aldatu laneko profilera"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktuak"</string>
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"atzitu kontaktuak"</string>
- <string name="permgrouprequest_contacts" msgid="6032805601881764300">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari kontaktuak atzitzeko baimena eman nahi diozu?"</string>
+ <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Kontaktuak atzitzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Kokapena"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"atzitu gailuaren kokapena"</string>
- <string name="permgrouprequest_location" msgid="3788275734953323491">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari gailuaren kokapena atzitzeko baimena eman nahi diozu?"</string>
+ <string name="permgrouprequest_location" msgid="3788275734953323491">"Gailuaren kokapena atzitzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Hura erabiltzen ari zarenean soilik atzituko du aplikazioak kokapena"</string>
- <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari gailuaren kokapena <b>beti</b> atzitzeko baimena eman nahi diozu?"</string>
+ <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Gailuaren kokapena <b>beti</b> atzitzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Aplikazioak hura darabilzunean atzi dezake kokapena"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Egutegia"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"atzitu egutegia"</string>
- <string name="permgrouprequest_calendar" msgid="289900767793189421">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari egutegia atzitzeko baimena eman nahi diozu?"</string>
+ <string name="permgrouprequest_calendar" msgid="289900767793189421">"Egutegia atzitzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS mezuak"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"bidali eta ikusi SMS mezuak"</string>
- <string name="permgrouprequest_sms" msgid="7168124215838204719">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari SMS mezuak bidaltzeko eta ikusteko baimena eman nahi diozu?"</string>
+ <string name="permgrouprequest_sms" msgid="7168124215838204719">"SMS mezuak bidaltzeko eta ikusteko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Memoria"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"atzitu gailuko argazkiak, multimedia-edukia eta fitxategiak"</string>
- <string name="permgrouprequest_storage" msgid="7885942926944299560">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari gailuko argazkiak, multimedia-edukia eta fitxategiak atzitzeko baimena eman nahi diozu?"</string>
+ <string name="permgrouprequest_storage" msgid="7885942926944299560">"Gailuko argazkiak, multimedia-edukia eta fitxategiak atzitzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofonoa"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"grabatu audioa"</string>
- <string name="permgrouprequest_microphone" msgid="9167492350681916038">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari audioa grabatzeko baimena eman nahi diozu?"</string>
+ <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Audioa grabatzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"Ariketa fisikoa"</string>
<string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"ariketa fisikoak atzitu"</string>
<string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"Zure ariketa fisikoak atzitzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"atera argazkiak eta grabatu bideoak"</string>
- <string name="permgrouprequest_camera" msgid="1299833592069671756">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari argazkiak ateratzeko eta bideoak grabatzeko baimena eman nahi diozu?"</string>
+ <string name="permgrouprequest_camera" msgid="1299833592069671756">"Argazkiak ateratzeko eta bideoak grabatzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgrouplab_calllog" msgid="8798646184930388160">"Deien erregistroa"</string>
<string name="permgroupdesc_calllog" msgid="3006237336748283775">"irakurri telefonoko deien erregistroa eta idatzi bertan"</string>
- <string name="permgrouprequest_calllog" msgid="8487355309583773267">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari telefonoko deien erregistroa atzitzeko baimena eman nahi diozu?"</string>
+ <string name="permgrouprequest_calllog" msgid="8487355309583773267">"Telefonoko deien erregistroa atzitzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefonoa"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"egin eta kudeatu telefono-deiak"</string>
- <string name="permgrouprequest_phone" msgid="9166979577750581037">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari telefono-deiak egiteko eta kudeatzeko baimena eman nahi diozu?"</string>
+ <string name="permgrouprequest_phone" msgid="9166979577750581037">"Telefono-deiak egiteko eta kudeatzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
<string name="permgrouplab_sensors" msgid="4838614103153567532">"Gorputz-sentsoreak"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"atzitu bizi-konstanteei buruzko sentsorearen datuak"</string>
<string name="permgrouprequest_sensors" msgid="6349806962814556786">"Bizi-konstanteei buruzko sentsorearen datuak atzitzeko baimena eman nahi diozu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS mezuak jasotzeko eta prozesatzeko baimena ematen die aplikazioei. Horrela, aplikazioak gailura bidalitako mezuak kontrola eta ezaba ditzake zuri erakutsi gabe."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"jaso testu-mezuak (MMSak)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS mezuak jasotzeko eta prozesatzeko baimena ematen die aplikazioei. Horrela, aplikazioak gailura bidalitako mezuak kontrola eta ezaba ditzake zuri erakutsi gabe."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"irakurri sare mugikor bidezko igorpen-mezuak"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Gailuak jasotako sare mugikor bidezko igorpenen mezuak irakurtzeko baimena ematen die aplikazioei. Sare mugikor bidezko igorpen-alertak kokapen batzuetan ematen dira larrialdi-egoeren berri emateko. Aplikazio gaiztoek gailuaren errendimendua edo funtzionamendua oztopa dezakete larrialdi-igorpen horietako bat jasotzen denean."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"irakurri harpidetutako jarioak"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"\"Ez molestatu\" konfigurazioa irakurtzeko eta bertan idazteko baimena ematen die aplikazioei."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"hasi ikusteko baimena erabiltzen"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Aplikazioaren baimena erabiltzen hasteko baimena ematen die titularrei. Aplikazio normalek ez lukete beharko."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"erabilerraztasun-lasterbidearen helburua"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Erabilerraztasun-lasterbidearen helburua zehazteko baimena ematen dio aplikazioari."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Ezarri pasahitzen arauak"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolatu pantaila blokeoaren pasahitzen eta PINen luzera eta onartutako karaktereak."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Gainbegiratu pantaila desblokeatzeko saiakerak"</string>
@@ -1260,7 +1266,7 @@
<string name="wifi_suggestion_title" msgid="6396033039578436801">"Iradokitako wifi-sareak baimendu nahi dituzu?"</string>
<string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> aplikazioak sare batzuk iradoki ditu. Baliteke gailua automatikoki konektatzea."</string>
<string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Baimendu"</string>
- <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ez. Eskerrik asko."</string>
+ <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ez, eskerrik asko"</string>
<string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi konexioa automatikoki aktibatuko da"</string>
<string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Gordeta daukazun kalitate handiko sare batetik gertu zaudenean"</string>
<string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ez aktibatu berriro"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Hautatu USB arazketa desgaitzeko."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Proba-materialeko modua gaitu da"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Proba-materialaren modua desgaitzeko, berrezarri jatorrizko datuak."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serie-kontsola gaituta dago"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Funtzionamenduari eragiten dio. Desgaitzeko, joan abiarazlera."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Likidoa edo zikinkeriak daude USB atakan"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ataka automatikoki desgaitu da. Informazio gehiago lortzeko, sakatu hau."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Erabiltzeko moduan dago USB ataka"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Kategoriarik gabea"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Zuk ezarri duzu jakinarazpen hauen garrantzia."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Garrantzitsua da eragiten dien pertsonengatik."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> kontua duen erabiltzailea sortzeko baimena eman nahi diozu <xliff:g id="APP">%1$s</xliff:g> aplikazioari? (Badago kontu hori duen erabiltzaile bat)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> kontua duen erabiltzailea sortzeko baimena eman nahi diozu <xliff:g id="APP">%1$s</xliff:g> aplikazioari?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Gehitu hizkuntza"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Lurralde-hobespena"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Adierazi hizkuntza"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index ec5dbcb2..2b849d5 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"به برنامه اجازه میدهد پیامکها را دریافت و پردازش کند. این یعنی برنامه میتواند پیامهای ارسالی به دستگاه شما را بدون نمایش آنها به شما حذف یا کنترل کند."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"دریافت پیامهای نوشتاری (فراپیام)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"به برنامه اجازه میدهد پیامهای فراپیام را دریافت و پردازش کند. این یعنی برنامه میتواند پیامهای ارسالی به دستگاه شما را بدون نمایش آنها به شما حذف یا کنترل کند."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"خواندن پیامهای پخش سلولی"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"به برنامه اجازه میدهد پیامهای پخش سلولی دستگاه شما را بخواند. هشدارهای پخش سلولی در برخی از موقعیتهای مکانی تحویل داده میشوند تا موقعیتهای اضطراری را به شما اعلام کنند. وقتی پخش سلولی دریافت میشود، ممکن است برنامههای مخرب در عملکرد یا کارکرد دستگاه شما اختلال ایجاد کنند."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"خواندن فیدهای مشترک"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"به برنامه امکان میدهد پیکربندی «مزاحم نشوید» را بخواند و بنویسد."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"شروع مشاهده استفاده از مجوز"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"به دارنده اجازه شروع استفاده از مجوز را برای برنامه میدهد. هرگز برای برنامههای معمول نیاز نیست."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"مقصد میانبر دسترسپذیری"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"به برنامه اجازه میدهد مقصد میانبر دسترسپذیری را تعریف کند."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین گذرواژه"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"کنترل طول و نوع نویسههایی که در گذرواژه و پین قفل صفحه مجاز است."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"پایش تلاشهای باز کردن قفل صفحه"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"«حالت مجموعه دادههای تست» فعال شد"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"برای غیرفعال کردن «حالت مجموعه دادههای تست»، بازنشانی کارخانهای کنید."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"کنسول سریال فعال است"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"عملکرد تحتتأثیر قرار گرفته است. برای غیرفعال کردن، bootloader را بررسی کنید."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"مایعات یا خاکروبه در درگاه USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"درگاه USB بهطور خودکار غیرفعال شده است. برای اطلاعات بیشتر، ضربه بزنید."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"میتوان از درگاه USB استفاده کرد"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"دستهبندینشده"</string>
<string name="importance_from_user" msgid="7318955817386549931">"شما اهمیت این اعلانها را تنظیم میکنید."</string>
<string name="importance_from_person" msgid="9160133597262938296">"به دلیل افراد درگیر مهم است."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"به<xliff:g id="APP">%1$s</xliff:g> اجازه میدهید با <xliff:g id="ACCOUNT">%2$s</xliff:g> (کاربری با این حساب درحالحاضر وجود دارد) کاربری جدید ایجاد کند؟"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"به <xliff:g id="APP">%1$s</xliff:g> اجازه میدهید با <xliff:g id="ACCOUNT">%2$s</xliff:g> کاربری جدید ایجاد کند؟"</string>
<string name="language_selection_title" msgid="2680677278159281088">"افزودن زبان"</string>
<string name="country_selection_title" msgid="2954859441620215513">"اولویتهای منطقه"</string>
<string name="search_language_hint" msgid="7042102592055108574">"نام زبان را تایپ کنید"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index a94253b..c18e5bf 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Antaa sovelluksen vastaanottaa ja käsitellä tekstiviestejä. Sovellus voi valvoa tai poistaa laitteeseesi lähetettyjä viestejä näyttämättä niitä sinulle."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"vastaanota tekstiviestejä (multimedia)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Antaa sovelluksen vastaanottaa ja käsitellä multimediaviestejä. Sovellus voi valvoa tai poistaa laitteeseesi lähetettyjä viestejä näyttämättä niitä sinulle."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lue tiedotteita"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Antaa sovelluksen lukea laitteesi vastaanottamia tiedotteita. Tiedotteiden avulla ilmoitetaan hätätilanteista joissakin paikoissa. Haitalliset sovellukset voivat häiritä laitteen toimintaa laitteen vastaanottaessa hätätiedotteen."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lukea tilattuja syötteitä"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Sallii sovelluksen lukea ja muokata Älä häiritse -tilan asetuksia."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"aloita katseluoikeuksien käyttö"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Antaa luvanhaltijan käynnistää sovelluksen käyttöoikeuksien käytön. Ei tavallisten sovelluksien käyttöön."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"esteettömyystilan pikakuvakkeen kohde"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Sallii sovelluksen määrittää kohteen esteettömystilan pikakuvakkeelle."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Asentaa salasanasäännöt"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Hallinnoida ruudun lukituksen salasanoissa ja PIN-koodeissa sallittuja merkkejä ja niiden pituutta."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Tarkkailla näytön avaamisyrityksiä"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Testikehystila käytössä"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Palauta tehdasasetukset, niin voit poistaa testikehystilan käytöstä."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Sarjakonsoli käytössä"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Tämä vaikuttaa suorituskykyyn. Jos haluat poistaa toiminnon käytöstä, tarkista käynnistysohjelma."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Nestettä tai likaa USB-portissa"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-portti poistetaan käytöstä automaattisesti. Napauta nähdäksesi lisätietoja."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-portin käyttö on sallittu"</string>
@@ -1629,7 +1637,7 @@
<string name="kg_pattern_instructions" msgid="398978611683075868">"Piirrä kuvio"</string>
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Anna SIM-kortin PIN-koodi"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Anna PIN-koodi"</string>
- <string name="kg_password_instructions" msgid="5753646556186936819">"Anna salasana"</string>
+ <string name="kg_password_instructions" msgid="5753646556186936819">"Lisää salasana"</string>
<string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortti on nyt poistettu käytöstä. Jatka antamalla PUK-koodi. Saat lisätietoja ottamalla yhteyttä operaattoriin."</string>
<string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Anna haluamasi PIN-koodi"</string>
<string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Vahvista haluamasi PIN-koodi"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Luokittelematon"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Voit valita näiden ilmoitusten tärkeyden."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Tämä on tärkeää siihen liittyvien ihmisten perusteella."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Saako <xliff:g id="APP">%1$s</xliff:g> luoda uuden käyttäjän (<xliff:g id="ACCOUNT">%2$s</xliff:g>) – tällä käyttäjällä on jo tili?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Saako <xliff:g id="APP">%1$s</xliff:g> luoda uuden käyttäjän (<xliff:g id="ACCOUNT">%2$s</xliff:g>)?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Lisää kieli"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Alueasetus"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Anna kielen nimi"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 94f6acb..3bd5c23 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Permet à l\'application de recevoir et de traiter les messages texte. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"recevoir des messages multimédias"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permet à l\'application de recevoir et de traiter les messages multimédias. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lire les messages de diffusion cellulaire"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permet à l\'application de lire les messages de diffusion cellulaire que votre appareil reçoit. Dans certaines zones géographiques, des alertes vous sont envoyées afin de vous prévenir en cas de situation d\'urgence. Des applications malveillantes peuvent venir perturber les performances ou le fonctionnement de votre appareil lors de la réception d\'un message de diffusion cellulaire."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lire les flux auxquels vous êtes abonné"</string>
@@ -530,9 +534,9 @@
<string name="biometric_not_recognized" msgid="5770511773560736082">"Données biométriques non reconnues"</string>
<string name="biometric_error_canceled" msgid="349665227864885880">"Authentification annulée"</string>
<string name="biometric_error_device_not_secured" msgid="6583143098363528349">"Aucun NIP, schéma ou mot de passe défini"</string>
- <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Empreinte digitale partielle détectée. Veuillez essayer de nouveau."</string>
+ <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Empreinte digitale partielle détectée. Veuillez réessayer."</string>
<string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string>
- <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Le capteur d\'empreintes digitales est sale. Veuillez le nettoyer et essayer de nouveau."</string>
+ <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Le capteur d\'empreintes digitales est sale. Veuillez le nettoyer et réessayer."</string>
<string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Vous avez déplacé votre doigt trop rapidement. Veuillez réessayer."</string>
<string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
<string-array name="fingerprint_acquired_vendor">
@@ -540,10 +544,10 @@
<string name="fingerprint_authenticated" msgid="5309333983002526448">"Empreinte digitale authentifiée"</string>
<string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Visage authentifié"</string>
<string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Visage authentifié, veuillez appuyer sur le bouton Confirmer"</string>
- <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Matériel d\'empreinte numérique indisponible."</string>
+ <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Matériel d\'empreinte digitale numérique indisponible."</string>
<string name="fingerprint_error_no_space" msgid="1055819001126053318">"L\'empreinte digitale ne peut pas être enregistrée. Veuillez supprimer une empreinte existante."</string>
- <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Le temps attribué pour lire l\'empreinte est écoulé. Veuillez essayer de nouveau."</string>
- <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Opération d\'empreinte numérique annulée."</string>
+ <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Le temps attribué pour lire l\'empreinte digitale est écoulé. Veuillez réessayer."</string>
+ <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Opération d\'empreinte digitale numérique annulée."</string>
<string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"L\'opération d\'empreinte digitale a été annulée par l\'utilisateur."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Trop de tentatives. Veuillez réessayer plus tard."</string>
<string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Trop de tentatives. Capteur d\'empreintes digitales désactivé."</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permet à l\'application de consulter et de modifier la configuration du mode Ne pas déranger."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"démarrer l\'affichage de l\'usage des autorisations"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permet au détenteur de démarrer l\'usage des autorisations pour une application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cible du raccourci d\'accessibilité"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permet à une application de définir la cible du raccourci d\'accessibilité."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Gérer le nombre et le type de caractères autorisés dans les mots de passe et les NIP de verrouillage de l\'écran."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Mode Logiciel de test activé"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Effectuez une réinitialisation pour désactiver le mode Logiciel de test."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"La console série est activée"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"La performance est réduite. Pour désactiver cette fonction, vérifier le programme d\'amorçage."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquide ou débris dans le port USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Touchez ici pour en savoir plus."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Autorisation d\'utiliser le port USB"</string>
@@ -1579,8 +1587,8 @@
<string name="expires_on" msgid="3676242949915959821">"Expire le :"</string>
<string name="serial_number" msgid="758814067660862493">"Numéro de série :"</string>
<string name="fingerprints" msgid="4516019619850763049">"Empreintes :"</string>
- <string name="sha256_fingerprint" msgid="4391271286477279263">"Empreinte SHA-256 :"</string>
- <string name="sha1_fingerprint" msgid="7930330235269404581">"Empreinte SHA-1 :"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"Empreinte digitale SHA-256 :"</string>
+ <string name="sha1_fingerprint" msgid="7930330235269404581">"Empreinte digitale SHA-1 :"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Tout afficher"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Sélectionnez une activité"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Partagez avec"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Sans catégorie"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Vous définissez l\'importance de ces notifications."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Ces notifications sont importantes en raison des participants."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un utilisateur <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Un utilisateur est déjà associé à ce compte)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil d\'utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Ajouter une langue"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Préférences régionales"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Entrez la langue"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 11ba7dc..8520c13 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Permet à l\'application de recevoir et de traiter les SMS. Cette autorisation lui donne la possibilité de surveiller ou supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"recevoir des messages texte (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permet à l\'application de recevoir et de traiter les MMS. Cette autorisation lui donne la possibilité de surveiller ou supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lire les messages reçus via un canal de diffusion cellulaire"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permet à l\'application de lire les messages que votre appareil reçoit via un canal de diffusion cellulaire. Dans certaines zones géographiques, des alertes vous sont envoyées afin de vous prévenir en cas de situation d\'urgence. Les applications malveillantes peuvent venir perturber les performances ou le fonctionnement de votre appareil lorsqu\'un message est reçu via un canal de diffusion cellulaire."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lire les flux auxquels vous êtes abonné"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permet à l\'application de consulter et de modifier la configuration du mode Ne pas déranger."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"activer l\'utilisation de l\'autorisation d\'affichage"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permet à l\'application autorisée d\'activer l\'utilisation de l\'autorisation pour une application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cible du raccourci d\'accessibilité"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Autorise une application à définir la cible du raccourci d\'accessibilité."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Gérer le nombre et le type de caractères autorisés dans les mots de passe et les codes d\'accès de verrouillage de l\'écran"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Mode Atelier de test activé"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Rétablissez la configuration d\'usine pour désactiver le mode Atelier de test."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Console série activée"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Les performances sont affectées. Pour désactiver la console série, vérifiez le bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Présence de liquide ou de saletés dans le port USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Appuyez sur cette notification pour en savoir plus."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Le port USB peut être utilisé"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Sans catégorie"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Vous définissez l\'importance de ces notifications."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Ces notifications sont importantes en raison des participants."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g> (un utilisateur associé à ce compte existe déjà) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Ajouter une langue"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Préférences régionales"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Saisissez la langue"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 1becada..78c7d03 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite á aplicación recibir e procesar mensaxes SMS. Isto significa que a aplicación pode supervisar ou eliminar mensaxes enviadas ao teu dispositivo sen mostrarchas."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"recibir mensaxes de texto (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite á aplicación recibir e procesar mensaxes MMS. Isto significa que a aplicación pode supervisar ou eliminar mensaxes enviadas ao teu dispositivo sen mostrarchas."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ler mensaxes de difusión móbil"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite á aplicación ler mensaxes de difusión móbil recibidas polo teu dispositivo. As alertas de difusión móbil envíanse nalgunhas localizacións para avisar de situacións de emerxencia. É posible que aplicacións maliciosas afecten ao rendemento ou funcionamento do teu dispositivo cando se recibe unha difusión móbil de emerxencia."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds subscritos"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite á aplicación ler e escribir a configuración do modo Non molestar."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar uso de permiso de vista"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite ao propietario iniciar o uso de permisos dunha aplicación. As aplicacións normais non deberían precisalo nunca."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"obxectivo do atallo de accesibilidade"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite que unha aplicación defina o obxectivo do atallo de accesibilidade."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer as normas de contrasinal"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Controla a lonxitude e os caracteres permitidos nos contrasinais e nos PIN de bloqueo da pantalla."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Controlar os intentos de desbloqueo da pantalla"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecciona a opción para desactivar a depuración por USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Activouse o modo de axente de proba"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece a configuración de fábrica para desactivar o modo de axente de proba."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"A consola de serie está activada"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"O rendemento vese afectado. Para desactivar a consola, comproba o cargador de arranque."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hai líquido ou residuos no porto USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"O porto USB desactivouse automaticamente. Toca para obter máis información."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Pódese utilizar o porto USB"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Sen clasificar"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Ti defines a importancia destas notificacións."</string>
<string name="importance_from_person" msgid="9160133597262938296">"É importante polas persoas involucradas."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Xa existe un usuario con esta conta)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Queres permitir que <xliff:g id="APP">%1$s</xliff:g> cree un usuario novo con <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Engadir un idioma"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferencia de rexión"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Nome do idioma"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 09661c1..340245a 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -295,10 +295,10 @@
<string name="permgrouprequest_sms" msgid="7168124215838204719">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને SMS સંદેશા મોકલવા અને જોવાની મંજૂરી આપીએ?"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"સ્ટોરેજ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"તમારા ઉપકરણ પર ફોટો, મીડિયા અને ફાઇલો ઍક્સેસ કરવાની"</string>
- <string name="permgrouprequest_storage" msgid="7885942926944299560">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને તમારા ઉપકરણ પર ફોટા, મીડિયા અને ફાઇલોને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
+ <string name="permgrouprequest_storage" msgid="7885942926944299560">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને તમારા ડિવાઇસ પર ફોટા, મીડિયા અને ફાઇલોને ઍક્સેસ કરવાની મંજૂરી આપીએ?"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"માઇક્રોફોન"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ઑડિઓ રેકોર્ડ કરવાની"</string>
- <string name="permgrouprequest_microphone" msgid="9167492350681916038">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને ઑડિઓ રેકૉર્ડ કરવાની મંજૂરી આપીએ?"</string>
+ <string name="permgrouprequest_microphone" msgid="9167492350681916038">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને ઑડિયો રેકૉર્ડ કરવાની મંજૂરી આપીએ?"</string>
<string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"શારીરિક પ્રવૃત્તિ"</string>
<string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"તમારી શારીરિક પ્રવૃત્તિને ઍક્સેસ કરવી"</string>
<string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને તમારી શારીરિક પ્રવૃત્તિને ઍક્સેસ કરવાની મંજૂરી આપવી છે?"</string>
@@ -325,7 +325,7 @@
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"હાવભાવ કરો"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"ટૅપ, સ્વાઇપ, પિંચ કરી અને અન્ય હાવભાવ કરી શકે છે."</string>
<string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"ફિંગરપ્રિન્ટ સંકેતો"</string>
- <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"ઉપકરણના ફિંગરપ્રિન્ટ સેન્સર પર કરવામાં આવેલા સંકેતો કૅપ્ચર કરી શકે છે."</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"ડિવાઇસના ફિંગરપ્રિન્ટ સેન્સર પર કરવામાં આવેલા સંકેતો કૅપ્ચર કરી શકે છે."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"સ્ટેટસ બારને અક્ષમ કરો અથવા તેમાં ફેરફાર કરો"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ઍપ્લિકેશનને સ્ટેટસ બાર અક્ષમ કરવાની અથવા સિસ્ટમ આયકન્સ ઉમેરવા અને દૂર કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"સ્ટેટસ બારમાં બતાવો"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"ઍપ્લિકેશનને SMS સંદેશા પ્રાપ્ત કરવાની અને તેના પર પ્રક્રિયા કરવાની મંજૂરી આપે છે. આનો અર્થ એ કે ઍપ્લિકેશન તમને દર્શાવ્યા વિના તમારા ઉપકરણ પર મોકલેલ સંદેશાઓનું નિરીક્ષણ કરી શકે છે અથવા કાઢી નાખી શકે છે."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ટેક્સ્ટ સંદેશા (MMS) પ્રાપ્ત કરો"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"ઍપ્લિકેશનને MMS સંદેશા પ્રાપ્ત કરવાની અને તેના પર પ્રક્રિયા કરવાની મંજૂરી આપે છે. આનો અર્થ એ કે ઍપ્લિકેશન તમને દર્શાવ્યા વિના તમારા ઉપકરણ પર મોકલેલ સંદેશાઓનું નિરીક્ષણ કરી શકે છે અથવા કાઢી નાખી શકે છે."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"સેલ બ્રોડકાસ્ટ સંદેશા વાંચો"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"એપ્લિકેશનને તમારા ઉપકરણ દ્વારા પ્રાપ્ત થયેલ સેલ બ્રોડકાસ્ટ સંદેશાને વાંચવાની મંજૂરી આપે છે. સેલ બ્રોડકાસ્ટ ચેતવણીઓ તમને કટોકટીની સ્થિતિઓ અંગે ચેતવવા માટે કેટલાક સ્થાનોમાં વિતરિત થાય છે. જ્યારે કટોકટીનો સેલ બ્રોડકાસ્ટ પ્રાપ્ત થાય ત્યારે દુર્ભાવનાપૂર્ણ ઍપ્લિકેશનો તમારા ઉપકરણના પ્રદર્શન અથવા ઓપરેશનમાં હસ્તક્ષેપ કરી શકે છે."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"સબ્સ્ક્રાઇબ કરેલ ફીડ્સ વાંચો"</string>
@@ -513,9 +517,9 @@
<string name="permlab_useBiometric" msgid="8837753668509919318">"બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરો"</string>
<string name="permdesc_useBiometric" msgid="8389855232721612926">"ઍપને પ્રમાણીકરણ માટે બાયોમેટ્રિક હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
<string name="permlab_manageFingerprint" msgid="5640858826254575638">"ફિંગરપ્રિન્ટ હાર્ડવેરને સંચાલિત કરો"</string>
- <string name="permdesc_manageFingerprint" msgid="178208705828055464">"એપ્લિકેશનને ઉપયોગ માટે ફિંગરપ્રિન્ટ નમૂના ઉમેરવા અને કાઢી નાખવા માટે પદ્ધતિઓની વિનંતી કરવાની મંજૂરી આપે છે."</string>
+ <string name="permdesc_manageFingerprint" msgid="178208705828055464">"ઍપને ઉપયોગ માટે ફિંગરપ્રિન્ટ નમૂના ઉમેરવા અને કાઢી નાખવા માટે પદ્ધતિઓની વિનંતી કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_useFingerprint" msgid="3150478619915124905">"ફિંગરપ્રિન્ટ હાર્ડવેરનો ઉપયોગ કરો"</string>
- <string name="permdesc_useFingerprint" msgid="9165097460730684114">"એપ્લિકેશનને પ્રમાણીકરણ માટે ફિંગરપ્રિન્ટ હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
+ <string name="permdesc_useFingerprint" msgid="9165097460730684114">"ઍપને પ્રમાણીકરણ માટે ફિંગરપ્રિન્ટ હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
<string name="permlab_audioWrite" msgid="2661772059799779292">"આપનો સંગીત સંગ્રહ સંશોધિત કરવો"</string>
<string name="permdesc_audioWrite" msgid="8888544708166230494">"એપને તમારો સંગીત સંગ્રહ સંશોધિત કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_videoWrite" msgid="128769316366746446">"આપનો વિડિઓ સંગ્રહ સંશોધિત કરવો"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"એપ્લિકેશનને ખલેલ પાડશો નહીં ગોઠવણી વાંચવા અને લખવાની મંજૂરી આપે છે."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"પરવાનગી વપરાશ જુઓને શરૂ કરો"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"કોઈ ઍપ માટે પરવાનગી વપરાશ શરૂ કરવાની ધારકને મંજૂરી આપે છે. સામાન્ય ઍપ માટે ક્યારેય જરૂર પડી ન શકે."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ઍક્સેસિબિલિટી શૉર્ટકટ ટાર્ગેટ"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ઍપને ઍક્સેસિબિલિટી શૉર્ટકટ ટાર્ગેટ વ્યાખ્યાતિત કરવાની મંજૂરી આપે છે."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"પાસવર્ડ નિયમો સેટ કરો"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"સ્ક્રીન લૉક પાસવર્ડ અને પિનમાં મંજૂર લંબાઈ અને અક્ષરોને નિયંત્રિત કરો."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"સ્ક્રીનને અનલૉક કરવાના પ્રયત્નોનું નિયમન કરો"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ડિબગીંગને અક્ષમ કરવા માટે પસંદ કરો."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ટેસ્ટ હાર્નેસ મોડ ચાલુ કર્યો"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ટેસ્ટ હાર્નેસ મોડ બંધ કરવા માટે ફૅક્ટરી રીસેટ કરો."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"સિરીયલ કન્સોલ ચાલુ થયો"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"કાર્યપ્રદર્શનને અસર થાય છે. બંધ કરવા માટે, બૂટલોડર ચેક કરો."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB પોર્ટમાં પ્રવાહી કે ધૂળ"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB પોર્ટ ઑટોમૅટિક રીતે બંધ કરવામાં આવ્યો છે. વધુ જાણવા માટે ટૅપ કરો."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB પોર્ટનો ઉપયોગ કરવો યોગ્ય છે"</string>
@@ -1580,8 +1588,8 @@
<string name="expires_on" msgid="3676242949915959821">"આ રોજ સમાપ્ત:"</string>
<string name="serial_number" msgid="758814067660862493">"શૃંખલા ક્રમાંક:"</string>
<string name="fingerprints" msgid="4516019619850763049">"ફિંગરપ્રિંટ્સ:"</string>
- <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 ફિંગરપ્રિંટ:"</string>
- <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 ફિંગરપ્રિંટ:"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 ફિંગરપ્રિન્ટ:"</string>
+ <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 ફિંગરપ્રિન્ટ:"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"બધું જુઓ"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"પ્રવૃત્તિ પસંદ કરો"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"આની સાથે શેર કરો"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"અવર્ગીકૃત"</string>
<string name="importance_from_user" msgid="7318955817386549931">"તમે આ સૂચનાઓનું મહત્વ સેટ કર્યું છે."</string>
<string name="importance_from_person" msgid="9160133597262938296">"શામેલ થયેલ લોકોને કારણે આ મહત્વપૂર્ણ છે."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>ને <xliff:g id="ACCOUNT">%2$s</xliff:g> માટે એક નવા વપરાશકર્તા બનાવવાની મંજૂરી આપીએ (આ એકાઉન્ટ માટે એક વપરાશકર્તા પહેલાંથી અસ્તિત્વમાં છે) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>ને <xliff:g id="ACCOUNT">%2$s</xliff:g> માટે એક નવા વપરાશકર્તા બનાવવાની મંજૂરી આપીએ ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ભાષા ઉમેરો"</string>
<string name="country_selection_title" msgid="2954859441620215513">"પ્રદેશ પસંદગી"</string>
<string name="search_language_hint" msgid="7042102592055108574">"ભાષાનું નામ ટાઇપ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f21d138..8f78f95 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"एप्लिकेशन को मैसेज (एसएमएस) पाने और प्रोसेस करने देता है. इसका मतलब है कि एप्लिकेशन आपके डिवाइस पर भेजे गए मैसेज की निगरानी आपको दिखाए बिना कर सकता है और उन्हें हटा सकता है."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"मैसेज (एमएमएस) पाएं"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"ऐप को मल्टीमीडिया मैसेज (एमएमएस) को पाने और उन पर कार्रवाई करने देता है. इसका मतलब है कि ऐप आपके डिवाइस पर भेजे गए मैसेज की निगरानी आपको दिखाए बिना कर सकता है और उन्हें हटा सकता है."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल ब्रॉडकास्ट (CBC) मैसेज पढ़ें"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ऐप को, वो सेल ब्रॉडकास्ट (CBC) मैसेज पढ़ने देता है जो आपके डिवाइस को मिले हैं. सेल ब्रॉडकास्ट (CBC) अलर्ट कुछ स्थानों (लोकेशन) पर आपको आपातकालीन स्थितियों की चेतावनी देने के लिए दिए जाते हैं. आपातकालीन सेल ब्रॉडकास्ट (CBC) मिलने पर, धोखा देने वाले ऐप आपके डिवाइस के परफ़ॉर्मेंस या कार्यवाही में दखल दे सकते हैं."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्यता वाली फ़ीड पढ़ें"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ऐप को परेशान न करें कॉन्फ़िगरेशन पढ़ने और लिखने देती है."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"देखने की अनुमतियां चालू करें"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"इस्तेमाल करने वाले को किसी ऐप्लिकेशन के लिए अनुमतियों का इस्तेमाल शुरू करने देता है. सामान्य ऐप्लिकेशन के लिए इसकी ज़रूरत कभी नहीं पड़ती."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"सुलभता शॉर्टकट टारगेट"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"सुलभता शॉर्टकट टारगेट के बारे में बताने के लिए ऐप्लिकेशन को मंज़ूरी दें."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करना"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"स्क्रीन लॉक पासवर्ड और पिन की लंबाई और उनमें स्वीकृत वर्णों को नियंत्रित करना."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"स्क्रीन अनलॉक करने के की कोशिशों पर नज़र रखना"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबग करना अक्षम करने के लिए चुनें."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"टेस्ट हार्नेस मोड चालू किया गया"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"टेस्ट हार्नेस मोड बंद करने के लिए फ़ैक्ट्री रीसेट करें."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"सीरियल कंसोल को चालू करें"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"परफ़ॉर्मेंस पर असर पड़ा है. बंद करने के लिए बूटलोडर चुनें."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"यूएसबी पोर्ट में तरल चीज़ या कचरा है"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"यूएसबी पोर्ट अपने आप बंद हो गया है. ज़्यादा जानने के लिए टैप करें."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"यूएसबी पोर्ट का इस्तेमाल करना सुरक्षित है"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"बिना किसी श्रेणी के"</string>
<string name="importance_from_user" msgid="7318955817386549931">"आपने इन सूचनाओं की अहमियत सेट की है."</string>
<string name="importance_from_person" msgid="9160133597262938296">"यह मौजूद व्यक्तियों के कारण महत्वपूर्ण है."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> को <xliff:g id="ACCOUNT">%2$s</xliff:g> के नाम से एक नया उपयोगकर्ता बनाने की अनुमति दें (इस नाम से एक खाता पहले से मौजूद है)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Allow <xliff:g id="APP">%1$s</xliff:g> to create a new User with <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"भाषा जोड़ें"</string>
<string name="country_selection_title" msgid="2954859441620215513">"क्षेत्र प्राथमिकता"</string>
<string name="search_language_hint" msgid="7042102592055108574">"भाषा का नाम लिखें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 25007d5..8ddd5f8 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -347,6 +347,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Aplikaciji omogućuje primanje i obradu SMS poruka. To znači da aplikacija može nadzirati ili izbrisati poruke poslane na vaš uređaj, a da vam ih ne prikaže."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"primanje tekstnih poruka (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Aplikaciji omogućuje primanje i obradu MMS poruka. To znači da aplikacija može nadzirati ili izbrisati poruke poslane na vaš uređaj, a da vam ih ne prikaže."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čitaj poruke koje se emitiraju unutar mobilne mreže"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Omogućuje aplikaciji čitanje poruka emitiranih unutar mobilne mreže koje prima vaš uređaj. Upozorenja koja se emitiraju na području mobilne mreže dostavljaju se na nekim lokacijama kako bi upozorila korisnike na hitne situacije. Zlonamjerne aplikacije mogu ometati izvršavanje ili rad vašeg uređaja kada stigne hitno upozorenje koje se emitira unutar mobilne mreže."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"čitanje pretplaćenih feedova"</string>
@@ -658,6 +662,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Omogućuje aplikaciji čitanje i pisanje konfiguracije opcije Ne ometaj."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"pokrenuti upotrebu dopuštenja za pregled"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Dopušta nositelju pokretanje upotrebe dopuštenja za aplikaciju. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cilj prečaca pristupačnosti"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Aplikaciji omogućuje da definira cilj prečaca pristupačnosti."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Postavi pravila zaporke"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Upravlja duljinom i znakovima koji su dopušteni u zaporkama i PIN-ovima zaključavanja zaslona."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Nadziri pokušaje otključavanja zaslona"</string>
@@ -1383,6 +1389,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Odaberite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Omogućen je način testnog okvira"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Vratite na tvorničke postavke da biste onemogućili način testnog okvira."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serijska konzola omogućena"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Izvedba je otežana. Provjerite početni program za pokretanje da biste onemogućili konzolu."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tekućina ili prljavština u USB priključku"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB priključak automatski je onemogućen. Dodirnite da biste saznali više."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Možete koristiti USB priključak"</string>
@@ -1924,10 +1932,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Nema kategorije"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Postavili ste važnost tih obavijesti."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Važno je zbog uključenih osoba."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Dopustiti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da izradi novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g> (korisnik s ovim računom već postoji)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Dopustiti aplikaciji <xliff:g id="APP">%1$s</xliff:g> da izradi novog korisnika s računom <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Dodavanje jezika"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Postavke regije"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Unesite naziv jezika"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 0487601a..d910025 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Lehetővé teszi az alkalmazás számára, hogy SMS-eket fogadjon és dolgozzon fel. Ez azt jelenti, hogy az alkalmazás megfigyelheti vagy törölheti a beérkező üzeneteket anélkül, hogy Ön látná azokat."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"szöveges üzenetek (MMS) fogadása"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Lehetővé teszi az alkalmazás számára, hogy MMS-eket fogadjon és dolgozzon fel. Ez azt jelenti, hogy az alkalmazás megfigyelheti vagy törölheti a beérkező üzeneteket anélkül, hogy Ön látná azokat."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"cellán belüli üzenetek olvasása"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Lehetővé teszi az alkalmazás számára az eszközre érkező cellán belüli üzenetek olvasását. Bizonyos helyeken figyelmeztető üzeneteket kaphat a cellán belül a vészhelyzetekről. A rosszindulatú alkalmazások befolyásolhatják az eszköz teljesítményét vagy működését vészhelyzeti cellaüzenet érkezésekor."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"feliratkozott hírcsatornák olvasása"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Az alkalmazás olvashatja és szerkesztheti a „Ne zavarjanak” funkció beállításait."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"engedélyhasználat megtekintésének elindítása"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Lehetővé teszi a felhasználó számára, hogy elindítsa az alkalmazás engedélyhasználatát. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"A kisegítő lehetőségek gyorsparancs célja"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Engedélyezi az alkalmazásoknak a kisegítő lehetőségek gyorsparancs céljának meghatározását."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Jelszavakkal kapcsolatos szabályok beállítása"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"A képernyőzár jelszavaiban és PIN kódjaiban engedélyezett karakterek és hosszúság vezérlése."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Képernyőzár-feloldási kísérletek figyelése"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Tesztelési alapkörnyezet mód engedélyezve"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"A Tesztelési alapkörnyezet mód kikapcsolásához állítsa vissza a gyári beállításokat."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Soros konzol engedélyezve"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Ez hatással van a teljesítményre. A letiltáshoz ellenőrizze a rendszerindítót."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Folyadék vagy szennyeződés az USB-portban"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-port automatikusan letiltva. Koppintson, ha további információra van szüksége."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Az USB-port rendben használható"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Nincs kategóriába sorolva"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Ön állította be ezen értesítések fontossági szintjét."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Ez az üzenet a résztvevők miatt fontos."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Engedélyezi a(z) <xliff:g id="APP">%1$s</xliff:g> számára, hogy új felhasználót hozzon létre a(z) <xliff:g id="ACCOUNT">%2$s</xliff:g> fiókkal? (Már létezik felhasználó ezzel a fiókkal.)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Engedélyezi a(z) <xliff:g id="APP">%1$s</xliff:g> számára, hogy új felhasználót hozzon létre a(z) <xliff:g id="ACCOUNT">%2$s</xliff:g> fiókkal?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Nyelv hozzáadása"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Régió beállítása"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Adja meg a nyelvet"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index e6223f0..6f5507f 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Թույլ է տալիս հավելվածին ստանալ և մշակել SMS հաղորդագրությունները: Սա նշանակում է, որ հավելվածը կարող է ստուգել կամ ջնջել ձեր սարքին ուղարկված հաղորդագրությունները` առանց դրանք ձեզ ցուցադրելու:"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ստանալ տեքստային հաղորդագրություններ (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Թույլ է տալիս հավելվածին ստանալ և մշակել MMS հաղորդագրությունները: Սա նշանակում է, որ հավելվածը կարող է ստուգել կամ ջնջել ձեր սարքին ուղարկված հաղորդագրությունները` առանց դրանք ձեզ ցուցադրելու:"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"կարդալ բջջային զեկուցվող հաղորդագրությունները"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Թույլ է տալիս հավելվածին կարդալ ձեր սարքի կողմից ստացված բջջային հեռարձակվող հաղորդագրությունները: Բջջային հեռարձակվող զգուշացումները ուղարկվում են որոշ վայրերում` արտակարգ իրավիճակների մասին ձեզ զգուշացնելու համար: Վնասարար հավելվածները կարող են խանգարել ձեր սարքի արդյունավետությանը կամ շահագործմանը, երբ ստացվում է արտակարգ իրավիճակի մասին բջջային հաղորդում:"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"կարդալ բաժանորդագրված հոսքերը"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Թույլ է տալիս հավելվածին փոփոխել «Չանհանգստացնել» գործառույթի կազմաձևումը:"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"թույլտվությունների մասին տվյալների հասանելիություն"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Հավելվածին հասանելի կդառնան թույլտվությունների մասին տվյալները։ Այս թույլտվությունն անհրաժեշտ չէ սովորական հավելվածներին։"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"հատուկ գործառույթների դյուրանցումն օգտագործելու նպատակը"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Հավելվածին թույլ է տալիս որոշել հատուկ գործառույթների դյուրանցումն օգտագործելու նպատակը։"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Կառավարել էկրանի ապակողպման գաղտնաբառերի և PIN կոդերի թույլատրելի երկարությունն ու գրանշանները:"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Վերահսկել էկրանի ապակողպման փորձերը"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Սեղմեք՝ USB-ով վրիպազերծումն անջատելու համար:"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Թեստային ռեժիմը միացված է"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Թեստային ռեժիմն անջատելու համար զրոյացրեք կարգավորումները։"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Սերիական վահանակը միացված է"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Աշխատանքի արդյունավետությունը նվազում է։ Վահանակն անջատելու համար ստուգեք օպերացիոն համակարգի բեռնիչը։"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB միացքում ջուր կամ աղտ է հայտնաբերվել"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB միացքն ավտոմատ անջատվել է: Հպեք՝ ավելին իմանալու համար:"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB միացքը կարող է օգտագործվել"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Չդասակարգված"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Դուք սահմանել եք այս ծանուցումների կարևորությունը:"</string>
<string name="importance_from_person" msgid="9160133597262938296">"Կարևոր է, քանի որ որոշակի մարդիկ են ներգրավված:"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Թույլատրե՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել (նման հաշվով Օգտատեր արդեն գոյություն ունի):"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Թույլատրե՞լ <xliff:g id="APP">%1$s</xliff:g> հավելվածին <xliff:g id="ACCOUNT">%2$s</xliff:g> հաշվով նոր Օգտատեր ստեղծել:"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Ավելացնել լեզու"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Նախընտրելի տարածաշրջան"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Մուտքագրեք լեզուն"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 3c6ee83..88e396c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Memungkinkan aplikasi menerima dan memproses pesan SMS. Ini artinya aplikasi dapat memantau atau menghapus pesan yang dikirim ke perangkat Anda tanpa menunjukkannya kepada Anda."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"terima pesan teks (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Memungkinkan aplikasi menerima dan memproses pesan MMS. Ini artinya aplikasi dapat memantau atau menghapus pesan yang dikirim ke perangkat Anda tanpa menunjukkannya kepada Anda."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"membaca pesan siaran seluler"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Mengizinkan aplikasi membaca pesan siaran seluler yang diterima perangkat Anda. Notifikasi siaran seluler dikirimkan di beberapa lokasi untuk memperingatkan Anda tentang situasi darurat. Aplikasi berbahaya dapat mengganggu kinerja atau operasi perangkat Anda saat siaran seluler darurat diterima."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"baca feed langganan"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Mengizinkan aplikasi membaca dan menulis konfigurasi status Jangan Ganggu."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"mulai melihat penggunaan izin"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Memungkinkan pemegang memulai penggunaan izin untuk aplikasi. Tidak diperlukan untuk aplikasi normal."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"target pintasan aksesibilitas"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Mengizinkan aplikasi menentukan target pintasan aksesibilitas."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Setel aturan sandi"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Mengontrol panjang dan karakter yang diizinkan dalam sandi dan PIN kunci layar."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Pantau upaya pembukaan kunci layar"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Mode Tes Otomatis diaktifkan"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Lakukan reset ke setelan pabrik untuk menonaktifkan Mode Tes Otomatis."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Konsol serial diaktifkan"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Performa terpengaruh. Untuk menonaktifkan, periksa bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Cairan atau kotoran di port USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB otomatis dinonaktifkan. Ketuk untuk mempelajari lebih lanjut."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Boleh menggunakan port USB"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Belum dikategorikan"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Anda menyetel nilai penting notifikasi ini."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Ini penting karena orang-orang yang terlibat."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Izinkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baru dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> (Pengguna dengan akun ini sudah ada) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Izinkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baru dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Tambahkan bahasa"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferensi wilayah"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Ketik nama bahasa"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 59cd4c1..32461d3 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Leyfir forriti að taka á móti og vinna úr SMS-skilaboðum. Þetta þýðir að forritið getur fylgst með eða eytt skilaboðum sem send eru í tækið án þess að birta þér þau."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"taka á móti textaskilaboðum (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Leyfir forriti að taka á móti og vinna úr MMS-skilaboðum. Þetta þýðir að forritið getur fylgst með eða eytt skilaboðum sem send eru í tækið án þess að birta þér þau."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lesa skilaboð frá endurvarpa"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Leyfir forriti að lesa skilaboð frá endurvarpa sem tækið móttekur. Viðvaranir frá endurvarpa berast á tilteknum stöðum til að vara þig við neyðarástandi. Spilliforrit geta truflað afköst eða virkni tækisins þegar neyðarboð berast frá endurvarpa."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lesa strauma í áskrift"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Leyfir forriti að lesa og skrifa í grunnstillingu „Ónáðið ekki“."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"heimildanotkun upphafsyfirlits"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Leyfir handhafa að byrja heimildanotkun fyrir forrit. Ætti aldrei að þurfa fyrir venjuleg forrit."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"áfangastaður aðgengisflýtileiðar"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Leyfir forriti að skilgreina áfangastað aðgengisflýtileiðar."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Setja reglur um aðgangsorð"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Stjórna lengd og fjölda stafa í aðgangsorðum og PIN-númerum skjáláss."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Fylgjast með tilraunum til að taka skjáinn úr lás"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Veldu til að gera USB-villuleit óvirka."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Kveikt á stillingu prófunarvangs"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Núllstilltu til að slökkva á stillingu prófunarvangs."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Raðstjórnborð virkjað"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Þetta hefur áhrif á afköst. Athugaðu ræsiforritið ef þú vilt gera þetta óvirkt."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vökvi eða óhreinindi í USB-tengi"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-tengi er gert óvirkt sjálfkrafa. Ýttu til að fá frekari upplýsingar."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Óhætt að nota USB-tengi"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Óflokkað"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Þú stilltir mikilvægi þessara tilkynninga."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Þetta er mikilvægt vegna fólksins sem tekur þátt í þessu."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Viltu leyfa <xliff:g id="APP">%1$s</xliff:g> að stofna nýjan notanda með <xliff:g id="ACCOUNT">%2$s</xliff:g> (notandi með þennan reikning er þegar fyrir hendi)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Leyfa <xliff:g id="APP">%1$s</xliff:g> að stofna nýjan notanda með <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Bæta við tungumáli"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Svæðisval"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Sláðu inn heiti tungumáls"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index cbc9989..6e25563 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -283,7 +283,7 @@
<string name="permgrouprequest_contacts" msgid="6032805601881764300">"Consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere ai tuoi contatti?"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Geolocalizz."</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"accedere alla posizione di questo dispositivo"</string>
- <string name="permgrouprequest_location" msgid="3788275734953323491">"Consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere alla posizione di questo dispositivo?"</string>
+ <string name="permgrouprequest_location" msgid="3788275734953323491">"Consentire all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere alla posizione del dispositivo?"</string>
<string name="permgrouprequestdetail_location" msgid="1347189607421252902">"L\'app avrà accesso alla posizione soltanto quando la usi"</string>
<string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di accedere <b>sempre</b> alla posizione di questo dispositivo?"</string>
<string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"L\'app al momento può accedere alla posizione soltanto mentre la usi"</string>
@@ -324,8 +324,8 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Controlla il livello di zoom e la posizione del display."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Eseguire gesti"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Consente di toccare, far scorrere, pizzicare ed eseguire altri gesti."</string>
- <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gesti con sensore di impronte digitali"</string>
- <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"È in grado di rilevare i gesti compiuti con il sensore di impronte digitali dei dispositivi."</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gesti con sensore di impronte"</string>
+ <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"È in grado di rilevare i gesti compiuti con il sensore di impronte dei dispositivi."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"disattivazione o modifica della barra di stato"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"Consente all\'applicazione di disattivare la barra di stato o di aggiungere e rimuovere icone di sistema."</string>
<string name="permlab_statusBarService" msgid="4826835508226139688">"ruolo di barra di stato"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Consente all\'applicazione di ricevere ed elaborare messaggi SMS. Significa che l\'applicazione potrebbe monitorare o eliminare i messaggi inviati al tuo dispositivo senza mostrarteli."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ricezione messaggi di testo (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Consente all\'applicazione di ricevere ed elaborare messaggi MMS. Significa che l\'applicazione potrebbe monitorare o eliminare i messaggi inviati al tuo dispositivo senza mostrarteli."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lettura di messaggi cell broadcast"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Consente all\'applicazione di leggere i messaggi cell broadcast ricevuti dal dispositivo. Gli avvisi cell broadcast vengono trasmessi in alcune località per avvertire di eventuali situazioni di emergenza. Le applicazioni dannose potrebbero interferire con il rendimento o con il funzionamento del dispositivo quando si riceve un messaggio cell broadcast di emergenza."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lettura feed sottoscritti"</string>
@@ -512,10 +516,10 @@
<string name="permdesc_requestPasswordComplexity" msgid="4730994229754212347">"Consente all\'app di conoscere il livello di complessità del blocco schermo (alto, medio, basso o nessuno), che indica l\'intervallo di caratteri possibile e il tipo di blocco schermo. L\'app può inoltre suggerire agli utenti di aggiornare il blocco schermo a un livello specifico di complessità, ma gli utenti possono ignorare liberamente il suggerimento e uscire. Tieni presente che il blocco schermo non viene memorizzato come testo non crittografato, quindi l\'app non conosce la password esatta."</string>
<string name="permlab_useBiometric" msgid="8837753668509919318">"utilizzo di hardware biometrico"</string>
<string name="permdesc_useBiometric" msgid="8389855232721612926">"Consente all\'app di utilizzare hardware biometrico per eseguire l\'autenticazione"</string>
- <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gestione di hardware per il riconoscimento delle impronte digitali"</string>
- <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Consente all\'app di richiamare metodi per aggiungere e rimuovere modelli di impronte digitali da utilizzare."</string>
- <string name="permlab_useFingerprint" msgid="3150478619915124905">"utilizzo di hardware per il riconoscimento delle impronte digitali"</string>
- <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Consente all\'app di utilizzare l\'hardware per il riconoscimento delle impronte digitali per eseguire l\'autenticazione"</string>
+ <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gestione di hardware per il riconoscimento delle impronte"</string>
+ <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Consente all\'app di richiamare metodi per aggiungere e rimuovere modelli di impronte da utilizzare."</string>
+ <string name="permlab_useFingerprint" msgid="3150478619915124905">"utilizzo di hardware per il riconoscimento delle impronte"</string>
+ <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Consente all\'app di utilizzare l\'hardware per il riconoscimento delle impronte per eseguire l\'autenticazione"</string>
<string name="permlab_audioWrite" msgid="2661772059799779292">"modifica della tua raccolta musicale"</string>
<string name="permdesc_audioWrite" msgid="8888544708166230494">"Consente all\'app di modificare la tua raccolta musicale."</string>
<string name="permlab_videoWrite" msgid="128769316366746446">"modifica della tua raccolta di video"</string>
@@ -530,30 +534,30 @@
<string name="biometric_not_recognized" msgid="5770511773560736082">"Non riconosciuto"</string>
<string name="biometric_error_canceled" msgid="349665227864885880">"Autenticazione annullata"</string>
<string name="biometric_error_device_not_secured" msgid="6583143098363528349">"Non hai impostato PIN, sequenza o password"</string>
- <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Rilevata impronta digitale parziale. Riprova."</string>
- <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Impossibile elaborare l\'impronta digitale. Riprova."</string>
- <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Il sensore di impronte digitali è sporco. Puliscilo e riprova."</string>
+ <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Rilevata impronta parziale. Riprova."</string>
+ <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Impossibile elaborare l\'impronta. Riprova."</string>
+ <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Il sensore di impronte è sporco. Puliscilo e riprova."</string>
<string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Movimento del dito troppo rapido. Riprova."</string>
<string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Movimento del dito troppo lento. Riprova."</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
- <string name="fingerprint_authenticated" msgid="5309333983002526448">"Impronta digitale autenticata"</string>
+ <string name="fingerprint_authenticated" msgid="5309333983002526448">"Impronta autenticata"</string>
<string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Volto autenticato"</string>
<string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Volto autenticato, premi Conferma"</string>
- <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware per l\'impronta digitale non disponibile."</string>
- <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Impossibile memorizzare l\'impronta digitale. Rimuovi un\'impronta esistente."</string>
- <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Timeout impronta digitale. Riprova."</string>
- <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operazione associata all\'impronta digitale annullata."</string>
- <string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"Operazione di autenticazione dell\'impronta digitale annullata dall\'utente."</string>
+ <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware per l\'impronta non disponibile."</string>
+ <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Impossibile memorizzare l\'impronta. Rimuovi un\'impronta esistente."</string>
+ <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Timeout impronta. Riprova."</string>
+ <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operazione associata all\'impronta annullata."</string>
+ <string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"Operazione di autenticazione dell\'impronta annullata dall\'utente."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Troppi tentativi. Riprova più tardi."</string>
- <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Troppi tentativi. Sensore di impronte digitali disattivato."</string>
+ <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Troppi tentativi. Sensore di impronte disattivato."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Riprova."</string>
<string name="fingerprint_error_no_fingerprints" msgid="7654382120628334248">"Nessuna impronta digitale registrata."</string>
- <string name="fingerprint_error_hw_not_present" msgid="409523969613176352">"Questo dispositivo non dispone di sensore di impronte digitali."</string>
+ <string name="fingerprint_error_hw_not_present" msgid="409523969613176352">"Questo dispositivo non dispone di sensore di impronte."</string>
<string name="fingerprint_name_template" msgid="5870957565512716938">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
- <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona dell\'impronta digitale"</string>
+ <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona dell\'impronta"</string>
<string name="permlab_manageFace" msgid="7262837876352591553">"gestione dell\'hardware per Sblocco col sorriso"</string>
<string name="permdesc_manageFace" msgid="8919637120670185330">"Consente all\'app di richiamare i metodi per aggiungere e rimuovere i modelli di volti."</string>
<string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"utilizzo dell\'hardware per Sblocco col sorriso"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Consente all\'app di leggere e modificare la configurazione della funzione Non disturbare."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"avvio dell\'uso dell\'autorizzazione di visualizzazione"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Consente al titolare di avviare l\'uso delle autorizzazioni per un\'app. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"target della scorciatoia Accessibilità"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Consente a un\'app di definire il target della scorciatoia Accessibilità"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Impostare regole per le password"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Controlla la lunghezza e i caratteri ammessi nelle password e nei PIN del blocco schermo."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorare tentativi di sblocco dello schermo"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modalità test harness attivata"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Ripristina le impostazioni di fabbrica per disattivare la modalità test harness."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Console seriale attivata"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Ci sono conseguenze sulle prestazioni. Per disattivare, seleziona il bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquidi o detriti nella porta USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"La porta USB viene disattivata automaticamente. Tocca per avere ulteriori informazioni."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Utilizzo porta USB consentito"</string>
@@ -1579,8 +1587,8 @@
<string name="expires_on" msgid="3676242949915959821">"Scade il:"</string>
<string name="serial_number" msgid="758814067660862493">"Numero di serie:"</string>
<string name="fingerprints" msgid="4516019619850763049">"Fingerprint:"</string>
- <string name="sha256_fingerprint" msgid="4391271286477279263">"Fingerprint SHA-256:"</string>
- <string name="sha1_fingerprint" msgid="7930330235269404581">"Fingerprint SHA-1:"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"Impronta SHA-256:"</string>
+ <string name="sha1_fingerprint" msgid="7930330235269404581">"Impronta SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Mostra tutto"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Scegli attività"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Condividi con"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Senza categoria"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Stabilisci tu l\'importanza di queste notifiche."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Importante a causa delle persone coinvolte."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g> (esiste già un utente con questo account)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Consentire a <xliff:g id="APP">%1$s</xliff:g> di creare un nuovo utente con l\'account <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Aggiungi una lingua"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Area geografica preferita"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Digita nome lingua"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 0a721a8..6e61213 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -350,6 +350,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"מאפשר לאפליקציה לקבל ולעבד הודעות SMS. משמעות הדבר היא שהאפליקציה יכולה לעקוב אחר הודעות שנשלחו למכשיר או למחוק אותן מבלי להציג לך אותן."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"קבלת הודעות טקסט (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"מאפשר לאפליקציה לקבל ולעבד הודעות MMS. משמעות הדבר היא שהאפליקציה יכולה לעקוב אחר הודעות שנשלחו למכשיר או למחוק אותן מבלי להציג לך אותן."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"קריאת הודעות שידור סלולרי"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"מאפשר לאפליקציה לקרוא הודעות שידור סלולרי שהתקבלו במכשיר שלך. התראות שידור סלולרי נשלחות במקומות מסוימים על מנת להזהיר אותך מפני מצבי חירום. אפליקציות זדוניות עשויות להפריע לביצועים או לפעולה של המכשיר שלך כאשר מתקבל שידור חירום סלולרי."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"קרא עדכוני מנויים"</string>
@@ -661,6 +665,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"מאפשר לאפליקציה לקרוא ולכתוב את התצורה של \'נא לא להפריע\'."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"התחלת צפייה בהרשאות השימוש"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"מאפשרת לבעלים להפעיל את השימוש בהרשאות עבור אפליקציה מסוימת. הרשאה זו אף פעם לא נדרשת עבור אפליקציות רגילות."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"קיצור דרך ליעד של פעולת נגישות"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"מאפשרת לאפליקציה להגדיר את קיצור הדרך ליעד של פעולת נגישות."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"קביעת האורך הנדרש והתווים המותרים בסיסמאות ובקודי הגישה של מסך הנעילה."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"מעקב אחר ניסיונות לביטול של נעילת המסך"</string>
@@ -1405,6 +1411,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"בחר להשבית ניפוי באגים ב-USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"מצב מסגרת בדיקה הופעל"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"כדי להשבית את מצב מסגרת בדיקה צריך לאפס להגדרות היצרן."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"קונסולה סדרתית מופעלת"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"קיימת השפעה על הביצועים. כדי להשבית, יש לבדוק את תוכנת האתחול."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"יש נוזלים או חלקיקים ביציאת ה-USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"יציאת ה-USB הושבתה באופן אוטומטי. יש להקיש לקבלת מידע נוסף."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ניתן להשתמש ביציאת ה-USB"</string>
@@ -1958,10 +1966,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"ללא שיוך לקטגוריה"</string>
<string name="importance_from_user" msgid="7318955817386549931">"עליך להגדיר את החשיבות של ההתראות האלה."</string>
<string name="importance_from_person" msgid="9160133597262938296">"ההודעה חשובה בשל האנשים המעורבים."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"האם לאפשר לאפליקציה <xliff:g id="APP">%1$s</xliff:g> ליצור משתמש חדש באמצעות <xliff:g id="ACCOUNT">%2$s</xliff:g> (כבר קיים משתמש לחשבון הזה) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"האם לאפשר לאפליקציה <xliff:g id="APP">%1$s</xliff:g> ליצור משתמש חדש באמצעות <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"הוספת שפה"</string>
<string name="country_selection_title" msgid="2954859441620215513">"העדפת אזור"</string>
<string name="search_language_hint" msgid="7042102592055108574">"הקלד שם שפה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index fe45c1f..15e10e4 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"SMSメッセージの受信と処理をアプリに許可します。これにより、アプリがデバイスに届いたメッセージを表示することなく監視または削除できるようになります。"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"テキストメッセージ(MMS)の受信"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMSメッセージの受信と処理をアプリに許可します。これにより、アプリがデバイスに届いたメッセージを表示することなく監視または削除できるようになります。"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"緊急速報メール SMS の読み取り"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"デバイスで受信した緊急速報メール SMS の読み取りをアプリに許可します。緊急速報メールは、緊急事態を警告する目的で一部の地域に配信されます。緊急速報メールの受信時に、悪意のあるアプリによってデバイスの動作や処理が妨害される恐れがあります。"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"登録したフィードの読み取り"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"サイレント モード設定の読み取りと書き込みをアプリに許可します。"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"表示権限の使用の開始"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"アプリの権限使用の開始を所有者に許可します。通常のアプリでは不要です。"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ユーザー補助ショートカットのターゲット"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ユーザー補助ショートカットのターゲットの定義付けをアプリに許可します。"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"画面ロックのパスワードとPINの長さと使用できる文字を制御します。"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"画面ロック解除試行の監視"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"テストハーネス モード有効"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"出荷時設定にリセットしてテストハーネス モードを無効にしてください。"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"シリアル コンソールは有効です"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"シリアル コンソールを有効にすると、パフォーマンスに影響します。無効にするには、ブートローダーをチェックしてください。"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ポート内の液体やゴミ"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ポートが自動的に無効になりました。タップして詳細をご確認ください。"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ポートを安全に使用できます"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"カテゴリなし"</string>
<string name="importance_from_user" msgid="7318955817386549931">"このような通知の重要度を設定します。"</string>
<string name="importance_from_person" msgid="9160133597262938296">"関係するユーザーのため、この設定は重要です。"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> が <xliff:g id="ACCOUNT">%2$s</xliff:g> で新しいユーザーを作成できるようにしますか?(このアカウントのユーザーはすでに存在します)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> が <xliff:g id="ACCOUNT">%2$s</xliff:g> で新しいユーザーを作成できるようにしますか?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"言語を追加"</string>
<string name="country_selection_title" msgid="2954859441620215513">"地域設定"</string>
<string name="search_language_hint" msgid="7042102592055108574">"言語名を入力"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 00afe026..a66d897 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"აპს შეეძლება SMS შეტყობინებების მიღება და დამუშავება. ეს ნიშნავს, რომ აპს შეეძლება თქვენ მოწყობილობაზე გამოგზავნილი შეტყობინებების მონიტორინგი და მათი წაშლა თქვენთვის ჩვენების გარეშე."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ტექსტური შეტყობინებების (MMS) მიღება"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"აპს შეეძლება MMS შეტყობინებების მიღება და დამუშავება. ეს ნიშნავს, რომ აპს შეეძლება შეტყობინებების მონიტორინგი და მათი წაშლა თქვენთვის ჩვენების გარეშე."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"მასიური დაგზავნის შეტყობინებების წაკითხვა"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"აპს შეეძლება, წაიკითხოს თქვენს მოწყობილობაზე გამოგზავნილი ქსელის სამაუწყებლო შეტყობინებები. სამაუწყებლო გაფრთხილებები მოგეწოდებათ ზოგიერთ ადგილზე ექსტრემალური სიტუაციების შესახებ გასაფრთხილებლად. ქსელის გადაუდებელი შეტყონიბენის მიღების დროს მავნე აპებმა შეიძლება ხელი შეუშალონ თქვენი მოწყობილობის ფუნქციონირებას ან ოპერაციებს."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"გამოწერილი არხების წაკითხვა"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"საშუალებას აძლევს აპს, წაიკითხოს და დაწეროს კონფიგურაცია „არ შემაწუხოთ“."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ნახვის ნებართვის გამოყენების დაწყება"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"მფლობელს საშუალებას აძლევს, დაიწყოს აპის ნებართვის გამოყენება. ჩვეულებრივი აპებისთვის არასოდეს უნდა იყოს საჭირო."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"მარტივი წვდომის მალსახმობის სამიზნე"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"აპს აძლევს მარტივი წვდომის მალსახმობის სამიზნის განსაზღვრის საშუალებას."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"აკონტროლეთ ეკრანის ბლოკირების პაროლებისა და PIN-ების სიმბოლოების სიგრძე."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"ეკრანის განბლოკვის მცდელობების მონიტორინგი"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"მონიშნეთ რათა შეწყვიტოთ USB-ის გამართვა"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"რეჟიმი „გარემო ტესტირებისთვის“ ჩართულია"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"დააბრუნეთ ქარხნული პარამეტრები „გარემო ტესტირებისთვის“ რეჟიმის გასათიშად."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"სერიული კონსოლი ჩართულია"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"მუშაობა შეფერხებულია. გასათიშად მონიშნეთ ჩამტვირთავი."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB პორტში აღმოჩენილია სითხე ან ჭუჭყი"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB პორტი ავტომატურად გათიშულია. შეეხეთ დამატებითი ინფორმაციისთვის."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"თანხმობა USB პორტის გამოყენებაზე"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"კატეგორიის გარეშე"</string>
<string name="importance_from_user" msgid="7318955817386549931">"ამ შეტყობინებების მნიშვნელობის დონე განისაზღვრა თქვენ მიერ."</string>
<string name="importance_from_person" msgid="9160133597262938296">"მნიშვნელოვანია ჩართული მომხმარებლების გამო."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"მიეცეს უფლება <xliff:g id="APP">%1$s</xliff:g>-ს <xliff:g id="ACCOUNT">%2$s</xliff:g>-ის მეშვეობით ახალი მომხმარებელი შექმნას (ამ ანგარიშის მქონე მომხმარებელი უკვე არსებობს)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"მიეცეს უფლება <xliff:g id="APP">%1$s</xliff:g>-ს <xliff:g id="ACCOUNT">%2$s</xliff:g>-ის მეშვეობით ახალი მომხმარებელი შექმნას?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ენის დამატება"</string>
<string name="country_selection_title" msgid="2954859441620215513">"რეგიონის პარამეტრები"</string>
<string name="search_language_hint" msgid="7042102592055108574">"აკრიფეთ ენის სახელი"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 81f512b..af6b788 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Қолданбаға SMS хабарларын алу және өңдеу мүмкіндігін береді. Бұл қолданба құрылғыңызға жіберілген хабарларды сізге көрсетпестен қабылдай және жоя алады дегенді білдіреді."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"мәтін хабарларын алу (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Қолданбаға MMS хабарларын алу және өңдеу мүмкіндігін береді. Бұл қолданба құрылғыңызға жіберілген хабарларды сізге көрсетпестен қабылдай және жоя алады дегенді білдіреді."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ұялы хабар тарату хабарларын оқу"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Қолданбаға ұялы таратылым хабарларын оқу мүмкіндігін береді. Ұялы таратылым дабылдары кейбір аймақтарда төтенше жағдай туралы ескерту үшін қолданылады. Төтенше ұялы хабарлар келгенде залалды қолданбалар құрылғының жұмысына кедергі жасауы мүмкін."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"жазылған ағындарды оқу"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Қолданбаға «Мазаламау» конфигурациясын оқу және жазу мүмкіндігін береді."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"рұқсаттарды пайдалану туралы деректерді көру"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Пайдаланушы қолданбаға берілетін рұқсаттарды басқара алады. Ондай рұқсаттар әдеттегі қолданбаларға керек емес."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"арнайы мүмкіндіктер таңбашасының мақсаты"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Қолданбаға арнайы мүмкіндіктер таңбашасының мақсатын анықтауға мүмкіндік береді."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Құпия сөз ережелерін тағайындау"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Экран бекітпесінің құпия сөздерінің және PIN кодтарының ұзындығын және оларда рұқсат етілген таңбаларды басқару."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Экран құлпын ашу әркеттерін бақылау"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB түзетуін өшіру үшін таңдаңыз."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Сынақ бағдарламасы режимі қосылды"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Сынақ бағдарламасы режимін өшіру үшін зауыттық күйіне қайтарыңыз."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Сериялық консоль қосылды"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Өнімділікке әсер етеді. Өшіру үшін жүктегішті тексеріңіз."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB портына сұйықтық немесе қоқыс кірді"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порты автоматты түрде өшірілді. Толығырақ ақпарат алу үшін түртіңіз."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портын пайдалана беруге болады"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Санатқа жатқызылмаған"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Сіз осы хабарландырулардың маңыздылығын орнатасыз."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Қатысты адамдарға байланысты бұл маңызды."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> қолданбасына <xliff:g id="ACCOUNT">%2$s</xliff:g> есептік жазбасы бар жаңа пайдаланушы (мұндай есептік жазбаға ие пайдаланушы бұрыннан бар) жасауға рұқсат етілсін бе?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> қолданбасына <xliff:g id="ACCOUNT">%2$s</xliff:g> есептік жазбасы бар жаңа пайдаланушы жасауға рұқсат етілсін бе?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Тілді қосу"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Аймақ параметрі"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Тіл атауын теріңіз"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 539747b..cf9b9d2 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"ឲ្យកម្មវិធីទទួល និងដំណើរការសារ MMS ។ មានន័យថា កម្មវិធីអាចត្រួតពិនិត្យ ឬលុបសារដែលបានផ្ញើទៅឧបករណ៍របស់អ្នក ដោយមិនបង្ហាញអ្នក។"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ទទួលសារអត្ថបទ (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"ឲ្យកម្មវិធីទទួល និងដំណើរការសារ MMS ។ វាមានន័យថា កម្មវិធីអាចតាមដាន ឬលុបសារដែលបានផ្ញើទៅឧបករណ៍របស់អ្នកដោយមិនបង្ហាញពួកវា។"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"អានសារប្រកាសចល័ត"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ឲ្យកម្មវិធីអានសារប្រកាសការហៅដែលឧបករណ៍របស់អ្នកបានទទួល។ ការជូនដំណឹងប្រកាសចល័តត្រូវបានបញ្ជូនទៅទីតាំងមួយចំនួន ដើម្បីព្រមានអ្នកអំពីស្ថានភាពអាសន្ន។ កម្មវិធីព្យាបាទអាចជ្រៀតជ្រែកការអនុវត្ត ឬប្រតិបត្តិការឧបករណ៍របស់អ្នកពេលទទួលការប្រកាសចល័តពេលអាសន្ន។"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"អានអត្ថបទព័ត៌មានបានជាវ"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"អនុញ្ញាតឲ្យកម្មវិធីអាន និងសរសេរការកំណត់រចនាសម្ព័ន្ធមុខងារ កុំរំខាន។"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ចាប់ផ្ដើមមើលការប្រើប្រាស់ការអនុញ្ញាត"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"អនុញ្ញាតឱ្យម្ចាស់ចាប់ផ្ដើមការប្រើប្រាស់ការអនុញ្ញាតសម្រាប់កម្មវិធី។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"គោលដៅផ្លូវកាត់ភាពងាយស្រួល"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"អនុញ្ញាតឱ្យកម្មវិធីកំណត់គោលដៅផ្លូវកាត់ភាពងាយស្រួល។"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"កំណត់ក្បួនពាក្យសម្ងាត់"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"គ្រប់គ្រងប្រវែង និងតួអក្សរដែលអនុញ្ញាតឲ្យប្រើក្នុងពាក្យសម្ងាត់ និងលេខសម្ងាត់ចាក់សោអេក្រង់។"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"តាមដានការព្យាយាមដោះសោអេក្រង់"</string>
@@ -1363,6 +1369,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ជ្រើសរើស ដើម្បីបិទការកែកំហុសតាម USB ។"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"បានបើកមុខងារប្រមូលធ្វើតេស្ត"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ធ្វើការកំណត់ដូចដើមឡើងវិញ ដើម្បីបិទមុខងារប្រមូលធ្វើតេស្ត។"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"កុងសូលស៊េរីត្រូវបានបើក"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"ប្រតិបត្តិការទទួលរងការប៉ះពាល់។ សូមពិនិត្យមើលកម្មវិធីដំណើរការប្រព័ន្ធ ដើម្បីបិទ។"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"មានទឹក ឬកម្ទេចផ្សេងៗនៅក្នុងរន្ធ USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"រន្ធ USB ត្រូវបានបិទដោយស្វ័យប្រវត្តិ។ សូមចុចដើម្បីស្វែងយល់បន្ថែម។"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"អាចប្រើរន្ធ USB បាន"</string>
@@ -1581,8 +1589,8 @@
<string name="expires_on" msgid="3676242949915959821">"ផុតកំណត់នៅ៖"</string>
<string name="serial_number" msgid="758814067660862493">"លេខស៊េរី៖"</string>
<string name="fingerprints" msgid="4516019619850763049">"ស្នាមម្រាមដៃ៖"</string>
- <string name="sha256_fingerprint" msgid="4391271286477279263">"ស្នាមម្រាមដៃ SHA-256 ៖"</string>
- <string name="sha1_fingerprint" msgid="7930330235269404581">"ស្នាមម្រាមដៃ SHA-1 ៖"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"ស្នាមម្រាមដៃ SHA-256៖"</string>
+ <string name="sha1_fingerprint" msgid="7930330235269404581">"ស្នាមម្រាមដៃ SHA-1៖"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"មើលទាំងអស់"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"ជ្រើសសកម្មភាព"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"ចែករំលែកជាមួយ"</string>
@@ -1892,10 +1900,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"មិនបែងចែកប្រភេទ"</string>
<string name="importance_from_user" msgid="7318955817386549931">"អ្នកបានកំណត់សារៈសំខាន់នៃការជូនដំណឹងទាំងនេះ"</string>
<string name="importance_from_person" msgid="9160133597262938296">"វាមានសារៈសំខាន់ដោយសារតែមនុស្សដែលពាក់ព័ន្ធ"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"អនុញ្ញាតឱ្យ <xliff:g id="APP">%1$s</xliff:g> បង្កើតអ្នកប្រើប្រាស់ថ្មីដោយប្រើ <xliff:g id="ACCOUNT">%2$s</xliff:g> (អ្នកប្រើប្រាស់ដែលមានគណនីនេះមានរួចហើយ) ដែរឬទេ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"អនុញ្ញាតឱ្យ <xliff:g id="APP">%1$s</xliff:g> បង្កើតអ្នកប្រើប្រាស់ថ្មីដោយប្រើ <xliff:g id="ACCOUNT">%2$s</xliff:g> ដែរឬទេ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"បន្ថែមភាសា"</string>
<string name="country_selection_title" msgid="2954859441620215513">"ចំណូលចិត្តតំបន់"</string>
<string name="search_language_hint" msgid="7042102592055108574">"វាយបញ្ចូលឈ្មោះភាសា"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index c7d0fea..028d563 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS ಸಂದೇಶಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಮತ್ತು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಇದರರ್ಥ, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಕಳುಹಿಸಲಾಗಿರುವ ಸಂದೇಶಗಳನ್ನು ನಿಮಗೆ ತೋರಿಸದೆಯೇ, ಅಪ್ಲಿಕೇಶನ್ ಅವುಗಳನ್ನು ಮಾನಿಟರ್ ಮಾಡಬಹುದು ಅಥವಾ ಅಳಿಸಬಹುದು."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ಪಠ್ಯ ಸಂದೇಶಗಳನ್ನು ಸ್ವೀಕರಿಸಿ (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS ಸಂದೇಶಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಮತ್ತು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಇದರರ್ಥ, ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಕಳುಹಿಸಲಾಗಿರುವ ಸಂದೇಶಗಳನ್ನು ನಿಮಗೆ ತೋರಿಸದೆಯೇ, ಅಪ್ಲಿಕೇಶನ್ ಅವುಗಳನ್ನು ಮಾನಿಟರ್ ಮಾಡಬಹುದು ಅಥವಾ ಅಳಿಸಬಹುದು."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ಸೆಲ್ ಪ್ರಸಾರದ ಸಂದೇಶಗಳನ್ನು ಓದಿರಿ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ನಿಮ್ಮ ಸಾಧನದಿಂದ ಸ್ವೀಕರಿಸಿದ ಸೆಲ್ ಪ್ರಸಾರ ಸಂದೇಶಗಳನ್ನು ರೀಡ್ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸೆಲ್ ಪ್ರಸಾರ ಎಚ್ಚರಿಕೆಗಳನ್ನು ತುರ್ತು ಸಂದರ್ಭಗಳಲ್ಲಿ ನಿಮಗೆ ಎಚ್ಚರಿಸುವ ಸಲುವಾಗಿ ಕೆಲವು ಸ್ಥಳಗಳಲ್ಲಿ ವಿತರಿಸಲಾಗುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ತುರ್ತು ಸೆಲ್ ಪ್ರಸಾರವನ್ನು ಸ್ವೀಕರಿಸುವಾಗ, ನಿಮ್ಮ ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆ ಇಲ್ಲವೇ ಕಾರ್ಯಾಚರಣೆಯಲ್ಲಿ ಹಸ್ತಕ್ಷೇಪ ಮಾಡಬಹುದು."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ಚಂದಾದಾರ ಫೀಡ್ಗಳನ್ನು ಓದಿ"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಓದಲು ಮತ್ತು ಬರೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ವೀಕ್ಷಣಾ ಅನುಮತಿಯ ಬಳಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಿ"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ಆ್ಯಪ್ಗಾಗಿ ಅನುಮತಿ ಬಳಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸಾಮಾನ್ಯ ಆ್ಯಪ್ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್ಕಟ್ ಟಾರ್ಗೆಟ್"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್ಕಟ್ ಟಾರ್ಗೆಟ್ ಅನ್ನು ವಿವರಿಸಲು ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"ಪಾಸ್ವರ್ಡ್ ನಿಮಯಗಳನ್ನು ಹೊಂದಿಸಿ"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"ಪರದೆ ಲಾಕ್ನಲ್ಲಿನ ಪಾಸ್ವರ್ಡ್ಗಳು ಮತ್ತು ಪಿನ್ಗಳ ಅನುಮತಿಸಲಾದ ಅಕ್ಷರಗಳ ಪ್ರಮಾಣವನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"ಪರದೆಯ ಅನ್ಲಾಕ್ ಪ್ರಯತ್ನಗಳನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ಸ್ವಯಂ ಪರೀಕ್ಷೆಯಾಗುವಿಕೆ ಮೋಡ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ಸ್ವಯಂ ಪರೀಕ್ಷೆಯಾಗುವಿಕೆ ಮೋಡ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಫ್ಯಾಕ್ಟರಿ ರಿಸೆಟ್ ಮಾಡಬೇಕು."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"ಸರಣಿ ಕನ್ಸೋಲ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"ಕಾರ್ಯಕ್ಷಮತೆಯ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ. ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು, ಬೂಟ್ಲೋಡರ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ಪೋರ್ಟ್ನಲ್ಲಿ ದ್ರವ ಅಥವಾ ಧೂಳಿನ ಕಣಗಳಿವೆ"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ಪೋರ್ಟ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ಪೋರ್ಟ್ ಬಳಸಲು ಸರಿ ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"ವರ್ಗೀಕರಿಸದಿರುವುದು"</string>
<string name="importance_from_user" msgid="7318955817386549931">"ನೀವು ಈ ಅಧಿಸೂಚನೆಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಿರುವಿರಿ."</string>
<string name="importance_from_person" msgid="9160133597262938296">"ಜನರು ತೊಡಗಿಕೊಂಡಿರುವ ಕಾರಣ ಇದು ಅತ್ಯಂತ ಪ್ರಮುಖವಾಗಿದೆ."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (ಈ ಖಾತೆಯ ಬಳಕೆದಾರರು ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದ್ದಾರೆ) ಮೂಲಕ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು <xliff:g id="APP">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸಬೇಕೆ ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ಮೂಲಕ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು <xliff:g id="APP">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸುವುದೇ ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ಭಾಷೆ ಸೇರಿಸಿ"</string>
<string name="country_selection_title" msgid="2954859441620215513">"ಪ್ರದೇಶ ಪ್ರಾಶಸ್ತ್ಯ"</string>
<string name="search_language_hint" msgid="7042102592055108574">"ಭಾಷೆ ಹೆಸರನ್ನು ಟೈಪ್ ಮಾಡಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index c0dd8b1..f81cc00 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"앱이 SMS 메시지를 수신하고 처리할 수 있도록 허용합니다. 앱이 사용자에게 표시하지 않고 기기로 전송된 메시지를 확인 또는 삭제할 수도 있습니다."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"문자 메시지 받기(MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"앱이 MMS 메시지를 수신하고 처리할 수 있도록 허용합니다. 앱이 사용자에게 표시하지 않고 기기로 전송된 메시지를 확인 또는 삭제할 수도 있습니다."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"셀 브로드캐스트 메시지 읽기"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"앱이 기기가 수신한 셀 브로드캐스트 메시지를 읽을 수 있도록 합니다. 비상 상황임을 알리기 위해 일부 지역에서 셀 브로드캐스트 경고가 전달됩니다. 비상 셀 브로드캐스트를 수신할 때 악성 앱이 기기의 성능이나 작동을 방해할 수 있습니다."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"가입된 피드 읽기"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"앱에서 방해 금지 모드 설정을 읽고 작성하도록 허용합니다."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"권한 사용 보기 시작"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"앱의 권한 사용을 시작하려면 보유자를 허용하세요. 일반 앱에는 필요하지 않습니다."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"접근성 단축키 대상"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"앱이 접근성 단축키 대상을 정의할 수 있도록 허용합니다."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"화면 잠금 비밀번호와 PIN에 허용되는 길이와 문자 수를 제어합니다."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"화면 잠금 해제 시도 모니터링"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"테스트 하네스 모드 사용 설정됨"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"테스트 하네스 모드를 사용 중지하려면 초기화하세요."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"시리얼 콘솔 사용 설정됨"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"성능에 영향을 미쳤습니다. 사용 중지하려면 부트로더를 확인하세요."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 포트에서 액체 또는 이물질 감지됨"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 포트가 자동으로 사용 중지되었습니다. 자세한 내용을 보려면 탭하세요."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB 포트를 사용해도 좋음"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"지정된 카테고리 없음"</string>
<string name="importance_from_user" msgid="7318955817386549931">"이러한 알림의 중요도를 설정했습니다."</string>
<string name="importance_from_person" msgid="9160133597262938296">"관련된 사용자가 있으므로 중요합니다."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>에서 <xliff:g id="ACCOUNT">%2$s</xliff:g> 계정으로 신규 사용자를 만들도록 허용하시겠습니까? 이 계정으로 등록된 사용자가 이미 존재합니다."</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>에서 <xliff:g id="ACCOUNT">%2$s</xliff:g> 계정으로 신규 사용자를 만들도록 허용하시겠습니까?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"언어 추가"</string>
<string name="country_selection_title" msgid="2954859441620215513">"지역 환경설정"</string>
<string name="search_language_hint" msgid="7042102592055108574">"언어 이름 입력"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 9182563..c61992c 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -283,7 +283,7 @@
<string name="permgrouprequest_contacts" msgid="6032805601881764300">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосуна байланыштарыңызды пайдаланууга уруксат берилсинби?"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Жайгашкан жер"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"түзмөктүн жайгашкан жерин аныктоого"</string>
- <string name="permgrouprequest_location" msgid="3788275734953323491">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосу бул түзмөктүн кайда жүргөнүн көрүп турганга уруксат бересизби?"</string>
+ <string name="permgrouprequest_location" msgid="3788275734953323491">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосу бул түзмөктүн кайда жүргөнүн көрүп турсунбу?"</string>
<string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Колдонмону колдонуп жаткан маалда гана, ал сиздин кайда жүргөнүңүздү билип турат."</string>
<string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосу бул түзмөктүн жүргөн жерин <b>ар дайым</b> билип турсунбу?"</string>
<string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Колдонмону пайдаланып жаткан учурда гана ал жайгашкан жерди көрө алат"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Колдонмого SMS билдирүүлөрүн кабыл алууга жана аларды иштетип чыгууга уруксат берет. Бул, колдонмо сизге билгизбестен түзмөгүңүзгө жөнөтүлгөн билдирүүлөрдү мониторлой же жок кыла алат дегенди билдирет."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"билдирүүлөрдү (MMS) кабыл алуу"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Колдонмого MMS билдирүүлөрүн кабыл алууга жана аларды иштетип чыгууга уруксат берет. Бул, колдонмо сизге билгизбестен түзмөгүңүзгө жөнөтүлгөн билдирүүлөрдү мониторлой же жок кыла алат дегенди билдирет."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"уюктук берүү билдирүүлөрүн окуу"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Колдонмого түзмөгүңүз кабыл алган уюк берүүнүн билдирүүлөрүн окууга жол берет. Шашылыш эскертүү билдирүүлөрү кээ бир жерлердеги өзгөчө кырдаалдар тууралу сизди эскертүү үчүн жөнөтүлөт. Зыяндуу колдономолор шашылыш эскертүүлөр берилип жатканда, сиздин түзмөктүн иштешине жолтоо болушу мүмкүн."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"жазылган түрмөктөрдү окуу"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Колдонмого \"Тынчымды алба\" режиминин конфигурациясын окуу жана жазуу мүмкүнчүлүгүн берет."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"уруксаттын колдонулушун көрүп баштоо"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Колдонмонун пайдаланылышына уруксат берүүгө мүмкүнчүлүк берет. Кадимки колдонмолорго эч качан талап кылынбашы керек."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"максаттуу атайын мүмкүнчүлүк аракетине кыска жол"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Колдонмого максаттуу атайын мүмкүнчүлүк аракетине кыска жолду аныктоого уруксат берет."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Сырсөз эрежелерин коюу"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Экран кулпусунун сырсөздөрү менен PIN\'дерине уруксат берилген узундук менен белгилерди көзөмөлдөө."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Экран кулпусун ачуу аракеттерин көзөмөлдөө"</string>
@@ -1075,7 +1081,7 @@
<string name="Midnight" msgid="5630806906897892201">"Түн ортосу"</string>
<string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
- <string name="selectAll" msgid="6876518925844129331">"Бардыгын тандоо"</string>
+ <string name="selectAll" msgid="6876518925844129331">"Баарын тандоо"</string>
<string name="cut" msgid="3092569408438626261">"Кесүү"</string>
<string name="copy" msgid="2681946229533511987">"Көчүрүү"</string>
<string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"Алмашуу буферине көчүрүлбөй калды"</string>
@@ -1315,7 +1321,7 @@
<string name="sms_control_title" msgid="7296612781128917719">"SMS билдирүүлөр жөнөтүлүүдө"</string>
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> көп SMS билдирүүлөрдү жөнөтүп жатат. Бул колдонмо билдирүүлөрдү жөнөтө берсинби?"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"Ооба"</string>
- <string name="sms_control_no" msgid="625438561395534982">"Жок"</string>
+ <string name="sms_control_no" msgid="625438561395534982">"Тыюу салынат"</string>
<string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> номуруна билдирүү жөнөткөнү жатат."</string>
<string name="sms_short_code_details" msgid="5873295990846059400">"Бул уюлдук эсебиңиздеги төлөмдөргө "<b>"алып келиши мүмкүн"</b>"."</string>
<string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Бул уюлдук эсебиңиздеги төлөмдөргө алып келет."</b></string>
@@ -1357,12 +1363,14 @@
<string name="usb_power_notification_message" msgid="4647527153291917218">"Туташкан түзмөк кубатталууда. Дагы параметрлерди көрүү үчүн таптап коюңуз."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Аналогдук аудио жабдуу табылды"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Тиркелген түзмөк бул телефонго шайкеш келбейт. Көбүрөөк маалымат алуу үчүн таптап коюңуз."</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"Мүчүлүштүктөрдү USB аркылуу оңдоо иштетилген"</string>
- <string name="adb_active_notification_message" msgid="7463062450474107752">"USB арклуу мүчүлштктрдү оңдоону өчрүү үчүн басып коюңуз"</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"Мүчүлүштүктөрдү USB аркылуу оңдоо иштеп жатат"</string>
+ <string name="adb_active_notification_message" msgid="7463062450474107752">"Өчүрүү үчүн тийип коюңуз"</string>
<!-- no translation found for adb_active_notification_message (8470296818270110396) -->
<skip />
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Сыноо программасынын режими иштетилди"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Сыноо программасынын режимин өчүрүү үчүн, баштапкы жөндөөлөргө кайтарыңыз."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Сериялык консоль иштетилди"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Майнаптуулугуна таасири тиет. Аны өчүрүү үчүн операциялык тутумду жүктөгүчтү текшериңиз."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB портунда суюктук же урандылар бар"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порт автоматтык түрдө өчүрүлдү. Кененирээк маалымат алуу үчүн таптап коюңуз."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портун колдонууга болот"</string>
@@ -1451,7 +1459,7 @@
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Бул өтүнүчкө уруксат бересизби?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"Жетки талабы"</string>
<string name="allow" msgid="7225948811296386551">"Уруксат берүү"</string>
- <string name="deny" msgid="2081879885755434506">"Жок"</string>
+ <string name="deny" msgid="2081879885755434506">"Уруксат берилбейт"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"Уруксат талап кылуу"</string>
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Кийинки эсепке\nуруксат талап кылынууда: <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
<string name="forward_intent_to_owner" msgid="1207197447013960896">"Бул колдонмо жумуш профилиңиздин сыртында колдонулуп жатат"</string>
@@ -1892,10 +1900,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Категорияларга бөлүнгөн эмес"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Бул эскертмелердин маанилүүлүгүн белгиледиңиз."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Булар сиз үчүн маанилүү адамдар."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> колдонмосуна <xliff:g id="ACCOUNT">%2$s</xliff:g> аккаунту менен жаңы колдонуучу түзүүгө уруксат бересизби (мындай аккаунту бар колдонуучу мурунтан эле бар)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> колдонмосуна <xliff:g id="ACCOUNT">%2$s</xliff:g> аккаунту менен жаңы колдонуучу түзүүгө уруксат бересизби?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Тил кошуу"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Чөлкөмдүк жөндөөлөр"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Тилди киргизиңиз"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 0189c08..fb3afb3 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"ອະນຸຍາດໃຫ້ແອັບຯຮັບ ແລະປະມວນຜົນຂໍ້ຄວາມ SMS. ນີ້ໝາຍຄວາມວ່າແອັບຯສາມາດຕິດຕາມ ຫຼືລຶບຂໍ້ຄວາມທີ່ສົ່ງເຂົ້າອຸປະກອນຂອງທ່ານ ໂດຍທີ່ບໍ່ສະແດງພວກມັນໃຫ້ທ່ານເຫັນ."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ຮັບຂໍ້ຄວາມ (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"ອະນຸຍາດໃຫ້ແອັບຯ ຮັບແລະປະມວນຜົນຂໍ້ຄວາມ MMS. ນີ້ໝາຍຄວາມວ່າແອັບຯສາມາດຕິດຕາມ ຫຼືລຶບຂໍ້ຄວາມທີ່ສົ່ງເຂົ້າອຸປະກອນຂອງທ່ານ ໂດຍທີ່ບໍ່ສະແດງພວກມັນໃຫ້ທ່ານເຫັນ."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ອ່ານຂໍ້ຄວາມກະຈາຍສັນຍານຂອງເສົາສັນຍານ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ອະນຸຍາດໃຫ້ແອັບຯ ສາມາດອ່ານຂໍ້ຄວາມແຈ້ງເຕືອນເຫດສຸກເສີນ ທີ່ໄດ້ຮັບໂດຍອຸປະກອນຂອງທ່ານ. ການແຈ້ງເຕືອນສຸກເສີນທີ່ມີໃຫ້ບໍລິການໃນບາງພື້ນທີ່ ເພື່ອແຈ້ງເຕືອນໃຫ້ທ່ານຮູ້ເຖິງສະຖານະການສຸກເສີນ. ແອັບພລິເຄຊັນທີ່ເປັນອັນຕະລາຍອາດລົບກວນປະສິດທິພາບ ຫຼືການດຳເນີນງານຂອງອຸປະກອນຂອງທ່ານ ເມື່ອໄດ້ການຮັບແຈ້ງເຕືອນສຸກເສີນຈາກສະຖານີມືຖື."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ອ່ານຂໍ້ມູນຟີດທີ່ສະໝັກໄວ້"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ອະນຸຍາດໃຫ້ແອັບອ່ານ ແລະຂຽນການກນຳດຄ່າ ບໍ່ລົບກວນ."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ເລີ່ມການໃຊ້ສິດອະນຸຍາດການເບິ່ງ"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ອະນຸຍາດໃຫ້ຜູ້ຖືເລີ່ມການໃຊ້ສິດອະນຸຍາດສຳລັບແອັບໃດໜຶ່ງໄດ້. ແອັບປົກກະຕິບໍ່ຄວນຕ້ອງໃຊ້."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ເປົ້າໝາຍທາງລັດການຊ່ວຍເຂົ້າເຖິງ"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ອະນຸຍາດໃຫ້ແອັບລະບຸເປົ້າໝາຍທາງລັດການຊ່ວຍເຂົ້າເຖິງ."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"ຄວບຄຸມຄວາມຍາວ ແລະຕົວອັກສອນທີ່ອະນຸຍາດໃຫ້ຢູ່ໃນລະຫັດລັອກໜ້າຈໍ ແລະ PIN."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"ເລືອກເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ເປີດໃຊ້ໂໝດ Test Harness ແລ້ວ"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ດຳເນີນການຣີເຊັດເປັນຄ່າຈາກໂຮງງານເພື່ອປິດການນຳໃຊ້ໂໝດ Test Harness."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"ເປີດນຳໃຊ້ຊີຣຽວຄອນໂຊແລ້ວ"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"ມີຜົນກະທົບກັບປະສິດທິພາບ. ເພື່ອປິດການນຳໃຊ້, ໃຫ້ກວດສອບ bootloader ເບິ່ງ."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ມີຂອງແຫລວ ຫຼື ເສດດິນໃນຜອດ USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"ປິດຜອດ USB ໂດຍອັດຕະໂນມັດແລ້ວ. ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ສາມາດໃຊ້ຜອດ USB ໄດ້"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"ບໍ່ມີໝວດໝູ່"</string>
<string name="importance_from_user" msgid="7318955817386549931">"ທ່ານຕັ້ງຄວາມສຳຄັນຂອງການແຈ້ງເຕືອນເຫຼົ່ານີ້."</string>
<string name="importance_from_person" msgid="9160133597262938296">"ຂໍ້ຄວາມນີ້ສຳຄັນເນື່ອງຈາກບຸກຄົນທີ່ກ່ຽວຂ້ອງ."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"ອະນຸຍາດໃຫ້ <xliff:g id="APP">%1$s</xliff:g> ສ້າງຜູ້ໃຊ້ໃໝ່ກັບ <xliff:g id="ACCOUNT">%2$s</xliff:g> ໄດ້ບໍ່ (ມີຜູ້ໃຊ້ທີ່ໃຊ້ບັນຊີນີ້ຢູ່ກ່ອນແລ້ວ) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"ອະນຸຍາດໃຫ້ <xliff:g id="APP">%1$s</xliff:g> ສ້າງຜູ້ໃຊ້ໃໝ່ກັບ <xliff:g id="ACCOUNT">%2$s</xliff:g> ໄດ້ບໍ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ເພີ່ມພາສາ"</string>
<string name="country_selection_title" msgid="2954859441620215513">"ການຕັ້ງຄ່າພາກພື້ນ"</string>
<string name="search_language_hint" msgid="7042102592055108574">"ພິມຊື່ພາສາ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 0d29c84..be9e32f 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -350,6 +350,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Leidžiama programai gauti ir apdoroti SMS pranešimus. Tai reiškia, kad programa gali stebėti ir ištrinti į jūsų įrenginį siunčiamus pranešimus jums jų neparodžiusi."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"gauti teksto pranešimus (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Leidžiama programai gauti ir apdoroti MMS pranešimus. Tai reiškia, kad programa gali stebėti ir ištrinti į jūsų įrenginį siunčiamus pranešimus jums jų neparodžiusi."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"skaityti mobiliuoju transliuojamus pranešimus"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Programai leidžiama skaityti mobiliuoju transliuojamus pranešimus, gaunamus jūsų įrenginyje. Mobiliuoju transliuojami įspėjimai pristatomi kai kuriose vietose, kad įspėtų apie kritines situacijas. Kai gaunamas mobiliuoju transliuojamas pranešimas apie kritinę situaciją, kenkėjiškos programos gali trukdyti įrenginiui veikti ar jį naudoti."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"skaityti prenumeruojamus tiekimus"</string>
@@ -661,6 +665,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Leidžiama programai skaityti ir rašyti „Do Not Disturb“ konfigūraciją."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"pradėti peržiūrėti leidimo naudojimą"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Leidžia savininkui pradėti naudoti programos leidimą. Įprastoms programoms to neturėtų prireikti."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"pritaikomumo sparčiojo klavišo tikslas"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Programai leidžiama apibrėžti pritaikomumo sparčiojo klavišo tikslą."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nustatyti slaptažodžio taisykles"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Valdykite, kokio ilgio ekrano užrakto slaptažodžius ir PIN kodus galima naudoti."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Stebėti bandymus atrakinti ekraną"</string>
@@ -1405,6 +1411,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Testavimo sistemos režimas įgalintas"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Atkurkite gamyklinius duomenis, kad išjungtumėte testavimo sistemos režimą."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serijos pultas įgalintas"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Našumas paveiktas. Norėdami išjungti, patikrinkite paleidyklę."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB prievade yra skysčių ar smulkių dalelių"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB prievadas automatiškai išjungtas. Palieskite, kad sužinotumėte daugiau."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Saugu naudoti USB prievadą"</string>
@@ -1958,10 +1966,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Be kategorijos"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Galite nustatyti šių pranešimų svarbą."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Tai svarbu dėl susijusių žmonių."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Leisti „<xliff:g id="APP">%1$s</xliff:g>“ kurti naują <xliff:g id="ACCOUNT">%2$s</xliff:g> naudotoją (šią paskyrą naudojantis naudotojas jau yra)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Leisti „<xliff:g id="APP">%1$s</xliff:g>“ kurti naują <xliff:g id="ACCOUNT">%2$s</xliff:g> naudotoją?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Pridėkite kalbą"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Regiono nuostata"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Įveskite kalbos pav."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 2547ba9..89575c6 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -347,6 +347,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Ļauj lietotnei saņemt un apstrādāt īsziņas. Tas nozīmē, ka lietotne var pārraudzīt vai dzēst uz jūsu ierīci nosūtītos ziņojumus, neparādot tos jums."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"saņemt ziņojumus (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Ļauj lietotnei saņemt un apstrādāt multiziņas. Tas nozīmē, ka lietotne var pārraudzīt vai dzēst uz jūsu ierīci nosūtītos ziņojumus, neparādot tos jums."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"šūnu apraides ziņojumu lasīšana"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ļauj lietotnei lasīt ierīcē saņemtos šūnu apraides ziņojumus. Šūnu apraides brīdinājumi tiek piegādāti dažās atrašanās vietās, lai brīdinātu jūs par ārkārtas situācijām. Ļaunprātīgas lietotnes var traucēt ierīces veiktspēju vai darbības, kad ir saņemts ārkārtas šūnas apraides ziņojums."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lasīt abonētās plūsmas"</string>
@@ -658,6 +662,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Ļauj lietotnei lasīt un rakstīt režīma “Netraucēt” konfigurāciju."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"Datu skatīšana par izmantojamajām atļaujām"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Ļauj atļaujas īpašniekam sākt lietotnes atļauju izmantošanu. Parastām lietotnēm tas nekad nav nepieciešams."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"pieejamības īsinājumtaustiņa mērķis"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Ļauj lietotnei definēt pieejamības īsinājumtaustiņa mērķi."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Paroles kārtulu iestatīšana"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolēt ekrāna bloķēšanas paroļu un PIN garumu un tajos atļautās rakstzīmes."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Ekrāna atbloķēšanas mēģinājumu pārraudzīšana"</string>
@@ -1383,6 +1389,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Drošības pārbaudes režīms ir iespējots"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Lai atspējotu drošības pārbaudes režīmu, veiciet rūpnīcas datu atiestatīšanu."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Seriālā konsole ir iespējota"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Tiek ietekmēta veiktspēja. Lai atspējotu, pārbaudiet operētājsistēmu ielādes rīku."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB pieslēgvietā ir šķidrums vai daļiņas"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB pieslēgvieta ir automātiski atspējota. Pieskarieties, lai uzzinātu vairāk."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB pieslēgvietu drīkst izmantot"</string>
@@ -1924,10 +1932,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Nav kategorijas"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Jūs iestatījāt šo paziņojumu svarīguma līmeni."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Tas ir svarīgi iesaistīto personu dēļ."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Vai atļaut lietotnei <xliff:g id="APP">%1$s</xliff:g> izveidot jaunu lietotāju, izmantojot e-pasta adresi <xliff:g id="ACCOUNT">%2$s</xliff:g> (lietotājs ar šādu kontu jau pastāv)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Vai atļaut lietotnei <xliff:g id="APP">%1$s</xliff:g> izveidot jaunu lietotāju, izmantojot e-pasta adresi <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Pievienot valodu"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Reģiona preference"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Ierakstiet valodas nosaukumu"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 9949eaa..7144e4d 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -283,7 +283,7 @@
<string name="permgrouprequest_contacts" msgid="6032805601881764300">"Дали да се дозволи <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да пристапува до контактите?"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"пристапува до локацијата на овој уред"</string>
- <string name="permgrouprequest_location" msgid="3788275734953323491">"Дали да се дозволи <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да пристапува до локацијата на уредот?"</string>
+ <string name="permgrouprequest_location" msgid="3788275734953323491">"Дали да се дозволи <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да пристапува до локацијата на уредов?"</string>
<string name="permgrouprequestdetail_location" msgid="1347189607421252902">"Апликацијата ќе има пристап до локацијата само додека ја користите"</string>
<string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"Да се дозволи <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да пристапува до локацијата на уредов <b>во секое време</b>?"</string>
<string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Апликацијата во моментов може да пристапува до локацијата само додека ја користите"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Овозможува апликацијата да прима и да обработува SMS пораки. Тоа значи дека апликацијата може да следи или да брише пораки испратени до вашиот уред без да ви ги прикаже вам."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"прими текстуални пораки (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Овозможува апликацијата да прима и да обработува MMS пораки. Тоа значи дека апликацијата може да следи или да брише пораки испратени до вашиот уред без да ви ги прикаже вам."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"прочитај пораки за мобилно емитување"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Овозможува апликациите да ги читаат пораките за мобилно емитување што ги прима вашиот уред. Предупредувањата за мобилно емитување се доставуваат на некои локации, за да ве предупредат на итни ситуации. Злонамерните апликации може да пречат во ефикасноста или работењето на вашиот уред кога се прима емитување за итен случај."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"читај претплатени навестувања на содржина"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Дозволува апликацијата да чита и пишува конфигурација Не вознемирувај."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"започнете со користење на дозволата за приказ"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Дозволува сопственикот да почне со користење на дозволата за апликација. Не треба да се користи за стандардни апликации."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"цел на кратенката за пристапност"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Дозволува апликација да одреди цел на кратенката за пристапност."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Постави правила за лозинката"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Контролирај ги должината и знаците што се дозволени за лозинки и PIN-броеви за отклучување екран."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Следи ги обидите за отклучување на екранот"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете за да се оневозможи отстранување грешки на USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Овозможен е режимот на рамка за тестирање"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Извршете фабричко ресетирање за да го оневозможите режимот на рамка за тестирање."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Сериската конзола е овозможена"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Перформансите се засегнати. За да оневозможите, проверете го подигнувачот."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или нечистотија во USB-портата"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-портата е автоматски оневозможена. Допрете за да дознаете повеќе."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Во ред е да се користи USB-порта"</string>
@@ -1893,10 +1901,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Некатегоризирано"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Ја поставивте важноста на известувањава."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Ова е важно заради луѓето кои се вклучени."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Дозволувате <xliff:g id="APP">%1$s</xliff:g> да создаде нов корисник со <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Веќе постои корисник со оваа сметка.)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Дозволувате <xliff:g id="APP">%1$s</xliff:g> да создаде нов корисник со <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Додај јазик"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Претпочитувања за регион"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Внеси име на јазик"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index f711158..479bb3a 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS സന്ദേശങ്ങൾ നേടാനും പ്രോസസ്സുചെയ്യാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ ഉപകരണത്തിലേക്ക് അയയ്ക്കുന്ന സന്ദേശങ്ങൾ നിങ്ങൾക്ക് ദൃശ്യമാക്കാതെ തന്നെ അപ്ലിക്കേഷന് നിരീക്ഷിക്കാനോ ഇല്ലാതാക്കാനോ കഴിയുമെന്നാണ് ഇതിനർത്ഥം."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"വാചക സന്ദേശം നേടുക (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS സന്ദേശങ്ങൾ നേടാനും പ്രോസസ്സുചെയ്യാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങളുടെ ഉപകരണത്തിലേക്ക് അയയ്ക്കുന്ന സന്ദേശങ്ങൾ നിങ്ങൾക്ക് ദൃശ്യമാക്കാതെ തന്നെ അപ്ലിക്കേഷന് നിരീക്ഷിക്കാനോ ഇല്ലാതാക്കാനോ കഴിയുമെന്നാണ് ഇതിനർത്ഥം."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"സെൽ പ്രക്ഷേപണ സന്ദേശങ്ങൾ റീഡുചെയ്യുക"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"നിങ്ങളുടെ ഉപകരണത്തിൽ ലഭിച്ച സെൽ പ്രക്ഷേപണ സന്ദേശങ്ങൾ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. അടിയന്തര സാഹചര്യങ്ങളെക്കുറിച്ച് നിങ്ങൾക്ക് മുന്നറിയിപ്പ് നൽകാനായി ചില ലൊക്കേഷനുകളിൽ നൽകപ്പെടുന്നവയാണ് സെൽ പ്രക്ഷേപണ അലേർട്ടുകൾ. ഒരു അടിയന്തര സെൽ പ്രക്ഷേപണം ലഭിക്കുമ്പോൾ, ക്ഷുദ്രകരമായ അപ്ലിക്കേഷനുകൾ നിങ്ങളുടെ ഉപകരണത്തിന്റെ പ്രകടനമോ പ്രവർത്തനമോ തടസ്സപ്പെടുത്താനിടയുണ്ട്."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"സബ്സ്ക്രൈബ് ചെയ്ത ഫീഡുകൾ വായിക്കുക"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"\'ശല്യപ്പെടുത്തരുത്\' കോൺഫിഗറേഷൻ വായിക്കുന്നതിനും എഴുതുന്നതിനും ആപ്പിനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"അനുമതി ഉപയോഗം കാണാൻ ആരംഭിക്കുക"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ഒരു ആപ്പിനുള്ള അനുമതി ഉപയോഗം ആരംഭിക്കാൻ ഹോൾഡറിനെ അനുവദിക്കുന്നു. സാധാരണ ആപ്പുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ഉപയോഗസഹായി കുറുക്കുവഴിയുടെ ടാർഗറ്റ്"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ഉപയോഗസഹായി കുറുക്കുവഴിയുടെ ടാർഗറ്റ് നിർവ്വചിക്കാൻ ആപ്പിനെ അനുവദിക്കുക."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"പാസ്വേഡ് നിയമങ്ങൾ സജ്ജീകരിക്കുക"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"സ്ക്രീൻ ലോക്ക് പാസ്വേഡുകളിലും PIN-കളിലും അനുവദിച്ചിരിക്കുന്ന ദൈർഘ്യവും പ്രതീകങ്ങളും നിയന്ത്രിക്കുക."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"സ്ക്രീൻ അൺലോക്ക് ശ്രമങ്ങൾ നിരീക്ഷിക്കുക"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ഡീബഗ്ഗുചെയ്യൽ പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"പരിശോധനാ സംവിധാനങ്ങൾ മോഡ് പ്രവർത്തനക്ഷമമാക്കി"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"പരിശോധനാ സംവിധാന മോഡ് പ്രവർത്തനരഹിതമാക്കാൻ ഫാക്ടറി പുനഃക്രമീകരണം നിർവഹിക്കുക."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"സീരിയൽ കൺസോൾ പ്രവർത്തനക്ഷമമാക്കി"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"പ്രകടനത്തെ ബാധിച്ചു. പ്രവർത്തനരഹിതമാക്കാൻ, ബൂട്ട് ലോഡർ പരിശോധിക്കുക."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB പോർട്ടിൽ ദ്രാവകമോ പൊടിയോ കണ്ടെത്തി"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB പോർട്ടർ സ്വയമേവ പ്രവർത്തനരഹിതമായി. കൂടുതലറിയാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ഇനി USB പോർട്ട് ഉപയോഗിക്കാം"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"വർഗ്ഗീകരിച്ചിട്ടില്ലാത്ത"</string>
<string name="importance_from_user" msgid="7318955817386549931">"ഈ അറിയിപ്പുകളുടെ പ്രാധാന്യം നിങ്ങൾ സജ്ജീകരിച്ചു."</string>
<string name="importance_from_person" msgid="9160133597262938296">"ഉൾപ്പെട്ടിട്ടുള്ള ആളുകളെ കണക്കിലെടുക്കുമ്പോള് ഇത് പ്രധാനപ്പെട്ടതാണ്."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> എന്ന അക്കൗണ്ട് (ഈ അക്കൗണ്ട് ഉപയോഗിക്കുന്ന ഒരു ഉപയോക്താവ് നിലവിലുണ്ട്) ഉപയോഗിച്ച് പുതിയ ഉപയോക്താവിനെ സൃഷ്ടിക്കാൻ <xliff:g id="APP">%1$s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> എന്ന അക്കൗണ്ട് ഉപയോഗിച്ച് പുതിയ ഉപയോക്താവിനെ സൃഷ്ടിക്കാൻ <xliff:g id="APP">%1$s</xliff:g> എന്നതിനെ അനുവദിക്കണോ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ഒരു ഭാഷ ചേർക്കുക"</string>
<string name="country_selection_title" msgid="2954859441620215513">"മേഖലാ മുൻഗണന"</string>
<string name="search_language_hint" msgid="7042102592055108574">"ഭാഷയുടെ പേര് ടൈപ്പുചെയ്യുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 7570028..1f29956 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Апп нь SMS мессежийг хүлээн авах болон гүйцэтгэх боломжтой. Ингэснээр апп нь таны төхөөрөмжрүү илгээсэн мессежийг танд үзүүлэхгүйгээр хянах болон устгаж чадна."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"текст мессеж(МMS) хүлээж авах"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Апп нь MMS мессежийг хүлээн авах болон гүйцэтгэх боломжтой. Ингэснээр апп нь таны төхөөрөмжрүү илгээсэн мессежийг танд үзүүлэхгүйгээр хянах болон устгаж чадна."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"үүрэн өргөн дамжууллын мессеж унших"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Апп нь таны төхөөрөмжийн хүлээн авсан үүрэн өргөн дамжуулах мессежийг унших боломжтой. Үүрэн өргөн дамжууллын мэдэгдэл нь яаралтай нөхцөл байдлыг анхааруулах зорилгоор зарим байршлуудад хүрдэг. Хортой апп нь яаралтай үүрэн өргөн дамжууллыг хүлээн авсан үед таны төхөөрөмжийн ажиллагаа болон чадамжид нөлөөлөх боломжтой."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"бүртгүүлсэн хангамжийг унших"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Апп-д Бүү саад бол тохируулгыг уншиж, бичихийг зөвшөөрөх"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"зөвшөөрлийн ашиглалтыг харж эхлэх"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Эзэмшигчид аппын зөвшөөрлөө ашиглаж эхлэхийг зөвшөөрдөг. Энгийн аппуудад шаардлагагүй."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"хандалтын товчлолын зорилт"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Аппад хандалтын товчлолын зорилтыг тодорхойлохыг зөвшөөрдөг."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Дэлгэц түгжих нууц үг болон ПИН кодны урт болон нийт тэмдэгтийн уртыг хянах."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Дэлгэцийн түгжээг тайлах оролдлогыг хянах"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB дебаг хийхийг идэвхгүй болгох бол сонгоно уу."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Туршилтын цогц горимыг идэвхжүүлсэн"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Туршилтын цогц горимыг идэвхгүй болгохын тулд үйлдвэрийн төлөвт шинэчилнэ үү."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Цуваа консолыг идэвхжүүлсэн"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Гүйцэтгэлд нөлөөлнө. Идэвхгүй болгохын тулд эхэлж ачаалагчийг шалгана уу."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB порт дээрх шингэн зүйл эсвэл бохирдол"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB портыг автоматаар идэвхгүй болгосон байна. Дэлгэрэнгүй мэдээлэл авахын тулд товшино уу."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портыг ашиглахад зүгээр"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Ангилаагүй"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Та эдгээр мэдэгдлийн ач холбогдлыг тогтоосон."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Оролцсон хүмүүсээс шалтгаалан энэ нь өндөр ач холбогдолтой."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>-д <xliff:g id="ACCOUNT">%2$s</xliff:g>-тай (ийм бүртгэлтэй хэрэглэгч аль хэдийн байна) шинэ хэрэглэгч үүсгэхийг зөвшөөрөх үү ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>-д <xliff:g id="ACCOUNT">%2$s</xliff:g>-тай шинэ хэрэглэгч үүсгэхийг зөвшөөрөх үү?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Хэл нэмэх"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Бүс нутгийн тохиргоо"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Улсын хэлийг бичнэ үү"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index e22bca0..5c6e358 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS मेसेज प्राप्त करण्याची आणि त्यावर प्रक्रिया करण्याची अॅप ला अनुमती देते. म्हणजेच अॅप आपल्या डीव्हाइसवर पाठविलेले मेसेज तुम्हाला न दर्शवता त्यांचे परीक्षण करू किंवा ते हटवू शकतो."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"मजकूर मेसेज मिळवा (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS मेसेज प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यास अॅप ला अनुमती देते. म्हणजेच अॅप आपल्या डिव्हाइसवर पाठविलेले मेसेज तुम्हाला न दर्शवता त्यांचे परीक्षण करू किंवा ते हटवू शकतो."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारण मेसेज वाचा"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"आपल्या डिव्हाइसद्वारे प्राप्त केलेले सेल प्रसारण मेसेज वाचण्यासाठी अॅप ला अनुमती देते. काही स्थानांमध्ये तुम्हाला आणीबाणीच्या परिस्थितीची चेतावणी देण्यासाठी सेल प्रसारण सूचना वितरीत केल्या जातात. आणीबाणी सेल प्रसारण प्राप्त होते तेव्हा आपल्या डिव्हाइसच्या कार्यप्रदर्शनात किंवा कार्यात दुर्भावनापूर्ण अॅप्स व्यत्यय आणू शकतात."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्यता घेतलेली फीड वाचा"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"व्यत्यय आणू नका कॉन्फिगरेशन वाचण्यासाठी आणि लिहिण्यासाठी अॅपला अनुमती देते."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"व्ह्यू परवानगी वापर सुरू करा"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"धारकास अॅपसाठी परवानगी वापरणे सुरू करण्याची अनुमती देते. सामान्य अॅप्ससाठी कधीही आवश्यकता नसते."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"अॅक्सेसिबिलिटी शॉर्टकट लक्ष्य"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"अॅपला अॅक्सेसिबिलिटी शॉर्टकट लक्ष्याबद्दल सांगण्यासाठी अनुमती द्या."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करा"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"स्क्रीन लॉक पासवर्ड आणि पिन मध्ये अनुमती दिलेले लांबी आणि वर्ण नियंत्रित करा."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"स्क्रीन अनलॉक प्रयत्नांचे परीक्षण करा"</string>
@@ -999,7 +1005,7 @@
<string name="weeks" msgid="6509623834583944518">"आठवडे"</string>
<string name="year" msgid="4001118221013892076">"वर्ष"</string>
<string name="years" msgid="6881577717993213522">"वर्षे"</string>
- <string name="now_string_shortest" msgid="8912796667087856402">"आत्ता"</string>
+ <string name="now_string_shortest" msgid="8912796667087856402">"आता"</string>
<plurals name="duration_minutes_shortest" formatted="false" msgid="3957499975064245495">
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>मि</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>मि</item>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबगिंग बंद करण्यासाठी निवडा."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"टेस्ट हार्नेस मोड सुरू केला आहे"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"टेस्ट हार्नेस मोड बंद करण्यासाठी फॅक्टरी रीसेट करा."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"सिरीअल कन्सोल सुरू केला आहे"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"परफॉर्मन्सवर परिणाम होतो. बंद करण्यासाठी, बूटलोडर तपासा."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB पोर्ट मध्ये ओलावा किंवा धूळ आहे"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB पोर्ट आपोआप बंद होईल. अधिक जाणून घेण्यासाठी टॅप करा."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB पोर्ट वापरण्यासाठी ठीक आहे"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"वर्गीकरण न केलेले"</string>
<string name="importance_from_user" msgid="7318955817386549931">"तुम्ही या सूचनांचे महत्त्व सेट केले."</string>
<string name="importance_from_person" msgid="9160133597262938296">"सामील असलेल्या लोकांमुळे हे महत्वाचे आहे."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> सह नवीन वापरकर्ता तयार करण्याची (हे खाते असलेला वापरकर्ता आधीपासून अस्तित्वात आहे) <xliff:g id="APP">%1$s</xliff:g> ला अनुमती द्यायची आहे का?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> सह नवीन वापरकर्ता तयार करण्याची <xliff:g id="APP">%1$s</xliff:g> ला अनुमती द्यायची आहे का?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"एक भाषा जोडा"</string>
<string name="country_selection_title" msgid="2954859441620215513">"प्रदेश प्राधान्य"</string>
<string name="search_language_hint" msgid="7042102592055108574">"भाषा नाव टाइप करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 35e3658..a7a4c99 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Membenarkan apl menerima dan memproses mesej SMS. Ini bermakna apl boleh memantau atau memadam mesej yang dihantar ke peranti anda tanpa menunjukkannya kepada anda."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"terima mesej teks (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Membenarkan apl menerima dan memproses mesej MMS. Ini bermakna apl boleh memantau atau memadam mesej yang dihantar ke peranti anda tanpa menunjukkannya kepada anda."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"baca mesej siaran sel"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Membolehkan apl membaca mesej siaran sel yang diterima oleh peranti anda. Isyarat siaran sel dihantar di beberapa lokasi untuk memberi amaran kepada anda tentang situasi kecemasan. Apl hasad boleh mengganggu prestasi atau operasi peranti anda apabila siaran sel kecemasan diterima."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"baca suapan langganan"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Membenarkan apl membaca dan menulis konfigurasi Jangan Ganggu."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"mulakan lihat penggunaan kebenaran"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Membenarkan pemegang memulakan penggunaan kebenaran untuk apl. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"sasaran pintasan kebolehaksesan"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Membenarkan apl mentakrifkan sasaran pintasan kebolehaksesan."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan dan PIN kunci skrin."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Pantau percubaan buka kunci skrin"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk melumpuhkan penyahpepijatan USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Mod Abah-abah Ujian didayakan"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Laksanakan tetapan semula kilang untuk melumpuhkan Mod Abah-abah Ujian."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Konsol bersiri didayakan"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Prestasi terjejas. Untuk melumpuhkan, semak pemuat but."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Cecair atau serpihan dalam port USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB dilumpuhkan secara automatik. Ketik untuk mengetahui lebih lanjut."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK untuk menggunakan port USB"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Tidak dikategorikan"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Anda menetapkan kepentingan pemberitahuan ini."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Mesej ini penting disebabkan orang yang terlibat."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Benarkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baharu dengan <xliff:g id="ACCOUNT">%2$s</xliff:g> (Pengguna dengan akaun ini sudah wujud) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Benarkan <xliff:g id="APP">%1$s</xliff:g> membuat Pengguna baharu dengan <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Tambahkan bahasa"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Pilihan wilayah"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Taipkan nama bahasa"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index d69b7d1..cbe8af4 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"အပလီကေးရှင်းအား စာတိုများ လက်ခံခြင်း၊ ဆောင်ရွက်ခြင်း ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်တွင် အပလီကေးရှင်းအနေဖြင့် သင် လက်ခံရရှိသော စာများအား သင့်အား မပြပဲစောင့်ကြည့်ခွင့်နှင့် ဖျက်ပစ်ခွင့်များ ပါဝင်ပါသည်။"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"စာပို့ခြင်းအား လက်ခံရယူခြင်း (ရုပ်သံစာ)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"အပလီကေးရှင်းအား ရုပ်သံစာများ လက်ခံခြင်း၊ ဆောင်ရွက်ခြင်း ခွင့်ပြုပါ။ ဤခွင့်ပြုချက်တွင် အပလီကေးရှင်းအနေဖြင့် သင် လက်ခံရရှိသော စာများအား သင့်အား မပြပဲစောင့်ကြည့်ခွင့်နှင့် ဖျက်ပစ်ခွင့်များ ပါဝင်ပါသည်။"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"စာတိုများ ဖြန့်ဝေခြင်းစနစ်အား ဖတ်ခြင်း"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"အပလီကေးရှင်းကို သင်၏ စက်ပစ္စည်းမှ လက်ခံရရှိသော အများလွှင့်ထုတ်ချက်များကို ဖတ်ရန် ခွင့်ပြုသည်။ အများလွှင့်ထုတ်ချက်များသည် အရေးပေါ်အခြေအနေများကို သင့်အား သတိပေးရန် အချို့ နေရာများတွင် ပို့ပေးသည်။ အရေးပေါ်သတိပေးချက် ထုတ်လွှင့်ချက်ကို လက်ခံရရှိချိန်တွင်အန္တရာယ် ဖြစ်စေနိုင်သော အပလီကေးရှင်းများသည် သင့်စက်ပစ္စည်း၏ လုပ်ငန်းလည်ပတ်မှုနှင့် စွမ်းဆောင်မှုကို ဝင်စွက်ဖက်နိုင်သည်။"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"အမည်သွင်းထားသောဖိဖ့်များကို ဖတ်ခြင်း"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"မနှောင့်ယှက်ရန် ချိန်ညှိမှုကို အပ်ဖ်များ ဖတ်ခြင်း ပြင်ခြင်းပြုလုပ်နိုင်ရန် ခွင့်ပြုမည်။"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"အစမြင်ကွင်း ခွင့်ပြုချက် အသုံးပြုမှု"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"အက်ပ်တစ်ခုအတွက် ခွင့်ပြုချက်စတင်အသုံးပြုမှုကို ကိုင်ဆောင်သူအား ခွင့်ပြုသည်။ ပုံမှန်အက်ပ်များအတွက် ဘယ်သောအခါမျှ မလိုအပ်ပါ။"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ် ပစ်မှတ်"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ် ပစ်မှတ်ကို အက်ပ်အား သတ်မှတ်ခွင့်ပြုသည်။"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"စကားဝှက်စည်းမျဥ်းကိုသတ်မှတ်ရန်"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"မျက်နှာပြင်သော့ခတ်သည့် စကားဝှက်များနှင့် PINများရှိ ခွင့်ပြုထားသည့် စာလုံးအရေအတွက်နှင့် အက္ခရာများအား ထိန်းချုပ်ရန်။"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"မျက်နှာပြင်လော့ခ်ဖွင့်ရန် ကြိုးပမ်းမှုများကို စောင့်ကြည့်ပါ"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ဖြင့် အမှားရှာပြင်ခြင်းကို ပိတ်ရန် ရွေးပါ။"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"\'စမ်းသပ်ခြင်းစနစ်မုဒ်\' ဖွင့်ထားသည်"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"\'စမ်းသပ်ခြင်းစနစ် မုဒ်\' ကိုပိတ်ရန် စက်ရုံထုတ်အတိုင်း ပြင်ဆင်သတ်မှတ်ပါ။"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"အမှတ်စဉ် ကွန်ဆိုးလ်ကို ဖွင့်ထားသည်"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"စွမ်းဆောင်ရည်အပေါ် သက်ရောက်မှုရှိနိုင်ပါသည်။ ပိတ်ရန် bootloader ကို စစ်ဆေးပါ။"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ပို့တ်တွင် အရည် သို့မဟုတ် အမှိုက်စ ရှိနေသည်"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ပို့တ်ကို အလိုအလျောက် ပိတ်ထားသည်။ ပိုမိုလေ့လာရန် တို့ပါ။"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ပို့တ်ကို အသုံးပြုနိုင်သည်"</string>
@@ -1449,8 +1457,8 @@
<string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"အောက်ပါထဲက အက်ပ်တစ်ခု သို့မဟုတ် ပိုလျက် သင်၏ အကောင့်ကို၊ ယခု နှင့် အနာဂတ်မှာ ရယူအသုံးချရန် ခွင့်ပြုချက်ကို တောင်းထားသည်။"</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"ဤတောင်းခံမှုအားခွင့်ပြုမည်လား"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"သုံးစွဲခွင့် တောင်းဆိုရန်"</string>
- <string name="allow" msgid="7225948811296386551">"ခွင့်ပြုသည်"</string>
- <string name="deny" msgid="2081879885755434506">"ငြင်းပယ်သည်"</string>
+ <string name="allow" msgid="7225948811296386551">"ခွင့်ပြုရန်"</string>
+ <string name="deny" msgid="2081879885755434506">"ငြင်းပယ်ရန်"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"ခွင့်ပြုချက် တောင်းခံထားခြင်း"</string>
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"အကောင့် <xliff:g id="ACCOUNT">%s</xliff:g> အတွက် \n ခွင့်ပြုချက် တောင်းခံထားပြီး"</string>
<string name="forward_intent_to_owner" msgid="1207197447013960896">"သင်သည် ဒီအက်ပ်ကို သင့်အလုပ်ပရိုဖိုင် ပြင်ပတွင် အသုံးပြုနေ၏"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"အမျိုးအစားမခွဲရသေးပါ"</string>
<string name="importance_from_user" msgid="7318955817386549931">"ဤသတိပေးချက်များ၏ အရေးပါမှုကိုသတ်မှတ်ပြီးပါပြီ။"</string>
<string name="importance_from_person" msgid="9160133597262938296">"ပါဝင်သည့်လူများကြောင့် အရေးပါပါသည်။"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ဖြင့်အသုံးပြုသူအသစ်ကို <xliff:g id="APP">%1$s</xliff:g> အား ဖန်တီးခွင့်ပြုလိုပါသလား (ဤအကောင့်ဖြင့် အသုံးပြုသူ ရှိနှင့်ပြီးဖြစ်သည်) ။"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ဖြင့်အသုံးပြုသူအသစ်ကို <xliff:g id="APP">%1$s</xliff:g> အား ဖန်တီးခွင့်ပြုလိုပါသလား ။"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ဘာသာစကားတစ်ခု ထည့်ပါ"</string>
<string name="country_selection_title" msgid="2954859441620215513">"ဒေသရွေးချယ်မှု"</string>
<string name="search_language_hint" msgid="7042102592055108574">"ဘာသာစကားအမည် ထည့်ပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index a597170..183e2e2 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -226,7 +226,7 @@
<string name="global_actions" product="default" msgid="2406416831541615258">"Telefoninnstillinger"</string>
<string name="global_action_lock" msgid="2844945191792119712">"Lås skjermen"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"Slå av"</string>
- <string name="global_action_emergency" msgid="7112311161137421166">"Nødsituasjon"</string>
+ <string name="global_action_emergency" msgid="7112311161137421166">"Nødssituasjon"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Feilrapport"</string>
<string name="global_action_logout" msgid="935179188218826050">"Avslutt økten"</string>
<string name="global_action_screenshot" msgid="8329831278085426283">"Skjermdump"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Lar appen motta og behandle tekstmeldinger. Dette betyr at appen kan overvåke eller slette meldinger som er sendt til enheten din uten at du har sett dem."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"motta tekstmeldinger (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Lar appen motta og behandle multimediemeldinger. Dette betyr at appen kan overvåke eller slette meldinger som er sendt til enheten din uten at du har sett dem."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lese kringkastede meldinger"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Tillater at appen kan lese kringkastede meldinger enheten din mottar. Kringkastede varsler leveres noen steder for å advare deg om nødssituasjoner. Skadelige apper kan forstyrre ytelsen eller funksjonen til enheten din når en kringkastet nødmelding mottas."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lese abonnement på nyhetskilder"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Lar appen lese og skrive konfigurasjon av Ikke forstyrr."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"start visning av bruk av tillatelser"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Lar innehaveren starte bruk av tillatelser for en app. Dette skal aldri være nødvendig for vanlige apper."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"mål for tilgjengelighetssnarvei"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Tillat at en app definerer målet for tilgjengelighetssnarveien."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Angi passordregler"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrollerer tillatt lengde og tillatte tegn i passord og PIN-koder for opplåsing av skjermen."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Overvåk forsøk på å låse opp skjermen"</string>
@@ -815,7 +821,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Trykk på menyknappen for å låse opp eller ringe et nødnummer."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Trykk på menyknappen for å låse opp."</string>
<string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Tegn mønster for å låse opp"</string>
- <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødsituasjon"</string>
+ <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødssituasjon"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Tilbake til samtale"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Riktig!"</string>
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Prøv på nytt"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Testrammeverk-modus er slått på"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Tilbakestill enheten til fabrikkstandard for å slå av Testrammeverk-modus."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Seriekonsollen er aktivert"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Ytelsen er påvirket. Sjekk oppstartsinnlasteren for å deaktivere."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Væske eller rusk i USB-porten"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten deaktiveres automatisk. Trykk for å finne ut mer."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Trygt å bruke USB-porten"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Uten kategori"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Du angir viktigheten for disse varslene."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Dette er viktig på grunn av folkene som er involvert."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Vil du la <xliff:g id="APP">%1$s</xliff:g> opprette en ny bruker med <xliff:g id="ACCOUNT">%2$s</xliff:g> (en bruker med denne kontoen eksisterer allerede)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Vil du la <xliff:g id="APP">%1$s</xliff:g> opprette en ny bruker med <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Legg til et språk"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Regionsinnstilling"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Skriv inn språknavn"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 0cbaaa0..4c4e1f0 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"अनुप्रयोगलाई SMS सन्देशहरू प्राप्त गर्न र प्रक्रिया गर्न अनुमति दिन्छ। यसको मतलब अनुप्रयोगले तपाईंको उपकरणमा पठाइएको सन्देशहरू तपाईंलाई नदेखाईनै मोनिटर गर्न वा मेटाउन सक्दछ।"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"पाठ सन्देश (MMS) प्राप्त गर्नुहोस्"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"अनुप्रयोगलाई MMS सन्देशहरू प्राप्त गर्न र प्रकृया गर्न अनुमति दिन्छ। यसको मतलब अनुप्रयोगले तपाईंको उपकरणमा पठाइएको सन्देशहरू तपाईंलाई नदेखाईनै मोनिटर गर्न वा मेटाउन सक्दछ।"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"सेल प्रसारित सन्देशहरू पढ्नुहोस्"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"तपाईंको उपकरणद्वारा प्राप्त सेल प्रसारण सन्देशहरू अनुप्रयोगलाई पढ्न अनुमति दिन्छ। सेल प्रसारण चेतावनीहरू केही स्थानहरूमा तपाईंलाई आपतकालीन गतिविधिहरूको बारेमा सचेत गराउन गरिएका छन्। खराब अनुप्रयोगहरूले एउटा आपतकालीन सेल प्रसारण प्राप्त गर्दछ जब तपाईंको उपकरणको प्रदर्शन वा अपरेशनको साथ हस्तक्षेप गर्न सक्दछन्।"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"सदस्य बनाइका फिडहरू पढ्नुहोस्"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"बाधा नपुर्याउँनुहोस् कन्फिगरेसन पढ्न र लेख्नको लागि अनुप्रयोगलाई अनुमति दिनुहोस्।"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"हेर्ने अनुमतिको प्रयोग सुरु गर्नुहोस्"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"वाहकलाई कुनै अनुप्रयोगसम्बन्धी अनुमतिको प्रयोग सुरु गर्न दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक नपर्नु पर्ने हो।"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"पहुँचसम्बन्धी सर्टकटको लक्ष्य"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"कुनै अनुप्रयोगलाई पहुँचसम्बन्धी सर्टकटको लक्ष्य परिभाषित गर्न दिन्छ।"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियमहरू मिलाउनुहोस्"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"स्क्रिन लक पासवर्ड र PIN हरूमा अनुमति दिइएको लम्बाइ र वर्णहरूको नियन्त्रण गर्नुहोस्।"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"मनिटरको स्क्रिन अनलक गर्ने प्रयासहरू"</string>
@@ -1367,6 +1373,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डिबगिङलाई असक्षम पार्न ट्याप गर्नुहोस्।"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"परीक्षण प्याकेज मोड सक्षम पारियो"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"परीक्षण प्याकेज मोड असक्षम पार्न फ्याक्ट्री रिसेट गर्नुहोस्।"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"क्रमसम्बन्धी कन्सोल सक्षम पारियो"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"कार्यसम्पादनमा प्रभाव परेको छ। यसलाई असक्षम पार्न बुटलोडरको जाँच गर्नुहोस्।"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB पोर्टमा तरल पदार्थ वा धुलो भएको कुरा पत्ता लाग्यो"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB पोर्ट स्वतः असक्षम पारियो। थप जान्न ट्याप गर्नुहोस्।"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB पोर्ट प्रयोग गर्दा हुन्छ"</string>
@@ -1896,10 +1904,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"वर्गीकरण नगरिएको"</string>
<string name="importance_from_user" msgid="7318955817386549931">"तपाईंले यी सूचनाहरूको महत्त्व सेट गर्नुहोस् ।"</string>
<string name="importance_from_person" msgid="9160133597262938296">"यसमा सङ्लग्न भएका मानिसहरूको कारणले गर्दा यो महत्वपूर्ण छ।"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (यस खाताको प्रयोगकर्ता पहिले नै अवस्थित छ) मा नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> मा नयाँ प्रयोगकर्ता सिर्जना गर्न <xliff:g id="APP">%1$s</xliff:g> लाई अनुमति दिने हो?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"भाषा थप्नुहोस्"</string>
<string name="country_selection_title" msgid="2954859441620215513">"क्षेत्रको प्राथमिकता"</string>
<string name="search_language_hint" msgid="7042102592055108574">"भाषाको नाम टाइप गर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index e898389..b3cc884 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Hiermee kan de app sms-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"tekstberichten (MMS) ontvangen"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Hiermee kan de app MMS-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar je apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"infodienstberichten lezen"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Toestaan dat de app infodienstberichten leest die worden ontvangen op je apparaat. Infodienstberichten worden verzonden naar bepaalde locaties om u te waarschjeen voor noodsituaties. Schadelijke apps kunnen de prestaties of verwerking van je apparaat verstoren wanneer een infodienstbericht wordt ontvangen."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Geabonneerde feeds lezen"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Hiermee kan de app configuratie voor Niet storen lezen en schrijven."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"rechtengebruik starten"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Hiermee kan de houder het rechtengebruik voor een app starten. Nooit vereist voor normale apps."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"doel van snelkoppeling voor toegankelijkheid"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Hiermee kan een app het doel van de snelkoppeling voor toegankelijkheid definiëren."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"De lengte en het aantal tekens beheren die zijn toegestaan in wachtwoorden en pincodes voor schermvergrendeling."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Pogingen voor schermontgrendeling bijhouden"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test harness-modus is ingeschakeld"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Reset de fabrieksinstellingen om de test harness-modus uit te schakelen."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Seriële console ingeschakeld"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Dit is van invloed op de prestaties. Controleer de bootloader om dit uit te schakelen."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vloeistof of vuil in USB-poort"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-poort is automatisch uitgeschakeld. Tik voor meer informatie."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-poort kan worden gebruikt"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Geen categorie"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Je stelt het belang van deze meldingen in."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Dit is belangrijk vanwege de betrokken mensen."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Toestaan dat <xliff:g id="APP">%1$s</xliff:g> een nieuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> maakt (er is al een gebruiker met dit account)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Toestaan dat <xliff:g id="APP">%1$s</xliff:g> een nieuwe gebruiker met <xliff:g id="ACCOUNT">%2$s</xliff:g> maakt?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Een taal toevoegen"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Regiovoorkeur"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Typ een taalnaam"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index bd6d2cc..eb8f4c6 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS ମେସେଜ୍ ପ୍ରାପ୍ତ କରିବାକୁ ତଥା ପ୍ରକ୍ରିୟା କରାଇବାକୁ ଆପ୍ଟିକୁ ଅନୁମତି ଦିଏ। ଏହାର ଅର୍ଥ ହେଉଛି, ଆପଣଙ୍କ ଡିଭାଇସ୍କୁ ପଠାଯାଇଥିବା ମେସେଜ୍ ଆପଣଙ୍କୁ ନଦେଖାଇ ଆପ୍ଟି ମନିଟର୍ କିମ୍ବା ଡିଲିଟ୍ କରିପାରେ।"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ଟେକ୍ସଟ୍ ମେସେଜ୍ (MMS) ପ୍ରାପ୍ତ କରନ୍ତୁ"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS ମେସେଜ୍ ପ୍ରାପ୍ତ କରିବାକୁ ତଥା ପ୍ରକ୍ରିୟା କରାଇବାକୁ ଆପ୍ଟିକୁ ଅନୁମତି ଦିଏ। ଏହାର ଅର୍ଥ, ଆପଣଙ୍କ ଡିଭାଇସ୍କୁ ପଠାଯାଇଥିବା ମେସେଜ୍ ଆପଣଙ୍କୁ ନଦେଖାଇ ଆପ୍ଟି ମନିଟର୍ କିମ୍ବା ଡିଲିଟ୍ କରିପାରେ।"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ସେଲ୍ ବ୍ରଡ୍କାଷ୍ଟ ମେସେଜ୍ ପଢ଼ନ୍ତୁ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ଆପଣଙ୍କ ଡିଭାଇସ୍ରେ ପ୍ରାପ୍ତ ହୋଇଥିବା ସେଲ୍ ବ୍ରଡ୍କାଷ୍ଟ ମେସେଜ୍ ପଢିବାକୁ ଆପ୍କୁ ଅନୁମତି ଦିଏ। ଜରୁରୀକାଳୀନ ଅବସ୍ଥା ବିଷୟରେ ଆପଣଙ୍କୁ ସତର୍କ କରାଇବାକୁ କିଛି ଲୋକେଶନ୍ରେ ସେଲ୍ ବ୍ରଡ୍କାଷ୍ଟ ସତର୍କ ଡେଲିଭର୍ କରାଯାଇଥାଏ। ଏକ ଜରୁରୀକାଳୀନ ସେଲ୍ ବ୍ରଡ୍କାଷ୍ଟ ପ୍ରାପ୍ତ ହେବାପରେ ହାନୀକାରକ ଆପ୍ ଆପଣଙ୍କ ଡିଭାଇସ୍ର କାର୍ଯ୍ୟକ୍ଷମତା କିମ୍ବା ସଞ୍ଚାଳନାରେ ବାଧା ପହଞ୍ଚାଇପାରନ୍ତି।"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ସବସ୍କ୍ରାଇବ୍ ହୋଇଥିବା ଫୀଡ୍କୁ ପଢ଼ନ୍ତୁ"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" କନଫିଗରେଶନ୍ ପଢ଼ିବା ତଥା ଲେଖିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ଅନୁମତି ବ୍ୟବହାର ଦେଖିବା ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ଏକ ଆପ୍ ପାଇଁ ଅନୁମତିର ବ୍ୟବହାର ଆରମ୍ଭ କରିବାକୁ ଧାରକକୁ ଅନୁମତି ଦେଇଥାଏ। ସାଧାରଣ ଆପ୍ଗୁଡ଼ିକ ପାଇଁ ଏହା ଆବଶ୍ୟକ ନୁହେଁ।"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍ ଟାର୍ଗେଟ୍"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍ ଟାର୍ଗେଟ୍ ବ୍ୟାଖ୍ୟା କରିବା ପାଇଁ ଯେ କୌଣସି ଆପ୍କୁ ଅନୁମତି ଦିଏ।"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"ପାସ୍ୱର୍ଡ ନିୟମାବଳୀ ସେଟ୍ କରନ୍ତୁ"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"ଲକ୍ ସ୍କ୍ରୀନ୍ ପାସ୍ୱର୍ଡ ଓ PINରେ ଅନୁମୋଦିତ ଦୀର୍ଘତା ଓ ବର୍ଣ୍ଣ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ।"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"ସ୍କ୍ରୀନ୍-ଅନଲକ୍ କରିବା ଉଦ୍ୟମ ନୀରିକ୍ଷଣ କରନ୍ତୁ"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ଡିବଗିଙ୍ଗକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଚୟନ କରନ୍ତୁ।"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ଟେଷ୍ଟ ହାର୍ନେସ୍ ମୋଡ୍ ସକ୍ଷମ ଅଛି"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ଟେଷ୍ଟ ହାର୍ନେସ୍ ମୋଡ୍ ଅକ୍ଷମ କରିବାକୁ ଏକ ଫ୍ୟାକ୍ଟରୀ ରିସେଟ୍ କରନ୍ତୁ।"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"କ୍ରମିକ କନ୍ସୋଲ୍କୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"କାର୍ଯ୍ୟଦକ୍ଷତା ପ୍ରଭାବିତ ହୋଇଛି। ଅକ୍ଷମ କରିବା ପାଇଁ, ବୁଟ୍ଲୋଡର୍ର ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ପୋର୍ଟରେ ତରଳ ପଦାର୍ଥ ବା ଧୂଳି"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ପୋର୍ଟ ସ୍ୱଚାଳିତ ଭାବେ ଅକ୍ଷମ ହୋଇଛି। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ପୋର୍ଟ ବ୍ୟବହାର କରିବା ପାଇଁ ଠିକ୍ ଅଟେ"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"ଅବର୍ଗୀକୃତ"</string>
<string name="importance_from_user" msgid="7318955817386549931">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ପ୍ରମୁଖତା ଆପଣ ସେଟ୍ କରନ୍ତି।"</string>
<string name="importance_from_person" msgid="9160133597262938296">"ସମ୍ପୃକ୍ତ ଲୋକଙ୍କ କାରଣରୁ ଏହା ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ ଅଟେ।"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ (ପୂର୍ବରୁ ଏହି ଆକାଉଣ୍ଟ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନାମରେ ଅଛି) ଅନୁମତି ଦେବେ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g>ରେ ଏକ ନୂଆ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରିବା ପାଇଁ <xliff:g id="ACCOUNT">%2$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ଏକ ଭାଷା ଯୋଡ଼ନ୍ତୁ"</string>
<string name="country_selection_title" msgid="2954859441620215513">"ପସନ୍ଦର ଅଞ୍ଚଳ"</string>
<string name="search_language_hint" msgid="7042102592055108574">"ଭାଷାର ନାମ ଟାଇପ୍ କରନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index a9e93d4..bc68885 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"ਐਪ ਨੂੰ SMS ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਮਿਟਾ ਸਕਦੀ ਹੈ।"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ਟੈਕਸਟ ਸੁਨੇਹੇ (MMS) ਪੜ੍ਹੋ"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"ਐਪ ਨੂੰ MMS ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਕਰਨ ਅਤੇ ਉਹਨਾਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਸਦਾ ਮਤਲਬ ਹੈ ਕਿ ਐਪ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੇ ਭੇਜੇ ਗਏ ਸੁਨੇਹਿਆਂ ਨੂੰ ਤੁਹਾਨੂੰ ਦਿਖਾਏ ਬਿਨਾਂ ਨਿਰੀਖਣ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਮਿਟਾ ਸਕਦੀ ਹੈ।"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ਸੈਲ ਪ੍ਰਸਾਰਨ ਸੁਨੇਹੇ ਪੜ੍ਹੋ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ਐਪ ਨੂੰ ਤੁਹਾਡੀ ਡੀਵਾਈਸ ਵੱਲੋਂ ਪ੍ਰਾਪਤ ਕੀਤੇ ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਸੁਨੇਹੇ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਚਿਤਾਵਨੀਆਂ ਤੁਹਾਨੂੰ ਸੰਕਟਕਾਲੀਨ ਸਥਿਤੀਆਂ ਦੀ ਚਿਤਾਵਨੀ ਦੇਣ ਲਈ ਕੁਝ ਨਿਰਧਾਰਤ ਟਿਕਾਣਿਆਂ ਤੇ ਪ੍ਰਦਾਨ ਕੀਤੀਆਂ ਜਾਂਦੀਆਂ ਹਨ। ਖਰਾਬ ਐਪਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਪ੍ਰਦਰਸ਼ਨ ਜਾਂ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾ ਸਕਦੀਆਂ ਹਨ ਜਦੋਂ ਇੱਕ ਸੰਕਟਕਾਲੀਨ ਸੈੱਲ ਪ੍ਰਸਾਰਣ ਪ੍ਰਾਪਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ਸਬਸਕ੍ਰਾਈਬ ਕੀਤੇ ਫੀਡਸ ਪੜ੍ਹੋ"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ਐਪ ਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਕੌਂਫਿਗਰੇਸ਼ਨ ਨੂੰ ਪੜ੍ਹਨ ਅਤੇ ਲਿਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"ਇਜਾਜ਼ਤ ਵਰਤੋਂ ਦੇਖਣਾ ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ਧਾਰਕ ਨੂੰ ਕਿਸੇ ਹੋਰ ਐਪ ਲਈ ਇਜਾਜ਼ਤ ਵਰਤੋਂ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੋੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਟੀਚਾ"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ਕਿਸੇ ਐਪ ਨੂੰ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਟੀਚੇ ਨੂੰ ਪਰਿਭਾਸ਼ਿਤ ਕਰਨ ਦਿਓ।"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"ਪਾਸਵਰਡ ਨਿਯਮ ਸੈੱਟ ਕਰੋ"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"ਸਕ੍ਰੀਨ ਲਾਕ ਪਾਸਵਰਡਾਂ ਅਤੇ ਪਿੰਨ ਵਿੱਚ ਆਗਿਆ ਦਿੱਤੀ ਲੰਮਾਈ ਅਤੇ ਅੱਖਰਾਂ ਤੇ ਨਿਯੰਤਰਣ ਪਾਓ।"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"ਸਕ੍ਰੀਨ ਅਣਲਾਕ ਕਰਨ ਦੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ \'ਤੇ ਨਿਗਰਾਨੀ ਰੱਖੋ"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ਡੀਬੱਗਿੰਗ ਅਯੋਗ ਬਣਾਉਣ ਲਈ ਚੁਣੋ।"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਚਾਲੂ ਹੈ"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਬੰਦ ਕਰਨ ਲਈ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਕਰੋ।"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"ਸੀਰੀਅਲ ਕੰਸੋਲ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"ਕਾਰਗੁਜ਼ਾਰੀ ਪ੍ਰਭਾਵਿਤ ਹੋਈ ਹੈ। ਬੰਦ ਕਰਨ ਲਈ, ਬੂਟਲੋਡਰ ਦੇਖੋ।"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ਪੋਰਟ ਵਿੱਚ ਪਾਣੀ ਜਾਂ ਧੂੜ-ਮਿੱਟੀ"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ਪੋਰਟ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ। ਹੋਰ ਜਾਣਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ਪੋਰਟ ਵਰਤਣ ਲਈ ਠੀਕ ਹੈ"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"ਗੈਰ-ਸ਼੍ਰੇਣੀਕਿਰਤ"</string>
<string name="importance_from_user" msgid="7318955817386549931">"ਤੁਸੀਂ ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਦੀ ਮਹੱਤਤਾ ਸੈੱਟ ਕੀਤੀ।"</string>
<string name="importance_from_person" msgid="9160133597262938296">"ਇਹ ਸ਼ਾਮਲ ਲੋਕਾਂ ਦੇ ਕਾਰਨ ਮਹੱਤਵਪੂਰਨ ਹੈ।"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ (ਇਸ ਖਾਤੇ ਨਾਲ ਇੱਕ ਵਰਤੋਂਕਾਰ ਪਹਿਲਾਂ ਤੋਂ ਹੀ ਮੌਜੂਦ ਹੈ)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"ਕੀ <xliff:g id="APP">%1$s</xliff:g> ਨੂੰ <xliff:g id="ACCOUNT">%2$s</xliff:g> ਨਾਲ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਬਣਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਦੇਣੀ ਹੈ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ਇੱਕ ਭਾਸ਼ਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="country_selection_title" msgid="2954859441620215513">"ਖੇਤਰ ਤਰਜੀਹ"</string>
<string name="search_language_hint" msgid="7042102592055108574">"ਭਾਸ਼ਾ ਨਾਮ ਟਾਈਪ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 537089c..1dbe1c1 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -350,6 +350,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Pozwala aplikacji na odbieranie i przetwarzanie SMS-ów. To oznacza, że aplikacja będzie mogła bez Twojej wiedzy monitorować i usuwać wiadomości wysyłane do Twojego urządzenia."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"odbieranie wiadomości tekstowych (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Pozwala aplikacji na odbieranie i przetwarzanie MMS-ów. To oznacza, że aplikacja będzie mogła bez Twojej wiedzy monitorować i usuwać wiadomości wysyłane do Twojego urządzenia."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"odczyt komunikatów z sieci komórkowej"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Zezwala aplikacji na odczyt komunikatów z sieci komórkowej odebranych na urządzeniu. Komunikaty alarmowe z sieci komórkowej są dostarczane w niektórych lokalizacjach w celu ostrzeżenia Cię o sytuacjach zagrożenia. Złośliwe aplikacje mogą wpływać na wydajność lub zakłócać działanie urządzenia po odebraniu komunikatu alarmowego z sieci komórkowej."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"czytanie subskrybowanych źródeł"</string>
@@ -661,6 +665,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Pozwala aplikacji na odczyt i zmianę konfiguracji trybu Nie przeszkadzać."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"rozpocząć wyświetlanie użycia uprawnień"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Umożliwia rozpoczęcie korzystania z uprawnienia dotyczącego danej aplikacji jego posiadaczowi. Zwykłe aplikacje nie powinny potrzebować tego uprawnienia."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cel skrótu do ułatwień dostępu"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Pozwala aplikacji definiować cel skrótu do ułatwień dostępu."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Określ reguły hasła"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolowanie długości haseł blokady ekranu i kodów PIN oraz dozwolonych w nich znaków."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorowanie prób odblokowania ekranu"</string>
@@ -1405,6 +1411,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Tryb jarzma testowego został włączony"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Przywróć ustawienia fabryczne, by wyłączyć tryb jarzma testowego."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Konsola szeregowa włączona"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Wpływa na wydajność. Aby wyłączyć, sprawdź program rozruchowy."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Wilgoć lub brud w porcie USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB został automatycznie wyłączony. Kliknij, by dowiedzieć się więcej."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Możesz używać portu USB"</string>
@@ -1958,10 +1966,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Bez kategorii"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Ustawiłeś ważność tych powiadomień."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Ta wiadomość jest ważna ze względu na osoby uczestniczące w wątku."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Zezwolić aplikacji <xliff:g id="APP">%1$s</xliff:g> na utworzenie nowego użytkownika dla konta <xliff:g id="ACCOUNT">%2$s</xliff:g> (użytkownik dla tego konta już istnieje)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Zezwolić aplikacji <xliff:g id="APP">%1$s</xliff:g> na utworzenie nowego użytkownika dla konta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Dodaj język"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Ustawienie regionu"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Wpisz nazwę języka"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index ba8285f..c5bcb1d 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que o app receba e processe mensagens SMS. Isso significa que o app pode monitorar ou excluir mensagens enviadas para o dispositivo sem mostrá-las para você."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"receber mensagens de texto (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite que o app receba e processe mensagens MMS. Isso significa que o app pode monitorar ou excluir as mensagens enviadas para o dispositivo sem mostrá-las para você."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ler mensagens de difusão celular"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que o app leia mensagens de difusão celular recebidas por seu dispositivo. Alertas de difusão celular são recebidos em alguns locais para avisar você de situações de emergência. Apps maliciosos podem interferir no desempenho ou funcionamento de seu dispositivo quando uma difusão celular de emergência é recebida."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds inscritos"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permitir que o app leia e grave a configuração \"Não perturbe\"."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar uso da permissão para visualização"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite que o sistema inicie o uso de permissão para um app. Não deve ser necessário para apps comuns."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"objetivo do atalho de acessibilidade"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite que um app defina o objetivo do atalho de acessibilidade."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Controla o tamanho e os caracteres permitidos nos PINs e nas senhas do bloqueio de tela."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorar tentativas de desbloqueio de tela"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modo Arcabouço de testes ativado"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Console serial ativado"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"O desempenho foi impactado. Para desativar, verifique o carregador de inicialização."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou detrito na porta USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é desativada automaticamente. Toque para saber mais."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro usar a porta USB"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Sem classificação"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Você definiu a importância dessas notificações."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Isso é importante por causa das pessoas envolvidas."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um usuário com essa conta)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Adicionar um idioma"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Digitar nome do idioma"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c7df3a7..29ef549 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -229,7 +229,7 @@
<string name="global_action_emergency" msgid="7112311161137421166">"Emergência"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de erros"</string>
<string name="global_action_logout" msgid="935179188218826050">"Terminar sessão"</string>
- <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de ecrã"</string>
+ <string name="global_action_screenshot" msgid="8329831278085426283">"Capt. ecrã"</string>
<string name="bugreport_title" msgid="5981047024855257269">"Relatório de erro"</string>
<string name="bugreport_message" msgid="398447048750350456">"Será recolhida informação sobre o estado atual do seu dispositivo a enviar através de uma mensagem de email. Demorará algum tempo até que o relatório de erro esteja pronto para ser enviado. Aguarde um pouco."</string>
<string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Relatório interativo"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que a aplicação receba e processe mensagens SMS. Isto significa que a aplicação poderá monitorizar ou eliminar mensagens enviadas para o seu dispositivo sem as apresentar."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"receber mensagens de texto (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite que a aplicação receba e processe mensagens MMS. Isto significa que a aplicação poderá monitorizar ou eliminar mensagens enviadas para o seu dispositivo sem as apresentar."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ler mensagens de transmissão celular"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que a aplicação leia mensagens de transmissão celular recebidas pelo seu dispositivo. Os alertas de transmissão celular são fornecidos em algumas localizações para avisá-lo sobre situações de emergência. As aplicações maliciosas podem interferir com o desempenho ou funcionamento do seu dispositivo quando for recebida uma transmissão celular de emergência."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds subscritos"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite à aplicação ler e alterar a configuração de Não incomodar"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar utilização da autorização de visualização"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite que o titular inicie a utilização de autorizações para uma aplicação. Nunca deverá ser necessário para aplicações normais."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"alvo do atalho de acessibilidade"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite a uma aplicação definir o alvo do atalho de acessibilidade."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras de palavra-passe"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Controlar o comprimento e os carateres permitidos nos PINs e nas palavras-passe do bloqueio de ecrã."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorizar tentativas de desbloqueio do ecrã"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração por USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modo de estrutura de teste ativado"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Efetue uma reposição de dados de fábrica para desativar o Modo de estrutura de teste."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Consola de série ativada"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"O desempenho é afetado. Para desativar, selecione o carregador de arranque."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou resíduos na porta USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é automaticamente desativada. Toque para saber mais."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro utilizar a porta USB"</string>
@@ -1508,7 +1516,7 @@
<string name="sync_really_delete" msgid="2572600103122596243">"Eliminar os itens"</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"Anular as eliminações"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"Não fazer nada por agora"</string>
- <string name="choose_account_label" msgid="5655203089746423927">"Selecionar uma conta"</string>
+ <string name="choose_account_label" msgid="5655203089746423927">"Selecione uma conta"</string>
<string name="add_account_label" msgid="2935267344849993553">"Adicionar uma conta"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Adicionar conta"</string>
<string name="number_picker_increment_button" msgid="2412072272832284313">"Aumentar"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Sem categoria"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Definiu a importância destas notificações."</string>
<string name="importance_from_person" msgid="9160133597262938296">"É importante devido às pessoas envolvidas."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Pretende permitir que a aplicação <xliff:g id="APP">%1$s</xliff:g> crie um novo utilizador com a conta <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um utilizador com esta conta)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Pretende permitir que a aplicação <xliff:g id="APP">%1$s</xliff:g> crie um novo utilizador com a conta <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Adicionar um idioma"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Intr. nome do idioma"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index ba8285f..c5bcb1d 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que o app receba e processe mensagens SMS. Isso significa que o app pode monitorar ou excluir mensagens enviadas para o dispositivo sem mostrá-las para você."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"receber mensagens de texto (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite que o app receba e processe mensagens MMS. Isso significa que o app pode monitorar ou excluir as mensagens enviadas para o dispositivo sem mostrá-las para você."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ler mensagens de difusão celular"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que o app leia mensagens de difusão celular recebidas por seu dispositivo. Alertas de difusão celular são recebidos em alguns locais para avisar você de situações de emergência. Apps maliciosos podem interferir no desempenho ou funcionamento de seu dispositivo quando uma difusão celular de emergência é recebida."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds inscritos"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permitir que o app leia e grave a configuração \"Não perturbe\"."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"iniciar uso da permissão para visualização"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite que o sistema inicie o uso de permissão para um app. Não deve ser necessário para apps comuns."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"objetivo do atalho de acessibilidade"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite que um app defina o objetivo do atalho de acessibilidade."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Controla o tamanho e os caracteres permitidos nos PINs e nas senhas do bloqueio de tela."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorar tentativas de desbloqueio de tela"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modo Arcabouço de testes ativado"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Console serial ativado"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"O desempenho foi impactado. Para desativar, verifique o carregador de inicialização."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou detrito na porta USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é desativada automaticamente. Toque para saber mais."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro usar a porta USB"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Sem classificação"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Você definiu a importância dessas notificações."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Isso é importante por causa das pessoas envolvidas."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g> (já existe um usuário com essa conta)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Permitir que o app <xliff:g id="APP">%1$s</xliff:g> crie um novo usuário com <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Adicionar um idioma"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferência de região"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Digitar nome do idioma"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7277228..8ee45f9 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -347,6 +347,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite aplicației să primească și să proceseze mesaje SMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau șterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"primește mesaje text (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Permite aplicației să primească și să proceseze mesaje MMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau șterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"citește mesajele cu transmisie celulară"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite aplicației să citească mesajele primite prin transmisie celulară de dispozitivul dvs. Alertele cu transmisie celulară sunt difuzate în unele locații pentru a vă avertiza cu privire la situațiile de urgență. Aplicațiile rău intenționate pot afecta performanța sau funcționarea dispozitivului dvs. când este primită o transmisie celulară de urgență."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"citire feeduri abonat"</string>
@@ -658,6 +662,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite aplicației să citească și să scrie configurația Nu deranja."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"porniți folosirea permisiunii de vizualizare"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Permite proprietarului să pornească folosirea permisiunii pentru o aplicație. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ținta comenzii rapide de accesibilitate"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Permite unei aplicații să definească ținta comenzii rapide de accesibilitate."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Să seteze reguli pentru parolă"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Stabiliți lungimea și tipul de caractere permise pentru parolele și codurile PIN de blocare a ecranului."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Să monitorizeze încercările de deblocare a ecranului"</string>
@@ -1383,6 +1389,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Selectați pentru a dezactiva remedierea erorilor prin USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modul Set de testare este activat"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Reveniți la setările din fabrică pentru a dezactiva modul Set de testare."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Consola din serie este activată"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Performanța este afectată. Pentru a dezactiva, verificați programul bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Lichide sau reziduuri în portul USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Portul USB este dezactivat automat. Atingeți ca să aflați mai multe."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Portul USB poate fi folosit"</string>
@@ -1924,10 +1932,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Neclasificate"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Dvs. setați importanța acestor notificări."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Notificarea este importantă având în vedere persoanele implicate."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Permiteți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>? (există deja un utilizator cu acest cont)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Permiteți ca <xliff:g id="APP">%1$s</xliff:g> să creeze un nou utilizator folosind <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Adăugați o limbă"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Regiunea preferată"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Numele limbii"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index e458e46..655cf1b 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -350,6 +350,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Приложение сможет получать и обрабатывать SMS. Это значит, что оно сможет отслеживать и удалять отправленные на ваше устройство сообщения, не показывая их."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"Прием MMS-сообщений"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Приложение сможет получать и обрабатывать MMS. Это значит, что оно сможет отслеживать и удалять отправленные на ваше устройство сообщения, не показывая их."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Читать сообщения массовой рассылки"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Приложение получит доступ к сообщениям широковещательных SMS-служб, которые в некоторых странах используются для информирования населения об экстренных ситуациях. Вредоносные программы могут помешать работе устройства, на которое поступают такие сообщения."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Просмотр фидов пользователя"</string>
@@ -661,6 +665,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Открывает приложению доступ к настройкам режима \"Не беспокоить\" и позволяет изменять их."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"Просмотр данных об используемых разрешениях"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Приложение получит доступ к данным об используемых разрешениях. Это разрешение не требуется обычным приложениям."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"Цель быстрого включения"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Приложение сможет определять цель быстрого включения."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Настройка правил для паролей"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Контролировать длину и символы при вводе пароля и PIN-кода."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Отслеживание попыток разблокировать экран"</string>
@@ -1405,6 +1411,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку по USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Тестовый режим включен"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Чтобы отключить тестовый режим, сбросьте настройки до заводских."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Консоль последовательного порта включена"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Производительность устройства снижена. Чтобы отключить консоль, перейдите в загрузчик операционной системы."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"В USB-порт попала вода или грязь"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-порт был автоматически отключен. Нажмите, чтобы узнать подробности."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-порт можно использовать"</string>
@@ -1958,10 +1966,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Без категории"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Вы определяете важность этих уведомлений."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Важное (люди)"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Разрешить приложению \"<xliff:g id="APP">%1$s</xliff:g>\" создать нового пользователя с аккаунтом <xliff:g id="ACCOUNT">%2$s</xliff:g> (пользователь с этим аккаунтом уже существует)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Разрешить приложению \"<xliff:g id="APP">%1$s</xliff:g>\" создать нового пользователя с аккаунтом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Добавьте язык"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Региональные настройки"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Введите язык"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 3e0f582..5fc6b53 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS පණිවිඩ ලැබීමට සහ ක්රියාත්මක කිරීමට යෙදුමට අවසර දෙන්න. මෙහි තේරුම යෙදුමට ඔබගේ උපාංගයට ලැබෙන පණිවිඩ අධීක්ෂණය කිරීමට හැකිවීම වන අතර, ඒවා ඔබට නොපෙන්වා මකා දැමීමටද හැකි වීමයි."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"පෙළ පණිවුඩ ලබාගන්න (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS පණිවිඩ සොයා ලබාගැනීමට සහ ක්රියාත්මක කිරීමට යෙදුමට අවසර දෙන්න. යෙදුම නිරීක්ෂණය කරනු ලබන අතර ඔබට ලැබුන පණිවිඩ පෙන්වීමෙන් තොරවම මකා දැමිය හැකි බව මෙමඟින් අදහස් කරයි."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"සෙල් ප්රචාරණ පණිවිඩ කියවීම"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ඔබගේ උපාංගයට ලැබුණු සෙල් විකාශන පණිවිඩ කියවීමට යෙදුමට අවසර දෙන්න. ඔබට හදිසි අවස්ථාවන් පිළිබඳ අනතුරු ඇඟවීමට සෙල් විකාශන පණිවිඩ ඇතැම් ස්ථානවල සිට යවනු ලබයි. හදිසි සෙල් විකාශන ලැබෙන අවස්ථාවකදී, අනිෂ්ට යෙදුම් මඟින් ඔබගේ උපාංගයට කාර්ය සාධනයට හෝ ක්රියකරණයට බාධා සිදුවිය හැක."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"දායක වූ සංග්රහ කියවීම"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"බාධා නොකරන්න වින්යාස කිරීම කියවීමට සහ ලිවීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"අවසර භාවිතය බැලීමට ආරම්භ කරන්න"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"තබා සිටින්නාට යෙදුමක් සඳහා අවසර භාවිතය ආරම්භ කිරීමට ඉඩ දෙයි. සාමාන්ය යෙදුම් සඳහා කිසි විටෙක අවශ්ය නොවිය යුතු ය."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ප්රවේශ්යතා කෙටිමං ඉලක්කය"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ප්රවේශ්යතා කෙටිමං ඉලක්කය නිර්වචනය කිරීමට යෙදුමකට ඉඩ දෙන්න."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"මුරපද නීති සකස් කිරීම"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"තිර අගුලු මුරපද සහ PIN තුළ ඉඩ දෙන දිග සහ අනුලකුණු පාලනය කිරීම."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"තිරය අගුළු ඇරීමේ උත්සාහයන් නිරීක්ෂණය කරන්න"</string>
@@ -1363,6 +1369,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB නිදොස්කරණය අබල කිරීමට තෝරන්න."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"පුරක පරීක්ෂා ප්රකාරය සබලයි"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"පුරක පරීක්ෂා ප්රකාරය අබල කිරීමට කර්මාන්තශාලා යළි සැකසීමක් ඉටු කරන්න."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"අනුක්රමික කොන්සෝලය සබලයි"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"කාර්ය සාධනය බලපෑමට ලක් වී ඇත. අබල කිරීමට, ආරම්භකය පරීක්ෂා කරන්න."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB තොට තුළ ද්රව හෝ කුණු"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB තොට ස්වයංක්රීයව අබල කෙරේ. තවත් දැන ගැනීමට තට්ටු කරන්න."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB තොට භාවිත කළාට කමක් නැත"</string>
@@ -1892,10 +1900,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"වර්ගීකරණය නොකළ"</string>
<string name="importance_from_user" msgid="7318955817386549931">"ඔබ මෙම දැනුම්දීම්වල වැදගත්කම සකසා ඇත."</string>
<string name="importance_from_person" msgid="9160133597262938296">"සම්බන්ධ වූ පුද්ගලයන් නිසා මෙය වැදගත් වේ."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> හට <xliff:g id="ACCOUNT">%2$s</xliff:g> සමගින් නව පරිශීලකයෙකු සෑදීමට ඉඩ දෙන්නද (මෙම ගිණුම සහිත පරිශීලකයෙකු දැනටමත් සිටී) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> හට <xliff:g id="ACCOUNT">%2$s</xliff:g> සමගින් නව පරිශීලකයෙකු සෑදීමට ඉඩ දෙන්නද ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"භාෂාවක් එක් කරන්න"</string>
<string name="country_selection_title" msgid="2954859441620215513">"ප්රදේශ මනාපය"</string>
<string name="search_language_hint" msgid="7042102592055108574">"භාෂා නම ටයිප් කරන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 015cd91..ce17331 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -350,6 +350,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Umožňuje aplikácii prijímať a spracovávať správy SMS. Znamená to, že aplikácia môže sledovať správy odoslané na vaše zariadenie alebo ich odstrániť bez toho, aby sa vám zobrazili."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"prijímať textové správy (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Umožňuje aplikácii prijímať a spracovávať správy MMS. Znamená to, že aplikácia môže sledovať správy odoslané na vaše zariadenie alebo ich odstrániť bez toho, aby sa vám zobrazili."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čítať správy informačných služieb"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Umožňuje aplikácii čítať správy informačných služieb prijaté vaším zariadením. Správy informačných služieb sa doručujú na určitých miestach a upozorňujú na tiesňové situácie. Škodlivé aplikácie môžu pri prijatí správy informačnej služby narušiť výkonnosť alebo prevádzku vášho zariadenia."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"čítať odoberané informačné kanály"</string>
@@ -661,6 +665,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Umožňuje aplikácii čítať a zapisovať konfiguráciu režimu bez vyrušení."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"spustenie používania povolenia na zobrazenie"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Umožňuje držiteľovi spustiť používanie povolenia aplikáciou. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cieľ skratky dostupnosti"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Umožňuje aplikácii definovať cieľ skratky dostupnosti."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastaviť pravidlá pre heslo"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Nastavte dĺžku hesiel na odomknutie obrazovky aj kódov PIN a v nich používané znaky."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Sledovanie pokusov o odomknutie obrazovky"</string>
@@ -1405,6 +1411,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Vyberte, ak chcete zakázať ladenie cez USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Režim správcu testov je aktivovaný"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Ak chcete zakázať režim správcu testov, obnovte výrobné nastavenia."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Sériová konzola je povolená"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Ovplyvňuje výkon. Ak ju chcete zakázať, skontrolujte zavádzací program systému."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tekutina alebo nečistoty v porte USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB je automaticky deaktivovaný. Ďalšie informácie zobrazíte klepnutím."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Port USB môžete použiť"</string>
@@ -1958,10 +1966,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizované"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Nastavili ste dôležitosť týchto upozornení."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Táto správa je dôležitá vzhľadom na osoby, ktorých sa to týka."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Chcete povoliť aplikácii <xliff:g id="APP">%1$s</xliff:g> vytvoriť nového používateľa pomocou účtu <xliff:g id="ACCOUNT">%2$s</xliff:g> (používateľ s týmto účtom už existuje)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Chcete povoliť aplikácii <xliff:g id="APP">%1$s</xliff:g> vytvoriť nového používateľa pomocou účtu <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Pridať jazyk"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferovaný región"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Zadajte názov jazyka"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 54da1dc..ec0863f 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -350,6 +350,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Aplikaciji omogoča prejemanje in obdelavo SMS-ov. S tem lahko aplikacija nadzoruje ali izbriše sporočila, poslana v napravo, ne da bi vam jih pokazala."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"prejemanje sporočil (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Aplikaciji omogoča prejemanje in obdelavo MMS-ov. S tem lahko aplikacija nadzoruje ali izbriše sporočila, poslana v napravo, ne da bi vam jih pokazala."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"branje sporočil oddaje v celici"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Omogoča aplikaciji branje sporočil oddaje v celici, ki jih prejme naprava. Opozorila oddaje v celici so dostavljena na nekaterih lokacijah, da vas opozorijo na izredne razmere. Zlonamerne aplikacije lahko vplivajo na delovanje naprave, ko dobi sporočilo oddaje v celici."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"branje naročenih virov"</string>
@@ -661,6 +665,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Aplikaciji omogoča branje in pisanje konfiguracije načina »ne moti«."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"začetek uporabe dovoljenja za ogledovanje"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Imetniku omogoča začetek uporabe dovoljenj za aplikacijo. Nikoli ni potrebno za navadne aplikacije."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"cilj bližnjice funkcije za ljudi s posebnimi potrebami"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Aplikaciji dovoljuje, da določi cilj bližnjice funkcije za ljudi s posebnimi potrebami."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavitev pravil za geslo"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Nadzor nad dolžino in znaki, ki so dovoljeni v geslih in kodah PIN za odklepanje zaslona."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Nadzor nad poskusi odklepanja zaslona"</string>
@@ -1405,6 +1411,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Način preizkusnega ogrodja je omogočen"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Če želite onemogočiti način preizkusnega ogrodja, ponastavite napravo na tovarniške nastavitve."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Serijska konzola je omogočena"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Učinkovitost delovanja je slabša. Uporabo konzole lahko onemogočite v zagonskem nalagalniku."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"V vratih USB je tekočina ali umazanija"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Vrata USB so samodejno onemogočena. Dotaknite se, če želite izvedeti več."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Vrata USB so varna za uporabo"</string>
@@ -1958,10 +1966,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Nekategorizirano"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Vi določite raven pomembnosti teh obvestil."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Pomembno zaradi udeleženih ljudi."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Ali aplikaciji <xliff:g id="APP">%1$s</xliff:g> dovolite, da ustvari novega uporabnika za račun <xliff:g id="ACCOUNT">%2$s</xliff:g> (uporabnik s tem računom že obstaja)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Ali aplikaciji <xliff:g id="APP">%1$s</xliff:g> dovolite, da ustvari novega uporabnika za račun <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Dodajanje jezika"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Nastavitev območja"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Vnesite ime jezika"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 48ae4d7..95359cc 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Lejon aplikacionin të marrë dhe përpunojë mesazhe SMS. Kjo do të thotë se aplikacioni mund të monitorojë ose fshijë mesazhe të dërguara në pajisjen tënde, pa t\'i treguar ato."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"prano mesazhe në tekst (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Lejon aplikacionin të marrë dhe përpunojë mesazhe MMS. Kjo do të thotë se aplikacioni mund të monitorojë ose fshijë mesazhe të dërguara në pajisjen tënde, pa t\'i treguar ato."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"lexo mesazhet e transmetimit të qelizës"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Lejon aplikacionin të lexojë mesazhet e transmetimit të qelizës, të marra nga pajisja jote. Alarmet e transmetimit të qelizës dërgohen në disa vendndodhje për të të paralajmëruar në situata urgjente. Aplikacionet keqdashëse mund të ndërhyjnë në veprimtarinë ose operacionin e pajisjes tënde kur merret një transmetim urgjent i qelizës."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lexo informacione të abonuara"</string>
@@ -549,7 +553,7 @@
<string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Shumë përpjekje. Sensori i gjurmës së gishtit u çaktivizua."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Provo përsëri."</string>
<string name="fingerprint_error_no_fingerprints" msgid="7654382120628334248">"Nuk ka asnjë gjurmë gishti të regjistruar."</string>
- <string name="fingerprint_error_hw_not_present" msgid="409523969613176352">"Kjo pajisje nuk ka një sensor të gjurmës së gishtit."</string>
+ <string name="fingerprint_error_hw_not_present" msgid="409523969613176352">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
<string name="fingerprint_name_template" msgid="5870957565512716938">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Lejon aplikacionin të lexojë dhe shkruajë konfigurimin e \"Mos shqetëso\"."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"nis përdorimin e lejes për shikimin"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Lejon që mbajtësi të nisë përdorimin e lejeve për një aplikacion. Nuk duhet të nevojitet asnjëherë për aplikacionet normale."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"objektivi i shkurtores së qasshmërisë"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Lejon që një aplikacion të përcaktojë objektivin e shkurtores së qasshmërisë."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Cakto rregullat e fjalëkalimit"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrollo gjatësinë dhe karakteret e lejuara në fjalëkalimet dhe kodet PIN të kyçjes së ekranit."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Monitoro tentativat e shkyçjes së ekranit"</string>
@@ -1357,11 +1363,13 @@
<string name="usb_power_notification_message" msgid="4647527153291917218">"Pajisja e lidhur po karikohet. Trokit për opsione të tjera."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"U zbulua aksesor i audios analoge"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Pajisja e bashkuar nuk është e pajtueshme me këtë telefon. Trokit për të mësuar më shumë."</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së është i lidhur"</string>
<string name="adb_active_notification_message" msgid="7463062450474107752">"Trokit për të çaktivizuar korrigjimin e USB-së"</string>
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Përzgjidhe për të çaktivizuar korrigjimin e gabimeve të USB-së"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Modaliteti i lidhjes së testimit është aktivizuar"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Kryej një rivendosje në cilësimet e fabrikës për të çaktivizuar \"Modalitetin e lidhjes së testimit\"."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Paneli komandues i serisë është aktivizuar"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Ndikohet cilësia e funksionimit. Për ta çaktivizuar, kontrollo ngarkuesin e sistemit."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Lëngje ose papastërti në portën e USB-së"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Porta e USB-së është çaktivizuar automatikisht. Trokit për të mësuar më shumë."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Në rregulloj për përdorimin e portës USB"</string>
@@ -1580,8 +1588,8 @@
<string name="expires_on" msgid="3676242949915959821">"Skadon më:"</string>
<string name="serial_number" msgid="758814067660862493">"Numri serik:"</string>
<string name="fingerprints" msgid="4516019619850763049">"Shenjat e gishtave:"</string>
- <string name="sha256_fingerprint" msgid="4391271286477279263">"Shenja e gishtit SHA-256:"</string>
- <string name="sha1_fingerprint" msgid="7930330235269404581">"Shenja e gishtit SHA-1:"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"Gjurma e gishtit SHA-256:"</string>
+ <string name="sha1_fingerprint" msgid="7930330235269404581">"Gjurma e gishtit SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Shikoji të gjitha"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Zgjidh aktivitetin"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Shpërnda publikisht me"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"E pakategorizuara"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Ke caktuar rëndësinë e këtyre njoftimeve."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Është i rëndësishëm për shkak të personave të përfshirë."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Të lejohet <xliff:g id="APP">%1$s</xliff:g> që të krijojë një përdorues të ri me <xliff:g id="ACCOUNT">%2$s</xliff:g> (një përdorues me këtë llogari ekziston tashmë) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Të lejohet <xliff:g id="APP">%1$s</xliff:g> që të krijojë një përdorues të ri me <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Shto një gjuhë"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Preferenca e rajonit"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Shkruaj emrin e gjuhës"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 75fc1ce..39ad5f4 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -27,7 +27,7 @@
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
- <string name="untitled" msgid="4638956954852782576">"<Без наслова>"</string>
+ <string name="untitled" msgid="4638956954852782576">"<Без имена>"</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Нема броја телефона)"</string>
<string name="unknownName" msgid="6867811765370350269">"Непознато"</string>
<string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Гласовна пошта"</string>
@@ -347,6 +347,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Дозвољава апликацији да прима и обрађује SMS поруке. То значи да апликација може да надгледа или брише поруке које се шаљу уређају, а да вам их не прикаже."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"пријем текстуалних порука (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Дозвољава апликацији да прима и обрађује MMS поруке. То значи да апликација може да надгледа или брише поруке које се шаљу уређају, а да вам их не прикаже."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"читање порука инфо сервиса"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Омогућава апликацији да чита поруке инфо сервиса које уређај прима. Упозорења инфо сервиса се на неким локацијама примају као упозорења на хитне случајеве. Злонамерне апликације могу да утичу на учинак или ометају функционисање уређаја када се прими порука инфо сервиса о хитном случају."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"читање пријављених фидова"</string>
@@ -658,6 +662,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Дозвољава апликацији да чита и уписује конфигурацију подешавања Не узнемиравај."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"почетак коришћења дозволе за преглед"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Дозвољава власнику да започне коришћење дозволе за апликацију. Никада не би требало да буде потребна за уобичајене апликације."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"циљ пречице за приступачност"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Дозвољава апликацији да дефинише циљ пречице за приступачност."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Контролише дужину и знакове дозвољене у лозинкама и PIN-овима за закључавање екрана."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Надгледајте покушаје откључавања екрана"</string>
@@ -1383,6 +1389,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Омогућен је режим пробног коришћења"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Обавите ресетовање на фабричка подешавања да бисте онемогућили режим пробног коришћења."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Серијска конзола је омогућена"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Учинак је смањен. Да бисте онемогући конзолу, проверите покретачки програм."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или нечистоћа у USB порту"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порт је аутоматски искључен. Додирните да бисте сазнали више."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Коришћење USB порта је дозвољено"</string>
@@ -1924,10 +1932,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Некатегоризовано"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Ви подешавате важност ових обавештења."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Ово је важно због људи који учествују."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Желите ли да дозволите да <xliff:g id="APP">%1$s</xliff:g> направи новог корисника са налогом <xliff:g id="ACCOUNT">%2$s</xliff:g> (корисник са тим налогом већ постоји)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Желите ли да дозволите да <xliff:g id="APP">%1$s</xliff:g> направи новог корисника са налогом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Додајте језик"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Подешавање региона"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Унесите назив језика"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index fdd0b7b..061d7b7 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Tillåter att appen tar emot och hanterar SMS. Detta innebär att appen kan övervaka eller ta bort meddelanden som skickats till enheten utan att visa dem för dig."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"ta emot textmeddelanden (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Tillåter att appen tar emot och hanterar MMS-meddelanden. Detta innebär att appen kan övervaka eller ta bort meddelanden som skickats till enheten utan att visa dem för dig."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"läsa SMS-meddelanden"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Appen tillåts läsa SMS som skickas till din enhet. På vissa platser skickas SMS för att varna för nödsituationer. Skadliga appar kan påverka enhetens prestanda eller funktionalitet när du får ett meddelande om en nödsituation via SMS."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"läsa flöden som du prenumererar på"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Ger appen läs- och skrivbehörighet till konfigurationen för Stör ej."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"börja visa behörighetsanvändningen"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Gör att innehavaren kan öppna behörighetsanvändning för en app. Ska inte behövas för vanliga appar."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"mål för Aktivera tillgänglighet snabbt"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Tillåter att en app kan definiera målet för Aktivera tillgänglighet snabbt."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Ange lösenordsregler"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Styr tillåten längd och tillåtna tecken i lösenord och pinkoder för skärmlåset."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Övervaka försök att låsa upp skärmen"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Välj för att inaktivera USB-felsökning."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Läget för testverktyg har aktiverats"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Inaktivera testverktygsläget genom att göra en återställning till standardinställningarna."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Seriekonsolen är aktiverad"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Prestandan påverkas. Inaktivera via starthanteraren."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Vätska eller smuts i USB-porten"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-porten har inaktiverats automatiskt. Tryck för att läsa mer."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Nu kan du använda USB-porten"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Okategoriserad"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Du anger hur viktiga aviseringarna är."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Detta är viktigt på grund av personerna som deltar."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Tillåter du att <xliff:g id="APP">%1$s</xliff:g> skapar en ny användare för <xliff:g id="ACCOUNT">%2$s</xliff:g> (det finns redan en användare med det här kontot)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Tillåter du att <xliff:g id="APP">%1$s</xliff:g> skapar en ny användare för <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Lägg till ett språk"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Regionsinställningar"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Ange språket"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index c8c582f..16df4e3 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Inaruhusu programu kupokea na kuchakata ujumbe wa SMS. Hii inamaanisha programu hii inaweza kuchunguza na kufuta ujumbe uliotumwa katika kifaa chako bila ya kukuonyesha."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"pokea ujumbe wa maandishi wa MMS"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Inaruhusu programu kupokea na kuchakata ujumbe medianwai (MMS). Hii inamaanisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwa kifaa chako bila ya kukuonyesha."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"soma mawasiliano ya matangazo ya simu"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Huruhusu programu kusoma mawasiliano ya matangazo ya simu yaliyoingia kwenye kifaa chako. Arifa za matangazo ya simu huwasilishwa katika maeneo mengine ili kukuonya juu ya hali za dharura. Huenda programu hasidi zikatatiza utendajikazi au shughuli ya kifaa chako wakati matangazo ya simu ya dharura yameingia."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"kusoma mipasho kutoka vyanzo unavyofuatilia"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Inaruhusu programu kusoma na kuandika usanidi wa kipengee cha Usinisumbue."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"anzisha kipengele cha kuona matumizi ya ruhusa"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Huruhusu kishikiliaji kuanzisha matumizi ya ruhusa ya programu. Haipaswi kuhitajika kwa ajili ya programu za kawaida."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"kulenga njia ya mkato ya ufikivu"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Huruhusu programu kubainisha ulengaji wa njia ya mkato ya ufikivu."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Kuweka kanuni za nenosiri"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Dhibiti urefu na maandishi yanayokubalika katika nenosiri la kufunga skrini na PIN."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Kuhesabu mara ambazo skrini inajaribu kufunguliwa"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chagua ili kulemaza utatuaji USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Hali ya Muunganisho wa Majaribio imewashwa"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Rejesha mipangilio iliyotoka nayo kiwandani ili uzime hali ya Muunganisho wa Majaribio."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Muunganisho kupitia mlango umewashwa"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Utendaji unaathirika. lli uzime, teua programu ya kuwasha mfumo wa uendeshaji."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Unyevu au uchafu katika mlango wa USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Mlango wa USB umezimwa kiotomatiki. Gusa ili upate maelezo zaidi."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ni sawa kutumia mlango wa USB"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Ambazo aina haijabainishwa"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Uliweka mipangilio ya umuhimu wa arifa hizi."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Hii ni muhimu kwa sababu ya watu waliohusika."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Ruhusu <xliff:g id="APP">%1$s</xliff:g> iweke Mtumiaji mpya ikitumia <xliff:g id="ACCOUNT">%2$s</xliff:g> (Je, tayari kuna mtumiaji anayetumia akaunti hii)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Ungependa kuruhusu <xliff:g id="APP">%1$s</xliff:g> iweke Mtumiaji mpya ikitumia <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Ongeza lugha"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Mapendeleo ya eneo"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Weka jina la lugha"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 0956aad..3b80a43 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -220,7 +220,7 @@
<string name="reboot_safemode_title" msgid="7054509914500140361">"பாதுகாப்பான பயன்முறைக்கு மீண்டும் தொடங்கவும்"</string>
<string name="reboot_safemode_confirm" msgid="55293944502784668">"பாதுகாப்பான பயன்முறைக்குச் செல்ல மீண்டும் துவக்க விரும்புகிறீர்களா? நீங்கள் நிறுவிய எல்லா மூன்றாம் தரப்பு பயன்பாடுகளையும் இது முடக்கும். நீங்கள் மீண்டும் மறுதொடக்கம் செய்யும்போது அவை மீட்டமைக்கப்படும்."</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"சமீபத்தியவை"</string>
- <string name="no_recent_tasks" msgid="8794906658732193473">"சமீபத்திய பயன்பாடுகள் எதுவுமில்லை."</string>
+ <string name="no_recent_tasks" msgid="8794906658732193473">"சமீபத்திய ஆப்ஸ் எதுவுமில்லை."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"டேப்லெட் விருப்பங்கள்"</string>
<string name="global_actions" product="tv" msgid="9091480417912345975">"Android TV விருப்பத்தேர்வுகள்"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"தொலைபேசி விருப்பங்கள்"</string>
@@ -271,7 +271,7 @@
<string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"ஆப்ஸ் இயங்குகிறது"</string>
<string name="notification_channel_foreground_service" msgid="3931987440602669158">"பேட்டரியைப் பயன்படுத்தும் ஆப்ஸ்"</string>
<string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகிறது"</string>
- <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> பயன்பாடுகள் பேட்டரியைப் பயன்படுத்துகின்றன"</string>
+ <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகின்றன"</string>
<string name="foreground_service_tap_for_details" msgid="372046743534354644">"பேட்டரி மற்றும் டேட்டா உபயோக விவரங்களைக் காண, தட்டவும்"</string>
<string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"பாதுகாப்பு பயன்முறை"</string>
@@ -344,12 +344,16 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS செய்திகளைப் பெற, செயற்படுத்தப் ஆப்ஸை அனுமதிக்கிறது. இதற்கு அர்த்தம் உங்கள் சாதனத்திற்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிப்பதற்கு அல்லது நீக்குவதற்கு ஆப்ஸால் முடியும் என்பதாகும்."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"உரைச் செய்திகளை (MMS) பெறுதல்"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS செய்திகளைப் பெற, செயற்படுத்தப் ஆப்ஸை அனுமதிக்கிறது. இதற்கு அர்த்தம் உங்கள் சாதனத்திற்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிக்கவோ, நீக்கவோ ஆப்ஸால் முடியும் என்பதாகும்."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"செல் அலைபரப்புச் செய்திகளைப் படித்தல்"</string>
- <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"உங்கள் சாதனத்தில் பெறப்படும் செல் அலைபரப்புச் செய்திகளைப் படிப்பதற்குப் ஆப்ஸை அனுமதிக்கிறது. அவசரநிலை சூழ்நிலைகளை உங்களுக்கு எச்சரிக்கைச் செய்வதற்கு சில இடங்களில் செல் அலைபரப்பு விழிப்பூட்டல்கள் வழங்கப்படும். அவசரநிலை மொபைல் அலைபரப்புப் பெறப்படும்போது உங்கள் சாதனத்தின் செயல்திறன் அல்லது செயல்பாட்டுடன் தீங்கிழைக்கும் பயன்பாடுகள் அதைத் தடுக்கலாம்."</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"உங்கள் சாதனத்தில் பெறப்படும் செல் அலைபரப்புச் செய்திகளைப் படிப்பதற்குப் ஆப்ஸை அனுமதிக்கிறது. அவசரநிலை சூழ்நிலைகளை உங்களுக்கு எச்சரிக்கைச் செய்வதற்கு சில இடங்களில் செல் அலைபரப்பு விழிப்பூட்டல்கள் வழங்கப்படும். அவசரநிலை மொபைல் அலைபரப்புப் பெறப்படும்போது உங்கள் சாதனத்தின் செயல்திறன் அல்லது செயல்பாட்டுடன் தீங்கிழைக்கும் ஆப்ஸ் அதைத் தடுக்கலாம்."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"குழுசேர்ந்த ஊட்டங்களைப் படித்தல்"</string>
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"தற்போது ஒத்திசைந்த ஊட்டங்களைப் பற்றிய விவரங்களைப் பெற ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_sendSms" msgid="7544599214260982981">"SMS செய்திகளை அனுப்புதல் மற்றும் பார்த்தல்"</string>
- <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS செய்திகளை அனுப்ப ஆப்ஸை அனுமதிக்கிறது. இதற்கு எதிர்பாராத பேமெண்ட்கள் விதிக்கப்படலாம். தீங்கு விளைவிக்கும் பயன்பாடுகள் உங்களின் உறுதிப்படுத்தல் எதுவுமின்றி செய்திகளை அனுப்பி உங்களுக்குக் கட்டணம் விதிக்கலாம்."</string>
+ <string name="permdesc_sendSms" msgid="7094729298204937667">"SMS செய்திகளை அனுப்ப ஆப்ஸை அனுமதிக்கிறது. இதற்கு எதிர்பாராத பேமெண்ட்கள் விதிக்கப்படலாம். தீங்கு விளைவிக்கும் ஆப்ஸ் உங்களின் உறுதிப்படுத்தல் எதுவுமின்றி செய்திகளை அனுப்பி உங்களுக்குக் கட்டணம் விதிக்கலாம்."</string>
<string name="permlab_readSms" msgid="8745086572213270480">"உங்கள் உரைச் செய்திகளை (SMS அல்லது MMS) படித்தல்"</string>
<string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"இந்த ஆப்ஸ் உங்கள் டேப்லெட்டில் சேமிக்கப்பட்டுள்ள எல்லா SMS (உரை) செய்திகளையும் படிக்கலாம்."</string>
<string name="permdesc_readSms" product="tv" msgid="9106832390302749856">"உங்கள் Android TVயில் சேமித்துள்ள அனைத்து மெசேஜ்களையும் இந்த ஆப்ஸால் தெரிந்துகொள்ள முடியும்."</string>
@@ -357,7 +361,7 @@
<string name="permlab_receiveWapPush" msgid="5991398711936590410">"உரைச் செய்திகளைப் (WAP) பெறுதல்"</string>
<string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP செய்திகளைப் பெற, செயற்படுத்தப் ஆப்ஸை அனுமதிக்கிறது. உங்களுக்கு அனுப்பப்படும் செய்திகளை உங்களுக்குக் காட்டாமல் கண்காணிக்க அல்லது நீக்குவதற்கான திறன் இந்த அனுமதியில் உள்ளடங்கும்."</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"இயங்கும் ஆப்ஸை மீட்டெடுத்தல்"</string>
- <string name="permdesc_getTasks" msgid="7454215995847658102">"நடப்பில் மற்றும் சமீபத்தில் இயங்கும் காரியங்களின் தகவலைப் பெற ஆப்ஸை அனுமதிக்கிறது. சாதனத்தில் எந்தப் பயன்பாடுகள் பயன்படுத்தப்படுகின்றன என்பது குறித்த தகவலைக் கண்டறிய ஆப்ஸை இது அனுமதிக்கலாம்."</string>
+ <string name="permdesc_getTasks" msgid="7454215995847658102">"நடப்பில் மற்றும் சமீபத்தில் இயங்கும் காரியங்களின் தகவலைப் பெற ஆப்ஸை அனுமதிக்கிறது. சாதனத்தில் எந்த ஆப்ஸ் பயன்படுத்தப்படுகின்றன என்பது குறித்த தகவலைக் கண்டறிய ஆப்ஸை இது அனுமதிக்கலாம்."</string>
<string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"சுயவிவரத்தையும் சாதன உரிமையாளர்களையும் நிர்வகித்தல்"</string>
<string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"சுயவிவர உரிமையாளர்களையும் சாதன உரிமையாளரையும் அமைக்க, ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"இயங்கும் ஆப்ஸை மறுவரிசைப்படுத்தல்"</string>
@@ -365,9 +369,9 @@
<string name="permlab_enableCarMode" msgid="5684504058192921098">"கார் பயன்முறையை இயக்குதல்"</string>
<string name="permdesc_enableCarMode" msgid="4853187425751419467">"கார் முறையை இயக்க, ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"பிற ஆப்ஸை மூடுதல்"</string>
- <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"பிற ஆப்ஸின் பின்புலச் செயல்முறைகளை நிறுத்த ஆப்ஸை அனுமதிக்கிறது. இதனால் பிற பயன்பாடுகள் இயங்குவதை நிறுத்தலாம்."</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"பிற ஆப்ஸின் பின்புலச் செயல்முறைகளை நிறுத்த ஆப்ஸை அனுமதிக்கிறது. இதனால் பிற ஆப்ஸ் இயங்குவதை நிறுத்தலாம்."</string>
<string name="permlab_systemAlertWindow" msgid="7238805243128138690">"இந்த ஆப்ஸ் பிற ஆப்ஸின் மேலே தோன்றலாம்"</string>
- <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"இந்த ஆப்ஸ் பிற ஆப்ஸின் மேலே அல்லது திரையின் பிற பகுதிகளில் தோன்றலாம். இது வழக்கமான ஆப்ஸ் உபயோகத்தில் குறுக்கிட்டு, பிற பயன்பாடுகள் தோன்றும் விதத்தை மாற்றக்கூடும்."</string>
+ <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"இந்த ஆப்ஸ் பிற ஆப்ஸின் மேலே அல்லது திரையின் பிற பகுதிகளில் தோன்றலாம். இது வழக்கமான ஆப்ஸ் உபயோகத்தில் குறுக்கிட்டு, பிற ஆப்ஸ் தோன்றும் விதத்தை மாற்றக்கூடும்."</string>
<string name="permlab_runInBackground" msgid="7365290743781858803">"பின்னணியில் இயக்கு"</string>
<string name="permdesc_runInBackground" msgid="7370142232209999824">"இந்த ஆப்ஸ், பின்னணியில் இயங்கலாம். இதனால் பேட்டரி விரைவாகத் தீர்ந்துவிடக்கூடும்."</string>
<string name="permlab_useDataInBackground" msgid="8694951340794341809">"பின்னணியில் தரவைப் பயன்படுத்து"</string>
@@ -381,7 +385,7 @@
<string name="permlab_getPackageSize" msgid="7472921768357981986">"பயன்பாட்டுச் சேமிப்பு இடத்தை அளவிடல்"</string>
<string name="permdesc_getPackageSize" msgid="3921068154420738296">"ஆப்ஸ், அதன் குறியீடு, தரவு, மற்றும் தற்காலிகச் சேமிப்பு அளவுகளை மீட்டெடுக்க அனுமதிக்கிறது"</string>
<string name="permlab_writeSettings" msgid="2226195290955224730">"சாதன அமைப்புகளை மாற்றுதல்"</string>
- <string name="permdesc_writeSettings" msgid="7775723441558907181">"முறைமையின் அமைப்பு தரவைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. தீங்குவிளைவிக்கும் பயன்பாடுகள், முறைமையின் உள்ளமைவைச் சிதைக்கலாம்."</string>
+ <string name="permdesc_writeSettings" msgid="7775723441558907181">"முறைமையின் அமைப்பு தரவைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. தீங்குவிளைவிக்கும் ஆப்ஸ், முறைமையின் உள்ளமைவைச் சிதைக்கலாம்."</string>
<string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"தொடக்கத்தில் இயக்குதல்"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"மறுஇயக்கம் முடிந்தது, விரைவில் தானாகவே தொடங்க, ஆப்ஸை அனுமதிக்கிறது. இதனால் டேப்லெட் நீண்ட நேரம் கழித்து தொடங்கும் மற்றும் எப்போதும் இயங்குகின்ற டேப்லெட்டின் ஒட்டுமொத்தச் செயல்பாட்டையும் தாமதமாகும்."</string>
<string name="permdesc_receiveBootCompleted" product="tv" msgid="6725487837446317527">"சாதனம் தொடங்கியவுடன் ஆப்ஸைத் தானாகவே தொடங்க அனுமதிக்கும். இது Android TV தொடங்குவதற்கான நேரத்தைத் தாமதமாக்குவதோடு எப்போதும் இயங்கிக்கொண்டிருப்பதன் மூலம் ஒட்டுமொத்த சாதனத்தின் வேகத்தைக் குறைக்கும்."</string>
@@ -391,9 +395,9 @@
<string name="permdesc_broadcastSticky" product="tv" msgid="5029460344724532288">"வலைபரப்பு முடிந்த பின்னரும் தங்கிவிடும் ஸ்டிக்கி வலைபரப்புகளை அனுப்ப ஆப்ஸை அனுமதிக்கும். அளவுக்கதிகமான உபயோகம் Android TVயின் வேகத்தைக் குறைக்கவோ நிலையற்றதாகவோ ஆக்கக்கூடும். இதனால் அதிகமான நினைவகம் பயன்படுத்தப்படும்."</string>
<string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"அலைபரப்பு முடிந்த பின்னும் இருக்கும், தொடர்ந்து அணுகத்தக்க அலைபரப்பை அனுப்பப் ஆப்ஸை அனுமதிக்கிறது. அதிகமாகப் பயன்படுத்தினால், மொபைலானது நினைவகத்தை மிக அதிகமாகப் பயன்படுத்துவதால் வேகம் குறைந்ததாகவும், நிலையற்றதாகவும் ஆகலாம்."</string>
<string name="permlab_readContacts" msgid="8348481131899886131">"உங்கள் தொடர்புகளைப் படித்தல்"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உட்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் பயன்பாடுகள் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உட்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string>
<string name="permdesc_readContacts" product="tv" msgid="3890061004911027912">"உங்கள் Android TVயில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவைத் தெரிந்துகொள்ள ஆப்ஸை அனுமதிக்கும். குறிப்பிட்ட தனிநபரை எத்தனை முறை அழைத்தீர்கள், பிறவழிகளில் தொடர்புகொண்டீர்கள் அல்லது அவருக்கு எத்தனை முறை மின்னஞ்சல் அனுப்பினீர்கள் என்பதும் இதில் அடங்கும். இது உங்கள் தொடர்புத் தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கும், அத்துடன் தீங்குவிளைவிக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்புத் தரவைப் பகிரக்கூடும்."</string>
- <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்ட எண்ணிக்கை உட்பட, உங்கள் மொபைலில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் பயன்பாடுகள் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string>
+ <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"குறிப்பிட்டவர்களுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்ட எண்ணிக்கை உட்பட, உங்கள் மொபைலில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைப் படிக்க ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதி, உங்கள் தொடர்பு தரவைச் சேமிக்க ஆப்ஸை அனுமதிக்கிறது, மேலும் தீங்கிழைக்கும் ஆப்ஸ் உங்களுக்குத் தெரியாமல் தொடர்பு தரவைப் பகிரலாம்."</string>
<string name="permlab_writeContacts" msgid="5107492086416793544">"உங்கள் தொடர்புகளை மாற்றுதல்"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"குறிப்பிட்ட தொடர்புகளுடன் நீங்கள் அழைத்த, மின்னஞ்சல் அனுப்பிய அல்லது வேறு வழியில் தொடர்புகொண்டதின் எண்ணிக்கை உள்பட, உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உங்கள் தொடர்புகள் குறித்த தரவைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இந்த அனுமதியானது தொடர்புத் தரவை நீக்க ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permdesc_writeContacts" product="tv" msgid="307929337692573341">"உங்கள் Android TVயில் சேமித்துள்ள தொடர்புகள் பற்றிய தரவை மாற்ற ஆப்ஸை அனுமதிக்கும். குறிப்பிட்ட தொடர்பை எத்தனை முறை அழைத்தீர்கள், பிறவழிகளில் தொடர்புகொண்டீர்கள் அல்லது அவருக்கு எத்தனை முறை மின்னஞ்சல் அனுப்பினீர்கள் என்பதும் இதில் அடங்கும். தொடர்புத் தரவை நீக்க ஆப்ஸை இது அனுமதிக்கும்."</string>
@@ -401,9 +405,9 @@
<string name="permlab_readCallLog" msgid="3478133184624102739">"அழைப்புப் பதிவைப் படித்தல்"</string>
<string name="permdesc_readCallLog" msgid="3204122446463552146">"இந்த ஆப்ஸ் உங்கள் அழைப்பு வரலாற்றைப் படிக்கலாம்."</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"அழைப்புப் பதிவை எழுதுதல்"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் டேப்லெட்டின் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் டேப்லெட்டின் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="7939219462637746280">"உள்வரும், வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உட்பட உங்கள் Android TVயின் அழைப்புப் பதிவைத் திருத்த ஆப்ஸை அனுமதிக்கும். உங்கள் அழைப்புப் பதிவை அழிக்கவோ திருத்தவோ தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தக்கூடும்."</string>
- <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் மொபைல் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
+ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"உள்வரும் மற்றும் வெளிச்செல்லும் அழைப்புகள் குறித்த தகவல் உள்பட உங்கள் மொபைல் அழைப்புப் பதிவைத் திருத்துவதற்குப் ஆப்ஸை அனுமதிக்கிறது. உங்கள் அழைப்பின் பதிவை அழிக்க அல்லது திருத்த தீங்கு விளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string>
<string name="permlab_bodySensors" msgid="4683341291818520277">"உடல் உணர்விகளை (இதயத் துடிப்பு மானிட்டர்கள் போன்றவை) அணுகுதல்"</string>
<string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"உங்கள் இதயத்துடிப்பு விகிதம் போன்ற உங்கள் உடல்நிலையைக் கண்காணிக்கும் உணர்விகளில் இருந்து தரவை அணுக ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_readCalendar" msgid="6716116972752441641">"கேலெண்டர் நிகழ்வுகளையும் விவரங்களையும் படிக்கலாம்"</string>
@@ -439,7 +443,7 @@
<string name="permlab_vibrate" msgid="7696427026057705834">"அதிர்வைக் கட்டுப்படுத்துதல்"</string>
<string name="permdesc_vibrate" msgid="6284989245902300945">"அதிர்வைக் கட்டுப்படுத்தப் ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"தொலைபேசி எண்களை நேரடியாக அழைத்தல்"</string>
- <string name="permdesc_callPhone" msgid="3740797576113760827">"உங்கள் தலையீட்டின்றி மொபைல் எண்களை அழைக்கப் ஆப்ஸை அனுமதிக்கிறது. இதன் விளைவாக எதிர்பாராத கட்டணங்களோ அழைப்புகளோ ஏற்படலாம். அவசரகால எண்களை அழைக்க இது ஆப்ஸை அனுமதிக்காது என்பதை நினைவில்கொள்ளவும். தீங்கிழைக்கும் பயன்பாடுகள், உங்கள் உறுதிப்படுத்தல் இன்றி அழைப்புகளைச் செய்வதால் உங்களுக்குச் செலவு ஏற்படக்கூடும்."</string>
+ <string name="permdesc_callPhone" msgid="3740797576113760827">"உங்கள் தலையீட்டின்றி மொபைல் எண்களை அழைக்கப் ஆப்ஸை அனுமதிக்கிறது. இதன் விளைவாக எதிர்பாராத கட்டணங்களோ அழைப்புகளோ ஏற்படலாம். அவசரகால எண்களை அழைக்க இது ஆப்ஸை அனுமதிக்காது என்பதை நினைவில்கொள்ளவும். தீங்கிழைக்கும் ஆப்ஸ், உங்கள் உறுதிப்படுத்தல் இன்றி அழைப்புகளைச் செய்வதால் உங்களுக்குச் செலவு ஏற்படக்கூடும்."</string>
<string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS அழைப்புச் சேவையை அணுகுதல்"</string>
<string name="permdesc_accessImsCallService" msgid="8992884015198298775">"உங்கள் குறுக்கீடின்றி IMS சேவையைப் பயன்படுத்தி அழைப்பதற்கு, ஆப்ஸை அனுமதிக்கும்."</string>
<string name="permlab_readPhoneState" msgid="9178228524507610486">"மொபைல் நிலை மற்றும் அடையாளத்தைப் படித்தல்"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"தொந்தரவு செய்ய வேண்டாம் உள்ளமைவைப் படிக்கவும் எழுதவும், ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"அனுமதி உபயோகத்தை அணுகுதல்"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"ஆப்ஸிற்கான அனுமதி உபயோகத்தை ஹோல்டருக்கு வழங்கும். இயல்பான ஆப்ஸிற்கு இது எப்போதுமே தேவைப்படாது."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"அணுகலம்ச ஷார்ட்கட் இலக்கு"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"அணுகலம்ச ஷார்ட்கட் இலக்கை விளக்க ஆப்ஸை அனுமதிக்கும்."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"கடவுச்சொல் விதிகளை அமைக்கவும்"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"திரைப் பூட்டின் கடவுச்சொற்கள் மற்றும் பின்களில் அனுமதிக்கப்படும் நீளத்தையும் எழுத்துக்குறிகளையும் கட்டுப்படுத்தும்."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"திரையைத் திறப்பதற்கான முயற்சிகளைக் கண்காணி"</string>
@@ -939,15 +945,15 @@
<string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"உங்கள் இணையப் புத்தக்கக்குறிகள் மற்றும் வரலாற்றைப் படித்தல்"</string>
<string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"உலாவி மூலம் பார்வையிட்ட எல்லா URLகளின் வரலாற்றையும், உலாவியில் குறிக்கப்பட்ட எல்லா புத்தகக்குறிகளையும் படிக்கப் ஆப்ஸை அனுமதிக்கிறது. குறிப்பு: மூன்றாம் தரப்பு உலாவிகள் அல்லது இணைய உலாவல் திறன்களுடன் கூடிய பிற பயன்பாடுகளால் இந்த அனுமதி செயற்படுத்தப்படாமல் போகலாம்."</string>
<string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"இணையப் புத்தகக்குறிகளையும், வரலாற்றையும் எழுதுதல்"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற பயன்பாடுகள் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"உங்கள் டேப்லெட்டில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற ஆப்ஸ் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string>
<string name="permdesc_writeHistoryBookmarks" product="tv" msgid="6340829212433680418">"Android TVயில் சேமித்துள்ள உலாவியின் மூலம் பார்க்கப்பட்ட தளங்களையோ புக்மார்க்குகளையோ திருத்த ஆப்ஸை அனுமதிக்கும். இது உலாவியின் தரவை அழிக்கவோ திருத்தவோ ஆப்ஸை அனுமதிக்கக்கூடும். கவனத்திற்கு: மூன்றாம் தரப்பு உலாவிகளோ இணைய உலாவல் திறன்களுடன் கூடிய பிற ஆப்ஸோ இந்த அனுமதியைச் செயல்படுத்த முடியாது."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"உங்கள் மொபைலில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற பயன்பாடுகள் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"உங்கள் மொபைலில் சேமிக்கப்பட்ட உலாவியின் வரலாறு அல்லது புத்தகக்குறிகளைத் திருத்த ஆப்ஸை அனுமதிக்கிறது. இது உலாவியின் தரவை அழிக்கவோ, திருத்தவோ ஆப்ஸை அனுமதிக்கலாம். குறிப்பு: இணைய உலாவல் செயல்திறன்கள் மூலம் மூன்றாம் தரப்பு உலாவிகள் அல்லது பிற ஆப்ஸ் இந்த அனுமதியைச் செயற்படுத்த முடியாது."</string>
<string name="permlab_setAlarm" msgid="1379294556362091814">"அலாரத்தை அமைத்தல்"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"நிறுவிய அலார கடிகாரப் பயன்பாட்டில் அலாரத்தை அமைக்க, ஆப்ஸை அனுமதிக்கிறது. சில அலார கடிகார பயன்பாடுகளில் இந்த அம்சம் இல்லாமல் இருக்கலாம்."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"குரலஞ்சலைச் சேர்த்தல்"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"குரலஞ்சல் இன்பாக்ஸில் செய்திகளைச் சேர்க்க, ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்துதல்"</string>
- <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. இடத் தகவலை தன்னிச்சையான இணையதளங்களுக்கு அனுப்புவதை அனுமதிக்க, தீங்குவிளைவிக்கும் பயன்பாடுகள் இதைப் பயன்படுத்தலாம்."</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"உலாவியின் புவியியல் இருப்பிடம் சார்ந்த அனுமதிகளைத் திருத்த, ஆப்ஸை அனுமதிக்கிறது. இடத் தகவலை தன்னிச்சையான இணையதளங்களுக்கு அனுப்புவதை அனுமதிக்க, தீங்குவிளைவிக்கும் ஆப்ஸ் இதைப் பயன்படுத்தலாம்."</string>
<string name="save_password_message" msgid="767344687139195790">"இந்தக் கடவுச்சொல்லை உலாவி நினைவில்கொள்ள விரும்புகிறீர்களா?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"இப்போது இல்லை"</string>
<string name="save_password_remember" msgid="6491879678996749466">"நினைவில்கொள்"</string>
@@ -1156,10 +1162,10 @@
<string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"படமெடு"</string>
<string name="alwaysUse" msgid="4583018368000610438">"இந்தச் செயலுக்கு இயல்பாகப் பயன்படுத்து."</string>
<string name="use_a_different_app" msgid="8134926230585710243">"வேறு ஆப்ஸைப் பயன்படுத்தவும்"</string>
- <string name="clearDefaultHintMsg" msgid="3252584689512077257">"முறைமை அமைப்பு > பயன்பாடுகள் > பதிவிறக்கியவை என்பதில் உள்ள இயல்பை அழிக்கவும்."</string>
+ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"முறைமை அமைப்பு > ஆப்ஸ் > பதிவிறக்கியவை என்பதில் உள்ள இயல்பை அழிக்கவும்."</string>
<string name="chooseActivity" msgid="7486876147751803333">"செயலைத் தேர்ந்தெடுக்கவும்"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"USB சாதனத்திற்கான பயன்பாட்டைத் தேர்வுசெய்க"</string>
- <string name="noApplications" msgid="2991814273936504689">"இந்தச் செயலைச் செய்ய பயன்பாடுகள் எதுவுமில்லை."</string>
+ <string name="noApplications" msgid="2991814273936504689">"இந்தச் செயலைச் செய்ய ஆப்ஸ் எதுவுமில்லை."</string>
<string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> செயலிழந்தது"</string>
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> செயலிழந்தது"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> தொடர்ந்து செயலிழக்கிறது"</string>
@@ -1184,7 +1190,7 @@
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> உண்மையாக வெளியிடப்பட்டது."</string>
<string name="screen_compat_mode_scale" msgid="3202955667675944499">"அளவு"</string>
<string name="screen_compat_mode_show" msgid="4013878876486655892">"எப்போதும் காட்டு"</string>
- <string name="screen_compat_mode_hint" msgid="1064524084543304459">"சிஸ்டம் அமைப்பு > பயன்பாடுகள் > பதிவிறக்கம் என்பதில் இதை மீண்டும் இயக்கவும்."</string>
+ <string name="screen_compat_mode_hint" msgid="1064524084543304459">"சிஸ்டம் அமைப்பு > ஆப்ஸ் > பதிவிறக்கம் என்பதில் இதை மீண்டும் இயக்கவும்."</string>
<string name="unsupported_display_size_message" msgid="6545327290756295232">"தற்போதைய திரை அளவு அமைப்பை <xliff:g id="APP_NAME">%1$s</xliff:g> ஆதரிக்காததால், அது வழக்கத்திற்கு மாறாகச் செயல்படக்கூடும்."</string>
<string name="unsupported_display_size_show" msgid="7969129195360353041">"எப்போதும் காட்டு"</string>
<string name="unsupported_compile_sdk_message" msgid="4253168368781441759">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாடானது, இந்தச் சாதனத்தின் Android OSக்கு இணக்கமற்ற பதிப்பிற்காக உருவாக்கப்பட்டதால், இதில் சரியாகச் செயல்படாது. இந்த ஆப்ஸின் புதுப்பிக்கப்பட்ட பதிப்பானது தற்போது கிடைக்கக்கூடும்."</string>
@@ -1204,7 +1210,7 @@
<string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g>ஐ மேம்படுத்துகிறது…"</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_0">%1$d</xliff:g> / <xliff:g id="NUMBER_1">%2$d</xliff:g> ஆப்ஸை ஒருங்கிணைக்கிறது."</string>
<string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g>ஐத் தயார்செய்கிறது."</string>
- <string name="android_upgrading_starting_apps" msgid="451464516346926713">"பயன்பாடுகள் தொடங்கப்படுகின்றன."</string>
+ <string name="android_upgrading_starting_apps" msgid="451464516346926713">"ஆப்ஸ் தொடங்கப்படுகின்றன."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"துவக்குதலை முடிக்கிறது."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> இயங்குகிறது"</string>
<string name="heavy_weight_notification_detail" msgid="2304833848484424985">"கேமிற்குச் செல்ல, தட்டவும்"</string>
@@ -1322,7 +1328,7 @@
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"அனுப்பு"</string>
<string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ரத்துசெய்"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"எனது விருப்பத்தேர்வை நினைவில்கொள்"</string>
- <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"அமைப்பு > பயன்பாடுகள் என்பதில் பிறகு நீங்கள் மாற்றலாம்"</string>
+ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"அமைப்பு > ஆப்ஸ் என்பதில் பிறகு நீங்கள் மாற்றலாம்"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"எப்போதும் அனுமதி"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"ஒருபோதும் அனுமதிக்காதே"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"சிம் கார்டு அகற்றப்பட்டது"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB பிழைதிருத்தத்தை முடக்க, தேர்ந்தெடுக்கவும்."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"\'தன்னியக்க சோதனைப்\' பயன்முறை இயக்கப்பட்டது"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"’தன்னியக்க சோதனைப்\' பயன்முறையை முடக்க ஆரம்பநிலைக்கு மீட்டமைக்கவும்."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"சீரியல் கன்சோல் இயக்கப்பட்டது"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"செயல்திறன் பாதிக்கப்பட்டுள்ளது. முடக்குவதற்கு பூட்லோடரைத் தேர்வுசெய்யவும்."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB போர்ட்டில் சேதம் உள்ளது"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB போர்ட் தானாகவே முடக்கப்பட்டது மேலும் அறிய, தட்டவும்."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB போர்ட்டைப் பயன்படுத்தலாம்"</string>
@@ -1446,7 +1454,7 @@
<string name="ime_action_default" msgid="2840921885558045721">"செயலாக்கு"</string>
<string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> ஐப் பயன்படுத்தி\nஅழை"</string>
<string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g> ஐப்\nபயன்படுத்தி தொடர்பை உருவாக்கு"</string>
- <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"பின்வரும் ஒன்று அல்லது அதற்கு மேற்பட்ட பயன்பாடுகள், இப்போதும் எதிர்காலத்திலும் உங்கள் கணக்கை அணுகுவதற்கான அனுமதியைக் கோருகின்றன."</string>
+ <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"பின்வரும் ஒன்று அல்லது அதற்கு மேற்பட்ட ஆப்ஸ், இப்போதும் எதிர்காலத்திலும் உங்கள் கணக்கை அணுகுவதற்கான அனுமதியைக் கோருகின்றன."</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"இந்தக் கோரிக்கையை அனுமதிக்க விரும்புகிறீர்களா?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"அணுகல் கோரிக்கை"</string>
<string name="allow" msgid="7225948811296386551">"அனுமதி"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"வகைப்படுத்தப்படாதவை"</string>
<string name="importance_from_user" msgid="7318955817386549931">"இந்த அறிவிப்புகளின் முக்கியத்துவத்தை அமைத்துள்ளீர்கள்."</string>
<string name="importance_from_person" msgid="9160133597262938296">"ஈடுபட்டுள்ளவர்களின் காரணமாக, இது முக்கியமானது."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g> மூலம் புதிய பயனரை உருவாக்க <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா (இந்தக் கணக்கில் ஏற்கெனவே ஒரு பயனர் உள்ளார்) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> மூலம் புதிய பயனரை உருவாக்க <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"மொழியைச் சேர்"</string>
<string name="country_selection_title" msgid="2954859441620215513">"மண்டல விருப்பம்"</string>
<string name="search_language_hint" msgid="7042102592055108574">"மொழி பெயரை உள்ளிடுக"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index a8550f8..37e0590 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"SMS సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి యాప్ను అనుమతిస్తుంది. యాప్ మీ డివైజ్కు పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగలదని లేదా తొలగించగలదని దీని అర్థం."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"వచన సందేశాలను (MMS) స్వీకరించడం"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"MMS సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి యాప్ను అనుమతిస్తుంది. యాప్ మీ డివైజ్కు పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగలదని లేదా తొలగించగలదని దీని అర్థం."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"సెల్ ప్రసార సందేశాలను చదవడం"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"మీ పరికరం స్వీకరించిన సెల్ ప్రసార సందేశాలను చదవడానికి యాప్ను అనుమతిస్తుంది. సెల్ ప్రసార హెచ్చరికలు అత్యవసర పరిస్థితుల గురించి మిమ్మల్ని హెచ్చరించడానికి కొన్ని స్థానాల్లో అందించబడతాయి. అత్యవసర సెల్ ప్రసారం స్వీకరించినప్పుడు హానికరమైన యాప్లు మీ పరికరం యొక్క పనితీరు లేదా నిర్వహణకు అంతరాయం కలిగించవచ్చు."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"చందా చేయబడిన ఫీడ్లను చదవడం"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"అంతరాయం కలిగించవద్దు ఎంపిక కాన్ఫిగరేషన్ చదవడానికి మరియు వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"వీక్షణ అనుమతి వినియోగాన్ని ప్రారంభించండి"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"యాప్నకు అనుమతి వినియోగాన్ని ప్రారంభించడానికి హోల్డర్ను అనుమతిస్తుంది. సాధారణ యాప్లకు ఎప్పటికీ ఇటువంటి అనుమతి అవసరం ఉండదు."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"యాక్సెసిబిలిటీ షార్ట్కట్ లక్ష్యం"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"యాక్సెసిబిలిటీ షార్ట్కట్ లక్ష్యాన్ని నిర్వచించడానికి యాప్ను అనుమతించండి."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"పాస్వర్డ్ నియమాలను సెట్ చేయండి"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"స్క్రీన్ లాక్ పాస్వర్డ్లు మరియు PINల్లో అనుమతించబడిన పొడవు మరియు అక్షరాలను నియంత్రిస్తుంది."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"స్క్రీన్ అన్లాక్ ప్రయత్నాలను పర్యవేక్షించండి"</string>
@@ -1330,7 +1336,7 @@
<string name="sim_done_button" msgid="827949989369963775">"పూర్తయింది"</string>
<string name="sim_added_title" msgid="3719670512889674693">"సిమ్ కార్డు జోడించబడింది"</string>
<string name="sim_added_message" msgid="6599945301141050216">"మొబైల్ నెట్వర్క్ను యాక్సెస్ చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string>
- <string name="sim_restart_button" msgid="4722407842815232347">"పునఃప్రారంభించు"</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"రీస్టార్ట్ చేయి"</string>
<string name="install_carrier_app_notification_title" msgid="9056007111024059888">"మొబైల్ సేవను సక్రియం చేయండి"</string>
<string name="install_carrier_app_notification_text" msgid="3346681446158696001">"మీ కొత్త SIMని సక్రియం చేయడానికి క్యారియర్ యాప్ను డౌన్లోడ్ చేయండి"</string>
<string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"మీ కొత్త SIMని సక్రియం చేయడం కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> యాప్ని డౌన్లోడ్ చేయండి"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"డీబగ్గింగ్ని నిలిపివేయడానికి ఎంచుకోండి."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"పరీక్ష నియంత్రణ మోడ్ ప్రారంభించబడింది"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"పరీక్ష నియంత్రణ మోడ్ను నిలిపివేయడానికి ఫ్యాక్టరీ రీసెట్ను అమలు చేయండి."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"సీరియల్ కన్సోల్ ప్రారంభించబడింది"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"పని తీరు ప్రభావితమైంది. నిలిపివేయడానికి, బూట్లోడర్ను తనిఖీ చేయండి."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB పోర్ట్లో ద్రవ లేదా వ్యర్థ పదార్థాలు ఉన్నాయి"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB పోర్ట్ ఆటోమేటిక్గా నిలిపివేయబడింది. మరింత తెలుసుకోవడానికి నొక్కండి."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB పోర్ట్ను ఉపయోగించడం సురక్షితం"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"వర్గీకరించబడలేదు"</string>
<string name="importance_from_user" msgid="7318955817386549931">"మీరు ఈ నోటిఫికేషన్ల ప్రాముఖ్యతను సెట్ చేసారు."</string>
<string name="importance_from_person" msgid="9160133597262938296">"ఇందులో పేర్కొనబడిన వ్యక్తులను బట్టి ఇది చాలా ముఖ్యమైనది."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని సృష్టించడానికి <xliff:g id="APP">%1$s</xliff:g>ను అనుమతించాలా (ఈ ఖాతాతో ఇప్పటికే ఒక వినియోగదారు ఉన్నారు) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g>తో కొత్త వినియోగదారుని సృష్టించడానికి <xliff:g id="APP">%1$s</xliff:g>ను అనుమతించాలా?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"భాషను జోడించండి"</string>
<string name="country_selection_title" msgid="2954859441620215513">"ప్రాంతం ప్రాధాన్యత"</string>
<string name="search_language_hint" msgid="7042102592055108574">"భాష పేరును టైప్ చేయండి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f2376d7..482288e 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -283,7 +283,7 @@
<string name="permgrouprequest_contacts" msgid="6032805601881764300">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงรายชื่อติดต่อไหม"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"ตำแหน่ง"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"เข้าถึงตำแหน่งของอุปกรณ์นี้"</string>
- <string name="permgrouprequest_location" msgid="3788275734953323491">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงตำแหน่งของอุปกรณ์นี้ไหม"</string>
+ <string name="permgrouprequest_location" msgid="3788275734953323491">"อนุญาตให้<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>เข้าถึงตำแหน่งของอุปกรณ์นี้ไหม"</string>
<string name="permgrouprequestdetail_location" msgid="1347189607421252902">"แอปจะมีสิทธิ์เข้าถึงตำแหน่งในขณะที่คุณใช้แอปเท่านั้น"</string>
<string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงตำแหน่งของอุปกรณ์นี้<b>ตลอดเวลา</b>ไหม"</string>
<string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"ปัจจุบันแอปมีสิทธิ์เข้าถึงตำแหน่งในขณะที่คุณใช้แอปเท่านั้น"</string>
@@ -298,7 +298,7 @@
<string name="permgrouprequest_storage" msgid="7885942926944299560">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงรูปภาพ สื่อ และไฟล์ในอุปกรณ์ไหม"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ไมโครโฟน"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"บันทึกเสียง"</string>
- <string name="permgrouprequest_microphone" msgid="9167492350681916038">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> บันทึกเสียงไหม"</string>
+ <string name="permgrouprequest_microphone" msgid="9167492350681916038">"อนุญาตให้<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>บันทึกเสียงไหม"</string>
<string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"การเคลื่อนไหวร่างกาย"</string>
<string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"เข้าถึงกิจกรรมการเคลื่อนไหวร่างกายของคุณ"</string>
<string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึงกิจกรรมการเคลื่อนไหวร่างกายของคุณไหม"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"อนุญาตให้แอปพลิเคชันรับและประมวลผลข้อความ SMS ซึ่งหมายความว่าแอปพลิเคชันจะสามารถตรวจสอบหรือลบข้อความที่ส่งมายังอุปกรณ์ของคุณได้โดยไม่ต้องแสดงให้คุณเห็น"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"รับข้อความ (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"อนุญาตให้แอปพลิเคชันรับและประมวลผลข้อความ MMS ซึ่งหมายความว่าแอปพลิเคชันจะสามารถตรวจสอบหรือลบข้อความที่ส่งมายังอุปกรณ์ของคุณได้โดยไม่ต้องแสดงให้คุณเห็น"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"อ่านข้อความที่ได้รับจากสถานีมือถือ"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"อนุญาตให้แอปอ่านข้อความจากสถานีมือถือที่อุปกรณ์ได้รับ การแจ้งเตือนทางมือถือมีให้บริการในบางพื้นที่ โดยจะแจ้งเตือนคุณเกี่ยวกับสถานการณ์ฉุกเฉิน แอปที่เป็นอันตรายอาจเข้าแทรกแซงการทำงานของอุปกรณ์เมื่อได้รับข้อความแจ้งเตือนฉุกเฉิน"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"อ่านฟีดข้อมูลที่สมัครไว้"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"อนุญาตให้แอปอ่านและเขียนการกำหนดค่าโหมดห้ามรบกวน"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"เริ่มการใช้สิทธิ์การดู"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"อนุญาตให้เจ้าของเริ่มการใช้สิทธิ์ของแอป ไม่จำเป็นสำหรับแอปทั่วไป"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"เป้าหมายทางลัดการช่วยเหลือพิเศษ"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"อนุญาตให้แอปกำหนดเป้าหมายทางลัดการช่วยเหลือพิเศษ"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"ควบคุมความยาวและอักขระที่สามารถใช้ในรหัสผ่านของการล็อกหน้าจอและ PIN"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"โหมดโปรแกรมทดสอบอัตโนมัติเปิดใช้อยู่"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"รีเซ็ตเป็นค่าเริ่มต้นเพื่อปิดใช้โหมดโปรแกรมทดสอบอัตโนมัติ"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"เปิดใช้คอนโซลการเรียงอันดับแล้ว"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"ประสิทธิภาพได้รับผลกระทบ ตรวจสอบ Bootloader เพื่อปิดใช้งาน"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"มีของเหลวหรือฝุ่นละอองในพอร์ต USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"พอร์ต USB ปิดใช้โดยอัตโนมัติ แตะเพื่อดูข้อมูลเพิ่มเติม"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ใช้พอร์ต USB ได้แล้ว"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"ไม่จัดอยู่ในหมวดหมู่ใดๆ"</string>
<string name="importance_from_user" msgid="7318955817386549931">"คุณตั้งค่าความสำคัญของการแจ้งเตือนเหล่านี้"</string>
<string name="importance_from_person" msgid="9160133597262938296">"ข้อความนี้สำคัญเนื่องจากบุคคลที่เกี่ยวข้อง"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"อนุญาตให้ <xliff:g id="APP">%1$s</xliff:g> สร้างผู้ใช้ใหม่ด้วย <xliff:g id="ACCOUNT">%2$s</xliff:g> ไหม (มีผู้ใช้ที่มีบัญชีนี้อยู่แล้ว)"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"อนุญาตให้ <xliff:g id="APP">%1$s</xliff:g> สร้างผู้ใช้ใหม่ด้วย <xliff:g id="ACCOUNT">%2$s</xliff:g> ไหม"</string>
<string name="language_selection_title" msgid="2680677278159281088">"เพิ่มภาษา"</string>
<string name="country_selection_title" msgid="2954859441620215513">"ค่ากำหนดภูมิภาค"</string>
<string name="search_language_hint" msgid="7042102592055108574">"พิมพ์ชื่อภาษา"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 9acd72a..f2db658 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Pinapayagan ang app na tumanggap at magproseso ng mga mensaheng SMS. Nangangahulugan ito na maaaring sumubaybay o magtanggal ang app ng mga mensaheng ipinapadala sa iyong device nang hindi ipinapakita ang mga ito sa iyo."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"tumanggap ng mga text message (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Pinapayagan ang app na tumanggap at magproseso ng mga mensaheng MMS. Nangangahulugan ito na maaaring sumubaybay o magtanggal ang app ng mga mensaheng ipinapadala sa iyong device nang hindi ipinapakita ang mga ito sa iyo."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"basahin ang mga mensahe ng cell broadcast"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Binibigyang-daan ang app na magbasa ng mga mensahe ng cell broadcast na natanggap ng iyong device. Inihahatid ang mga alerto ng cell broadcast sa ilang lokasyon upang balaan ka tungkol sa mga emergency na sitwasyon. Maaaring makaabala ang nakakahamak na apps sa performance o pagpapatakbo ng iyong device kapag nakatanggap ng emergency na cell broadcast."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"magbasa ng mga na-subscribe na feed"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Nagbibigay-daan sa app na basahin at isulat ang configuration ng Huwag Istorbohin."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"simulan ang paggamit sa pahintulot sa pagtingin"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Binibigyang-daan ang may hawak na simulan ang paggamit ng pahintulot para sa isang app. Hindi dapat kailanganin kailanman para sa mga normal na app."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"Target ng shortcut sa pagiging accessible"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Nagbibigay-daan sa isang app na tukuyin ang target ng shortcut sa pagiging accessible."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Magtakda ng mga panuntunan sa password"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolin ang haba at ang mga character na pinapayagan sa mga password at PIN sa screen lock."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Subaybayan ang mga pagsubok sa pag-unlock ng screen"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Piliin upang i-disable ang debugging ng USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Naka-enable ang Test Harness Mode"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Mag-factory reset para i-disable ang Test Harness Mode."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Naka-enable ang serial console"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Naaapektuhan ang performance. Para i-disable, lagyan ng check ang bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquid o debris sa USB port"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Awtomatikong na-disable ang USB port. Mag-tap para matuto pa."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ayos na gamitin ang USB port"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Di-nakategorya"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Ikaw ang magtatakda sa kahalagahan ng mga notification na ito."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Mahalaga ito dahil sa mga taong kasangkot."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Payagan ang <xliff:g id="APP">%1$s</xliff:g> na gumawa ng bagong User sa <xliff:g id="ACCOUNT">%2$s</xliff:g> (mayroon nang User sa account na ito) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Payagan ang <xliff:g id="APP">%1$s</xliff:g> na gumawa ng bagong User sa <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Magdagdag ng wika"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Kagustuhan sa rehiyon"</string>
<string name="search_language_hint" msgid="7042102592055108574">"I-type ang wika"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index e2bda9f..cf3fbfc 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Uygulamaya SMS iletilerini alma ve işleme izni verir. Bu izin, uygulamanın cihazınıza gönderilen iletileri takip edip size göstermeden silebileceği anlamına gelir."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"kısa mesajları (MMS) al"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Uygulamaya MMS iletilerini alma ve işleme izni verir. Bu izin, uygulamanın cihazınıza gönderilen iletileri takip edip size göstermeden silebileceği anlamına gelir."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"hücre yayını mesajlarını oku"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Uygulamaya, cihazınız tarafından alınan hücre yayını mesajlarını okuma izni verir. Hücre yayını uyarıları bazı yerlerde acil durumlar konusunda sizi uyarmak için gönderilir. Kötü amaçlı uygulamalar acil hücre yayını alındığında cihazınızın performansına ya da çalışmasına engel olabilir."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"abone olunan yayınları okuma"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Uygulamaya, Rahatsız Etmeyin yapılandırmasını okuma ve yazma izni verir."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"izin kullanımı görüntülemeye başlama"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"İzin sahibinin bir uygulama için izin kullanımı başlatmasına olanak tanır. Normal uygulamalar için hiçbir zaman kullanılmamalıdır."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"erişilebilirlik kısayolu hedefi"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Uygulamaların erişilebilirlik kısayolu hedefi tanımlamasına izin verir."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Şifre kuralları ayarla"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Ekran kilidini açma şifrelerinde ve PIN\'lerde izin verilen uzunluğu ve karakterleri denetleyin."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Ekran kilidini açma denemelerini izle"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için seçin."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Test Bandı Modu etkin"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Test Bandı Modu\'nu devre dışı bırakmak için cihazı fabrika ayarlarına sıfırlayın."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Seri konsol etkinleştirildi"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Performans etkilendi. Devre dışı bırakmak için bootloader\'ı kontrol edin."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB bağlantı noktasında sıvı veya toz var"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB bağlantı noktası otomatik olarak devre dışı bırakıldı. Daha fazla bilgi için dokunun."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB bağlantı noktasını kullanabilirsiniz"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Kategorize edilmemiş"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Bu bildirimlerin önem derecesini ayarladınız."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Bu, dahil olan kişiler nedeniyle önemlidir."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabına sahip yeni bir Kullanıcı eklemesine izin verilsin mi (bu hesaba sahip bir kullanıcı zaten var)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> uygulamasının <xliff:g id="ACCOUNT">%2$s</xliff:g> hesabına sahip yeni bir Kullanıcı eklemesine izin verilsin mi?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Dil ekleyin"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Bölge tercihi"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Dil adını yazın"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index ee52575..0ac716d 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -350,6 +350,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Дозволяє програмі отримувати й обробляти SMS-повідомлення. Це означає, що програма може відстежувати чи видаляти повідомлення, надіслані на ваш пристрій, навіть не показуючи їх вам."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"отримувати текстові повідомлення (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Дозволяє програмі отримувати й обробляти MMS-повідомлення. Це означає, що програма може відстежувати чи видаляти повідомлення, надіслані на ваш пристрій, навіть не показуючи їх вам."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"читати широкомовні повідомлення мережі"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Дозволяє програмі читати широкомовні повідомлення мережі, отримані пристроєм. Широкомовні сповіщення мережі надсилаються в деяких країнах для попередження про надзвичайні ситуації. Шкідливі програми можуть втручатися у швидкодію чи роботу пристрою під час отримання широкомовного повідомлення мережі про надзвичайну ситуацію."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"читати підписані канали"</string>
@@ -661,6 +665,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Додаток зможе переглядати та змінювати конфігурацію режиму \"Не турбувати\"."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"перегляньте дані про використання дозволів"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Власник зможе використовувати дозволи для цього додатка. Цей дозвіл не потрібен для звичайних додатків."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"потрібні засоби спеціальних можливостей"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Дає додатку змогу визначати потрібні засоби спеціальних можливостей."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Укажіть максимальну довжину та кількість символів для паролів розблокування екрана та PIN-кодів."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Відстежувати спроби розблокування екрана"</string>
@@ -1405,6 +1411,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Виберіть, щоб вимкнути налагодження за USB"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Увімкнено режим автоматизованого тестування"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Щоб вимкнути режим автоматизованого тестування, відновіть заводські налаштування."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Послідовну консоль увімкнено"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Продуктивність зазнала впливу. Щоб вимкнути, перевірте завантажувач операційної системи."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Рідина або сміття в USB-порту"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-порт автоматично вимкнено. Торкніться, щоб дізнатися більше."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Можна використовувати USB-порт"</string>
@@ -1958,10 +1966,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Без категорії"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Ви вказуєте пріоритет цих сповіщень."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Важливе з огляду на учасників."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Дозволити додатку <xliff:g id="APP">%1$s</xliff:g> створити нового користувача з обліковим записом <xliff:g id="ACCOUNT">%2$s</xliff:g> (користувач із таким обліковим записом уже існує)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Дозволити додатку <xliff:g id="APP">%1$s</xliff:g> створити нового користувача з обліковим записом <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Додати мову"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Вибір регіону"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Введіть назву мови"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 5cc8db7..43ecaf6 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -324,7 +324,7 @@
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"ڈسپلے کے زوم کی سطح اور پوزیشن کو کنٹرول کریں۔"</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"اشارے انجام دینے کی"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"تھپتھپانا، سوائپ کرنا، چٹکی بھرنا اور دیگر اشارے انجام دے سکتی ہے"</string>
- <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"فنگرپرنٹ کے اشارے"</string>
+ <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"فنگر پرنٹ کے اشارے"</string>
<string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"آلہ کے فنگر پرنٹ سینسر پر کیے گئے اشاروں کو کیپچر کر سکتا ہے۔"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"اسٹیٹس بار کو غیر فعال یا اس میں ترمیم کریں"</string>
<string name="permdesc_statusBar" msgid="8434669549504290975">"ایپ کو اسٹیٹس بار غیر فعال کرنے یا سسٹم آئیکنز شامل کرنے اور ہٹانے کی اجازت دیتا ہے۔"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"ایپ کو SMS پیغامات حاصل اور ان پر کارروائی کرنے کی اجازت دیتا ہے۔ اس کا مطلب ہے کہ ایپ آپ کے آلے پر مرسلہ پیغامات آپ کو دکھائے بغیر ان پر نگاہ رکھ یا انہیں حذف کرسکتی ہے۔"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"متنی پیغامات (MMS) حاصل کریں"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"ایپ کو MMS پیغامات حاصل اور ان پر کارروائی کرنے کی اجازت دیتا ہے۔ اس کا مطلب ہے کہ ایپ آپ کے آلے پر مرسلہ پیغامات آپ کو دکھائے بغیر ان پر نگاہ رکھ یا انہیں حذف کرسکتی ہے۔"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"سیل کے نشریاتی پیغامات پڑھیں"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"ایپ کو آپ کے آلے کو موصولہ سیل کے نشریاتی پیغامات پڑھنے کی اجازت دیتا ہے۔ سیل کی نشریاتی الرٹس آپ کو ہنگامی حالات سے مطلع کرنے کیلئے کچھ مقامات میں مہیا کی جاتی ہیں۔ نقصان دہ ایپس کوئی ہنگامی سیل کا نشریہ موصول ہونے پر آپ کے آلے کی کارکردگی یا عمل میں خلل ڈال سکتی ہیں۔"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"سبسکرائب کردہ فیڈز پڑھیں"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"ایپ کو ڈسٹرب نہ کریں کنفیگریشن لکھنے اور پڑھنے کے قابل کرتا ہے۔"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"اجازت کی استعمال کا ملاحظہ شروع کریں"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"حامل کو ایپ کی اجازت کے استعمال کو شروع کرنے کی اجازت دیتا ہے۔ عام ایپس کے لیے کبھی بھی درکار نہیں ہونا چاہیے۔"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"ایکسیسبیلٹی شارٹ کٹ ہدف"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"ایپ کو ایکسیسبیلٹی شارٹ کٹ ہدف کی وضاحت کرنے کے ليے اجازتیں۔"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"پاس ورڈ کے اصول سیٹ کریں"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"اسکرین لاک پاس ورڈز اور PINs میں اجازت یافتہ لمبائی اور حروف کو کنٹرول کریں۔"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"اسکرین غیر مقفل کرنے کی کوششیں مانیٹر کریں"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ڈیبگ کرنے کو غیر فعال کرنے کیلئے منتخب کریں۔"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"ٹیسٹ ہارنیس موڈ فعال ہے"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ٹیسٹ ہارنیس موڈ غیر فعال کرنے کے لیے فیکٹری ری سیٹ کریں۔"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"شمار کونسول فعال ہے"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"کارکردگی پر اثر پڑا ہے۔ غیر فعال کرنے کے ليے، بوٹ لوڈر چیک کریں۔"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB پورٹ میں سیال یا دھول ہے"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB پورٹ خودکار طور پر غیر فعال کر دیا گیا۔ مزید جاننے کیلئے تھپتھپائیں۔"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB پورٹ کا استعمال ٹھیک ہے"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"غیر زمرہ بند"</string>
<string name="importance_from_user" msgid="7318955817386549931">"ان اطلاعات کی اہمیت آپ مقرر کرتے ہیں۔"</string>
<string name="importance_from_person" msgid="9160133597262938296">"اس میں موجود لوگوں کی وجہ سے یہ اہم ہے۔"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> کو <xliff:g id="ACCOUNT">%2$s</xliff:g> کے ساتھ ایک نیا صارف بنانے کی اجازت دیں (اس اکاؤنٹ کے ساتھ ایک صارف پہلے سے موجود ہے) ؟"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="ACCOUNT">%2$s</xliff:g> کے ساتھ نئے صارف کو تخلیق کرنے کے لیے <xliff:g id="APP">%1$s</xliff:g> کو اجازت دیں ؟"</string>
<string name="language_selection_title" msgid="2680677278159281088">"ایک زبان شامل کریں"</string>
<string name="country_selection_title" msgid="2954859441620215513">"علاقہ کی ترجیح"</string>
<string name="search_language_hint" msgid="7042102592055108574">"زبان کا نام ٹائپ کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index cb5191d..5ebda207 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Ilovaga SMS xabarlarini qabul qilish va va ularni qayta ishlash uchun ruxsat beradi. Bu sizga yuborilgan xabarlarni ilova sizga ko‘rsatmasdan kuzatishi va o‘chirishi mumkinligini bildiradi."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"MMS xabarlarni olish"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Ilovaga MMS xabarlarini qabul qilish va ularni qayta ishlash uchun ruxsat beradi. Bu sizga yuborilgan xabarlarni ilova sizga ko‘rsatmasdan kuzatishi va o‘chirishi mumkinligini bildiradi."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"uyali tarmoq operatori xabarlarini o‘qish"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ilovaga qurilmangiz tomonidan qabul qilingan uyali tarmoq operatori xabarlarini o‘qish uchun ruxsat beradi. Uyali tarmoq operatorining ogohlantiruvchi xabarlari ba’zi manzillarga favqulodda holatlar haqida ogohlantirish uchun jo‘natiladi. Zararli ilovalar uyali tarmoq orqali favqulodda xabar qabul qilinganda qurilmangizning ish faoliyati yoki amallariga xalaqit qilishi mumkin"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"obunalarni o‘qish"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"“Bezovta qilinmasin” rejimi sozlamalarini ko‘rish va o‘zgartirish."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"foydalaniladigan ruxsatlar axborotini ochish"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Ilova foydalanadigan ruxsatlar axborotini ishga tushirishga ruxsat beradi. Oddiy ilovalar uchun talab qilinmaydi."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"tezkor yoqish maqsadi"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Ilova tezkor yoqish maqsadini aniqlay oladi."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Parol qoidalarini o‘rnatish"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Ekran qulfi paroli va PIN kodlari uchun qo‘yiladigan talablarni (belgilar soni va uzunligi) nazorat qiladi."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Ekranni qulfdan chiqarishga urinishlarni nazorat qilish"</string>
@@ -1362,6 +1368,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB orqali nosozliklarni tuzatishni o‘chirib qo‘yish uchun bosing."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Xavfsizlik sinovi rejimi yoqildi"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Xavfsizlik sinovi rejimini faolsizlantirish uchun zavod sozlamalariga qaytaring."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Davomiy port terminali yoqildi"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Samaradorlik pasaydi. Terminalni faolsizlantirish uchun operatsion tizim yuklagichini oching."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB portda suyuqlik yoki parcha bor"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB port avtomatik tarzda faolsizlashtirildi. Batafsil axborot olish uchun bosing."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB portdan foydalanish mumkin"</string>
@@ -1891,10 +1899,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Turkumlanmagan"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Siz ushbu bildirishnomalarning muhimligini belgilagansiz."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Bu odamlar siz uchun muhim."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"<xliff:g id="APP">%1$s</xliff:g> ilovasiga <xliff:g id="ACCOUNT">%2$s</xliff:g> hisobi bilan yangi foydalanuvchi yaratishiga ruxsat berilsinmi (bunday hisobdagi foydalanuvchi allaqachon mavjud) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"<xliff:g id="APP">%1$s</xliff:g> ilovasiga <xliff:g id="ACCOUNT">%2$s</xliff:g> hisobi bilan yangi foydalanuvchi yaratishiga ruxsat berilsinmi ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Til qoʻshish"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Hudud sozlamalari"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Til nomini kiriting"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index e41dc43..a34585b 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Cho phép ứng dụng nhận và xử lý tin nhắn SMS. Điều này có nghĩa là ứng dụng có thể theo dõi hoặc xóa tin nhắn được gửi đến thiết bị của bạn mà không hiển thị chúng cho bạn."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"nhận tin nhắn văn bản (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Cho phép ứng dụng nhận và xử lý tin nhắn MMS. Điều này có nghĩa là ứng dụng có thể theo dõi hoặc xóa tin nhắn được gửi đến thiết bị của bạn mà không hiển thị chúng cho bạn."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"đọc tin nhắn quảng bá"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Cho phép ứng dụng đọc tin nhắn quảng bá mà thiết bị của bạn nhận được. Tin nhắn quảng bá cảnh báo được gửi ở một số địa điểm nhằm cảnh báo cho bạn về các tình huống khẩn cấp. Các ứng dụng độc hại có thể gây ảnh hưởng đến hiệu suất hoặc hoạt động của thiết bị của bạn khi nhận được tin nhắn quảng bá khẩn cấp."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"đọc nguồn cấp dữ liệu đã đăng ký"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Cho phép ứng dụng đọc và ghi cấu hình Không làm phiền."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"cấp quyền xem"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Cho phép chủ sở hữu cấp quyền cho một ứng dụng. Các ứng dụng thông thường sẽ không bao giờ cần quyền này."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"đích đến của phím tắt hỗ trợ tiếp cận"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Cho phép ứng dụng xác định đích đến của phím tắt hỗ trợ tiếp cận."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Đặt quy tắc mật khẩu"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kiểm soát độ dài và ký tự được phép trong mật khẩu khóa màn hình và mã PIN."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Giám sát những lần thử mở khóa màn hình"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chọn để tắt chế độ gỡ lỗi qua USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Đã bật Chế độ khai thác kiểm thử"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Khôi phục cài đặt gốc để tắt Chế độ khai thác kiểm thử."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"Đã bật bảng điều khiển cổng nối tiếp"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Hiệu suất sẽ bị ảnh hưởng. Để tắt, hãy chọn trình tải khởi động."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Có chất lỏng hoặc mảnh vỡ trong cổng USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Cổng USB đã tự động tắt. Nhấn để tìm hiểu thêm."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Có thể sử dụng cổng USB"</string>
@@ -1579,8 +1587,8 @@
<string name="expires_on" msgid="3676242949915959821">"Hết hạn vào:"</string>
<string name="serial_number" msgid="758814067660862493">"Số sê-ri:"</string>
<string name="fingerprints" msgid="4516019619850763049">"Tệp tham chiếu:"</string>
- <string name="sha256_fingerprint" msgid="4391271286477279263">"Tệp tham chiếu SHA-256:"</string>
- <string name="sha1_fingerprint" msgid="7930330235269404581">"Tệp tham chiếu SHA-1:"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"Vân tay SHA-256:"</string>
+ <string name="sha1_fingerprint" msgid="7930330235269404581">"Vân tay SHA-1:"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Xem tất cả"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Chọn hoạt động"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Chia sẻ với"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Chưa được phân loại"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Bạn đặt tầm quan trọng của các thông báo này."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Thông báo này quan trọng vì những người có liên quan."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Cho phép <xliff:g id="APP">%1$s</xliff:g> tạo người dùng mới bằng <xliff:g id="ACCOUNT">%2$s</xliff:g> (đã tồn tại người dùng có tài khoản này)?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Cho phép <xliff:g id="APP">%1$s</xliff:g> tạo người dùng mới bằng <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Thêm ngôn ngữ"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Tùy chọn khu vực"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Nhập tên ngôn ngữ"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index ba39f1e2..64e0a1b 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"允许该应用接收和处理短信。这就意味着,该应用可能会监视发送到您设备的短信,或删除发送到您设备的短信而不向您显示。"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"接收讯息(彩信)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"允许该应用接收和处理彩信。这就意味着,该应用可能会监视发送到您设备的彩信,或删除发送到您设备的彩信而不向您显示。"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"读取小区广播消息"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"允许应用读取您的设备收到的小区广播消息。小区广播消息是在某些地区发送的、用于发布紧急情况警告的提醒信息。恶意应用可能会在您收到小区紧急广播时干扰您设备的性能或操作。"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"读取订阅的供稿"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"允许此应用读取和写入“勿扰”模式配置。"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"授权使用“查看权限”"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"允许该应用开始查看应用的权限使用情况(普通应用绝不需要此权限)。"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"无障碍功能快捷方式目标"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"允许应用定义无障碍功能快捷方式目标。"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"控制锁屏密码和 PIN 码所允许的长度和字符。"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"监控屏幕解锁尝试次数"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"选择即可停用 USB 调试功能。"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"自动化测试框架模式已启用"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"恢复出厂设置以停用自动化测试框架模式。"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"已启用序列控制台"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"性能受到影响。要停用,请查看引导加载程序。"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 端口中有液体或碎屑"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 端口已自动停用。点按即可了解详情。"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"允许使用 USB 端口"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"未分类"</string>
<string name="importance_from_user" msgid="7318955817386549931">"这些通知的重要程度由您来设置。"</string>
<string name="importance_from_person" msgid="9160133597262938296">"这条通知涉及特定的人,因此被归为重要通知。"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"允许<xliff:g id="APP">%1$s</xliff:g>使用 <xliff:g id="ACCOUNT">%2$s</xliff:g>(目前已有用户使用此帐号)创建新用户吗?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"允许<xliff:g id="APP">%1$s</xliff:g>使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 创建新用户吗?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"添加语言"</string>
<string name="country_selection_title" msgid="2954859441620215513">"区域偏好设置"</string>
<string name="search_language_hint" msgid="7042102592055108574">"输入语言名称"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index f0fce71..67a7dbb 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -201,7 +201,7 @@
<string name="turn_on_radio" msgid="3912793092339962371">"開啟無線網絡"</string>
<string name="turn_off_radio" msgid="8198784949987062346">"關閉無線網絡"</string>
<string name="screen_lock" msgid="799094655496098153">"螢幕鎖定"</string>
- <string name="power_off" msgid="4266614107412865048">"關閉"</string>
+ <string name="power_off" msgid="4266614107412865048">"關機"</string>
<string name="silent_mode_silent" msgid="319298163018473078">"鈴聲關閉"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"鈴聲震動"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"鈴聲開啟"</string>
@@ -225,7 +225,7 @@
<string name="global_actions" product="tv" msgid="9091480417912345975">"Android TV 選項"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"手機選項"</string>
<string name="global_action_lock" msgid="2844945191792119712">"螢幕鎖定"</string>
- <string name="global_action_power_off" msgid="4471879440839879722">"關閉"</string>
+ <string name="global_action_power_off" msgid="4471879440839879722">"關機"</string>
<string name="global_action_emergency" msgid="7112311161137421166">"緊急"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
<string name="global_action_logout" msgid="935179188218826050">"結束工作階段"</string>
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"允許應用程式接收和處理短訊。這表示應用程式可監控傳送至您裝置的訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"接收短訊 (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"允許應用程式接收和處理 MMS 訊息。這表示應用程式可監控傳送至您裝置的訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"讀取區域廣播訊息"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"允許應用程式讀取您裝置接收的區域廣播訊息。某些地點會發出區域廣播警報,警告您發生緊急狀況。惡意應用程式可能會在裝置收到緊急區域廣播時,干擾裝置的性能或運作。"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"讀取訂閱的資訊提供"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"允許應用程式讀取和寫入「請勿騷擾」設定。"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"開始查看權限使用情況"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"允許應用程式開始查看應用程式的權限使用情況 (一般應用程式並不需要)。"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"無障礙功能捷徑目標位置"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"允許應用程式定義無障礙功能捷徑目標位置。"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"控制螢幕鎖定密碼和 PIN 所允許的長度和字元。"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"監控螢幕解鎖嘗試次數"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取即可停用 USB 偵錯。"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"已啟用測試工具模式"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"請將裝置回復原廠設定,以停用測試工具模式。"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"已啟用序列控制器"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"效能受到影響,勾選啟動程式即可停用。"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或碎片"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 連接埠已自動停用。輕按即可瞭解詳情。"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB 連接埠可安全使用"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"未分類"</string>
<string name="importance_from_user" msgid="7318955817386549931">"您可以設定這些通知的重要性。"</string>
<string name="importance_from_person" msgid="9160133597262938296">"列為重要的原因:涉及的人。"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"要允許 <xliff:g id="APP">%1$s</xliff:g> 使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者 (此帳戶目前已有此使用者) 嗎?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"要允許 <xliff:g id="APP">%1$s</xliff:g> 使用 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者嗎?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"新增語言"</string>
<string name="country_selection_title" msgid="2954859441620215513">"地區偏好設定"</string>
<string name="search_language_hint" msgid="7042102592055108574">"輸入語言名稱"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 1f13208..923a23f 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"允許應用程式接收和處理簡訊。這項設定可讓應用程式監控傳送至你裝置的訊息,或在你閱讀訊息前擅自刪除訊息。"</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"接收簡訊 (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"允許應用程式接收和處理多媒體訊息。這項設定可讓應用程式監控傳送至你裝置的訊息,或在你閱讀訊息前擅自刪除訊息。"</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"讀取區域廣播訊息"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"允許應用程式讀取你裝置收到的區域廣播訊息。某些地點會發出區域廣播警示,警告你有緊急狀況發生。請注意,惡意應用程式可能會在裝置收到緊急區域廣播時,干擾裝置的效能或運作。"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"讀取訂閱資訊提供"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"允許應用程式讀取及寫入「零打擾」設定。"</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"啟動檢視權限用途"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"允許應用程式開始使用其他應用程式 (一般應用程式並不需要)。"</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"指定無障礙捷徑目標"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"允許應用程式定義指定的無障礙捷徑目標。"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"管理螢幕鎖定密碼和 PIN 碼支援的字元和長度上限。"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"監控螢幕解鎖嘗試次數"</string>
@@ -1361,10 +1367,12 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"選取這個選項以停用 USB 偵錯功能。"</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"測試控管工具模式已啟用"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"恢復原廠設定以停用測試控管工具模式。"</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"已啟用序列主控台"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"效能已受到影響。如要停用,請檢查系統啟動載入程式。"</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或灰塵"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"系統已自動停用 USB 連接埠。輕觸即可瞭解詳情。"</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"現在可以使用 USB 連接埠"</string>
- <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手機目前無法偵測液體或灰塵。"</string>
+ <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手機目前沒有偵測到液體或灰塵。"</string>
<string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string>
<string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
<string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"正在分享錯誤報告…"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"未分類"</string>
<string name="importance_from_user" msgid="7318955817386549931">"這些通知的重要性由你決定。"</string>
<string name="importance_from_person" msgid="9160133597262938296">"這則通知涉及特定人士,因此被歸為重要通知。"</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"要允許「<xliff:g id="APP">%1$s</xliff:g>」替 <xliff:g id="ACCOUNT">%2$s</xliff:g> (這個帳戶目前已有使用者) 建立新使用者嗎?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"要允許「<xliff:g id="APP">%1$s</xliff:g>」替 <xliff:g id="ACCOUNT">%2$s</xliff:g> 建立新使用者嗎?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"新增語言"</string>
<string name="country_selection_title" msgid="2954859441620215513">"地區偏好設定"</string>
<string name="search_language_hint" msgid="7042102592055108574">"請輸入語言名稱"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index f707fcc..04091ff 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -344,6 +344,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Ivumela uhlelo lokusebenza ukuthola nokucubungula imilayezo ye-SMS. Loku kuchaza ukuthi uhlelo lokusebenza lungangamela noma lesuse imilayezo ethunyelwe kudivayisi yakho ngaphandle kokukubonisa yona."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"thola imiyalezo ebhaliwe (i-MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Ivumela uhlelo lokusebenza ukuthola nokucubungula imilayezo ye-MMS. Loku kuchaza ukuthi uhlelo lokusebenza lungangamela noma lesuse imilayezo ethunyelwe kudivayisi yakho ngaphandle kokukubonisa yona."</string>
+ <!-- no translation found for permlab_bindCellBroadcastService (4468585041824555604) -->
+ <skip />
+ <!-- no translation found for permdesc_bindCellBroadcastService (9073440260695196089) -->
+ <skip />
<string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"funda imilayezo yokusakaza yeselula"</string>
<string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ivumela uhlelo lokusebenza ukufunda imilayezo yokusakaza yeselula etholwe idivayisi yakho. Izaziso zokusakaza zeselula zilethwa kwezinye izindawo ukukuxwayisa ngezimo ezisheshayo. Izinhlelo zokusebenza ezingalungile zingaphazamisana nokusebenza noma umsebenzi wedivayisi yakho uma ukusakaza kweselula kwesimo esisheshayo kutholwa."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"funda izifunzo ezikhokhelwayo"</string>
@@ -655,6 +659,8 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Ivumela izinhlelo zokusebenza ukufunda nokubhala ukulungiswa kokuthi Ungaphazamisi."</string>
<string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"qala ukusetshenziswa kokubuka imvume"</string>
<string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"Ivumela umphathi ukuthi aqale ukusetshenziswa kwemvume kohlelo lokusebenza. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
+ <string name="permlab_accessibilityShortcutTarget" msgid="1385930065395622809">"impokophelo yesinqamuleli sokufinyeleleka"</string>
+ <string name="permdesc_accessibilityShortcutTarget" msgid="562750894417800432">"Ivumela uhlelo lokusebenza ukuthi luchaze impokophelo yesinqamuleli sokufinyeleleka."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Misa imithetho yephasiwedi"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Lawula ubude nezinhlamvu ezivunyelwe kumaphasiwedi wokukhiya isikrini nama-PIN."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Qapha imizamo yokuvula isikrini sakho"</string>
@@ -1361,6 +1367,8 @@
<string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Khetha ukuvimbela ukulungisa iphutha le-USB."</string>
<string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Imodi yokuhlola i-harness inikwe amandla"</string>
<string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Yenza ukusetha kabusha kwasekuqaleni ukuze ukhubaze imodi yokuqina yokuhlola."</string>
+ <string name="console_running_notification_title" msgid="4955436518220103382">"I-serial console inikwe amandla"</string>
+ <string name="console_running_notification_message" msgid="1331995933976263865">"Ukusebenza kuyathinteka. Ukuze ukhubaze, hlola i-bootloader."</string>
<string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Uketshezi noma ama-debris kumbobo ye-USB"</string>
<string name="usb_contaminant_detected_message" msgid="832337061059487250">"Imbobo ye-USB inqanyulwa ngokuzenzakalela. Thepha ukuze ufunde kabanzi."</string>
<string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"KULUNGILE ukusebenzisa imbobo ye-USB"</string>
@@ -1890,10 +1898,8 @@
<string name="default_notification_channel_label" msgid="5929663562028088222">"Akufakwanga esigabeni"</string>
<string name="importance_from_user" msgid="7318955817386549931">"Usethe ukubaluleka kwalezi zaziso."</string>
<string name="importance_from_person" msgid="9160133597262938296">"Lokhu kubalulekile ngenxa yabantu ababandakanyekayo."</string>
- <!-- no translation found for user_creation_account_exists (6559477114648176531) -->
- <skip />
- <!-- no translation found for user_creation_adding (9089159170398841763) -->
- <skip />
+ <string name="user_creation_account_exists" msgid="6559477114648176531">"Vumela i-<xliff:g id="APP">%1$s</xliff:g> ukuthi idale umsebenzisi omusha nge-<xliff:g id="ACCOUNT">%2$s</xliff:g> (Umsebenzisi onale akhawunti usevele ukhona) ?"</string>
+ <string name="user_creation_adding" msgid="9089159170398841763">"Vumela i-<xliff:g id="APP">%1$s</xliff:g> ukuthi idale umsebenzisi omusha nge-<xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
<string name="language_selection_title" msgid="2680677278159281088">"Engeza ulwimi"</string>
<string name="country_selection_title" msgid="2954859441620215513">"Okuncamelayo kwesifunda"</string>
<string name="search_language_hint" msgid="7042102592055108574">"Thayipha igama lolimi"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 0c9ae85..14f5d97 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3755,6 +3755,16 @@
<attr name="summary" />
</declare-styleable>
+ <!-- Use <code>accessibility-shortcut-target</code> as the root tag of the XML resource that
+ describes an activity, which is referenced from the
+ <code>android.accessibilityshortcut.target</code> meta-data entry. -->
+ <declare-styleable name="AccessibilityShortcutTarget">
+ <!-- Short description of the target of accessibility shortcut purpose or behavior.-->
+ <attr name="description" />
+ <!-- Brief summary of the target of accessibility shortcut purpose or behavior. -->
+ <attr name="summary" />
+ </declare-styleable>
+
<!-- Use <code>print-service</code> as the root tag of the XML resource that
describes an {@link android.printservice.PrintService} service, which is
referenced from its {@link android.printservice.PrintService#SERVICE_META_DATA}
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 3ea8a77..381ed7f 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -349,10 +349,10 @@
will be given a single shared user ID, so they can for example run
in the same process. Note that for them to actually get the same
user ID, they must also be signed with the same signature.
- @deprecated Shared user id's cause non-deterministic behaviour within the
- package manager. As such, it's use is discouraged, deprecated, and will
- be removed altogether in a future version of Android. Instead, proper
- communication mechanisms such as services and providers should be used
+ @deprecated Shared user IDs cause non-deterministic behavior within the
+ package manager. As such, its use is strongly discouraged and may be
+ removed in a future version of Android. Instead, apps should use proper
+ communication mechanisms, such as services and content providers,
to facilitate interoperability between shared components. -->
<attr name="sharedUserId" format="string" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e3337b7..7eca699 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -433,6 +433,10 @@
-->
</string-array>
+ <!-- Package name for the default CellBroadcastService module [DO NOT TRANSLATE] -->
+ <string name="cellbroadcast_default_package" translatable="false">com.android.cellbroadcastreceiver
+ </string>
+
<!-- If the mobile hotspot feature requires provisioning, a package name and class name
can be provided to launch a supported application that provisions the devices.
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b53a399..bf5f706 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -890,6 +890,16 @@
messages. This means the app could monitor or delete messages sent to your
device without showing them to you.</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this.[CHAR LIMIT=NONE] -->
+ <string name="permlab_bindCellBroadcastService">Forward cell broadcast messages</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
+ <string name="permdesc_bindCellBroadcastService">Allows the app to bind to the
+ cell broadcast module in order to forward cell broadcast messages
+ as they are received. Cell broadcast alerts are delivered in some
+ locations to warn you of emergency situations. Malicious apps may
+ interfere with the performance or operation of your device when an
+ emergency cell broadcast is received.</string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readCellBroadcasts">read cell broadcast messages</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1745,11 +1755,6 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_startViewPermissionUsage">Allows the holder to start the permission usage for an app. Should never be needed for normal apps.</string>
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
- <string name="permlab_accessibilityShortcutTarget">accessibility shortcut target</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR_LIMIT=NONE] -->
- <string name="permdesc_accessibilityShortcutTarget">Allows an app to define the accessibility shortcut target.</string>
-
<!-- Policy administration -->
<!-- Title of policy access to limiting the user's password choices -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e2f2b2c..a8b5340 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -747,6 +747,7 @@
<java-symbol type="string" name="config_default_dns_server" />
<java-symbol type="string" name="config_ethernet_iface_regex" />
<java-symbol type="array" name="config_ethernet_interfaces" />
+ <java-symbol type="string" name="cellbroadcast_default_package" />
<java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
<java-symbol type="string" name="config_mms_user_agent" />
<java-symbol type="string" name="config_mms_user_agent_profile_url" />
diff --git a/core/tests/bugreports/Android.bp b/core/tests/bugreports/Android.bp
index d3bf0dd..e9d5bb1 100644
--- a/core/tests/bugreports/Android.bp
+++ b/core/tests/bugreports/Android.bp
@@ -20,7 +20,6 @@
"android.test.base",
],
static_libs: ["androidx.test.rules", "truth-prebuilt"],
- test_suites: ["general-tests"],
sdk_version: "test_current",
platform_apis: true,
}
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 2417209..c7e54f3 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1155,7 +1155,10 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ <category android:name="android.intent.category.ACCESSIBILITY_SHORTCUT_TARGET" />
</intent-filter>
+ <meta-data android:name="android.accessibilityshortcut.target"
+ android:resource="@xml/accessibility_shortcut_test_activity"/>
</activity>
<!-- Activity-level metadata -->
diff --git a/core/tests/coretests/res/values/strings.xml b/core/tests/coretests/res/values/strings.xml
index ef915bb..f630188 100644
--- a/core/tests/coretests/res/values/strings.xml
+++ b/core/tests/coretests/res/values/strings.xml
@@ -142,4 +142,10 @@
<!-- ResourcesLocaleResolutionTest -->
<string name="dummy_string">dummy string</string>
+
+ <!-- Description of the accessibility shortcut [CHAR LIMIT=NONE] -->
+ <string name="accessibility_shortcut_description">Accessibility shortcut description</string>
+
+ <!-- Summary of the accessibility shortcut [CHAR LIMIT=NONE] -->
+ <string name="accessibility_shortcut_summary">Accessibility shortcut summary</string>
</resources>
diff --git a/core/tests/coretests/res/xml/accessibility_shortcut_test_activity.xml b/core/tests/coretests/res/xml/accessibility_shortcut_test_activity.xml
new file mode 100644
index 0000000..60e2998
--- /dev/null
+++ b/core/tests/coretests/res/xml/accessibility_shortcut_test_activity.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ Copyright (C) 2019 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.
+ -->
+
+<accessibility-shortcut-target xmlns:android="http://schemas.android.com/apk/res/android"
+ android:description="@string/accessibility_shortcut_description"
+ android:summary="@string/accessibility_shortcut_summary"
+/>
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/accessibilityservice/AccessibilityShortcutInfoTest.java b/core/tests/coretests/src/android/accessibilityservice/AccessibilityShortcutInfoTest.java
new file mode 100644
index 0000000..abaeb0a
--- /dev/null
+++ b/core/tests/coretests/src/android/accessibilityservice/AccessibilityShortcutInfoTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 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 android.accessibilityservice;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityTestActivity;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+/**
+ * AccessibilityShortcutInfo can only be created by system. Verify the instance creation and
+ * basic function here.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityShortcutInfoTest {
+ private Context mTargetContext;
+ private PackageManager mPackageManager;
+ private AccessibilityShortcutInfo mShortcutInfo;
+
+ @Before
+ public void setUp() {
+ mTargetContext = InstrumentationRegistry.getInstrumentation()
+ .getTargetContext();
+ mPackageManager = mTargetContext.getPackageManager();
+
+ final ComponentName testShortcutName = new ComponentName(mTargetContext,
+ AccessibilityTestActivity.class);
+ final AccessibilityManager accessibilityManager = (AccessibilityManager) mTargetContext
+ .getSystemService(Context.ACCESSIBILITY_SERVICE);
+ final List<AccessibilityShortcutInfo> infoList = accessibilityManager
+ .getInstalledAccessibilityShortcutListAsUser(
+ mTargetContext, mTargetContext.getUserId());
+ for (AccessibilityShortcutInfo info : infoList) {
+ final ActivityInfo activityInfo = info.getActivityInfo();
+ final ComponentName name = new ComponentName(
+ activityInfo.packageName, activityInfo.name);
+ if (name.equals(testShortcutName)) {
+ mShortcutInfo = info;
+ break;
+ }
+ }
+
+ assertNotNull("Can't find " + testShortcutName, mShortcutInfo);
+ }
+
+ @Test
+ public void testDescription() {
+ final String description = mTargetContext.getResources()
+ .getString(R.string.accessibility_shortcut_description);
+
+ assertNotNull("Can't find description string", description);
+ assertThat("Description is not correct",
+ mShortcutInfo.loadDescription(mPackageManager), is(description));
+ }
+
+ @Test
+ public void testSummary() {
+ final String summary = mTargetContext.getResources()
+ .getString(R.string.accessibility_shortcut_summary);
+
+ assertNotNull("Can't find summary string", summary);
+ assertThat("Summary is not correct",
+ mShortcutInfo.loadSummary(mPackageManager), is(summary));
+ }
+}
diff --git a/core/tests/coretests/src/android/app/usage/UsageStatsTest.java b/core/tests/coretests/src/android/app/usage/UsageStatsTest.java
index 6ec3dc9..0ac00b8 100644
--- a/core/tests/coretests/src/android/app/usage/UsageStatsTest.java
+++ b/core/tests/coretests/src/android/app/usage/UsageStatsTest.java
@@ -173,7 +173,7 @@
left.update("com.test.activity1", 400000, ACTIVITY_STOPPED, 1);
assertEquals(left.mLastTimeUsed, 350000);
assertEquals(left.mLastTimeVisible, 400000);
- assertEquals(left.mActivities.get(1), ACTIVITY_STOPPED);
+ assertTrue(left.mActivities.indexOfKey(1) < 0);
assertEquals(left.mTotalTimeInForeground, 350000 - 200000);
assertEquals(left.mTotalTimeVisible, 400000 - 200000);
@@ -231,7 +231,7 @@
left.update("com.test.activity1", 400000, ACTIVITY_STOPPED, 1);
assertEquals(left.mLastTimeUsed, 300000);
assertEquals(left.mLastTimeVisible, 400000);
- assertEquals(left.mActivities.get(1), ACTIVITY_STOPPED);
+ assertTrue(left.mActivities.indexOfKey(1) < 0);
assertEquals(left.mTotalTimeInForeground, 300000 - 200000);
assertEquals(left.mTotalTimeVisible, 400000 - 100000);
}
@@ -249,7 +249,7 @@
left.update("com.test.activity1", 200000, ACTIVITY_STOPPED, 1);
assertEquals(left.mLastTimeUsed, 200000);
assertEquals(left.mLastTimeVisible, 200000);
- assertEquals(left.mActivities.get(1), ACTIVITY_STOPPED);
+ assertTrue(left.mActivities.indexOfKey(1) < 0);
assertEquals(left.mTotalTimeInForeground, 200000 - 100000);
assertEquals(left.mTotalTimeVisible, 200000 - 100000);
@@ -359,14 +359,14 @@
left.update("com.test.activity1", 550000, ACTIVITY_STOPPED, 1);
assertEquals(left.mLastTimeUsed, 450000);
assertEquals(left.mLastTimeVisible, 550000);
- assertEquals(left.mActivities.get(1), ACTIVITY_STOPPED);
+ assertTrue(left.mActivities.indexOfKey(1) < 0);
assertEquals(left.mTotalTimeInForeground, 350000);
assertEquals(left.mTotalTimeVisible, 350000 + 100000 /*550000 - 450000*/);
left.update("com.test.activity2", 650000, ACTIVITY_STOPPED, 2);
assertEquals(left.mLastTimeUsed, 450000);
assertEquals(left.mLastTimeVisible, 650000);
- assertEquals(left.mActivities.get(2), ACTIVITY_STOPPED);
+ assertTrue(left.mActivities.indexOfKey(2) < 0);
assertEquals(left.mTotalTimeInForeground, 350000);
assertEquals(left.mTotalTimeVisible, 450000 + 100000 /*650000 - 550000*/);
}
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
index 682416c..3586216a 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
@@ -23,8 +23,6 @@
import android.os.Bundle;
import android.os.IBinder;
-import java.util.List;
-
/**
* Stub implementation of IAccessibilityServiceConnection so each test doesn't need to implement
* all of the methods
@@ -73,7 +71,7 @@
return null;
}
- public List<AccessibilityWindowInfo> getWindows() {
+ public AccessibilityWindowInfo.WindowListSparseArray getWindows() {
return null;
}
diff --git a/core/tests/featureflagtests/OWNERS b/core/tests/featureflagtests/OWNERS
index 1a8fd2b..2ff4f5a 100644
--- a/core/tests/featureflagtests/OWNERS
+++ b/core/tests/featureflagtests/OWNERS
@@ -1,2 +1,2 @@
sbasi@google.com
-zhfan@google.com
\ No newline at end of file
+tmfang@google.com
\ No newline at end of file
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
index 054f68b..f1ba3f6 100644
--- a/data/etc/hiddenapi-package-whitelist.xml
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -53,6 +53,10 @@
<hidden-api-whitelisted-app package="com.android.providers.media" />
<hidden-api-whitelisted-app package="com.android.providers.tv" />
<hidden-api-whitelisted-app package="com.android.providers.userdictionary" />
+ <!-- TODO (b/141954427): Remove networkstack -->
+ <hidden-api-whitelisted-app package="com.android.networkstack" />
+ <!-- TODO (b/141954427): Remove wifistack -->
+ <hidden-api-whitelisted-app package="com.android.server.wifistack" />
<hidden-api-whitelisted-app package="com.android.smspush" />
<hidden-api-whitelisted-app package="com.android.spare_parts" />
<hidden-api-whitelisted-app package="com.android.statementservice" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 89523d6..51136b9 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -127,6 +127,7 @@
<permission name="android.permission.ACCESS_IMS_CALL_SERVICE"/>
<permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
<permission name="android.permission.BIND_CARRIER_SERVICES"/>
+ <permission name="android.permission.BIND_CELL_BROADCAST_SERVICE"/>
<permission name="android.permission.BIND_IMS_SERVICE"/>
<permission name="android.permission.BIND_TELEPHONY_DATA_SERVICE"/>
<permission name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 2dfb777..34b3951 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1,16 +1,2170 @@
{
"version": "1.0.0",
"messages": {
+ "-2146181682": {
+ "message": "Releasing screen wakelock, obscured by %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_KEEP_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-2138637148": {
+ "message": "Clearing focused app, displayId=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/ActivityDisplay.java"
+ },
+ "-2109864870": {
+ "message": "app-release(): mOuter=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "-2086729999": {
+ "message": "Removing app token: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-2072089308": {
+ "message": "Attempted to add window with token that is a sub-window: %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-2039580386": {
+ "message": "Attempted to add input method window with unknown token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-2024464438": {
+ "message": "app-onAnimationFinished(): mOuter=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "-2012562539": {
+ "message": "startAnimation(): Notify animation start:",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "-2002500255": {
+ "message": "Defer removing snapshot surface in %dms",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/TaskSnapshotSurface.java"
+ },
+ "-1991255017": {
+ "message": "Drawing snapshot surface sizeMismatch=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/TaskSnapshotSurface.java"
+ },
+ "-1976930686": {
+ "message": "Attempted to add Accessibility overlay window with bad token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1963461591": {
+ "message": "Removing %s from %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1958209312": {
+ "message": "Clear freezing of %s: hidden=%b freezing=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
+ "-1953668890": {
+ "message": "Can't start recents animation, nextAppTransition=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "-1949279037": {
+ "message": "Attempted to add input method window with bad token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1939358269": {
+ "message": "mRecentScreenshotAnimator finish",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "-1938839202": {
+ "message": "SURFACE LEAK DESTROY: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "-1915280162": {
+ "message": "Attempted to add wallpaper window with bad token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1886298021": {
+ "message": "setAppStartingWindow: token=%s pkg=%s transferFrom=%s newTask=%b taskSwitch=%b processRunning=%b allowTaskSnapshot=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
+ "-1884933373": {
+ "message": "enableScreenAfterBoot: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_BOOT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1872288685": {
+ "message": "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "-1868124841": {
+ "message": "screenOnEarly=%b, awake=%b, currentAppOrientation=%d, orientationSensorEnabled=%b, keyguardDrawComplete=%b, windowManagerDrawComplete=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "-1862269827": {
+ "message": "applyAnimation: anim=%s transit=%s isEntrance=%b Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "-1838803135": {
+ "message": "Attempted to set windowing mode to a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1836092044": {
+ "message": "Creating SnapshotStartingData",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1824578273": {
+ "message": "Reporting new frame to %s: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_RESIZE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "-1822611824": {
+ "message": "\tRemove token=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "-1797409732": {
+ "message": "Skipping %s because %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "-1770075711": {
+ "message": "Adding window client %s that is dead, aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1768557332": {
+ "message": "removeWallpaperAnimation()",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "-1750206390": {
+ "message": "Exception thrown when creating surface for client %s (%s). %s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1747461042": {
+ "message": "set mOrientationChanging of %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "-1741065110": {
+ "message": "No app is requesting an orientation, return %d for display id=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "-1736245181": {
+ "message": "Tried to remove starting window but startingWindow was null: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1730156332": {
+ "message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "-1710206702": {
+ "message": "Display id=%d is frozen while keyguard locked, return %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "-1661704580": {
+ "message": "Attempted to set replacing window on non-existing app token %s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1661404819": {
+ "message": "applyAnimation: atoken=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1632122349": {
+ "message": "Changing surface while display frozen: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1597650595": {
+ "message": "removeAppToken: %s delayed=%b Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1596995693": {
+ "message": "startAnimation",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "-1587841219": {
+ "message": "Focus moving from %s to %s displayId=%d",
+ "level": "INFO",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1568331821": {
+ "message": "Enabling listeners",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "-1561845439": {
+ "message": "reParentWindowToken: removing window token=%s from task=%s",
+ "level": "INFO",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1545962566": {
+ "message": "View server did not start",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1526645239": {
+ "message": "Timeout waiting for drawn: undrawn=%s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1524305318": {
+ "message": "Nulling last startingData",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1519226370": {
+ "message": "startingData was nulled out before handling mAddStartingWindow: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1515151503": {
+ "message": ">>> OPEN TRANSACTION removeReplacedWindows",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+ },
+ "-1497837552": {
+ "message": "onAnimationFinished(): mPendingAnimations=%d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "-1483752006": {
+ "message": " THUMBNAIL %s: CREATE",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/AppWindowThumbnail.java"
+ },
+ "-1470632028": {
+ "message": "Marking app token %s with replacing windows.",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1455600136": {
+ "message": "Attempted to add Dream window with unknown token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1448427933": {
+ "message": "startingWindow was set but startingSurface==null, couldn't remove",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1443029505": {
+ "message": "SAFE MODE ENABLED (menu=%d s=%d dpad=%d trackball=%d)",
+ "level": "INFO",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1434147454": {
+ "message": "cleanupAnimation(): Notify animation finished mPendingAnimations=%d reorderMode=%d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "-1427184084": {
+ "message": "addWindow: New client %s: window=%s Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1413901262": {
+ "message": "startRecentsActivity(): intent=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "-1391944764": {
+ "message": "SURFACE DESTROY: %s. %s",
+ "level": "INFO",
+ "group": "WM_SHOW_SURFACE_ALLOC",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "-1389772804": {
+ "message": "Attempted to add voice interaction window with bad token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1350198040": {
+ "message": "hideBootMessagesLocked: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_BOOT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1318134223": {
+ "message": "No longer Stopped: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1270731689": {
+ "message": "Attempted to set replacing window on app token with no content %s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1270148832": {
+ "message": "Resize start waiting for draw, mDrawState=DRAW_PENDING in %s, surfaceController %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_RESIZE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "-1263554915": {
+ "message": "Attempted to add Dream window with bad token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1259022216": {
+ "message": "SURFACE HIDE ( %s ): %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "-1257821162": {
+ "message": "OUT SURFACE %s: copied",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1219773477": {
+ "message": "setInputConsumerEnabled(%s): mCanceled=%b",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "-1207757583": {
+ "message": "startAnimation(): Notify animation start: %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "-1176488860": {
+ "message": "SURFACE isSecure=%b: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "-1156118957": {
+ "message": "Updated config=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "-1144293044": {
+ "message": "SURFACE SET FREEZE LAYER: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "-1130891072": {
+ "message": "Orientation continue waiting for draw in %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "-1130868271": {
+ "message": "Resizing %s WITH DRAW PENDING",
+ "level": "INFO",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "-1117599386": {
+ "message": "Deferring rotation, display is not enabled.",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "-1113134997": {
+ "message": "Attempted to add application window with unknown token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1103716954": {
+ "message": "Not removing %s due to exit animation",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "-1103115659": {
+ "message": "Performing post-rotate rotation",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+ },
+ "-1099052739": {
+ "message": "\tAdd token=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "-1097148233": {
+ "message": "commitVisibility: %s: hidden=%b hiddenRequested=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1089874824": {
+ "message": "SURFACE SHOW (performLayout): %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "-1077196445": {
+ "message": "Add starting %s: startingData=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-1076978367": {
+ "message": "thawRotation: mRotation=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1060365734": {
+ "message": "Attempted to add QS dialog window with bad token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1047945589": {
+ "message": "Remove client=%x, surfaceController=%s Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "-1044506655": {
+ "message": "New transit away from wallpaper: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "-1042574499": {
+ "message": "Attempted to add Accessibility overlay window with unknown token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-1009117329": {
+ "message": "isFetchingAppTransitionSpecs=true",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "-1001633850": {
+ "message": "Removing focused app token:%s displayId=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-993378225": {
+ "message": "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_DRAW",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "-986746907": {
+ "message": "Starting window removed %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "-979259577": {
+ "message": "setAppVisibility(%s, visible=%b): %s hidden=%b hiddenRequested=%b Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-955458843": {
+ "message": "Set freezing of %s: hidden=%b freezing=%b hiddenRequested=%b. %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-953872371": {
+ "message": "setClientHidden: %s clientHidden=%b Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-928291778": {
+ "message": "applyAnimation: anim=%s nextAppTransition=%d transit=%s Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "-916108501": {
+ "message": "Adding %s to %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "-914253865": {
+ "message": "Attempted to add voice interaction window with unknown token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-883738232": {
+ "message": "Adding more than one toast window for UID at a time.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-874446906": {
+ "message": "showBootMessage: msg=%s always=%b mAllowBootMessages=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_BOOT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-861859917": {
+ "message": "Attempted to add window to a display that does not exist: %d. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-861707633": {
+ "message": "Destroying surface %s called by %s",
+ "level": "INFO",
+ "group": "WM_SHOW_SURFACE_ALLOC",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "-856025122": {
+ "message": "SURFACE transparentRegionHint=%s: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-853404763": {
+ "message": "\twallpaper=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "-853226675": {
+ "message": "Attempted to add window with exiting application token .%s Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-809771899": {
+ "message": "findFocusedWindow: Reached focused app=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "-807062773": {
+ "message": "Aborted starting %s: removed=%b startingData=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-793346159": {
+ "message": "New transit into wallpaper: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "-784959154": {
+ "message": "Attempted to add private presentation window to a non-private display. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-783405930": {
+ "message": "Performing post-rotate rotation",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-771282525": {
+ "message": "Losing focus: %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-760801764": {
+ "message": "onAnimationCancelled",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
+ },
+ "-754503024": {
+ "message": "Relayout %s: oldVis=%d newVis=%d. %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-747671114": {
+ "message": "Failed looking up window callers=%s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-714291355": {
+ "message": "Losing delayed focus: %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-694710814": {
+ "message": "Pausing rotation during drag",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DragState.java"
+ },
+ "-687185281": {
+ "message": "New topFocusedDisplayId=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+ },
+ "-666510420": {
+ "message": "With display frozen, orientationChangeComplete=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+ },
+ "-666419717": {
+ "message": "Creating animation bounds layer",
+ "level": "INFO",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-653156702": {
+ "message": "createAppAnimations()",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "-650040763": {
+ "message": "rotationForOrientation(orient=%d, last=%d); user=%d %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "-635082269": {
+ "message": "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b wallEnabled=%b haveKeyguard=%b",
+ "level": "INFO",
+ "group": "WM_DEBUG_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "-622997754": {
+ "message": "postWindowRemoveCleanupLocked: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-618015844": {
+ "message": "performEnableScreen: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b mOnlyCore=%b. %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_BOOT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-583031528": {
+ "message": "%s",
+ "level": "INFO",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-576070986": {
+ "message": "Performing post-rotate rotation after seamless rotation",
+ "level": "INFO",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "-573268667": {
+ "message": "applyAnimation: transition animation is disabled or skipped. atoken=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-554834595": {
+ "message": "Display id=%d is frozen, return %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "-549028919": {
+ "message": "enableScreenIfNeededLocked: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_BOOT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-545190927": {
+ "message": "<<< CLOSE TRANSACTION animate",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowAnimator.java"
+ },
+ "-519504830": {
+ "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s isEntrance=%b Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "-507657818": {
+ "message": "Window %s is already added",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-496681057": {
+ "message": "Attempted to get remove mode of a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-481924678": {
+ "message": "handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w.isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_KEEP_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+ },
+ "-477481651": {
+ "message": "SURFACE DESTROY PENDING: %s. %s",
+ "level": "INFO",
+ "group": "WM_SHOW_SURFACE_ALLOC",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "-445944810": {
+ "message": "finish(%b): mCanceled=%b",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "-444624452": {
+ "message": "REPARENT from: %s to: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "-439951996": {
+ "message": "Disabling listeners",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "-415912575": {
+ "message": "setTask: %s at top.",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
+ "-415865166": {
+ "message": "findFocusedWindow: Found new focus @ %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "-405536909": {
+ "message": "Removing snapshot surface",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/TaskSnapshotSurface.java"
+ },
+ "-393505149": {
+ "message": "unable to update pointer icon",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-386552155": {
+ "message": "Attempted to set system decors flag to a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-379068494": {
+ "message": "unknownApps is not empty: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "-371630969": {
+ "message": "New wallpaper target=%s, oldWallpaper=%s, openingApps=%s, closingApps=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "-367797467": {
+ "message": "Creating SplashScreenStartingData",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-344488673": {
+ "message": "Finishing drawing window %s: mDrawState=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "-336658140": {
+ "message": "Checking theme of starting window: 0x%x",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-324085783": {
+ "message": "SURFACE CROP %s: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "-322035974": {
+ "message": "App freeze timeout expired.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-320419645": {
+ "message": "Removing replaced window: %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "-198463978": {
+ "message": "updateRotationUnchecked: alwaysSendConfiguration=%b forceRelayout=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-193782861": {
+ "message": "Final remove of window: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_WINDOW_MOVEMENT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-167822951": {
+ "message": "Attempted to add starting window to token with already existing starting window",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-129722369": {
+ "message": "New transit: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "-121104356": {
+ "message": "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b mHasSurface=%b surfaceShowing=%b animating=%b app-animation=%b mWillReplaceWindow=%b inPendingTransaction=%b mDisplayFrozen=%b callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "-116086365": {
+ "message": "******************** ENABLING SCREEN!",
+ "level": "INFO",
+ "group": "WM_DEBUG_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-106400104": {
+ "message": "Preload recents with %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "-104758113": {
+ "message": "Removing app %s delayed=%b animation=%s animating=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-96848838": {
+ "message": "Gaining focus: %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-87705714": {
+ "message": "findFocusedWindow: focusedApp=null using new focus @ %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "-87703044": {
+ "message": "Boot completed: SurfaceFlinger is dead!",
+ "level": "ERROR",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "-86763148": {
+ "message": " KILL SURFACE SESSION %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/Session.java"
+ },
+ "-34965929": {
+ "message": "Moving pending starting from %s to %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "-29233992": {
+ "message": "SURFACE CLEAR CROP: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "-7343917": {
+ "message": "onAnimationFinished(): targetStack=%s targetActivity=%s mRestoreTargetBehindStack=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "9803449": {
+ "message": "startFreezingDisplayLocked: exitAnim=%d enterAnim=%d called by %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "10608884": {
+ "message": " FREEZE %s: CREATE",
+ "level": "INFO",
+ "group": "WM_SHOW_SURFACE_ALLOC",
+ "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
+ },
+ "11060725": {
+ "message": "Attempted to get system decors flag of a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "17696244": {
+ "message": "startAnimation(): mPendingStart=%b mCanceled=%b",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "38267433": {
+ "message": "Attempted to reset replacing window on non-existing app token %s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "44171776": {
+ "message": "Resetting app token %s of replacing window marks.",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "51200510": {
+ "message": " BLACK %s: DESTROY",
+ "level": "INFO",
+ "group": "WM_SHOW_SURFACE_ALLOC",
+ "at": "com\/android\/server\/wm\/BlackFrame.java"
+ },
+ "51628177": {
+ "message": "Attempted to get windowing mode of a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "83950285": {
+ "message": "removeAnimation(%d)",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "91350919": {
+ "message": "Attempted to set IME flag to a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "95281111": {
+ "message": "Attempted to get IME flag of a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "95902367": {
+ "message": "Relayout of %s: focusMayChange=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "100936473": {
+ "message": "Wallpaper animation!",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "115108840": {
+ "message": "Removing startingView=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "118187173": {
+ "message": "Enqueueing ADD_STARTING",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "123161180": {
+ "message": "SEVER CHILDREN",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "150351993": {
+ "message": "addWindow: %s startingWindow=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "152914409": {
+ "message": " BLACK %s: CREATE layer=%d",
+ "level": "INFO",
+ "group": "WM_SHOW_SURFACE_ALLOC",
+ "at": "com\/android\/server\/wm\/BlackFrame.java"
+ },
+ "154699456": {
+ "message": "Last window, removing starting window %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "173419252": {
+ "message": "No thumbnail header bitmap for: %d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "184362060": {
+ "message": "screenshotTask(%d): mCanceled=%b",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "186668272": {
+ "message": "Now changing app %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "194124419": {
+ "message": "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "196230599": {
+ "message": "Moving existing starting %s from %s to %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "221540118": {
+ "message": "mUserActivityTimeout set to %d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_KEEP_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+ },
+ "241961619": {
+ "message": "Adding %s to %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowToken.java"
+ },
+ "246676969": {
+ "message": "Attempted to add window with non-application token .%s Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "248210157": {
+ "message": "Finishing remote animation",
+ "level": "INFO",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "254883724": {
+ "message": "addWindowToken: Attempted to add binder token: %s for already created window token: %s displayId=%d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "255692476": {
+ "message": "**** GOOD TO GO",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "269576220": {
+ "message": "Resuming rotation after drag",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DragState.java"
+ },
+ "274773837": {
+ "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL transit=%s Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "285317231": {
+ "message": "Input focus has changed to %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/InputMonitor.java"
+ },
+ "288485303": {
+ "message": "Attempted to set remove mode to a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "289967521": {
+ "message": "Check opening app=%s: allDrawn=%b startingDisplayed=%b startingMoved=%b isRelaunching()=%b startingWindow=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "292904800": {
+ "message": "Deferring rotation, animation in progress.",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "302992539": {
+ "message": "addAnimation(%s)",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "309039362": {
+ "message": "SURFACE MATRIX [%f,%f,%f,%f]: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "342460966": {
+ "message": "DRAG %s: pos=(%d,%d)",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/DragState.java"
+ },
+ "344795667": {
+ "message": "*** APP TRANSITION TIMEOUT. displayId=%d isTransitionSet()=%b mOpeningApps.size()=%d mClosingApps.size()=%d mChangingApps.size()=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "355720268": {
+ "message": "stopFreezingDisplayLocked: Unfreezing now",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "371641947": {
+ "message": "Window Manager Crash %s",
+ "level": "WTF",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "374972436": {
+ "message": "performEnableScreen: Waiting for anim complete",
+ "level": "INFO",
+ "group": "WM_DEBUG_BOOT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "385096046": {
+ "message": "Delaying loss of focus...",
+ "level": "INFO",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "399841913": {
+ "message": "SURFACE RECOVER DESTROY: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_SURFACE_ALLOC",
+ "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+ },
+ "416664944": {
+ "message": "No longer freezing: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "417311568": {
+ "message": "onResize: Resizing %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RESIZE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "424524729": {
+ "message": "Attempted to add wallpaper window with unknown token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "435494046": {
+ "message": "Attempted to add window to a display for which the application does not have access: %d. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "457951957": {
+ "message": "\tNot visible=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
+ },
+ "463993897": {
+ "message": "Aborted waiting for drawn: %s",
+ "level": "WARN",
+ "group": "WM_DEBUG_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "474000473": {
+ "message": "No stack above target stack=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "481370485": {
+ "message": "Computed rotation=%d for display id=%d based on lastOrientation=%d and oldRotation=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "490877640": {
+ "message": "onStackOrderChanged(): stack=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "492980365": {
+ "message": "TRANSIT_TASK_OPEN_BEHIND, adding %s to mOpeningApps",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "495032901": {
+ "message": "Expected target stack=%s to restored behind stack=%s but it is behind stack=%s",
+ "level": "WARN",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "508887531": {
+ "message": "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "557227556": {
+ "message": "onAnimationFinished(): Notify animation finished:",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "558823034": {
+ "message": "SURFACE isOpaque=%b: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "585096182": {
+ "message": "SURFACE isColorSpaceAgnostic=%b: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "594260577": {
+ "message": "createWallpaperAnimations()",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "600140673": {
+ "message": "checkBootAnimationComplete: Waiting for anim complete",
+ "level": "INFO",
+ "group": "WM_DEBUG_BOOT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "608694300": {
+ "message": " NEW SURFACE SESSION %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/Session.java"
+ },
+ "620368427": {
+ "message": "******* TELLING SURFACE FLINGER WE ARE BOOTED!",
+ "level": "INFO",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "628276090": {
+ "message": "Delaying app transition for screen rotation animation to finish",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "631792420": {
+ "message": "Attempted to add window with token that is not a window: %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "633654009": {
+ "message": "SURFACE POS (setPositionInTransaction) @ (%f,%f): %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "644675193": {
+ "message": "Real start recents",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "646155519": {
+ "message": "Started intent=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "662572728": {
+ "message": "Attempted to add a toast window with bad token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "665256544": {
+ "message": "All windows drawn!",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "668425960": {
+ "message": "Notify removed startingWindow %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
"676824470": {
"message": "Test completed successfully: %b %d %o %x %e %g %f %% %s.",
"level": "ERROR",
"group": "TEST_GROUP",
"at": "com\/android\/server\/wm\/ProtoLogGroup.java"
+ },
+ "685047360": {
+ "message": "Resizing window %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_RESIZE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "690411811": {
+ "message": "goodToGo(): No apps to animate",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "693423992": {
+ "message": "setAnimationLocked: setting mFocusMayChange true",
+ "level": "INFO",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "704998117": {
+ "message": "Failed to create surface control for %s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "745391677": {
+ "message": " CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x \/ %s",
+ "level": "INFO",
+ "group": "WM_SHOW_SURFACE_ALLOC",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "758852025": {
+ "message": "Surface returned was null: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "765395228": {
+ "message": "onAnimationFinished(): controller=%s reorderMode=%d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "791468751": {
+ "message": "Pausing rotation during re-position",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/TaskPositioner.java"
+ },
+ "794570322": {
+ "message": "Now closing app %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "811802785": {
+ "message": "Changing app %s hidden=%b performLayout=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "829434921": {
+ "message": "Draw state now committed in %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "835814848": {
+ "message": "%s",
+ "level": "INFO",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "845234215": {
+ "message": "App is requesting an orientation, return %d for display id=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "847534382": {
+ "message": "Non-null appWindowToken for system window of rootType=%d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "853091290": {
+ "message": "Moved stack=%s behind stack=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "868946719": {
+ "message": "notifyAppResumed: wasStopped=%b %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "873914452": {
+ "message": "goodToGo()",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "884043983": {
+ "message": "removeDeadWindows: %s",
+ "level": "WARN",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "892244061": {
+ "message": "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d",
+ "level": "INFO",
+ "group": "WM_DEBUG_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "898863925": {
+ "message": "Attempted to add QS dialog window with unknown token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "913494177": {
+ "message": "removeAllWindowsIfPossible: removing win=%s",
+ "level": "WARN",
+ "group": "WM_DEBUG_WINDOW_MOVEMENT",
+ "at": "com\/android\/server\/wm\/WindowToken.java"
+ },
+ "916191774": {
+ "message": "Orientation change complete in %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "917739349": {
+ "message": "Set focused app to: %s moveFocusNow=%b displayId=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/ActivityDisplay.java"
+ },
+ "954470154": {
+ "message": "FORCED DISPLAY SCALING DISABLED",
+ "level": "INFO",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "990058731": {
+ "message": "notifyAppStopped: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "1001904964": {
+ "message": "***** BOOT TIMEOUT: forcing display enabled",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1004585481": {
+ "message": "%s forcing orientation to %d for display id=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "1021057640": {
+ "message": "Marking app token %s with replacing child windows.",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "1051545910": {
+ "message": "Exit animation finished in %s: remove=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "1073230342": {
+ "message": "startAnimation",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
+ },
+ "1089714158": {
+ "message": " FREEZE %s: DESTROY",
+ "level": "INFO",
+ "group": "WM_SHOW_SURFACE_ALLOC",
+ "at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
+ },
+ "1108406230": {
+ "message": "stopFreezingDisplayLocked: Returning mWaitingForConfig=%b, mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, mClientFreezingScreen=%b, mOpeningApps.size()=%d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1112047265": {
+ "message": "finishDrawingWindow: %s mDrawState=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1115417974": {
+ "message": "FORCED DISPLAY SIZE: %dx%d",
+ "level": "INFO",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1140424002": {
+ "message": "Finished screen turning on...",
+ "level": "INFO",
+ "group": "WM_DEBUG_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/DisplayPolicy.java"
+ },
+ "1160771501": {
+ "message": "Resize reasons for w=%s: %s surfaceResized=%b configChanged=%b dragResizingChanged=%b reportOrientationChanged=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_RESIZE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "1166381079": {
+ "message": "Execute app transition: %s, displayId: %d Callers=%s",
+ "level": "WARN",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "1195433019": {
+ "message": "Clearing startingData for token=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "1208313423": {
+ "message": "addWindowToken: Attempted to add token: %s for non-exiting displayId=%d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1219600119": {
+ "message": "addWindow: win=%s Callers=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/WindowToken.java"
+ },
+ "1220075598": {
+ "message": "SURFACE SIZE %dx%d: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowSurfaceController.java"
+ },
+ "1224307091": {
+ "message": "checkBootAnimationComplete: Animation complete!",
+ "level": "INFO",
+ "group": "WM_DEBUG_BOOT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1244668962": {
+ "message": "Added starting %s: startingWindow=%s startingView=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "1288731814": {
+ "message": "WindowState.hideLw: setting mFocusMayChange true",
+ "level": "INFO",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "1325649102": {
+ "message": "Bad requesting window %s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1329340614": {
+ "message": "Orientation not waiting for draw in %s, surfaceController %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "1331177619": {
+ "message": "Attempted to add a toast window with unknown token %s. Aborting.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1358462645": {
+ "message": "Looking for focus: %s, flags=%d, canReceive=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "1401700824": {
+ "message": "Window drawn win=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1404220922": {
+ "message": "Translucent=%s Floating=%s ShowWallpaper=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "1422781269": {
+ "message": "Resuming rotation after re-position",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/TaskPositioner.java"
+ },
+ "1423418408": {
+ "message": "unable to restore pointer icon",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1423592961": {
+ "message": "<<< CLOSE TRANSACTION removeReplacedWindows",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+ },
+ "1430336882": {
+ "message": "findFocusedWindow: focusedApp windows not focusable using new focus @ %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "1434383382": {
+ "message": "Attempted to get flag of a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1448683958": {
+ "message": "Override pending remote transitionSet=%b adapter=%s",
+ "level": "INFO",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "1457990604": {
+ "message": "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM_IN_PLACE transit=%s Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "1469292670": {
+ "message": "Changing focus from %s to %s displayId=%d Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "1495525537": {
+ "message": "createWallpaperAnimations()",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "1496418389": {
+ "message": "Removing starting %s from %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "1497304204": {
+ "message": "Deferring rotation, rotation is paused.",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "1504168072": {
+ "message": "removeIfPossible: %s callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "1518495446": {
+ "message": "removeWindowToken: Attempted to remove non-existing token: %s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1519757176": {
+ "message": "setHomeApp(%s)",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "1521476038": {
+ "message": "Attempted to set flag to a display that does not exist: %d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1525976603": {
+ "message": "cancelAnimation(): reason=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimationController.java"
+ },
+ "1531527061": {
+ "message": "createAnimationAdapter(): token=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "1563755163": {
+ "message": "Permission Denial: %s from pid=%d, uid=%d requires %s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1573332272": {
+ "message": "Display id=%d selected orientation %d, got rotation %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "1577579529": {
+ "message": "win=%s destroySurfaces: appStopped=%b win.mWindowRemovalAllowed=%b win.mRemoveOnExit=%b",
+ "level": "ERROR",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "1589610525": {
+ "message": "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: anim=%s transit=%s isEntrance=true Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "1628345525": {
+ "message": "Now opening app %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "1634557978": {
+ "message": "**** Dismissing screen rotation animation",
+ "level": "INFO",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1635462459": {
+ "message": "onMovedByResize: Moving %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RESIZE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "1637745145": {
+ "message": "Clear freezing of %s force=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "1720696061": {
+ "message": "Adding window to Display that has been removed.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1739298851": {
+ "message": "removeWindowToken: Attempted to remove token: %s for non-exiting displayId=%d",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1747941491": {
+ "message": "SURFACE controller=%s alpha=%f matrix=[%f*%f,%f*%f][%f*%f,%f*%f]: %s",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "1756082882": {
+ "message": "Orientation change skips hidden %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/WindowStateAnimator.java"
+ },
+ "1762317752": {
+ "message": "Expected target stack=%s to be top most but found stack=%s",
+ "level": "WARN",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RecentsAnimation.java"
+ },
+ "1764592478": {
+ "message": "reparent: moving app token=%s to task=%d at %d",
+ "level": "INFO",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "1774661765": {
+ "message": "Devices still not ready after waiting %d milliseconds before attempting to detect safe mode.",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1814552834": {
+ "message": "performLayout: App token exiting now removed %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "1836306327": {
+ "message": "Skipping set freeze of %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
+ "1865125884": {
+ "message": "finishScreenTurningOn: mAwake=%b, mScreenOnEarly=%b, mScreenOnFully=%b, mKeyguardDrawComplete=%b, mWindowManagerDrawComplete=%b",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/DisplayPolicy.java"
+ },
+ "1865246212": {
+ "message": "\tapp=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "1866772666": {
+ "message": "SAFE MODE not enabled",
+ "level": "INFO",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "1878395049": {
+ "message": "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s surfaceInsets=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "1883987026": {
+ "message": "removeAppToken make exiting: %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "1891501279": {
+ "message": "cancelAnimation(): reason=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "1921821199": {
+ "message": "Preserving %s until the new one is added",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "1947239194": {
+ "message": "Deferring rotation, still finishing previous rotation",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "1964565370": {
+ "message": "Starting remote animation",
+ "level": "INFO",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
+ "1984470582": {
+ "message": "Creating TaskScreenshotAnimatable: task: %s width: %d height: %d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_RECENTS_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/TaskScreenshotAnimatable.java"
+ },
+ "1984738415": {
+ "message": "Now animating app in place %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "1984782949": {
+ "message": ">>> OPEN TRANSACTION animate",
+ "level": "INFO",
+ "group": "WM_SHOW_TRANSACTIONS",
+ "at": "com\/android\/server\/wm\/WindowAnimator.java"
+ },
+ "1993685727": {
+ "message": "Setting mOrientationChangeComplete=true because wtoken %s numInteresting=%d numDrawn=%d",
+ "level": "INFO",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "2016061474": {
+ "message": "Prepare app transition: transit=%s %s alwaysKeepCurrent=%b displayId=%d Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "2018454757": {
+ "message": "WS.removeImmediately: %s Already removed...",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "2028163120": {
+ "message": "applyAnimation: anim=%s nextAppTransition=ANIM_SCALE_UP transit=%s isEntrance=%s Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
+ },
+ "2034780299": {
+ "message": "CHECK_IF_BOOT_ANIMATION_FINISHED:",
+ "level": "INFO",
+ "group": "WM_DEBUG_BOOT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "2045641491": {
+ "message": "Checking %d opening apps (frozen=%b timeout=%b)...",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/AppTransitionController.java"
+ },
+ "2054958632": {
+ "message": "Schedule remove starting %s startingWindow=%s startingView=%s Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "2057434754": {
+ "message": "\tvisible=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/WallpaperAnimationAdapter.java"
+ },
+ "2076259606": {
+ "message": "Finish starting %s: first real window is shown, no animation",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_STARTING_WINDOW",
+ "at": "com\/android\/server\/wm\/AppWindowToken.java"
+ },
+ "2083556954": {
+ "message": "Set mOrientationChanging of %s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "2086878461": {
+ "message": "Could not send command %s with parameters %s. %s",
+ "level": "WARN",
+ "group": "WM_ERROR",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "2088592090": {
+ "message": "handleNotObscuredLocked: %s was holding screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_KEEP_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+ },
+ "2096635066": {
+ "message": "Acquiring screen wakelock due to %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_KEEP_SCREEN_ON",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
+ "2114149926": {
+ "message": "Not removing %s because app died while it's visible",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ADD_REMOVE",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
+ "2128604122": {
+ "message": "findFocusedWindow: No focusable windows.",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
+ "2128917433": {
+ "message": "onProposedRotationChanged, rotation=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_ORIENTATION",
+ "at": "com\/android\/server\/wm\/DisplayRotation.java"
+ },
+ "2137411379": {
+ "message": "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b Callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/AppTransition.java"
}
},
"groups": {
"TEST_GROUP": {
"tag": "WindowManagetProtoLogTest"
+ },
+ "WM_DEBUG_ADD_REMOVE": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_APP_TRANSITIONS": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_APP_TRANSITIONS_ANIM": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_BOOT": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_DRAW": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_FOCUS": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_FOCUS_LIGHT": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_KEEP_SCREEN_ON": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_ORIENTATION": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_RECENTS_ANIMATIONS": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_REMOTE_ANIMATIONS": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_RESIZE": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_SCREEN_ON": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_STARTING_WINDOW": {
+ "tag": "WindowManager"
+ },
+ "WM_DEBUG_WINDOW_MOVEMENT": {
+ "tag": "WindowManager"
+ },
+ "WM_ERROR": {
+ "tag": "WindowManager"
+ },
+ "WM_SHOW_SURFACE_ALLOC": {
+ "tag": "WindowManager"
+ },
+ "WM_SHOW_TRANSACTIONS": {
+ "tag": "WindowManager"
}
}
}
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 1829d2f..bf23634 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -343,6 +343,16 @@
public static final int KEY_ATTESTATION_FAILURE = 4;
/**
+ * Used by DPC or delegated app in
+ * {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias} or
+ * {@link android.app.admin.DelegatedAdminReceiver#onChoosePrivateKeyAlias} to identify that
+ * the requesting app is not granted access to any key, and nor will the user be able to grant
+ * access manually.
+ */
+ public static final String KEY_ALIAS_SELECTION_DENIED =
+ "alias-selection-denied-ef829e15-210a-409d-96c9-ee684fc41972";
+
+ /**
* Returns an {@code Intent} that can be used for credential
* installation. The intent may be used without any extras, in
* which case the user will be able to install credentials from
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index fc26813..dc07f0d 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -39,7 +39,7 @@
// to the screen resolution. This is meant to be a conservative default based on
// that analysis. The 4.0f is used because the default pixel format is assumed to
// be ARGB_8888.
-#define SURFACE_SIZE_MULTIPLIER (12.0f * 4.0f)
+#define SURFACE_SIZE_MULTIPLIER (5.0f * 4.0f)
#define BACKGROUND_RETENTION_PERCENTAGE (0.5f)
CacheManager::CacheManager(const DisplayInfo& display)
@@ -135,7 +135,7 @@
return;
}
mGrContext->flush();
- mGrContext->purgeResourcesNotUsedInMs(std::chrono::seconds(30));
+ mGrContext->performDeferredCleanup(std::chrono::seconds(30));
}
sp<skiapipeline::VectorDrawableAtlas> CacheManager::acquireVectorDrawableAtlas() {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 684dc22..93fd0c8 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -491,9 +491,9 @@
swap.dequeueDuration = 0;
} else {
swap.dequeueDuration =
- us2ns(ANativeWindow_getLastDequeueDuration(mNativeSurface.get()));
+ ANativeWindow_getLastDequeueDuration(mNativeSurface.get());
}
- swap.queueDuration = us2ns(ANativeWindow_getLastQueueDuration(mNativeSurface.get()));
+ swap.queueDuration = ANativeWindow_getLastQueueDuration(mNativeSurface.get());
} else {
swap.dequeueDuration = 0;
swap.queueDuration = 0;
@@ -646,11 +646,11 @@
ATRACE_CALL();
if (!thread.getGrContext()) return;
ATRACE_CALL();
- if (level >= TRIM_MEMORY_COMPLETE) {
+ if (level >= TRIM_MEMORY_UI_HIDDEN) {
thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
+ }
+ if (level >= TRIM_MEMORY_COMPLETE) {
thread.destroyRenderingContext();
- } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
- thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
}
}
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 6b47d1d..f3d6875 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -27,7 +27,6 @@
import android.annotation.Nullable;
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
@@ -134,23 +133,27 @@
/**
* This key is no longer in use.
*
- * Key used for a Bundle extra holding an Integer status value
- * when a status change is broadcast using a PendingIntent.
+ * <p>Key used for a Bundle extra holding an Integer status value when a status change is
+ * broadcast using a PendingIntent.
*
- * @deprecated Status changes are deprecated and no longer broadcast.
+ * @deprecated Status changes are deprecated and no longer broadcast from Android Q onwards.
*/
@Deprecated
public static final String KEY_STATUS_CHANGED = "status";
/**
- * Key used for a Bundle extra holding an Boolean status value
- * when a provider enabled/disabled event is broadcast using a PendingIntent.
+ * Key used for an extra holding a boolean enabled/disabled status value when a provider
+ * enabled/disabled event is broadcast using a PendingIntent.
+ *
+ * @see #requestLocationUpdates(String, long, long, PendingIntent)
*/
public static final String KEY_PROVIDER_ENABLED = "providerEnabled";
/**
- * Key used for a Bundle extra holding a Location value
- * when a location change is broadcast using a PendingIntent.
+ * Key used for an extra holding a {@link Location} value when a location change is broadcast
+ * using a PendingIntent.
+ *
+ * @see #requestLocationUpdates(String, long, long, PendingIntent)
*/
public static final String KEY_LOCATION_CHANGED = "location";
@@ -382,7 +385,7 @@
}
/**
- * Returns the current enabled/disabled state of location.
+ * Returns the current enabled/disabled state of location for the given user.
*
* @param userHandle the user to query
* @return true if location is enabled and false if location is disabled.
@@ -399,7 +402,7 @@
}
/**
- * Enables or disables the location setting.
+ * Enables or disables location for the given user.
*
* @param enabled true to enable location and false to disable location.
* @param userHandle the user to set
@@ -455,7 +458,7 @@
@SystemApi
public boolean isProviderEnabledForUser(
@NonNull String provider, @NonNull UserHandle userHandle) {
- checkProvider(provider);
+ Preconditions.checkArgument(provider != null, "invalid null provider");
try {
return mService.isProviderEnabledForUser(provider, userHandle.getIdentifier());
@@ -484,7 +487,7 @@
@RequiresPermission(WRITE_SECURE_SETTINGS)
public boolean setProviderEnabledForUser(
@NonNull String provider, boolean enabled, @NonNull UserHandle userHandle) {
- checkProvider(provider);
+ Preconditions.checkArgument(provider != null, "invalid null provider");
return Settings.Secure.putStringForUser(
mContext.getContentResolver(),
@@ -494,57 +497,45 @@
}
/**
- * Get the last known location.
+ * Gets the last known location from the fused provider, or null if there is no last known
+ * location. The returned location may be quite old in some circumstances, so the age of the
+ * location should always be checked.
*
- * <p>This location could be very old so use
- * {@link Location#getElapsedRealtimeNanos} to calculate its age. It can
- * also return null if no previous location is available.
- *
- * <p>Always returns immediately.
- *
- * @return The last known location, or null if not available
- * @throws SecurityException if no suitable permission is present
+ * @return the last known location, or null if not available
+ * @throws SecurityException if no suitable location permission is present
*
* @hide
*/
@Nullable
+ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public Location getLastLocation() {
- String packageName = mContext.getPackageName();
-
try {
- return mService.getLastLocation(null, packageName);
+ return mService.getLastLocation(null, mContext.getPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
- * Returns a Location indicating the data from the last known
- * location fix obtained from the given provider.
- *
- * <p> This can be done
- * without starting the provider. Note that this location could
- * be out-of-date, for example if the device was turned off and
- * moved to another location.
- *
- * <p> If the provider is currently disabled, null is returned.
+ * Gets the last known location from the given provider, or null if there is no last known
+ * location. The returned location may be quite old in some circumstances, so the age of the
+ * location should always be checked.
*
* @param provider the name of the provider
- * @return the last known location for the provider, or null
- *
+ * @return the last known location for the given provider, or null if not available
* @throws SecurityException if no suitable permission is present
* @throws IllegalArgumentException if provider is null or doesn't exist
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
@Nullable
public Location getLastKnownLocation(@NonNull String provider) {
- checkProvider(provider);
- String packageName = mContext.getPackageName();
+ Preconditions.checkArgument(provider != null, "invalid null provider");
+
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
provider, 0, 0, true);
try {
- return mService.getLastLocation(request, packageName);
+ return mService.getLastLocation(request, mContext.getPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -554,7 +545,7 @@
* Register for a single location update using the named provider and
* a callback.
*
- * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
+ * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener, Looper)}
* for more detail on how to use this method.
*
* @param provider the name of the provider with which to register
@@ -568,12 +559,16 @@
* @throws IllegalArgumentException if provider is null or doesn't exist
* @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present
+ * @deprecated This method can drain much more battery than expected if it is not possible to
+ * calculate location. Prefer any of the requestLocationUpdates() methods which require explicit
+ * removal.
*/
+ @Deprecated
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestSingleUpdate(
@NonNull String provider, @NonNull LocationListener listener, @Nullable Looper looper) {
- checkProvider(provider);
- checkListener(listener);
+ Preconditions.checkArgument(provider != null, "invalid null provider");
+ Preconditions.checkArgument(listener != null, "invalid null listener");
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
provider, 0, 0, true);
@@ -599,14 +594,17 @@
* @throws IllegalArgumentException if criteria is null
* @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present
+ * @deprecated This method can drain much more battery than expected if it is not possible to
+ * calculate location. Prefer any of the requestLocationUpdates() methods which require explicit
+ * removal.
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestSingleUpdate(
@NonNull Criteria criteria,
@NonNull LocationListener listener,
@Nullable Looper looper) {
- checkCriteria(criteria);
- checkListener(listener);
+ Preconditions.checkArgument(criteria != null, "invalid null criteria");
+ Preconditions.checkArgument(listener != null, "invalid null listener");
LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
criteria, 0, 0, true);
@@ -625,10 +623,13 @@
* @throws IllegalArgumentException if provider is null or doesn't exist
* @throws IllegalArgumentException if intent is null
* @throws SecurityException if no suitable permission is present
+ * @deprecated This method can drain much more battery than expected if it is not possible to
+ * calculate location. Prefer any of the requestLocationUpdates() methods which require explicit
+ * removal.
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestSingleUpdate(@NonNull String provider, @NonNull PendingIntent intent) {
- checkProvider(provider);
+ Preconditions.checkArgument(provider != null, "invalid null provider");
checkPendingIntent(intent);
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
@@ -649,10 +650,13 @@
* @throws IllegalArgumentException if provider is null or doesn't exist
* @throws IllegalArgumentException if intent is null
* @throws SecurityException if no suitable permission is present
+ * @deprecated This method can drain much more battery than expected if it is not possible to
+ * calculate location. Prefer any of the requestLocationUpdates() methods which require explicit
+ * removal.
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestSingleUpdate(@NonNull Criteria criteria, @NonNull PendingIntent intent) {
- checkCriteria(criteria);
+ Preconditions.checkArgument(criteria != null, "invalid null criteria");
checkPendingIntent(intent);
LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
@@ -661,84 +665,121 @@
}
/**
- * Register for location updates using the named provider, and a
- * pending intent.
+ * Register for location updates from the given provider with the given arguments. {@link
+ * LocationListener} callbacks will take place on the given {@link Looper} or {@link Executor}.
+ * If a null {@link Looper} is supplied, the Looper of the calling thread will be used instead.
+ * Only one request can be registered for each unique listener, so any subsequent requests with
+ * the same listener will overwrite all associated arguments.
*
- * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
- * for more detail on how to use this method.
+ * <p> It may take a while to receive the first location update. If an immediate location is
+ * required, applications may use the {@link #getLastKnownLocation(String)} method.
+ *
+ * <p> The location update interval can be controlled using the minimum time parameter. The
+ * elapsed time between location updates will never be less than this parameter, although it may
+ * be more depending on location availability and other factors. Choosing a sensible value for
+ * the minimum time parameter is important to conserve battery life. Every location update
+ * requires power from a variety of sensors. Select a minimum time parameter as high as possible
+ * while still providing a reasonable user experience. If your application is not in the
+ * foreground and showing location to the user then your application should consider switching
+ * to the {@link #PASSIVE_PROVIDER} instead.
+ *
+ * <p> The minimum distance parameter can also be used to control the frequency of location
+ * updates. If it is greater than 0 then the location provider will only send your application
+ * an update when the location has changed by at least minDistance meters, AND when the minimum
+ * time has elapsed. However it is more difficult for location providers to save power using the
+ * minimum distance parameter, so the minimum time parameter should be the primary tool for
+ * conserving battery life.
+ *
+ * <p> If your application wants to passively observe location updates triggered by other
+ * applications, but not consume any additional power otherwise, then use the {@link
+ * #PASSIVE_PROVIDER}. This provider does not turn on or modify active location providers, so
+ * you do not need to be as careful about minimum time and minimum distance parameters. However,
+ * if your application performs heavy work on a location update (such as network activity) then
+ * you should select non-zero values for the parameters to rate-limit your update frequency in
+ * the case another application enables a location provider with extremely fast updates.
+ *
+ * <p>In case the provider you have selected is disabled, location updates will cease, and a
+ * provider availability update will be sent. As soon as the provider is enabled again, another
+ * provider availability update will be sent and location updates will immediately resume.
+ *
+ * <p> When location callbacks are invoked, the system will hold a wakelock on your
+ * application's behalf for some period of time, but not indefinitely. If your application
+ * requires a long running wakelock within the location callback, you should acquire it
+ * yourself.
+ *
+ * <p class="note"> Prior to Jellybean, the minTime parameter was only a hint, and some location
+ * provider implementations ignored it. For Jellybean and onwards however, it is mandatory for
+ * Android compatible devices to observe both the minTime and minDistance parameters.
+ *
+ * <p>To unregister for location updates, use {@link #removeUpdates(LocationListener)}.
*
* @param provider the name of the provider with which to register
- * @param minTime minimum time interval between location updates, in milliseconds
- * @param minDistance minimum distance between location updates, in meters
- * @param listener a {@link LocationListener} whose
- * {@link LocationListener#onLocationChanged} method will be called for
- * each location update
+ * @param minTimeMs minimum time interval between location updates in milliseconds
+ * @param minDistanceM minimum distance between location updates in meters
+ * @param listener the listener to receive location updates
*
* @throws IllegalArgumentException if provider is null or doesn't exist
- * on this device
* @throws IllegalArgumentException if listener is null
* @throws RuntimeException if the calling thread has no Looper
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance,
+ public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM,
@NonNull LocationListener listener) {
- checkProvider(provider);
- checkListener(listener);
+ Preconditions.checkArgument(provider != null, "invalid null provider");
+ Preconditions.checkArgument(listener != null, "invalid null listener");
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
- provider, minTime, minDistance, false);
+ provider, minTimeMs, minDistanceM, false);
requestLocationUpdates(request, listener, null);
}
/**
* Register for location updates using the named provider, and a callback on
- * the specified looper thread.
+ * the specified {@link Looper}.
*
- * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
- * for more detail on how to use this method.
+ * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+ * for more detail on how this method works.
*
* @param provider the name of the provider with which to register
- * @param minTime minimum time interval between location updates, in milliseconds
- * @param minDistance minimum distance between location updates, in meters
- * @param listener a {@link LocationListener} whose
- * {@link LocationListener#onLocationChanged} method will be called for
- * each location update
- * @param looper a Looper object whose message queue will be used to
- * implement the callback mechanism, or null to make callbacks on the calling
- * thread
+ * @param minTimeMs minimum time interval between location updates in milliseconds
+ * @param minDistanceM minimum distance between location updates in meters
+ * @param listener the listener to receive location updates
+ * @param looper the looper handling listener callbacks, or null to use the looper of the
+ * calling thread
*
* @throws IllegalArgumentException if provider is null or doesn't exist
* @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance,
+ public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM,
@NonNull LocationListener listener, @Nullable Looper looper) {
- checkProvider(provider);
- checkListener(listener);
+ Preconditions.checkArgument(provider != null, "invalid null provider");
+ Preconditions.checkArgument(listener != null, "invalid null listener");
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
- provider, minTime, minDistance, false);
+ provider, minTimeMs, minDistanceM, false);
requestLocationUpdates(request, listener, looper);
}
/**
- * Register for location updates from the given provider with the given arguments. {@link
- * LocationListener} callbacks will take place on the given {@link Executor}. Only one request
- * can be registered for each unique listener, so any subsequent requests with the same listener
- * will overwrite all associated arguments.
+ * Register for location updates using the named provider, and a callback on
+ * the specified {@link Executor}.
*
- * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener, Looper)} for
- * more information.
+ * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+ * for more detail on how this method works.
*
- * @param provider the name of the provider used for location updates
- * @param minTimeMs minimum time interval between location updates, in milliseconds
- * @param minDistanceM minimum distance between location updates, in meters
- * @param executor all listener updates will take place on this {@link Executor}
- * @param listener a {@link LocationListener} that will be called when updates are available
- * @throws IllegalArgumentException if provider, listener, or looper is null or nonexistant
- * @throws SecurityException if no suitable permission is present
+ * @param provider the name of the provider with which to register
+ * @param minTimeMs minimum time interval between location updates in milliseconds
+ * @param minDistanceM minimum distance between location updates in meters
+ * @param executor the executor handling listener callbacks
+ * @param listener the listener to receive location updates
+ *
+ * @throws IllegalArgumentException if provider is null or doesn't exist
+ * @throws IllegalArgumentException if executor is null
+ * @throws IllegalArgumentException if listener is null
+ * @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestLocationUpdates(
@@ -753,50 +794,49 @@
}
/**
- * Register for location updates using a Criteria, and a callback
- * on the specified looper thread.
+ * Register for location updates using a provider selected through the given Criteria, and a
+ * callback on the specified {@link Looper}.
*
- * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
- * for more detail on how to use this method.
+ * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+ * for more detail on how this method works.
*
- * @param minTime minimum time interval between location updates, in milliseconds
- * @param minDistance minimum distance between location updates, in meters
- * @param criteria contains parameters for the location manager to choose the
- * appropriate provider and parameters to compute the location
- * @param listener a {@link LocationListener} whose
- * {@link LocationListener#onLocationChanged} method will be called for
- * each location update
- * @param looper a Looper object whose message queue will be used to
- * implement the callback mechanism, or null to make callbacks on the calling
- * thread
+ * @param minTimeMs minimum time interval between location updates in milliseconds
+ * @param minDistanceM minimum distance between location updates in meters
+ * @param criteria contains parameters to choose the appropriate provider for location updates
+ * @param listener the listener to receive location updates
*
* @throws IllegalArgumentException if criteria is null
* @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(long minTime, float minDistance, @NonNull Criteria criteria,
- @NonNull LocationListener listener, @Nullable Looper looper) {
- checkCriteria(criteria);
- checkListener(listener);
+ public void requestLocationUpdates(long minTimeMs, float minDistanceM,
+ @NonNull Criteria criteria, @NonNull LocationListener listener,
+ @Nullable Looper looper) {
+ Preconditions.checkArgument(criteria != null, "invalid null criteria");
+ Preconditions.checkArgument(listener != null, "invalid null listener");
LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
- criteria, minTime, minDistance, false);
+ criteria, minTimeMs, minDistanceM, false);
requestLocationUpdates(request, listener, looper);
}
/**
- * Uses the given {@link Criteria} to select a single provider to use for location updates.
+ * Register for location updates using a provider selected through the given Criteria, and a
+ * callback on the specified {@link Executor}.
*
- * <p>See {@link #requestLocationUpdates(String, long, float, Executor, LocationListener)} for
- * more information.
+ * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+ * for more detail on how this method works.
*
- * @param minTimeMs minimum time interval between location updates, in milliseconds
- * @param minDistanceM minimum distance between location updates, in meters
- * @param criteria the {@link Criteria} used to select a provider for location updates
- * @param executor all listener updates will take place on this {@link Executor}
- * @param listener a {@link LocationListener} that will be called when updates are available
- * @throws IllegalArgumentException if criteria, listener, or looper is null
+ * @param minTimeMs minimum time interval between location updates in milliseconds
+ * @param minDistanceM minimum distance between location updates in meters
+ * @param criteria contains parameters to choose the appropriate provider for location updates
+ * @param executor the executor handling listener callbacks
+ * @param listener the listener to receive location updates
+ *
+ * @throws IllegalArgumentException if criteria is null
+ * @throws IllegalArgumentException if executor is null
+ * @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
@@ -812,191 +852,81 @@
}
/**
- * Register for location updates using the named provider, and a
- * pending intent.
+ * Register for location updates using the named provider, and callbacks delivered via the
+ * provided {@link PendingIntent}.
*
- * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
- * for more detail on how to use this method.
+ * <p>The delivered pending intents will contain extras with the callback information. The keys
+ * used for the extras are {@link #KEY_LOCATION_CHANGED} and {@link #KEY_PROVIDER_ENABLED}. See
+ * the documentation for each respective extra key for information on the values.
+ *
+ * <p>To unregister for location updates, use {@link #removeUpdates(PendingIntent)}.
+ *
+ * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+ * for more detail on how this method works.
*
* @param provider the name of the provider with which to register
- * @param minTime minimum time interval between location updates, in milliseconds
- * @param minDistance minimum distance between location updates, in meters
- * @param intent a {@link PendingIntent} to be sent for each location update
+ * @param minTimeMs minimum time interval between location updates in milliseconds
+ * @param minDistanceM minimum distance between location updates in meters
+ * @param pendingIntent the pending intent to send location updates
*
* @throws IllegalArgumentException if provider is null or doesn't exist
- * on this device
- * @throws IllegalArgumentException if intent is null
+ * @throws IllegalArgumentException if pendingIntent is null
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance,
- @NonNull PendingIntent intent) {
- checkProvider(provider);
- checkPendingIntent(intent);
+ public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM,
+ @NonNull PendingIntent pendingIntent) {
+ Preconditions.checkArgument(provider != null, "invalid null provider");
+ checkPendingIntent(pendingIntent);
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
- provider, minTime, minDistance, false);
- requestLocationUpdates(request, intent);
+ provider, minTimeMs, minDistanceM, false);
+ requestLocationUpdates(request, pendingIntent);
}
/**
- * Register for location updates using a Criteria and pending intent.
+ * Register for location updates using a provider selected through the given Criteria, and
+ * callbacks delivered via the provided {@link PendingIntent}.
*
- * <p>The <code>requestLocationUpdates()</code> and
- * <code>requestSingleUpdate()</code> register the current activity to be
- * updated periodically by the named provider, or by the provider matching
- * the specified {@link Criteria}, with location and status updates.
+ * <p>See {@link #requestLocationUpdates(String, long, float, PendingIntent)} for more detail on
+ * how this method works.
*
- * <p> It may take a while to receive the first location update. If
- * an immediate location is required, applications may use the
- * {@link #getLastKnownLocation(String)} method.
+ * @param minTimeMs minimum time interval between location updates in milliseconds
+ * @param minDistanceM minimum distance between location updates in meters
+ * @param criteria contains parameters to choose the appropriate provider for location updates
+ * @param pendingIntent the pending intent to send location updates
*
- * <p> Location updates are received either by {@link LocationListener}
- * callbacks, or by broadcast intents to a supplied {@link PendingIntent}.
- *
- * <p> If the caller supplied a pending intent, then location updates
- * are sent with a key of {@link #KEY_LOCATION_CHANGED} and a
- * {@link android.location.Location} value.
- *
- * <p> The location update interval can be controlled using the minTime parameter.
- * The elapsed time between location updates will never be less than
- * minTime, although it can be more depending on the Location Provider
- * implementation and the update interval requested by other applications.
- *
- * <p> Choosing a sensible value for minTime is important to conserve
- * battery life. Each location update requires power from
- * GPS, WIFI, Cell and other radios. Select a minTime value as high as
- * possible while still providing a reasonable user experience.
- * If your application is not in the foreground and showing
- * location to the user then your application should avoid using an active
- * provider (such as {@link #NETWORK_PROVIDER} or {@link #GPS_PROVIDER}),
- * but if you insist then select a minTime of 5 * 60 * 1000 (5 minutes)
- * or greater. If your application is in the foreground and showing
- * location to the user then it is appropriate to select a faster
- * update interval.
- *
- * <p> The minDistance parameter can also be used to control the
- * frequency of location updates. If it is greater than 0 then the
- * location provider will only send your application an update when
- * the location has changed by at least minDistance meters, AND
- * at least minTime milliseconds have passed. However it is more
- * difficult for location providers to save power using the minDistance
- * parameter, so minTime should be the primary tool to conserving battery
- * life.
- *
- * <p> If your application wants to passively observe location
- * updates triggered by other applications, but not consume
- * any additional power otherwise, then use the {@link #PASSIVE_PROVIDER}
- * This provider does not actively turn on or modify active location
- * providers, so you do not need to be as careful about minTime and
- * minDistance. However if your application performs heavy work
- * on a location update (such as network activity) then you should
- * select non-zero values for minTime and/or minDistance to rate-limit
- * your update frequency in the case another application enables a
- * location provider with extremely fast updates.
- *
- * <p>In case the provider is disabled by the user, updates will stop,
- * and a provider availability update will be sent.
- * As soon as the provider is enabled again,
- * location updates will immediately resume and a provider availability
- * update sent. Providers can also send status updates, at any time,
- * with extra's specific to the provider. If a callback was supplied
- * then status and availability updates are via
- * {@link LocationListener#onProviderDisabled},
- * {@link LocationListener#onProviderEnabled} or
- * {@link LocationListener#onStatusChanged}. Alternately, if a
- * pending intent was supplied then status and availability updates
- * are broadcast intents with extra keys of
- * {@link #KEY_PROVIDER_ENABLED} or {@link #KEY_STATUS_CHANGED}.
- *
- * <p> If a {@link LocationListener} is used but with no Looper specified
- * then the calling thread must already
- * be a {@link android.os.Looper} thread such as the main thread of the
- * calling Activity. If a Looper is specified with a {@link LocationListener}
- * then callbacks are made on the supplied Looper thread.
- *
- * <p> When location callbacks are invoked, the system will hold a wakelock
- * on your application's behalf for some period of time, but not
- * indefinitely. If your application requires a long running wakelock
- * within the location callback, you should acquire it yourself.
- *
- * <p class="note"> Prior to Jellybean, the minTime parameter was
- * only a hint, and some location provider implementations ignored it.
- * From Jellybean and onwards it is mandatory for Android compatible
- * devices to observe both the minTime and minDistance parameters.
- *
- * @param minTime minimum time interval between location updates, in milliseconds
- * @param minDistance minimum distance between location updates, in meters
- * @param criteria contains parameters for the location manager to choose the
- * appropriate provider and parameters to compute the location
- * @param intent a {@link PendingIntent} to be sent for each location update
- *
- * @throws IllegalArgumentException if criteria is null
- * @throws IllegalArgumentException if intent is null
+ * @throws IllegalArgumentException if provider is null or doesn't exist
+ * @throws IllegalArgumentException if pendingIntent is null
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(long minTime, float minDistance, @NonNull Criteria criteria,
- @NonNull PendingIntent intent) {
- checkCriteria(criteria);
- checkPendingIntent(intent);
+ public void requestLocationUpdates(long minTimeMs, float minDistanceM,
+ @NonNull Criteria criteria, @NonNull PendingIntent pendingIntent) {
+ Preconditions.checkArgument(criteria != null, "invalid null criteria");
+ checkPendingIntent(pendingIntent);
LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
- criteria, minTime, minDistance, false);
- requestLocationUpdates(request, intent);
+ criteria, minTimeMs, minDistanceM, false);
+ requestLocationUpdates(request, pendingIntent);
}
/**
- * Register for fused location updates using a LocationRequest and callback.
+ * Register for location updates using a {@link LocationRequest}, and a callback on the
+ * specified {@link Looper}.
*
- * <p>Upon a location update, the system delivers the new {@link Location} to the
- * provided {@link LocationListener}, by calling its {@link
- * LocationListener#onLocationChanged} method.</p>
+ * <p>The system will automatically select and enable the best provider based on the given
+ * {@link LocationRequest}. The LocationRequest can be null, in which case the system will
+ * choose default low power parameters for location updates, but this is heavily discouraged,
+ * and an explicit LocationRequest should always be provided.
*
- * <p>The system will automatically select and enable the best providers
- * to compute a location for your application. It may use only passive
- * locations, or just a single location source, or it may fuse together
- * multiple location sources in order to produce the best possible
- * result, depending on the quality of service requested in the
- * {@link LocationRequest}.
+ * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+ * for more detail on how this method works.
*
- * <p>LocationRequest can be null, in which case the system will choose
- * default, low power parameters for location updates. You will occasionally
- * receive location updates as available, without a major power impact on the
- * system. If your application just needs an occasional location update
- * without any strict demands, then pass a null LocationRequest.
- *
- * <p>Only one LocationRequest can be registered for each unique callback
- * or pending intent. So a subsequent request with the same callback or
- * pending intent will over-write the previous LocationRequest.
- *
- * <p> If a pending intent is supplied then location updates
- * are sent with a key of {@link #KEY_LOCATION_CHANGED} and a
- * {@link android.location.Location} value. If a callback is supplied
- * then location updates are made using the
- * {@link LocationListener#onLocationChanged} callback, on the specified
- * Looper thread. If a {@link LocationListener} is used
- * but with a null Looper then the calling thread must already
- * be a {@link android.os.Looper} thread (such as the main thread) and
- * callbacks will occur on this thread.
- *
- * <p> Provider status updates and availability updates are deprecated
- * because the system is performing provider fusion on the applications
- * behalf. So {@link LocationListener#onProviderDisabled},
- * {@link LocationListener#onProviderEnabled}, {@link LocationListener#onStatusChanged}
- * will not be called, and intents with extra keys of
- * {@link #KEY_PROVIDER_ENABLED} or {@link #KEY_STATUS_CHANGED} will not
- * be received.
- *
- * <p> To unregister for Location updates, use: {@link #removeUpdates(LocationListener)}.
- *
- * @param locationRequest quality of service required, null for default low power
- * @param listener a {@link LocationListener} whose
- * {@link LocationListener#onLocationChanged} method will be called when
- * the location update is available
- * @param looper a Looper object whose message queue will be used to
- * implement the callback mechanism, or null to make callbacks on the calling
- * thread
+ * @param locationRequest the location request containing location parameters
+ * @param listener the listener to receive location updates
+ * @param looper the looper handling listener callbacks, or null to use the looper of the
+ * calling thread
*
* @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present
@@ -1007,54 +937,26 @@
@TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestLocationUpdates(
- @NonNull LocationRequest locationRequest,
+ @Nullable LocationRequest locationRequest,
@NonNull LocationListener listener,
@Nullable Looper looper) {
- requestLocationUpdates(locationRequest,
- new LocationListenerTransport(looper == null ? new Handler() : new Handler(looper),
- listener));
+ Handler handler = looper == null ? new Handler() : new Handler(looper);
+ requestLocationUpdates(locationRequest, new HandlerExecutor(handler), listener);
}
/**
- * Register for location updates with the given {@link LocationRequest}.
+ * Register for location updates using a {@link LocationRequest}, and a callback on the
+ * specified {@link Executor}.
*
- * <p>See {@link #requestLocationUpdates(String, long, float, Executor, LocationListener)} for
- * more information.
+ * <p>See {@link #requestLocationUpdates(LocationRequest, LocationListener, Looper)} for more
+ * detail on how this method works.
*
- * @param locationRequest the {@link LocationRequest} being made
- * @param executor all listener updates will take place on this {@link Executor}
- * @param listener a {@link LocationListener} that will be called when updates are
- * available
- * @throws IllegalArgumentException if locationRequest, listener, or executor is null
- * @throws SecurityException if no suitable permission is present
- * @hide
- */
- @SystemApi
- @TestApi
- @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(
- @NonNull LocationRequest locationRequest,
- @NonNull @CallbackExecutor Executor executor,
- @NonNull LocationListener listener) {
- requestLocationUpdates(locationRequest, new LocationListenerTransport(executor, listener));
- }
-
- /**
- * Register for fused location updates using a LocationRequest and a pending intent.
+ * @param locationRequest the location request containing location parameters
+ * @param executor the executor handling listener callbacks
+ * @param listener the listener to receive location updates
*
- * <p>Upon a location update, the system delivers the new {@link Location} with your provided
- * {@link PendingIntent}, as the value for {@link LocationManager#KEY_LOCATION_CHANGED}
- * in the intent's extras.</p>
- *
- * <p> To unregister for Location updates, use: {@link #removeUpdates(PendingIntent)}.
- *
- * <p> See {@link #requestLocationUpdates(LocationRequest, LocationListener, Looper)}
- * for more detail.
- *
- * @param locationRequest quality of service required, null for default low power
- * @param pendingIntent a {@link PendingIntent} to be sent for the location update
- *
- * @throws IllegalArgumentException if intent is null
+ * @throws IllegalArgumentException if executor is null
+ * @throws IllegalArgumentException if listener is null
* @throws SecurityException if no suitable permission is present
*
* @hide
@@ -1063,7 +965,57 @@
@TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestLocationUpdates(
- @NonNull LocationRequest locationRequest,
+ @Nullable LocationRequest locationRequest,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull LocationListener listener) {
+ synchronized (mListeners) {
+ LocationListenerTransport transport = mListeners.get(listener);
+ if (transport != null) {
+ transport.unregister();
+ } else {
+ transport = new LocationListenerTransport(listener);
+ mListeners.put(listener, transport);
+ }
+ transport.register(executor);
+
+ boolean registered = false;
+ try {
+ mService.requestLocationUpdates(locationRequest, transport, null,
+ mContext.getPackageName());
+ registered = true;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } finally {
+ if (!registered) {
+ // allow gc after exception
+ transport.unregister();
+ mListeners.remove(listener);
+ }
+ }
+ }
+ }
+
+ /**
+ * Register for location updates using a {@link LocationRequest}, and callbacks delivered via
+ * the provided {@link PendingIntent}.
+ *
+ * <p>See {@link #requestLocationUpdates(LocationRequest, LocationListener, Looper)} and
+ * {@link #requestLocationUpdates(String, long, float, PendingIntent)} for more detail on how
+ * this method works.
+ *
+ * @param locationRequest the location request containing location parameters
+ * @param pendingIntent the pending intent to send location updates
+ *
+ * @throws IllegalArgumentException if pendingIntent is null
+ * @throws SecurityException if no suitable permission is present
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+ public void requestLocationUpdates(
+ @Nullable LocationRequest locationRequest,
@NonNull PendingIntent pendingIntent) {
Preconditions.checkArgument(locationRequest != null, "invalid null location request");
Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent");
@@ -1080,23 +1032,6 @@
}
}
- private void requestLocationUpdates(LocationRequest request,
- LocationListenerTransport transport) {
- synchronized (mListeners) {
- LocationListenerTransport oldTransport = mListeners.put(transport.getKey(), transport);
- if (oldTransport != null) {
- oldTransport.unregisterListener();
- }
-
- try {
- mService.requestLocationUpdates(request, transport, null,
- mContext.getPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
/**
* Set the last known location with a new location.
*
@@ -1105,31 +1040,41 @@
* chipset is in the process of getting the first fix. If the client has cached the location,
* it can inject the {@link Location}, so if an app requests for a {@link Location} from {@link
* #getLastKnownLocation(String)}, the location information is still useful before getting
- * the first fix.</p>
+ * the first fix.
*
- * <p> Useful in products like Auto.
+ * @param location newly available {@link Location} object
+ * @return true if the location was successfully injected, false otherwise
*
- * @param newLocation newly available {@link Location} object
- * @return true if update was successful, false if not
- *
- * @throws SecurityException if no suitable permission is present
+ * @throws IllegalArgumentException if location is null
+ * @throws SecurityException if permissions are not present
*
* @hide
*/
@RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION})
- public boolean injectLocation(@NonNull Location newLocation) {
+ public boolean injectLocation(@NonNull Location location) {
+ if (location == null) {
+ IllegalArgumentException e = new IllegalArgumentException("invalid null location");
+ if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
+ throw e;
+ } else {
+ Log.w(TAG, e);
+ return false;
+ }
+ }
+
try {
- return mService.injectLocation(newLocation);
+ return mService.injectLocation(location);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
- * Removes location updates for the specified LocationListener. Following this call, updates
- * will no longer occur for this listener.
+ * Removes location updates for the specified {@link LocationListener}. Following this call,
+ * the listener will no longer receive location updates.
*
* @param listener listener that no longer needs location updates
+ *
* @throws IllegalArgumentException if listener is null
*/
public void removeUpdates(@NonNull LocationListener listener) {
@@ -1140,7 +1085,7 @@
if (transport == null) {
return;
}
- transport.unregisterListener();
+ transport.unregister();
try {
mService.removeUpdates(transport, null, mContext.getPackageName());
@@ -1151,10 +1096,11 @@
}
/**
- * Removes all location updates for the specified pending intent. Following this call, updates
- * will no longer occur for this pending intent.
+ * Removes location updates for the specified {@link PendingIntent}. Following this call, the
+ * PendingIntent will no longer receive location updates.
*
* @param pendingIntent pending intent that no longer needs location updates
+ *
* @throws IllegalArgumentException if pendingIntent is null
*/
public void removeUpdates(@NonNull PendingIntent pendingIntent) {
@@ -1168,11 +1114,11 @@
}
/**
- * Returns a list of the names of all known location providers.
- * <p>All providers are returned, including ones that are not permitted to
- * be accessed by the calling activity or are currently disabled.
+ * Returns a list of the names of all known location providers. All providers are returned,
+ * including ones that are not permitted to be accessed by the calling activity or are currently
+ * disabled.
*
- * @return list of Strings containing names of the provider
+ * @return list of provider names
*/
public @NonNull List<String> getAllProviders() {
try {
@@ -1183,11 +1129,11 @@
}
/**
- * Returns a list of the names of location providers.
+ * Returns a list of the names of location providers. Only providers that the caller has
+ * permission to access will be returned.
*
- * @param enabledOnly if true then only the providers which are currently
- * enabled are returned.
- * @return list of Strings containing names of the providers
+ * @param enabledOnly if true then only enabled providers are included
+ * @return list of provider names
*/
public @NonNull List<String> getProviders(boolean enabledOnly) {
try {
@@ -1198,17 +1144,18 @@
}
/**
- * Returns a list of the names of LocationProviders that satisfy the given
- * criteria, or null if none do. Only providers that are permitted to be
- * accessed by the calling activity will be returned.
+ * Returns a list of the names of providers that satisfy the given criteria. Only providers that
+ * the caller has permission to access will be returned.
*
- * @param criteria the criteria that the returned providers must match
- * @param enabledOnly if true then only the providers which are currently
- * enabled are returned.
- * @return list of Strings containing names of the providers
+ * @param criteria the criteria that providers must match
+ * @param enabledOnly if true then only enabled providers are included
+ * @return list of provider names
+ *
+ * @throws IllegalArgumentException if criteria is null
*/
public @NonNull List<String> getProviders(@NonNull Criteria criteria, boolean enabledOnly) {
- checkCriteria(criteria);
+ Preconditions.checkArgument(criteria != null, "invalid null criteria");
+
try {
return mService.getProviders(criteria, enabledOnly);
} catch (RemoteException e) {
@@ -1217,11 +1164,10 @@
}
/**
- * Returns the name of the provider that best meets the given criteria. Only providers
- * that are permitted to be accessed by the calling activity will be
- * returned. If several providers meet the criteria, the one with the best
- * accuracy is returned. If no provider meets the criteria,
- * the criteria are loosened in the following sequence:
+ * Returns the name of the provider that best meets the given criteria. Only providers that are
+ * permitted to be accessed by the caller will be returned. If several providers meet the
+ * criteria, the one with the best accuracy is returned. If no provider meets the criteria, the
+ * criteria are loosened in the following order:
*
* <ul>
* <li> power requirement
@@ -1231,15 +1177,17 @@
* <li> altitude
* </ul>
*
- * <p> Note that the requirement on monetary cost is not removed
- * in this process.
+ * <p> Note that the requirement on monetary cost is not removed in this process.
*
* @param criteria the criteria that need to be matched
- * @param enabledOnly if true then only a provider that is currently enabled is returned
- * @return name of the provider that best matches the requirements
+ * @param enabledOnly if true then only enabled providers are included
+ * @return name of the provider that best matches the criteria, or null if none match
+ *
+ * @throws IllegalArgumentException if criteria is null
*/
public @Nullable String getBestProvider(@NonNull Criteria criteria, boolean enabledOnly) {
- checkCriteria(criteria);
+ Preconditions.checkArgument(criteria != null, "invalid null criteria");
+
try {
return mService.getBestProvider(criteria, enabledOnly);
} catch (RemoteException e) {
@@ -1248,24 +1196,22 @@
}
/**
- * Returns the information associated with the location provider of the
- * given name, or null if no provider exists by that name.
+ * Returns the information about the location provider with the given name, or null if no
+ * provider exists by that name.
*
- * @param name the provider name
- * @return a LocationProvider, or null
+ * @param provider the provider name
+ * @return location provider information, or null if provider does not exist
*
- * @throws IllegalArgumentException if name is null or does not exist
- * @throws SecurityException if the caller is not permitted to access the
- * given provider.
+ * @throws IllegalArgumentException if provider is null
*/
- public @Nullable LocationProvider getProvider(@NonNull String name) {
- checkProvider(name);
+ public @Nullable LocationProvider getProvider(@NonNull String provider) {
+ Preconditions.checkArgument(provider != null, "invalid null provider");
try {
- ProviderProperties properties = mService.getProviderProperties(name);
+ ProviderProperties properties = mService.getProviderProperties(provider);
if (properties == null) {
return null;
}
- return new LocationProvider(name, properties);
+ return new LocationProvider(provider, properties);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1292,10 +1238,10 @@
* Sends additional commands to a location provider. Can be used to support provider specific
* extensions to the Location Manager API.
*
- * @param provider name of the location provider.
- * @param command name of the command to send to the provider.
- * @param extras optional arguments for the command (or null).
- * @return true always
+ * @param provider name of the location provider
+ * @param command name of the command to send to the provider
+ * @param extras optional arguments for the command, or null
+ * @return true always, the return value may be ignored
*/
public boolean sendExtraCommand(
@NonNull String provider, @NonNull String command, @Nullable Bundle extras) {
@@ -1469,7 +1415,7 @@
@TestApi
@NonNull
public List<LocationRequest> getTestProviderCurrentRequests(String providerName) {
- checkProvider(providerName);
+ Preconditions.checkArgument(providerName != null, "invalid null provider");
try {
return mService.getTestProviderCurrentRequests(providerName,
mContext.getOpPackageName());
@@ -1558,10 +1504,9 @@
*/
public void removeProximityAlert(@NonNull PendingIntent intent) {
checkPendingIntent(intent);
- String packageName = mContext.getPackageName();
try {
- mService.removeGeofence(null, intent, packageName);
+ mService.removeGeofence(null, intent, mContext.getPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1609,7 +1554,7 @@
@NonNull Geofence fence,
@NonNull PendingIntent intent) {
checkPendingIntent(intent);
- checkGeofence(fence);
+ Preconditions.checkArgument(fence != null, "invalid null geofence");
try {
mService.requestGeofence(request, fence, intent, mContext.getPackageName());
@@ -1636,11 +1581,10 @@
*/
public void removeGeofence(@NonNull Geofence fence, @NonNull PendingIntent intent) {
checkPendingIntent(intent);
- checkGeofence(fence);
- String packageName = mContext.getPackageName();
+ Preconditions.checkArgument(fence != null, "invalid null geofence");
try {
- mService.removeGeofence(fence, intent, packageName);
+ mService.removeGeofence(fence, intent, mContext.getPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1659,10 +1603,9 @@
*/
public void removeAllGeofences(@NonNull PendingIntent intent) {
checkPendingIntent(intent);
- String packageName = mContext.getPackageName();
try {
- mService.removeGeofence(null, intent, packageName);
+ mService.removeGeofence(null, intent, mContext.getPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1723,15 +1666,16 @@
}
/**
- * Retrieves information about the current status of the GPS engine.
- * This should only be called from the {@link GpsStatus.Listener#onGpsStatusChanged}
- * callback to ensure that the data is copied atomically.
+ * Retrieves information about the current status of the GPS engine. This should only be called
+ * from within the {@link GpsStatus.Listener#onGpsStatusChanged} callback to ensure that the
+ * data is copied atomically.
*
- * The caller may either pass in a {@link GpsStatus} object to set with the latest
- * status information, or pass null to create a new {@link GpsStatus} object.
+ * The caller may either pass in an existing {@link GpsStatus} object to be overwritten, or pass
+ * null to create a new {@link GpsStatus} object.
*
* @param status object containing GPS status details, or null.
* @return status object containing updated GPS status.
+ *
* @deprecated GpsStatus APIs are deprecated, use {@link GnssStatus} APIs instead.
*/
@Deprecated
@@ -1756,12 +1700,21 @@
* @param listener GPS status listener object to register
* @return true if the listener was successfully added
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ *
* @deprecated use {@link #registerGnssStatusCallback(GnssStatus.Callback)} instead. No longer
* supported in apps targeting R and above.
*/
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean addGpsStatusListener(GpsStatus.Listener listener) {
+ UnsupportedOperationException ex = new UnsupportedOperationException(
+ "GpsStatus APIs not supported in R and above, use GnssStatus APIs instead");
+ if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
+ throw ex;
+ } else {
+ Log.w(TAG, ex);
+ }
+
try {
return mGnssStatusListenerManager.addListener(listener, new Handler());
} catch (RemoteException e) {
@@ -1773,11 +1726,20 @@
* Removes a GPS status listener.
*
* @param listener GPS status listener object to remove
+ *
* @deprecated use {@link #unregisterGnssStatusCallback(GnssStatus.Callback)} instead. No longer
* supported in apps targeting R and above.
*/
@Deprecated
public void removeGpsStatusListener(GpsStatus.Listener listener) {
+ UnsupportedOperationException ex = new UnsupportedOperationException(
+ "GpsStatus APIs not supported in R and above, use GnssStatus APIs instead");
+ if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
+ throw ex;
+ } else {
+ Log.w(TAG, ex);
+ }
+
try {
mGnssStatusListenerManager.removeListener(listener);
} catch (RemoteException e) {
@@ -1790,7 +1752,9 @@
*
* @param callback GNSS status callback object to register
* @return true if the listener was successfully added
+ *
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ *
* @deprecated Use {@link #registerGnssStatusCallback(GnssStatus.Callback, Handler)} or {@link
* #registerGnssStatusCallback(Executor, GnssStatus.Callback)} instead.
*/
@@ -1804,8 +1768,9 @@
* Registers a GNSS status callback.
*
* @param callback GNSS status callback object to register
- * @param handler a handler with a looper that the callback runs on.
+ * @param handler a handler with a looper that the callback runs on
* @return true if the listener was successfully added
+ *
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
@@ -1826,8 +1791,9 @@
* Registers a GNSS status callback.
*
* @param callback GNSS status callback object to register
- * @param executor the executor that the callback runs on.
+ * @param executor the executor that the callback runs on
* @return true if the listener was successfully added
+ *
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
@@ -1855,13 +1821,8 @@
}
/**
- * Adds an NMEA listener.
+ * No-op method to keep backward-compatibility.
*
- * @param listener a {@link GpsStatus.NmeaListener} object to register
- *
- * @return true if the listener was successfully added
- *
- * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
* @deprecated use {@link #addNmeaListener(OnNmeaMessageListener)} instead.
* @removed
*/
@@ -1872,9 +1833,8 @@
}
/**
- * Removes an NMEA listener.
+ * No-op method to keep backward-compatibility.
*
- * @param listener a {@link GpsStatus.NmeaListener} object to remove
* @deprecated use {@link #removeNmeaListener(OnNmeaMessageListener)} instead.
* @removed
*/
@@ -1951,30 +1911,26 @@
/**
* No-op method to keep backward-compatibility.
- * Don't use it. Use {@link #registerGnssMeasurementsCallback} instead.
+ *
* @hide
- * @deprecated Not supported anymore.
+ * @deprecated Use {@link #registerGnssMeasurementsCallback} instead.
* @removed
*/
@Deprecated
@SystemApi
- @SuppressLint("Doclava125")
public boolean addGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) {
return false;
}
/**
- * No-op method to keep backward-compatibility. Don't use it. Use {@link
- * #unregisterGnssMeasurementsCallback} instead.
+ * No-op method to keep backward-compatibility.
*
* @hide
- * @deprecated use {@link #unregisterGnssMeasurementsCallback(GnssMeasurementsEvent.Callback)}
- * instead.
+ * @deprecated Use {@link #unregisterGnssMeasurementsCallback} instead.
* @removed
*/
@Deprecated
@SystemApi
- @SuppressLint("Doclava125")
public void removeGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) {}
/**
@@ -2067,30 +2023,26 @@
/**
* No-op method to keep backward-compatibility.
- * Don't use it. Use {@link #registerGnssNavigationMessageCallback} instead.
+ *
* @hide
- * @deprecated Not supported anymore.
+ * @deprecated Use {@link #registerGnssNavigationMessageCallback} instead.
* @removed
*/
@Deprecated
@SystemApi
- @SuppressLint("Doclava125")
public boolean addGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {
return false;
}
/**
* No-op method to keep backward-compatibility.
- * Don't use it. Use {@link #unregisterGnssNavigationMessageCallback} instead.
+ *
* @hide
- * @deprecated use
- * {@link #unregisterGnssNavigationMessageCallback(GnssNavigationMessage.Callback)}
- * instead
+ * @deprecated Use {@link #unregisterGnssNavigationMessageCallback} instead.
* @removed
*/
@Deprecated
@SystemApi
- @SuppressLint("Doclava125")
public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {}
/**
@@ -2276,31 +2228,11 @@
}
}
- private static void checkProvider(String provider) {
- if (provider == null) {
- throw new IllegalArgumentException("invalid provider: " + provider);
- }
- }
-
- private static void checkCriteria(Criteria criteria) {
- if (criteria == null) {
- throw new IllegalArgumentException("invalid criteria: " + criteria);
- }
- }
-
- private static void checkListener(LocationListener listener) {
- if (listener == null) {
- throw new IllegalArgumentException("invalid listener: " + listener);
- }
- }
-
- private void checkPendingIntent(PendingIntent intent) {
- if (intent == null) {
- throw new IllegalArgumentException("invalid pending intent: " + intent);
- }
- if (!intent.isTargetedToPackage()) {
+ private void checkPendingIntent(PendingIntent pendingIntent) {
+ Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent");
+ if (!pendingIntent.isTargetedToPackage()) {
IllegalArgumentException e = new IllegalArgumentException(
- "pending intent must be targeted to package");
+ "invalid pending intent - must be targeted to package");
if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.JELLY_BEAN) {
throw e;
} else {
@@ -2309,57 +2241,47 @@
}
}
- private static void checkGeofence(Geofence fence) {
- if (fence == null) {
- throw new IllegalArgumentException("invalid geofence: " + fence);
- }
- }
-
private class LocationListenerTransport extends ILocationListener.Stub {
- private final Executor mExecutor;
- @Nullable private volatile LocationListener mListener;
+ private final LocationListener mListener;
+ @Nullable private volatile Executor mExecutor = null;
- private LocationListenerTransport(@NonNull Handler handler,
- @NonNull LocationListener listener) {
- Preconditions.checkArgument(handler != null, "invalid null handler");
+ private LocationListenerTransport(@NonNull LocationListener listener) {
Preconditions.checkArgument(listener != null, "invalid null listener");
-
- mExecutor = new HandlerExecutor(handler);
mListener = listener;
}
- private LocationListenerTransport(@NonNull Executor executor,
- @NonNull LocationListener listener) {
- Preconditions.checkArgument(executor != null, "invalid null executor");
- Preconditions.checkArgument(listener != null, "invalid null listener");
-
- mExecutor = executor;
- mListener = listener;
- }
-
- private LocationListener getKey() {
+ public LocationListener getKey() {
return mListener;
}
- private void unregisterListener() {
- mListener = null;
+ public void register(@NonNull Executor executor) {
+ Preconditions.checkArgument(executor != null, "invalid null executor");
+ mExecutor = executor;
+ }
+
+ public void unregister() {
+ mExecutor = null;
}
@Override
public void onLocationChanged(Location location) {
+ Executor currentExecutor = mExecutor;
+ if (currentExecutor == null) {
+ return;
+ }
+
try {
- mExecutor.execute(() -> {
+ currentExecutor.execute(() -> {
try {
- LocationListener listener = mListener;
- if (listener == null) {
+ if (currentExecutor != mExecutor) {
return;
}
// we may be under the binder identity if a direct executor is used
long identity = Binder.clearCallingIdentity();
try {
- listener.onLocationChanged(location);
+ mListener.onLocationChanged(location);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -2375,18 +2297,22 @@
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
+ Executor currentExecutor = mExecutor;
+ if (currentExecutor == null) {
+ return;
+ }
+
try {
- mExecutor.execute(() -> {
+ currentExecutor.execute(() -> {
try {
- LocationListener listener = mListener;
- if (listener == null) {
+ if (currentExecutor != mExecutor) {
return;
}
// we may be under the binder identity if a direct executor is used
long identity = Binder.clearCallingIdentity();
try {
- listener.onStatusChanged(provider, status, extras);
+ mListener.onStatusChanged(provider, status, extras);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -2402,18 +2328,22 @@
@Override
public void onProviderEnabled(String provider) {
+ Executor currentExecutor = mExecutor;
+ if (currentExecutor == null) {
+ return;
+ }
+
try {
- mExecutor.execute(() -> {
+ currentExecutor.execute(() -> {
try {
- LocationListener listener = mListener;
- if (listener == null) {
+ if (currentExecutor != mExecutor) {
return;
}
// we may be under the binder identity if a direct executor is used
long identity = Binder.clearCallingIdentity();
try {
- listener.onProviderEnabled(provider);
+ mListener.onProviderEnabled(provider);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -2429,18 +2359,22 @@
@Override
public void onProviderDisabled(String provider) {
+ Executor currentExecutor = mExecutor;
+ if (currentExecutor == null) {
+ return;
+ }
+
try {
- mExecutor.execute(() -> {
+ currentExecutor.execute(() -> {
try {
- LocationListener listener = mListener;
- if (listener == null) {
+ if (currentExecutor != mExecutor) {
return;
}
// we may be under the binder identity if a direct executor is used
long identity = Binder.clearCallingIdentity();
try {
- listener.onProviderDisabled(provider);
+ mListener.onProviderDisabled(provider);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 2d6cd24..f797da7 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1857,12 +1857,37 @@
}
/**
+ * @hide
+ * Sets the microphone from switch mute on or off.
+ * <p>
+ * This method should only be used by InputManager to notify
+ * Audio Subsystem about Microphone Mute switch state.
+ *
+ * @param on set <var>true</var> to mute the microphone;
+ * <var>false</var> to turn mute off
+ */
+ @UnsupportedAppUsage
+ public void setMicrophoneMuteFromSwitch(boolean on) {
+ final IAudioService service = getService();
+ try {
+ service.setMicrophoneMuteFromSwitch(on);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Checks whether the microphone mute is on or off.
*
* @return true if microphone is muted, false if it's not
*/
public boolean isMicrophoneMute() {
- return AudioSystem.isMicrophoneMuted();
+ final IAudioService service = getService();
+ try {
+ return service.isMicrophoneMuted();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 53babcb..5341d07 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -1357,6 +1357,7 @@
private AssetManager.AssetInputStream mAssetInputStream;
private boolean mIsInputStream;
private int mMimeType;
+ private boolean mIsStandalone;
@UnsupportedAppUsage
private final HashMap[] mAttributes = new HashMap[EXIF_TAGS.length];
private Set<Integer> mHandledIfdOffsets = new HashSet<>(EXIF_TAGS.length);
@@ -1411,6 +1412,7 @@
if (fileDescriptor == null) {
throw new NullPointerException("fileDescriptor cannot be null");
}
+
mAssetInputStream = null;
mFilename = null;
// When FileDescriptor is duplicated and set to FileInputStream, ownership needs to be
@@ -1442,26 +1444,61 @@
/**
* Reads Exif tags from the specified image input stream. Attribute mutation is not supported
- * for input streams. The given input stream will proceed its current position. Developers
+ * for input streams. The given input stream will proceed from its current position. Developers
* should close the input stream after use.
*/
public ExifInterface(@NonNull InputStream inputStream) throws IOException {
+ this(inputStream, false);
+ }
+
+ /**
+ * Reads Exif tags from the specified standalone input stream. Standalone data refers to Exif
+ * data that exists by itself and is not contained in a file format such as jpeg or png.
+ * The format of the standalone data must follow the below structure:
+ * Exif Identifier Code ("Exif\0\0") + TIFF header + IFD data
+ * See JEITA CP-3451C Section 4.5.2 and 4.5.4 specifications for more details.
+ * <p>
+ * Attribute mutation is not supported for this constructor. The given input stream will proceed
+ * from its current position. Developers should close the input stream after use. This
+ * constructor is not intended to be used with an input stream that performs any networking
+ * operations.
+ *
+ * @throws IOException if the data does not follow the aforementioned structure.
+ */
+ @NonNull
+ public static ExifInterface fromStandalone(@NonNull InputStream inputStream)
+ throws IOException {
+ if (isStandalone(inputStream)) {
+ return new ExifInterface(inputStream, true);
+ }
+ throw new IOException("Given data does not follow the structure of a standalone exif "
+ + "data.");
+ }
+
+ private ExifInterface(@NonNull InputStream inputStream, boolean isFromStandalone)
+ throws IOException {
if (inputStream == null) {
throw new NullPointerException("inputStream cannot be null");
}
mFilename = null;
- if (inputStream instanceof AssetManager.AssetInputStream) {
- mAssetInputStream = (AssetManager.AssetInputStream) inputStream;
- mSeekableFileDescriptor = null;
- } else if (inputStream instanceof FileInputStream
- && isSeekableFD(((FileInputStream) inputStream).getFD())) {
+
+ if (isFromStandalone) {
+ mIsStandalone = true;
mAssetInputStream = null;
- mSeekableFileDescriptor = ((FileInputStream) inputStream).getFD();
+ mSeekableFileDescriptor = null;
} else {
- mAssetInputStream = null;
- mSeekableFileDescriptor = null;
+ if (inputStream instanceof AssetManager.AssetInputStream) {
+ mAssetInputStream = (AssetManager.AssetInputStream) inputStream;
+ mSeekableFileDescriptor = null;
+ } else if (inputStream instanceof FileInputStream
+ && (isSeekableFD(((FileInputStream) inputStream).getFD()))) {
+ mAssetInputStream = null;
+ mSeekableFileDescriptor = ((FileInputStream) inputStream).getFD();
+ } else {
+ mAssetInputStream = null;
+ mSeekableFileDescriptor = null;
+ }
}
- mIsInputStream = true;
loadAttributes(inputStream);
}
@@ -1798,51 +1835,57 @@
}
// Check file type
- in = new BufferedInputStream(in, SIGNATURE_CHECK_SIZE);
- mMimeType = getMimeType((BufferedInputStream) in);
+ if (!mIsStandalone) {
+ in = new BufferedInputStream(in, SIGNATURE_CHECK_SIZE);
+ mMimeType = getMimeType((BufferedInputStream) in);
+ }
// Create byte-ordered input stream
ByteOrderedDataInputStream inputStream = new ByteOrderedDataInputStream(in);
- switch (mMimeType) {
- case IMAGE_TYPE_JPEG: {
- getJpegAttributes(inputStream, 0, IFD_TYPE_PRIMARY); // 0 is offset
- break;
+ if (!mIsStandalone) {
+ switch (mMimeType) {
+ case IMAGE_TYPE_JPEG: {
+ getJpegAttributes(inputStream, 0, IFD_TYPE_PRIMARY); // 0 is offset
+ break;
+ }
+ case IMAGE_TYPE_RAF: {
+ getRafAttributes(inputStream);
+ break;
+ }
+ case IMAGE_TYPE_HEIF: {
+ getHeifAttributes(inputStream);
+ break;
+ }
+ case IMAGE_TYPE_ORF: {
+ getOrfAttributes(inputStream);
+ break;
+ }
+ case IMAGE_TYPE_RW2: {
+ getRw2Attributes(inputStream);
+ break;
+ }
+ case IMAGE_TYPE_PNG: {
+ getPngAttributes(inputStream);
+ break;
+ }
+ case IMAGE_TYPE_ARW:
+ case IMAGE_TYPE_CR2:
+ case IMAGE_TYPE_DNG:
+ case IMAGE_TYPE_NEF:
+ case IMAGE_TYPE_NRW:
+ case IMAGE_TYPE_PEF:
+ case IMAGE_TYPE_SRW:
+ case IMAGE_TYPE_UNKNOWN: {
+ getRawAttributes(inputStream);
+ break;
+ }
+ default: {
+ break;
+ }
}
- case IMAGE_TYPE_RAF: {
- getRafAttributes(inputStream);
- break;
- }
- case IMAGE_TYPE_HEIF: {
- getHeifAttributes(inputStream);
- break;
- }
- case IMAGE_TYPE_ORF: {
- getOrfAttributes(inputStream);
- break;
- }
- case IMAGE_TYPE_RW2: {
- getRw2Attributes(inputStream);
- break;
- }
- case IMAGE_TYPE_PNG: {
- getPngAttributes(inputStream);
- break;
- }
- case IMAGE_TYPE_ARW:
- case IMAGE_TYPE_CR2:
- case IMAGE_TYPE_DNG:
- case IMAGE_TYPE_NEF:
- case IMAGE_TYPE_NRW:
- case IMAGE_TYPE_PEF:
- case IMAGE_TYPE_SRW:
- case IMAGE_TYPE_UNKNOWN: {
- getRawAttributes(inputStream);
- break;
- }
- default: {
- break;
- }
+ } else {
+ getStandaloneAttributes(inputStream);
}
// Set thumbnail image offset and length
setThumbnailData(inputStream);
@@ -2124,6 +2167,9 @@
}
if (mHasThumbnail) {
+ if (mIsStandalone) {
+ return new long[] { mThumbnailOffset + mExifOffset, mThumbnailLength };
+ }
return new long[] { mThumbnailOffset, mThumbnailLength };
} else {
return null;
@@ -2368,6 +2414,7 @@
// Checks the type of image file
private int getMimeType(BufferedInputStream in) throws IOException {
+ // TODO (b/142218289): Need to handle case where input stream does not support mark
in.mark(SIGNATURE_CHECK_SIZE);
byte[] signatureCheckBytes = new byte[SIGNATURE_CHECK_SIZE];
in.read(signatureCheckBytes);
@@ -2562,6 +2609,18 @@
return true;
}
+ private static boolean isStandalone(InputStream inputStream) throws IOException {
+ byte[] signatureCheckBytes = new byte[IDENTIFIER_EXIF_APP1.length];
+ inputStream.read(signatureCheckBytes);
+
+ for (int i = 0; i < IDENTIFIER_EXIF_APP1.length; i++) {
+ if (signatureCheckBytes[i] != IDENTIFIER_EXIF_APP1[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
/**
* Loads EXIF attributes from a JPEG input stream.
*
@@ -2633,7 +2692,6 @@
final long offset = start + IDENTIFIER_EXIF_APP1.length;
final byte[] value = Arrays.copyOfRange(bytes,
IDENTIFIER_EXIF_APP1.length, bytes.length);
-
readExifSegment(value, imageType);
// Save offset values for handleThumbnailFromJfif() function
@@ -2953,6 +3011,16 @@
}
}
+ private void getStandaloneAttributes(ByteOrderedDataInputStream in) throws IOException {
+ // TODO: Need to handle potential OutOfMemoryError
+ byte[] data = new byte[in.available()];
+ in.readFully(data);
+ readExifSegment(data, IFD_TYPE_PRIMARY);
+
+ // Save offset values for handleThumbnailFromJfif() function
+ mExifOffset = IDENTIFIER_EXIF_APP1.length;
+ }
+
/**
* ORF files contains a primary image data and a MakerNote data that contains preview/thumbnail
* images. Both data takes the form of IFDs and can therefore be read with the
@@ -3606,8 +3674,6 @@
int thumbnailOffset = jpegInterchangeFormatAttribute.getIntValue(mExifByteOrder);
int thumbnailLength = jpegInterchangeFormatLengthAttribute.getIntValue(mExifByteOrder);
- // The following code limits the size of thumbnail size not to overflow EXIF data area.
- thumbnailLength = Math.min(thumbnailLength, in.getLength() - thumbnailOffset);
if (mMimeType == IMAGE_TYPE_JPEG || mMimeType == IMAGE_TYPE_RAF
|| mMimeType == IMAGE_TYPE_RW2) {
thumbnailOffset += mExifOffset;
@@ -3615,6 +3681,9 @@
// Update offset value since RAF files have IFD data preceding MakerNote data.
thumbnailOffset += mOrfMakerNoteOffset;
}
+ // The following code limits the size of thumbnail size not to overflow EXIF data area.
+ thumbnailLength = Math.min(thumbnailLength, in.getLength() - thumbnailOffset);
+
if (DEBUG) {
Log.d(TAG, "Setting thumbnail attributes with offset: " + thumbnailOffset
+ ", length: " + thumbnailLength);
@@ -4123,6 +4192,7 @@
mDataInputStream = new DataInputStream(in);
mLength = mDataInputStream.available();
mPosition = 0;
+ // TODO (b/142218289): Need to handle case where input stream does not support mark
mDataInputStream.mark(mLength);
}
@@ -4138,6 +4208,7 @@
if (mPosition > byteCount) {
mPosition = 0;
mDataInputStream.reset();
+ // TODO (b/142218289): Need to handle case where input stream does not support mark
mDataInputStream.mark(mLength);
} else {
byteCount -= mPosition;
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 71f52a1..fc05610 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -106,8 +106,12 @@
List<AudioProductStrategy> getAudioProductStrategies();
+ boolean isMicrophoneMuted();
+
void setMicrophoneMute(boolean on, String callingPackage, int userId);
+ oneway void setMicrophoneMuteFromSwitch(boolean on);
+
void setRingerModeExternal(int ringerMode, String caller);
void setRingerModeInternal(int ringerMode, String caller);
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 1b713b6..81213b9 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -40,6 +40,7 @@
void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit);
void requestSetVolume(IMediaRouterClient client, String routeId, int volume);
void requestUpdateVolume(IMediaRouterClient client, String routeId, int direction);
+ void setControlCategories(IMediaRouterClient client, in List<String> categories);
// Methods for media router 2
void registerClient2(IMediaRouter2Client client, String packageName);
@@ -52,7 +53,7 @@
* @param route the route to be selected
*/
void selectRoute2(IMediaRouter2Client client, in @nullable MediaRoute2Info route);
- void setControlCategories(IMediaRouter2Client client, in List<String> categories);
+ void setControlCategories2(IMediaRouter2Client client, in List<String> categories);
void registerManager(IMediaRouter2Manager manager, String packageName);
void unregisterManager(IMediaRouter2Manager manager);
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 8887c7c..09221a37 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -23,7 +23,7 @@
import android.annotation.UnsupportedAppUsage;
import android.mtp.MtpConstants;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import java.util.HashMap;
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index d72231f..9cb7869 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -49,6 +49,8 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
@@ -82,6 +84,7 @@
final ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
final ArrayList<RouteCategory> mCategories = new ArrayList<RouteCategory>();
+ List<String> mControlCategories = Collections.emptyList();
final RouteCategory mSystemCategory;
@@ -358,6 +361,18 @@
return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
}
+ public void setControlCategories(Collection<String> controlCategories) {
+ List<String> newControlCategories = new ArrayList<>(controlCategories);
+ mControlCategories = newControlCategories;
+ if (mClient != null) {
+ try {
+ mMediaRouterService.setControlCategories(mClient, newControlCategories);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Unable to set control categories.", ex);
+ }
+ }
+ }
+
private void updatePresentationDisplays(int changedDisplayId) {
final int count = mRoutes.size();
for (int i = 0; i < count; i++) {
@@ -406,6 +421,7 @@
try {
Client client = new Client();
mMediaRouterService.registerClientAsUser(client, mPackageName, userId);
+ mMediaRouterService.setControlCategories(client, mControlCategories);
mClient = client;
} catch (RemoteException ex) {
Log.e(TAG, "Unable to register media router client.", ex);
@@ -1302,6 +1318,19 @@
sStatic.rebindAsUser(userId);
}
+ /**
+ * Sets the control categories of the application.
+ * Routes that support at least one of the given control categories only exists and are handled
+ * by the media router.
+ *
+ * @hide
+ */
+ public void setControlCategories(@NonNull Collection<String> controlCategories) {
+ Objects.requireNonNull(controlCategories, "control categories must not be null");
+
+ sStatic.setControlCategories(controlCategories);
+ }
+
static void updateRoute(final RouteInfo info) {
dispatchRouteChanged(info);
}
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 8e29e34..ed35ef6 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -129,7 +129,7 @@
Client client = new Client();
try {
mMediaRouterService.registerClient2(client, mPackageName);
- mMediaRouterService.setControlCategories(client, mControlCategories);
+ mMediaRouterService.setControlCategories2(client, mControlCategories);
mClient = client;
} catch (RemoteException ex) {
Log.e(TAG, "Unable to register media router.", ex);
@@ -188,7 +188,7 @@
}
if (client != null) {
try {
- mMediaRouterService.setControlCategories(client, newControlCategories);
+ mMediaRouterService.setControlCategories2(client, newControlCategories);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to set control categories.", ex);
}
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 6257feb..45ee210 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -59,7 +59,10 @@
"android.hidl.token@1.0-utils",
],
- header_libs: ["libhardware_headers"],
+ header_libs: [
+ "libhardware_headers",
+ "libmediadrm_headers",
+ ],
static_libs: ["libgrallocusage"],
diff --git a/media/jni/android_media_MediaDrm.h b/media/jni/android_media_MediaDrm.h
index 5ebac1d..684069b 100644
--- a/media/jni/android_media_MediaDrm.h
+++ b/media/jni/android_media_MediaDrm.h
@@ -20,15 +20,12 @@
#include "jni.h"
#include <media/stagefright/foundation/ABase.h>
-#include <media/IDrm.h>
-#include <media/IDrmClient.h>
+#include <mediadrm/IDrm.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
namespace android {
-struct IDrm;
-
class DrmListener: virtual public RefBase
{
public:
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
index 38f0175..481f479 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
@@ -31,7 +31,7 @@
import androidx.test.runner.AndroidJUnit4;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index 3abf0a4..a3ed07a 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -27,6 +27,7 @@
import android.content.Context;
import android.content.Intent;
import android.media.MediaRoute2Info;
+import android.media.MediaRouter;
import android.media.MediaRouter2;
import android.media.MediaRouter2Manager;
import android.support.test.InstrumentationRegistry;
@@ -72,7 +73,8 @@
private Context mContext;
private MediaRouter2Manager mManager;
- private MediaRouter2 mRouter;
+ private MediaRouter mRouter;
+ private MediaRouter2 mRouter2;
private Executor mExecutor;
private String mPackageName;
@@ -89,7 +91,8 @@
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mManager = MediaRouter2Manager.getInstance(mContext);
- mRouter = MediaRouter2.getInstance(mContext);
+ mRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ mRouter2 = MediaRouter2.getInstance(mContext);
//TODO: If we need to support thread pool executors, change this to thread pool executor.
mExecutor = Executors.newSingleThreadExecutor();
mPackageName = mContext.getPackageName();
@@ -131,12 +134,12 @@
//TODO: Figure out a more proper way to test.
// (Control requests shouldn't be used in this way.)
- mRouter.setControlCategories(CONTROL_CATEGORIES_ALL);
- mRouter.registerCallback(mExecutor, mockRouterCallback);
- mRouter.sendControlRequest(
+ mRouter2.setControlCategories(CONTROL_CATEGORIES_ALL);
+ mRouter2.registerCallback(mExecutor, mockRouterCallback);
+ mRouter2.sendControlRequest(
new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2).build(),
new Intent(ACTION_REMOVE_ROUTE));
- mRouter.unregisterCallback(mockRouterCallback);
+ mRouter2.unregisterCallback(mockRouterCallback);
verify(mockCallback, timeout(TIMEOUT_MS)).onRouteRemoved(argThat(
(MediaRoute2Info info) ->
@@ -148,15 +151,41 @@
* Tests if we get proper routes for application that has special control category.
*/
@Test
+ public void testControlCategoryWithMediaRouter() throws Exception {
+ MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
+ mManager.registerCallback(mExecutor, mockCallback);
+
+ MediaRouter.Callback mockRouterCallback = mock(MediaRouter.Callback.class);
+
+ mRouter.setControlCategories(CONTROL_CATEGORIES_SPECIAL);
+ mRouter.addCallback(MediaRouter.ROUTE_TYPE_USER, mockRouterCallback);
+
+ verify(mockCallback, timeout(TIMEOUT_MS))
+ .onRoutesChanged(argThat(routes -> routes.size() > 0));
+
+ Map<String, MediaRoute2Info> routes =
+ createRouteMap(mManager.getAvailableRoutes(mPackageName));
+
+ Assert.assertEquals(1, routes.size());
+ Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY));
+
+ mRouter.removeCallback(mockRouterCallback);
+ mManager.unregisterCallback(mockCallback);
+ }
+
+ /**
+ * Tests if we get proper routes for application that has special control category.
+ */
+ @Test
public void testControlCategory() throws Exception {
MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
mManager.registerCallback(mExecutor, mockCallback);
MediaRouter2.Callback mockRouterCallback = mock(MediaRouter2.Callback.class);
- mRouter.setControlCategories(CONTROL_CATEGORIES_SPECIAL);
- mRouter.registerCallback(mExecutor, mockRouterCallback);
- mRouter.unregisterCallback(mockRouterCallback);
+ mRouter2.setControlCategories(CONTROL_CATEGORIES_SPECIAL);
+ mRouter2.registerCallback(mExecutor, mockRouterCallback);
+ mRouter2.unregisterCallback(mockRouterCallback);
verify(mockCallback, timeout(TIMEOUT_MS))
.onRoutesChanged(argThat(routes -> routes.size() > 0));
@@ -177,15 +206,15 @@
public void testGetRoutes() throws Exception {
MediaRouter2.Callback mockCallback = mock(MediaRouter2.Callback.class);
- mRouter.setControlCategories(CONTROL_CATEGORIES_SPECIAL);
- mRouter.registerCallback(mExecutor, mockCallback);
+ mRouter2.setControlCategories(CONTROL_CATEGORIES_SPECIAL);
+ mRouter2.registerCallback(mExecutor, mockCallback);
verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce())
.onRoutesChanged(argThat(routes -> routes.size() > 0));
- Map<String, MediaRoute2Info> routes = createRouteMap(mRouter.getRoutes());
+ Map<String, MediaRoute2Info> routes = createRouteMap(mRouter2.getRoutes());
Assert.assertEquals(1, routes.size());
Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY));
- mRouter.unregisterCallback(mockCallback);
+ mRouter2.unregisterCallback(mockCallback);
}
@Test
@@ -194,8 +223,8 @@
MediaRouter2Manager.Callback managerCallback = mock(MediaRouter2Manager.Callback.class);
mManager.registerCallback(mExecutor, managerCallback);
- mRouter.setControlCategories(CONTROL_CATEGORIES_ALL);
- mRouter.registerCallback(mExecutor, mockRouterCallback);
+ mRouter2.setControlCategories(CONTROL_CATEGORIES_ALL);
+ mRouter2.registerCallback(mExecutor, mockRouterCallback);
verify(managerCallback, timeout(TIMEOUT_MS))
.onRoutesChanged(argThat(routes -> routes.size() > 0));
@@ -211,7 +240,7 @@
.onRouteAdded(argThat(route -> route.equals(routeToSelect)));
mManager.unregisterCallback(managerCallback);
- mRouter.unregisterCallback(mockRouterCallback);
+ mRouter2.unregisterCallback(mockRouterCallback);
}
/**
@@ -223,8 +252,8 @@
MediaRouter2.Callback routerCallback = mock(MediaRouter2.Callback.class);
mManager.registerCallback(mExecutor, managerCallback);
- mRouter.setControlCategories(CONTROL_CATEGORIES_ALL);
- mRouter.registerCallback(mExecutor, routerCallback);
+ mRouter2.setControlCategories(CONTROL_CATEGORIES_ALL);
+ mRouter2.registerCallback(mExecutor, routerCallback);
verify(managerCallback, timeout(TIMEOUT_MS))
.onRoutesChanged(argThat(routes -> routes.size() > 0));
@@ -248,7 +277,7 @@
.onRouteChanged(argThat(routeInfo -> TextUtils.equals(ROUTE_ID2, routeInfo.getId())
&& TextUtils.equals(routeInfo.getClientPackageName(), null)));
- mRouter.unregisterCallback(routerCallback);
+ mRouter2.unregisterCallback(routerCallback);
mManager.unregisterCallback(managerCallback);
}
diff --git a/mime/Android.bp b/mime/Android.bp
index 17bad74..8b2b059 100644
--- a/mime/Android.bp
+++ b/mime/Android.bp
@@ -12,23 +12,83 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+
+java_defaults {
+ name: "mimemap-defaults",
+ srcs: [
+ "java/android/content/type/DefaultMimeMapFactory.java",
+ ],
+ sdk_version: "core_platform",
+}
+
java_library {
name: "mimemap",
+ defaults: ["mimemap-defaults"],
+ static_libs: ["mimemap-res.jar"],
+ visibility: [
+ "//frameworks/base:__subpackages__",
+ ],
+}
+
+java_library {
+ name: "mimemap-testing",
+ defaults: ["mimemap-defaults"],
+ static_libs: ["mimemap-testing-res.jar"],
+ jarjar_rules: "jarjar-rules.txt",
visibility: [
"//cts/tests/tests/mimemap:__subpackages__",
"//frameworks/base:__subpackages__",
],
+}
- srcs: [
- "java/android/content/type/DefaultMimeMapFactory.java",
+// The mimemap-res.jar and mimemap-testing-res.jar genrules produce a .jar that
+// has the resource file in a subdirectory res/ and testres/, respectively.
+// They need to be in different paths because one of them ends up in a
+// bootclasspath jar whereas the other one ends up in a test jar. Bootclasspath
+// resources hide test or application resources under the same path because
+// ClassLoader.getResource(String) consults the parent ClassLoader first.
+//
+// Further notes:
+// - the "cp" command will flatten any directory paths that occur in $(in),
+// but here they happen to already be in the root directory. If we needed
+// to preserve sub paths then we might want to zip the files first and then
+// unzip them below the new parent directory.
+// - the path names "res/" and "testres/" and duplicated in .java source files
+// (DefaultMimeMapFactory.java and MimeMapTest.java, as of October 2019).
+java_genrule {
+ name: "mimemap-res.jar",
+ tools: [
+ "soong_zip",
],
+ srcs: [":mime.types"],
+ out: ["mimemap-res.jar"],
+ cmd: "mkdir $(genDir)/res/ && cp $(in) $(genDir)/res/ && $(location soong_zip) -C $(genDir) -o $(out) -D $(genDir)/res/",
+}
- java_resources: [
+// The same as mimemap-res.jar except that the resources are placed in a different directory.
+// They get bundled with CTS so that CTS can compare a device's MimeMap implementation vs.
+// the stock Android one from when CTS was built.
+java_genrule {
+ name: "mimemap-testing-res.jar",
+ tools: [
+ "soong_zip",
+ ],
+ srcs: [":mime.types"],
+ out: ["mimemap-testing-res.jar"],
+ cmd: "mkdir $(genDir)/testres/ && cp $(in) $(genDir)/testres/ && $(location soong_zip) -C $(genDir) -o $(out) -D $(genDir)/testres/",
+}
+
+// Combination of all *mime.types resources.
+filegroup {
+ name: "mime.types",
+ visibility: [
+ "//visibility:private",
+ ],
+ srcs: [
":debian.mime.types",
":android.mime.types",
+ ":vendor.mime.types",
],
-
- sdk_version: "core_platform",
}
filegroup {
@@ -41,3 +101,14 @@
"java-res/android.mime.types",
],
}
+
+filegroup {
+ name: "vendor.mime.types",
+ visibility: [
+ "//visibility:private",
+ ],
+ path: "java-res/",
+ srcs: [
+ "java-res/vendor.mime.types",
+ ],
+}
diff --git a/mime/TEST_MAPPING b/mime/TEST_MAPPING
new file mode 100644
index 0000000..8daab75
--- /dev/null
+++ b/mime/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsMimeMapTestCases"
+ }
+ ]
+}
diff --git a/mime/jarjar-rules.txt b/mime/jarjar-rules.txt
new file mode 100644
index 0000000..145d1db
--- /dev/null
+++ b/mime/jarjar-rules.txt
@@ -0,0 +1 @@
+rule android.content.type.DefaultMimeMapFactory android.content.type.cts.StockAndroidMimeMapFactory
\ No newline at end of file
diff --git a/mime/java-res/android.mime.types b/mime/java-res/android.mime.types
index 1ca912e..7a5299f 100644
--- a/mime/java-res/android.mime.types
+++ b/mime/java-res/android.mime.types
@@ -3,7 +3,7 @@
#
# Android-specific MIME type <-> extension mappings
#
-# Each line below defines an mapping from one MIME type to the first of the
+# Each line below defines a mapping from one MIME type to the first of the
# listed extensions, and from listed extension back to the MIME type.
# A mapping overrides any previous mapping _from_ that same MIME type or
# extension (put() semantics), unless that MIME type / extension is prefixed with '?'
diff --git a/mime/java-res/vendor.mime.types b/mime/java-res/vendor.mime.types
new file mode 100644
index 0000000..afb8f9e
--- /dev/null
+++ b/mime/java-res/vendor.mime.types
@@ -0,0 +1,41 @@
+###############################################################################
+#
+# Vendor-specific MIME type <-> extension mappings
+#
+# Each line below defines a mapping from one MIME type to the first of the
+# listed extensions, and from listed extension back to the MIME type.
+#
+# This file can _add_ additional mappings that are not in the default set,
+# but it it cannot _modify_ (replace or remove) any platform default mapping
+# (defined in files mime.types and android.mime.types).
+#
+###############################################################################
+#
+# EXAMPLES
+#
+# A line of the form (without the leading '#''):
+#
+# mime ext1 ext2 ext3
+#
+# affects the current mappings along the lines of the following pseudo code:
+#
+# mimeToExt.putIfAbsent("mime", "ext1");
+# extToMime.putIfAbsent("ext1", "mime");
+# extToMime.putIfAbsent("ext2", "mime");
+# extToMime.putIfAbsent("ext3", "mime");
+#
+# Optionally, MIME types or extensions may be prefixed by a single '?', which
+# will be ignored. I.e., the following example lines all have the same semantics:
+#
+# mime ext1 ext2 ext3
+# ?mime ext1 ext2 ext3
+# mime ?ext1 ext2 ?ext3
+# ?mime ?ext1 ?ext2 ?ext3
+#
+# By default, this file contains no mappings (which means that the platform
+# default mapping is used unmodified).
+#
+###############################################################################
+#
+# Add your custom mappings below this line (with no "#" at the start of the line):
+
diff --git a/mime/java/android/content/type/DefaultMimeMapFactory.java b/mime/java/android/content/type/DefaultMimeMapFactory.java
index 545fb3c..03b685d 100644
--- a/mime/java/android/content/type/DefaultMimeMapFactory.java
+++ b/mime/java/android/content/type/DefaultMimeMapFactory.java
@@ -16,13 +16,17 @@
package android.content.type;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import java.io.BufferedReader;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
import java.util.regex.Pattern;
/**
@@ -44,24 +48,33 @@
* Android's default mapping between MIME types and extensions.
*/
public static MimeMap create() {
- return parseFromResources("/mime.types", "/android.mime.types");
+ Class c = DefaultMimeMapFactory.class;
+ // The resources are placed into the res/ path by the "mimemap-res.jar" genrule.
+ return create(resourceName -> c.getResourceAsStream("/res/" + resourceName));
}
private static final Pattern SPLIT_PATTERN = Pattern.compile("\\s+");
- static MimeMap parseFromResources(String... resourceNames) {
+ /**
+ * Creates a {@link MimeMap} instance whose resources are loaded from the
+ * InputStreams looked up in {@code resourceSupplier}.
+ *
+ * @hide
+ */
+ public static MimeMap create(Function<String, InputStream> resourceSupplier) {
MimeMap.Builder builder = MimeMap.builder();
- for (String resourceName : resourceNames) {
- parseTypes(builder, resourceName);
- }
+ parseTypes(builder, true, resourceSupplier, "mime.types");
+ parseTypes(builder, true, resourceSupplier, "android.mime.types");
+ parseTypes(builder, false, resourceSupplier, "vendor.mime.types");
return builder.build();
}
- private static void parseTypes(MimeMap.Builder builder, String resource) {
- try (BufferedReader r = new BufferedReader(
- new InputStreamReader(DefaultMimeMapFactory.class.getResourceAsStream(resource)))) {
+ private static void parseTypes(MimeMap.Builder builder, boolean allowOverwrite,
+ Function<String, InputStream> resourceSupplier, String resourceName) {
+ try (InputStream inputStream = Objects.requireNonNull(resourceSupplier.apply(resourceName));
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
- while ((line = r.readLine()) != null) {
+ while ((line = reader.readLine()) != null) {
int commentPos = line.indexOf('#');
if (commentPos >= 0) {
line = line.substring(0, commentPos);
@@ -71,11 +84,28 @@
continue;
}
List<String> specs = Arrays.asList(SPLIT_PATTERN.split(line));
+ if (!allowOverwrite) {
+ // Pretend that the mimeType and each file extension listed in the line
+ // carries a "?" prefix, which means that it can add new mappings but
+ // not modify existing mappings (putIfAbsent() semantics).
+ specs = ensurePrefix("?", specs);
+ }
builder.put(specs.get(0), specs.subList(1, specs.size()));
}
} catch (IOException | RuntimeException e) {
- throw new RuntimeException("Failed to parse " + resource, e);
+ throw new RuntimeException("Failed to parse " + resourceName, e);
}
}
+ private static List<String> ensurePrefix(String prefix, List<String> strings) {
+ List<String> result = new ArrayList<>(strings.size());
+ for (String s : strings) {
+ if (!s.startsWith(prefix)) {
+ s = prefix + s;
+ }
+ result.add(s);
+ }
+ return result;
+ }
+
}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTask.java
new file mode 100644
index 0000000..619438c
--- /dev/null
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTask.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2019 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.server.backup.encryption.tasks;
+
+import android.annotation.Nullable;
+import android.app.backup.BackupDataInput;
+import android.content.Context;
+import android.os.ParcelFileDescriptor;
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+import android.security.keystore.recovery.LockScreenRequiredException;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.backup.encryption.CryptoSettings;
+import com.android.server.backup.encryption.chunking.ProtoStore;
+import com.android.server.backup.encryption.client.CryptoBackupServer;
+import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
+import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
+import com.android.server.backup.encryption.keys.TertiaryKeyManager;
+import com.android.server.backup.encryption.keys.TertiaryKeyRotationScheduler;
+import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
+import com.android.server.backup.encryption.protos.nano.KeyValueListingProto;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.util.Optional;
+
+// TODO(b/141975695): Create a base class for EncryptedKvBackupTask and EncryptedFullBackupTask.
+/** Performs encrypted key value backup, handling rotating the tertiary key as necessary. */
+public class EncryptedKvBackupTask {
+ private static final String TAG = "EncryptedKvBackupTask";
+
+ private final TertiaryKeyManager mTertiaryKeyManager;
+ private final RecoverableKeyStoreSecondaryKey mSecondaryKey;
+ private final ProtoStore<KeyValueListingProto.KeyValueListing> mKeyValueListingStore;
+ private final ProtoStore<ChunksMetadataProto.ChunkListing> mChunkListingStore;
+ private final KvBackupEncrypter mKvBackupEncrypter;
+ private final EncryptedBackupTask mEncryptedBackupTask;
+ private final String mPackageName;
+
+ /** Constructs new instances of {@link EncryptedKvBackupTask}. */
+ public static class EncryptedKvBackupTaskFactory {
+ /**
+ * Creates a new instance.
+ *
+ * <p>Either initializes encrypted backup or loads an existing secondary key as necessary.
+ *
+ * @param cryptoSettings to load secondary key state from
+ * @param fileDescriptor to read the backup data from
+ */
+ public EncryptedKvBackupTask newInstance(
+ Context context,
+ SecureRandom secureRandom,
+ CryptoBackupServer cryptoBackupServer,
+ CryptoSettings cryptoSettings,
+ RecoverableKeyStoreSecondaryKeyManager
+ .RecoverableKeyStoreSecondaryKeyManagerProvider
+ recoverableSecondaryKeyManagerProvider,
+ ParcelFileDescriptor fileDescriptor,
+ String packageName)
+ throws IOException, UnrecoverableKeyException, LockScreenRequiredException,
+ InternalRecoveryServiceException, InvalidKeyException {
+ RecoverableKeyStoreSecondaryKey secondaryKey =
+ new InitializeRecoverableSecondaryKeyTask(
+ context,
+ cryptoSettings,
+ recoverableSecondaryKeyManagerProvider.get(),
+ cryptoBackupServer)
+ .run();
+ KvBackupEncrypter backupEncrypter =
+ new KvBackupEncrypter(new BackupDataInput(fileDescriptor.getFileDescriptor()));
+ TertiaryKeyManager tertiaryKeyManager =
+ new TertiaryKeyManager(
+ context,
+ secureRandom,
+ TertiaryKeyRotationScheduler.getInstance(context),
+ secondaryKey,
+ packageName);
+
+ return new EncryptedKvBackupTask(
+ tertiaryKeyManager,
+ ProtoStore.createKeyValueListingStore(context),
+ secondaryKey,
+ ProtoStore.createChunkListingStore(context),
+ backupEncrypter,
+ new EncryptedBackupTask(
+ cryptoBackupServer, secureRandom, packageName, backupEncrypter),
+ packageName);
+ }
+ }
+
+ @VisibleForTesting
+ EncryptedKvBackupTask(
+ TertiaryKeyManager tertiaryKeyManager,
+ ProtoStore<KeyValueListingProto.KeyValueListing> keyValueListingStore,
+ RecoverableKeyStoreSecondaryKey secondaryKey,
+ ProtoStore<ChunksMetadataProto.ChunkListing> chunkListingStore,
+ KvBackupEncrypter kvBackupEncrypter,
+ EncryptedBackupTask encryptedBackupTask,
+ String packageName) {
+ mTertiaryKeyManager = tertiaryKeyManager;
+ mSecondaryKey = secondaryKey;
+ mKeyValueListingStore = keyValueListingStore;
+ mChunkListingStore = chunkListingStore;
+ mKvBackupEncrypter = kvBackupEncrypter;
+ mEncryptedBackupTask = encryptedBackupTask;
+ mPackageName = packageName;
+ }
+
+ /**
+ * Reads backup data from the file descriptor provided in the construtor, encrypts it and
+ * uploads it to the server.
+ *
+ * <p>The {@code incremental} flag indicates if the backup data provided is incremental or a
+ * complete set. Incremental backup is not possible if no previous crypto state exists, or the
+ * tertiary key must be rotated in the next backup. If the caller requests incremental backup
+ * but it is not possible, then the backup will not start and this method will throw {@link
+ * NonIncrementalBackupRequiredException}.
+ *
+ * <p>TODO(b/70704456): Update return code to indicate that we require non-incremental backup.
+ *
+ * @param incremental {@code true} if the data provided is a diff from the previous backup,
+ * {@code false} if it is a complete set
+ * @throws NonIncrementalBackupRequiredException if the caller provides an incremental backup but the task
+ * requires non-incremental backup
+ */
+ public void performBackup(boolean incremental)
+ throws GeneralSecurityException, IOException, NoSuchMethodException,
+ InstantiationException, IllegalAccessException, InvocationTargetException,
+ NonIncrementalBackupRequiredException {
+ if (mTertiaryKeyManager.wasKeyRotated()) {
+ Slog.d(TAG, "Tertiary key is new so clearing package state.");
+ deleteListings(mPackageName);
+ }
+
+ Optional<Pair<KeyValueListingProto.KeyValueListing, ChunksMetadataProto.ChunkListing>>
+ oldListings = getListingsAndEnsureConsistency(mPackageName);
+
+ if (oldListings.isPresent() && !incremental) {
+ Slog.d(
+ TAG,
+ "Non-incremental backup requested but incremental state existed, clearing it");
+ deleteListings(mPackageName);
+ oldListings = Optional.empty();
+ }
+
+ if (!oldListings.isPresent() && incremental) {
+ // If we don't have any state then we require a non-incremental backup, but this backup
+ // is incremental.
+ throw new NonIncrementalBackupRequiredException();
+ }
+
+ if (oldListings.isPresent()) {
+ mKvBackupEncrypter.setOldKeyValueListing(oldListings.get().first);
+ }
+
+ ChunksMetadataProto.ChunkListing newChunkListing;
+ if (oldListings.isPresent()) {
+ Slog.v(TAG, "Old listings existed, performing incremental backup");
+ newChunkListing =
+ mEncryptedBackupTask.performIncrementalBackup(
+ mTertiaryKeyManager.getKey(),
+ mTertiaryKeyManager.getWrappedKey(),
+ oldListings.get().second);
+ } else {
+ Slog.v(TAG, "Old listings did not exist, performing non-incremental backup");
+ // kv backups don't use this salt because they don't involve content-defined chunking.
+ byte[] fingerprintMixerSalt = null;
+ newChunkListing =
+ mEncryptedBackupTask.performNonIncrementalBackup(
+ mTertiaryKeyManager.getKey(),
+ mTertiaryKeyManager.getWrappedKey(),
+ fingerprintMixerSalt);
+ }
+
+ Slog.v(TAG, "Backup and upload succeeded, saving new listings");
+ saveListings(mPackageName, mKvBackupEncrypter.getNewKeyValueListing(), newChunkListing);
+ }
+
+ private Optional<Pair<KeyValueListingProto.KeyValueListing, ChunksMetadataProto.ChunkListing>>
+ getListingsAndEnsureConsistency(String packageName)
+ throws IOException, InvocationTargetException, NoSuchMethodException,
+ InstantiationException, IllegalAccessException {
+ Optional<KeyValueListingProto.KeyValueListing> keyValueListing =
+ mKeyValueListingStore.loadProto(packageName);
+ Optional<ChunksMetadataProto.ChunkListing> chunkListing =
+ mChunkListingStore.loadProto(packageName);
+
+ // Normally either both protos exist or neither exist, but we correct this just in case.
+ boolean bothPresent = keyValueListing.isPresent() && chunkListing.isPresent();
+ if (!bothPresent) {
+ Slog.d(
+ TAG,
+ "Both listing were not present, clearing state, key value="
+ + keyValueListing.isPresent()
+ + ", chunk="
+ + chunkListing.isPresent());
+ deleteListings(packageName);
+ return Optional.empty();
+ }
+
+ return Optional.of(Pair.create(keyValueListing.get(), chunkListing.get()));
+ }
+
+ private void saveListings(
+ String packageName,
+ KeyValueListingProto.KeyValueListing keyValueListing,
+ ChunksMetadataProto.ChunkListing chunkListing) {
+ try {
+ mKeyValueListingStore.saveProto(packageName, keyValueListing);
+ mChunkListingStore.saveProto(packageName, chunkListing);
+ } catch (IOException e) {
+ // If a problem occurred while saving either listing then they may be inconsistent, so
+ // delete
+ // both.
+ Slog.w(TAG, "Unable to save listings, deleting both for consistency", e);
+ deleteListings(packageName);
+ }
+ }
+
+ private void deleteListings(String packageName) {
+ mKeyValueListingStore.deleteProto(packageName);
+ mChunkListingStore.deleteProto(packageName);
+ }
+}
diff --git a/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTask.java b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTask.java
new file mode 100644
index 0000000..12b4459
--- /dev/null
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTask.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2019 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.server.backup.encryption.tasks;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import android.app.backup.BackupDataOutput;
+import android.content.Context;
+import android.os.ParcelFileDescriptor;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.backup.encryption.FullRestoreDownloader;
+import com.android.server.backup.encryption.chunking.ChunkHasher;
+import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
+import com.android.server.backup.encryption.keys.RestoreKeyFetcher;
+import com.android.server.backup.encryption.kv.DecryptedChunkKvOutput;
+import com.android.server.backup.encryption.protos.nano.KeyValuePairProto;
+import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+
+/**
+ * Performs a key value restore by downloading the backup set, decrypting it and writing it to the
+ * file provided by backup manager.
+ */
+public class EncryptedKvRestoreTask {
+ private static final String ENCRYPTED_FILE_NAME = "encrypted_kv";
+
+ private final File mTemporaryFolder;
+ private final ChunkHasher mChunkHasher;
+ private final FullRestoreToFileTask mFullRestoreToFileTask;
+ private final BackupFileDecryptorTask mBackupFileDecryptorTask;
+
+ /** Constructs new instances of the task. */
+ public static class EncryptedKvRestoreTaskFactory {
+ /**
+ * Constructs a new instance.
+ *
+ * <p>Fetches the appropriate secondary key and uses this to unwrap the tertiary key. Stores
+ * temporary files in {@link Context#getFilesDir()}.
+ */
+ public EncryptedKvRestoreTask newInstance(
+ Context context,
+ RecoverableKeyStoreSecondaryKeyManager
+ .RecoverableKeyStoreSecondaryKeyManagerProvider
+ recoverableSecondaryKeyManagerProvider,
+ FullRestoreDownloader fullRestoreDownloader,
+ String secondaryKeyAlias,
+ WrappedKeyProto.WrappedKey wrappedTertiaryKey)
+ throws EncryptedRestoreException, NoSuchAlgorithmException, NoSuchPaddingException,
+ KeyException, InvalidAlgorithmParameterException {
+ SecretKey tertiaryKey =
+ RestoreKeyFetcher.unwrapTertiaryKey(
+ recoverableSecondaryKeyManagerProvider,
+ secondaryKeyAlias,
+ wrappedTertiaryKey);
+
+ return new EncryptedKvRestoreTask(
+ context.getFilesDir(),
+ new ChunkHasher(tertiaryKey),
+ new FullRestoreToFileTask(fullRestoreDownloader),
+ new BackupFileDecryptorTask(tertiaryKey));
+ }
+ }
+
+ @VisibleForTesting
+ EncryptedKvRestoreTask(
+ File temporaryFolder,
+ ChunkHasher chunkHasher,
+ FullRestoreToFileTask fullRestoreToFileTask,
+ BackupFileDecryptorTask backupFileDecryptorTask) {
+ checkArgument(
+ temporaryFolder.isDirectory(), "Temporary folder must be an existing directory");
+
+ mTemporaryFolder = temporaryFolder;
+ mChunkHasher = chunkHasher;
+ mFullRestoreToFileTask = fullRestoreToFileTask;
+ mBackupFileDecryptorTask = backupFileDecryptorTask;
+ }
+
+ /**
+ * Runs the restore, writing the pairs in lexicographical order to the given file descriptor.
+ *
+ * <p>This will block for the duration of the restore.
+ *
+ * @throws EncryptedRestoreException if there is a problem decrypting or verifying the backup
+ */
+ public void getRestoreData(ParcelFileDescriptor output)
+ throws IOException, EncryptedRestoreException, BadPaddingException,
+ InvalidAlgorithmParameterException, NoSuchAlgorithmException,
+ IllegalBlockSizeException, ShortBufferException, InvalidKeyException {
+ File encryptedFile = new File(mTemporaryFolder, ENCRYPTED_FILE_NAME);
+ try {
+ downloadDecryptAndWriteBackup(encryptedFile, output);
+ } finally {
+ encryptedFile.delete();
+ }
+ }
+
+ private void downloadDecryptAndWriteBackup(File encryptedFile, ParcelFileDescriptor output)
+ throws EncryptedRestoreException, IOException, BadPaddingException, InvalidKeyException,
+ NoSuchAlgorithmException, IllegalBlockSizeException, ShortBufferException,
+ InvalidAlgorithmParameterException {
+ mFullRestoreToFileTask.restoreToFile(encryptedFile);
+ DecryptedChunkKvOutput decryptedChunkKvOutput = new DecryptedChunkKvOutput(mChunkHasher);
+ mBackupFileDecryptorTask.decryptFile(encryptedFile, decryptedChunkKvOutput);
+
+ BackupDataOutput backupDataOutput = new BackupDataOutput(output.getFileDescriptor());
+ for (KeyValuePairProto.KeyValuePair pair : decryptedChunkKvOutput.getPairs()) {
+ backupDataOutput.writeEntityHeader(pair.key, pair.value.length);
+ backupDataOutput.writeEntityData(pair.value, pair.value.length);
+ }
+ }
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/NonIncrementalBackupRequiredException.java
similarity index 67%
copy from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
copy to packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/NonIncrementalBackupRequiredException.java
index 8b35852..a3eda7d 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/packages/BackupEncryption/src/com/android/server/backup/encryption/tasks/NonIncrementalBackupRequiredException.java
@@ -14,13 +14,12 @@
* limitations under the License.
*/
-package android.hardware.biometrics;
+package com.android.server.backup.encryption.tasks;
+
+// TODO(141840878): Update documentation.
/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
- * @hide
+ * Exception thrown when the framework provides an incremental backup but the transport requires a
+ * non-incremental backup.
*/
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+public class NonIncrementalBackupRequiredException extends Exception {}
diff --git a/packages/BackupEncryption/test/robolectric-integration/Android.bp b/packages/BackupEncryption/test/robolectric-integration/Android.bp
index f696278..67365df 100644
--- a/packages/BackupEncryption/test/robolectric-integration/Android.bp
+++ b/packages/BackupEncryption/test/robolectric-integration/Android.bp
@@ -23,6 +23,7 @@
"platform-test-annotations",
"testng",
"truth-prebuilt",
+ "BackupEncryptionRoboTests",
],
static_libs: [
"androidx.test.core",
diff --git a/packages/BackupEncryption/test/robolectric-integration/src/com/android/server/backup/encryption/RoundTripTest.java b/packages/BackupEncryption/test/robolectric-integration/src/com/android/server/backup/encryption/RoundTripTest.java
index 8ec68fd..a432d91 100644
--- a/packages/BackupEncryption/test/robolectric-integration/src/com/android/server/backup/encryption/RoundTripTest.java
+++ b/packages/BackupEncryption/test/robolectric-integration/src/com/android/server/backup/encryption/RoundTripTest.java
@@ -19,21 +19,35 @@
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
+import android.os.ParcelFileDescriptor;
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+import android.security.keystore.recovery.RecoveryController;
import androidx.test.core.app.ApplicationProvider;
import com.android.server.backup.encryption.client.CryptoBackupServer;
+import com.android.server.backup.encryption.keys.KeyWrapUtils;
import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
+import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKeyManager;
import com.android.server.backup.encryption.keys.TertiaryKeyManager;
import com.android.server.backup.encryption.keys.TertiaryKeyRotationScheduler;
import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
import com.android.server.backup.encryption.tasks.EncryptedFullBackupTask;
import com.android.server.backup.encryption.tasks.EncryptedFullRestoreTask;
+import com.android.server.backup.encryption.tasks.EncryptedKvBackupTask;
+import com.android.server.backup.encryption.tasks.EncryptedKvRestoreTask;
+import com.android.server.testing.shadows.DataEntity;
+import com.android.server.testing.shadows.ShadowBackupDataInput;
+import com.android.server.testing.shadows.ShadowBackupDataOutput;
+import com.android.server.testing.shadows.ShadowRecoveryController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -42,15 +56,29 @@
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
+import java.util.Optional;
import java.util.Map;
+import java.util.Set;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
+@Config(
+ shadows = {
+ ShadowBackupDataInput.class,
+ ShadowBackupDataOutput.class,
+ ShadowRecoveryController.class
+ })
@RunWith(RobolectricTestRunner.class)
public class RoundTripTest {
+ private static final DataEntity[] KEY_VALUE_DATA = {
+ new DataEntity("test_key_1", "test_value_1"),
+ new DataEntity("test_key_2", "test_value_2"),
+ new DataEntity("test_key_3", "test_value_3")
+ };
+
/** Amount of data we want to round trip in this test */
private static final int TEST_DATA_SIZE = 1024 * 1024; // 1MB
@@ -59,6 +87,7 @@
/** Key parameters used for the secondary encryption key */
private static final String KEY_ALGORITHM = "AES";
+
private static final int KEY_SIZE_BITS = 256;
/** Package name for our test package */
@@ -77,25 +106,82 @@
private RecoverableKeyStoreSecondaryKey mSecondaryKey;
/** Source of random material which is considered non-predictable in its' generation */
- private SecureRandom mSecureRandom = new SecureRandom();
+ private final SecureRandom mSecureRandom = new SecureRandom();
+
+ private RecoverableKeyStoreSecondaryKeyManager.RecoverableKeyStoreSecondaryKeyManagerProvider
+ mSecondaryKeyManagerProvider;
+ private DummyServer mDummyServer;
+ private RecoveryController mRecoveryController;
+
+ @Mock private ParcelFileDescriptor mParcelFileDescriptor;
@Before
- public void setUp() throws NoSuchAlgorithmException {
+ public void setUp() throws NoSuchAlgorithmException, InternalRecoveryServiceException {
+ MockitoAnnotations.initMocks(this);
+
+ ShadowBackupDataInput.reset();
+ ShadowBackupDataOutput.reset();
+
mContext = ApplicationProvider.getApplicationContext();
mSecondaryKey = new RecoverableKeyStoreSecondaryKey(TEST_KEY_ALIAS, generateAesKey());
+ mDummyServer = new DummyServer();
+ mSecondaryKeyManagerProvider =
+ () ->
+ new RecoverableKeyStoreSecondaryKeyManager(
+ RecoveryController.getInstance(mContext), mSecureRandom);
+
fillBuffer(mOriginalData);
}
@Test
- public void testRoundTrip() throws Exception {
- byte[] backupData = performBackup(mOriginalData);
+ public void testFull_nonIncrementalBackupAndRestoreAreSuccessful() throws Exception {
+ byte[] backupData = performFullBackup(mOriginalData);
assertThat(backupData).isNotEqualTo(mOriginalData);
- byte[] restoredData = performRestore(backupData);
+ byte[] restoredData = performFullRestore(backupData);
assertThat(restoredData).isEqualTo(mOriginalData);
}
- /** Perform a backup and return the backed-up representation of the data */
- private byte[] performBackup(byte[] backupData) throws Exception {
+ @Test
+ public void testKeyValue_nonIncrementalBackupAndRestoreAreSuccessful() throws Exception {
+ byte[] backupData = performNonIncrementalKeyValueBackup(KEY_VALUE_DATA);
+
+ // Get the secondary key used to do backup.
+ Optional<RecoverableKeyStoreSecondaryKey> secondaryKey =
+ mSecondaryKeyManagerProvider.get().get(mDummyServer.mSecondaryKeyAlias);
+ assertThat(secondaryKey.isPresent()).isTrue();
+
+ Set<DataEntity> restoredData = performKeyValueRestore(backupData, secondaryKey.get());
+
+ assertThat(restoredData).containsExactly(KEY_VALUE_DATA).inOrder();
+ }
+
+ /** Perform a key/value backup and return the backed-up representation of the data */
+ private byte[] performNonIncrementalKeyValueBackup(DataEntity[] backupData)
+ throws Exception {
+ // Populate test key/value data.
+ for (DataEntity entity : backupData) {
+ ShadowBackupDataInput.addEntity(entity);
+ }
+
+ EncryptedKvBackupTask.EncryptedKvBackupTaskFactory backupTaskFactory =
+ new EncryptedKvBackupTask.EncryptedKvBackupTaskFactory();
+ EncryptedKvBackupTask backupTask =
+ backupTaskFactory.newInstance(
+ mContext,
+ mSecureRandom,
+ mDummyServer,
+ CryptoSettings.getInstance(mContext),
+ mSecondaryKeyManagerProvider,
+ mParcelFileDescriptor,
+ TEST_PACKAGE_NAME);
+
+ backupTask.performBackup(/* incremental */ false);
+
+ return mDummyServer.mStoredData;
+ }
+
+ /** Perform a full backup and return the backed-up representation of the data */
+ private byte[] performFullBackup(byte[] backupData) throws Exception {
DummyServer dummyServer = new DummyServer();
EncryptedFullBackupTask backupTask =
EncryptedFullBackupTask.newInstance(
@@ -109,8 +195,24 @@
return dummyServer.mStoredData;
}
- /** Perform a restore and resturn the bytes obtained from the restore process */
- private byte[] performRestore(byte[] backupData)
+ private Set<DataEntity> performKeyValueRestore(
+ byte[] backupData, RecoverableKeyStoreSecondaryKey secondaryKey) throws Exception {
+ EncryptedKvRestoreTask.EncryptedKvRestoreTaskFactory restoreTaskFactory =
+ new EncryptedKvRestoreTask.EncryptedKvRestoreTaskFactory();
+ EncryptedKvRestoreTask restoreTask =
+ restoreTaskFactory.newInstance(
+ mContext,
+ mSecondaryKeyManagerProvider,
+ new FakeFullRestoreDownloader(backupData),
+ secondaryKey.getAlias(),
+ KeyWrapUtils.wrap(
+ secondaryKey.getSecretKey(), getTertiaryKey(secondaryKey)));
+ restoreTask.getRestoreData(mParcelFileDescriptor);
+ return ShadowBackupDataOutput.getEntities();
+ }
+
+ /** Perform a full restore and return the bytes obtained from the restore process */
+ private byte[] performFullRestore(byte[] backupData)
throws IOException, NoSuchAlgorithmException, NoSuchPaddingException,
InvalidAlgorithmParameterException, InvalidKeyException,
IllegalBlockSizeException {
@@ -118,7 +220,9 @@
EncryptedFullRestoreTask restoreTask =
EncryptedFullRestoreTask.newInstance(
- mContext, new FakeFullRestoreDownloader(backupData), getTertiaryKey());
+ mContext,
+ new FakeFullRestoreDownloader(backupData),
+ getTertiaryKey(mSecondaryKey));
byte[] buffer = new byte[READ_BUFFER_SIZE];
int bytesRead = restoreTask.readNextChunk(buffer);
@@ -131,7 +235,7 @@
}
/** Get the tertiary key for our test package from the key manager */
- private SecretKey getTertiaryKey()
+ private SecretKey getTertiaryKey(RecoverableKeyStoreSecondaryKey secondaryKey)
throws IllegalBlockSizeException, InvalidAlgorithmParameterException,
NoSuchAlgorithmException, IOException, NoSuchPaddingException,
InvalidKeyException {
@@ -140,7 +244,7 @@
mContext,
mSecureRandom,
TertiaryKeyRotationScheduler.getInstance(mContext),
- mSecondaryKey,
+ secondaryKey,
TEST_PACKAGE_NAME);
return tertiaryKeyManager.getKey();
}
@@ -162,13 +266,13 @@
}
/**
- * Dummy backup data endpoint. This stores the data so we can use it
- * in subsequent test steps.
+ * Dummy backup data endpoint. This stores the data so we can use it in subsequent test steps.
*/
private static class DummyServer implements CryptoBackupServer {
private static final String DUMMY_DOC_ID = "DummyDoc";
byte[] mStoredData = null;
+ String mSecondaryKeyAlias;
@Override
public String uploadIncrementalBackup(
@@ -190,7 +294,7 @@
@Override
public void setActiveSecondaryKeyAlias(
String keyAlias, Map<String, WrappedKeyProto.WrappedKey> tertiaryKeys) {
- throw new RuntimeException("Not Implemented");
+ mSecondaryKeyAlias = keyAlias;
}
}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
new file mode 100644
index 0000000..fa4fef5
--- /dev/null
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvBackupTaskTest.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2019 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.server.backup.encryption.tasks;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertThrows;
+
+import android.app.Application;
+import android.util.Pair;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.server.backup.encryption.chunk.ChunkHash;
+import com.android.server.backup.encryption.chunking.ProtoStore;
+import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey;
+import com.android.server.backup.encryption.keys.TertiaryKeyManager;
+import com.android.server.backup.encryption.kv.KeyValueListingBuilder;
+import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
+import com.android.server.backup.encryption.protos.nano.KeyValueListingProto;
+import com.android.server.backup.encryption.protos.nano.WrappedKeyProto;
+import com.android.server.backup.testing.CryptoTestUtils;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.crypto.SecretKey;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class EncryptedKvBackupTaskTest {
+ private static final boolean INCREMENTAL = true;
+ private static final boolean NON_INCREMENTAL = false;
+
+ private static final String TEST_PACKAGE_1 = "com.example.app1";
+ private static final String TEST_KEY_1 = "key_1";
+ private static final String TEST_KEY_2 = "key_2";
+ private static final ChunkHash TEST_HASH_1 =
+ new ChunkHash(Arrays.copyOf(new byte[] {1}, ChunkHash.HASH_LENGTH_BYTES));
+ private static final ChunkHash TEST_HASH_2 =
+ new ChunkHash(Arrays.copyOf(new byte[] {2}, ChunkHash.HASH_LENGTH_BYTES));
+ private static final int TEST_LENGTH_1 = 200;
+ private static final int TEST_LENGTH_2 = 300;
+
+ @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+
+ @Captor private ArgumentCaptor<ChunksMetadataProto.ChunkListing> mChunkListingCaptor;
+
+ @Mock private TertiaryKeyManager mTertiaryKeyManager;
+ @Mock private RecoverableKeyStoreSecondaryKey mSecondaryKey;
+ @Mock private ProtoStore<KeyValueListingProto.KeyValueListing> mKeyValueListingStore;
+ @Mock private ProtoStore<ChunksMetadataProto.ChunkListing> mChunkListingStore;
+ @Mock private KvBackupEncrypter mKvBackupEncrypter;
+ @Mock private EncryptedBackupTask mEncryptedBackupTask;
+ @Mock private SecretKey mTertiaryKey;
+
+ private WrappedKeyProto.WrappedKey mWrappedTertiaryKey;
+ private KeyValueListingProto.KeyValueListing mNewKeyValueListing;
+ private ChunksMetadataProto.ChunkListing mNewChunkListing;
+ private EncryptedKvBackupTask mTask;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ Application application = ApplicationProvider.getApplicationContext();
+ mKeyValueListingStore = ProtoStore.createKeyValueListingStore(application);
+ mChunkListingStore = ProtoStore.createChunkListingStore(application);
+
+ mWrappedTertiaryKey = new WrappedKeyProto.WrappedKey();
+
+ when(mTertiaryKeyManager.wasKeyRotated()).thenReturn(false);
+ when(mTertiaryKeyManager.getKey()).thenReturn(mTertiaryKey);
+ when(mTertiaryKeyManager.getWrappedKey()).thenReturn(mWrappedTertiaryKey);
+
+ mNewKeyValueListing =
+ createKeyValueListing(
+ CryptoTestUtils.mapOf(
+ new Pair<>(TEST_KEY_1, TEST_HASH_1),
+ new Pair<>(TEST_KEY_2, TEST_HASH_2)));
+ mNewChunkListing =
+ createChunkListing(
+ CryptoTestUtils.mapOf(
+ new Pair<>(TEST_HASH_1, TEST_LENGTH_1),
+ new Pair<>(TEST_HASH_2, TEST_LENGTH_2)));
+ when(mKvBackupEncrypter.getNewKeyValueListing()).thenReturn(mNewKeyValueListing);
+ when(mEncryptedBackupTask.performIncrementalBackup(
+ eq(mTertiaryKey), eq(mWrappedTertiaryKey), any()))
+ .thenReturn(mNewChunkListing);
+ when(mEncryptedBackupTask.performNonIncrementalBackup(
+ eq(mTertiaryKey), eq(mWrappedTertiaryKey), any()))
+ .thenReturn(mNewChunkListing);
+
+ mTask =
+ new EncryptedKvBackupTask(
+ mTertiaryKeyManager,
+ mKeyValueListingStore,
+ mSecondaryKey,
+ mChunkListingStore,
+ mKvBackupEncrypter,
+ mEncryptedBackupTask,
+ TEST_PACKAGE_1);
+ }
+
+ @Test
+ public void testPerformBackup_rotationRequired_deletesListings() throws Exception {
+ mKeyValueListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
+ mChunkListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
+
+ when(mTertiaryKeyManager.wasKeyRotated()).thenReturn(true);
+ // Throw an IOException so it aborts before saving the new listings.
+ when(mEncryptedBackupTask.performNonIncrementalBackup(any(), any(), any()))
+ .thenThrow(IOException.class);
+
+ assertThrows(IOException.class, () -> mTask.performBackup(NON_INCREMENTAL));
+
+ assertFalse(mKeyValueListingStore.loadProto(TEST_PACKAGE_1).isPresent());
+ assertFalse(mChunkListingStore.loadProto(TEST_PACKAGE_1).isPresent());
+ }
+
+ @Test
+ public void testPerformBackup_rotationRequiredButIncremental_throws() throws Exception {
+ mKeyValueListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
+ mChunkListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
+
+ when(mTertiaryKeyManager.wasKeyRotated()).thenReturn(true);
+
+ assertThrows(NonIncrementalBackupRequiredException.class,
+ () -> mTask.performBackup(INCREMENTAL));
+ }
+
+ @Test
+ public void testPerformBackup_rotationRequiredAndNonIncremental_performsNonIncrementalBackup()
+ throws Exception {
+ mKeyValueListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
+ mChunkListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
+
+ when(mTertiaryKeyManager.wasKeyRotated()).thenReturn(true);
+
+ mTask.performBackup(NON_INCREMENTAL);
+
+ verify(mEncryptedBackupTask)
+ .performNonIncrementalBackup(eq(mTertiaryKey), eq(mWrappedTertiaryKey), any());
+ }
+
+ @Test
+ public void testPerformBackup_existingStateButNonIncremental_deletesListings() throws Exception {
+ mKeyValueListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
+ mChunkListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
+
+ // Throw an IOException so it aborts before saving the new listings.
+ when(mEncryptedBackupTask.performNonIncrementalBackup(any(), any(), any()))
+ .thenThrow(IOException.class);
+
+ assertThrows(IOException.class, () -> mTask.performBackup(NON_INCREMENTAL));
+
+ assertFalse(mKeyValueListingStore.loadProto(TEST_PACKAGE_1).isPresent());
+ assertFalse(mChunkListingStore.loadProto(TEST_PACKAGE_1).isPresent());
+ }
+
+ @Test
+ public void testPerformBackup_keyValueListingMissing_deletesChunkListingAndPerformsNonIncremental()
+ throws Exception {
+ mChunkListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
+
+ // Throw an IOException so it aborts before saving the new listings.
+ when(mEncryptedBackupTask.performNonIncrementalBackup(any(), any(), any()))
+ .thenThrow(IOException.class);
+
+ assertThrows(IOException.class, () -> mTask.performBackup(NON_INCREMENTAL));
+
+ verify(mEncryptedBackupTask).performNonIncrementalBackup(any(), any(), any());
+ assertFalse(mKeyValueListingStore.loadProto(TEST_PACKAGE_1).isPresent());
+ assertFalse(mChunkListingStore.loadProto(TEST_PACKAGE_1).isPresent());
+ }
+
+ @Test
+ public void testPerformBackup_chunkListingMissing_deletesKeyValueListingAndPerformsNonIncremental()
+ throws Exception {
+ mKeyValueListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
+
+ // Throw an IOException so it aborts before saving the new listings.
+ when(mEncryptedBackupTask.performNonIncrementalBackup(any(), any(), any()))
+ .thenThrow(IOException.class);
+
+ assertThrows(IOException.class, () -> mTask.performBackup(NON_INCREMENTAL));
+
+ verify(mEncryptedBackupTask).performNonIncrementalBackup(any(), any(), any());
+ assertFalse(mKeyValueListingStore.loadProto(TEST_PACKAGE_1).isPresent());
+ assertFalse(mChunkListingStore.loadProto(TEST_PACKAGE_1).isPresent());
+ }
+
+ @Test
+ public void testPerformBackup_existingStateAndIncremental_performsIncrementalBackup()
+ throws Exception {
+ mKeyValueListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
+ ChunksMetadataProto.ChunkListing oldChunkListing =
+ createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1)));
+ mChunkListingStore.saveProto(TEST_PACKAGE_1, oldChunkListing);
+
+ mTask.performBackup(INCREMENTAL);
+
+ verify(mEncryptedBackupTask)
+ .performIncrementalBackup(
+ eq(mTertiaryKey), eq(mWrappedTertiaryKey), mChunkListingCaptor.capture());
+ assertChunkListingsEqual(mChunkListingCaptor.getValue(), oldChunkListing);
+ }
+
+ @Test
+ public void testPerformBackup_noExistingStateAndNonIncremental_performsNonIncrementalBackup()
+ throws Exception {
+ mTask.performBackup(NON_INCREMENTAL);
+
+ verify(mEncryptedBackupTask)
+ .performNonIncrementalBackup(eq(mTertiaryKey), eq(mWrappedTertiaryKey), eq(null));
+ }
+
+ @Test
+ public void testPerformBackup_incremental_savesNewListings() throws Exception {
+ mKeyValueListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createKeyValueListing(CryptoTestUtils.mapOf(new Pair<>(TEST_KEY_1, TEST_HASH_1))));
+ mChunkListingStore.saveProto(
+ TEST_PACKAGE_1,
+ createChunkListing(CryptoTestUtils.mapOf(new Pair<>(TEST_HASH_1, TEST_LENGTH_1))));
+
+ mTask.performBackup(INCREMENTAL);
+
+ KeyValueListingProto.KeyValueListing actualKeyValueListing =
+ mKeyValueListingStore.loadProto(TEST_PACKAGE_1).get();
+ ChunksMetadataProto.ChunkListing actualChunkListing =
+ mChunkListingStore.loadProto(TEST_PACKAGE_1).get();
+ assertKeyValueListingsEqual(actualKeyValueListing, mNewKeyValueListing);
+ assertChunkListingsEqual(actualChunkListing, mNewChunkListing);
+ }
+
+ @Test
+ public void testPerformBackup_nonIncremental_savesNewListings() throws Exception {
+ mTask.performBackup(NON_INCREMENTAL);
+
+ KeyValueListingProto.KeyValueListing actualKeyValueListing =
+ mKeyValueListingStore.loadProto(TEST_PACKAGE_1).get();
+ ChunksMetadataProto.ChunkListing actualChunkListing =
+ mChunkListingStore.loadProto(TEST_PACKAGE_1).get();
+ assertKeyValueListingsEqual(actualKeyValueListing, mNewKeyValueListing);
+ assertChunkListingsEqual(actualChunkListing, mNewChunkListing);
+ }
+
+ private static KeyValueListingProto.KeyValueListing createKeyValueListing(
+ Map<String, ChunkHash> pairs) {
+ return new KeyValueListingBuilder().addAll(pairs).build();
+ }
+
+ private static ChunksMetadataProto.ChunkListing createChunkListing(
+ Map<ChunkHash, Integer> chunks) {
+ ChunksMetadataProto.Chunk[] listingChunks = new ChunksMetadataProto.Chunk[chunks.size()];
+ int chunksAdded = 0;
+ for (Entry<ChunkHash, Integer> entry : chunks.entrySet()) {
+ listingChunks[chunksAdded] = CryptoTestUtils.newChunk(entry.getKey(), entry.getValue());
+ chunksAdded++;
+ }
+ return CryptoTestUtils.newChunkListingWithoutDocId(
+ /* fingerprintSalt */ new byte[0],
+ ChunksMetadataProto.AES_256_GCM,
+ ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED,
+ listingChunks);
+ }
+
+ private static void assertKeyValueListingsEqual(
+ KeyValueListingProto.KeyValueListing actual,
+ KeyValueListingProto.KeyValueListing expected) {
+ KeyValueListingProto.KeyValueEntry[] actualEntries = actual.entries;
+ KeyValueListingProto.KeyValueEntry[] expectedEntries = expected.entries;
+ assertThat(actualEntries.length).isEqualTo(expectedEntries.length);
+ for (int i = 0; i < actualEntries.length; i++) {
+ assertWithMessage("entry " + i)
+ .that(actualEntries[i].key)
+ .isEqualTo(expectedEntries[i].key);
+ assertWithMessage("entry " + i)
+ .that(actualEntries[i].hash)
+ .isEqualTo(expectedEntries[i].hash);
+ }
+ }
+
+ private static void assertChunkListingsEqual(
+ ChunksMetadataProto.ChunkListing actual, ChunksMetadataProto.ChunkListing expected) {
+ ChunksMetadataProto.Chunk[] actualChunks = actual.chunks;
+ ChunksMetadataProto.Chunk[] expectedChunks = expected.chunks;
+ assertThat(actualChunks.length).isEqualTo(expectedChunks.length);
+ for (int i = 0; i < actualChunks.length; i++) {
+ assertWithMessage("chunk " + i)
+ .that(actualChunks[i].hash)
+ .isEqualTo(expectedChunks[i].hash);
+ assertWithMessage("chunk " + i)
+ .that(actualChunks[i].length)
+ .isEqualTo(expectedChunks[i].length);
+ }
+ assertThat(actual.cipherType).isEqualTo(expected.cipherType);
+ assertThat(actual.documentId)
+ .isEqualTo(expected.documentId == null ? "" : expected.documentId);
+ }
+}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTaskTest.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTaskTest.java
new file mode 100644
index 0000000..6666d95
--- /dev/null
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/backup/encryption/tasks/EncryptedKvRestoreTaskTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2019 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.server.backup.encryption.tasks;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertThrows;
+
+import android.os.ParcelFileDescriptor;
+
+import com.android.server.backup.encryption.chunk.ChunkHash;
+import com.android.server.backup.encryption.chunking.ChunkHasher;
+import com.android.server.backup.testing.CryptoTestUtils;
+import com.android.server.testing.shadows.DataEntity;
+import com.android.server.testing.shadows.ShadowBackupDataOutput;
+
+import com.google.protobuf.nano.MessageNano;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+@Config(shadows = {ShadowBackupDataOutput.class})
+@RunWith(RobolectricTestRunner.class)
+public class EncryptedKvRestoreTaskTest {
+ private static final String TEST_KEY_1 = "test_key_1";
+ private static final String TEST_KEY_2 = "test_key_2";
+ private static final String TEST_KEY_3 = "test_key_3";
+ private static final byte[] TEST_VALUE_1 = {1, 2, 3};
+ private static final byte[] TEST_VALUE_2 = {4, 5, 6};
+ private static final byte[] TEST_VALUE_3 = {20, 25, 30, 35};
+
+ @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ private File temporaryDirectory;
+
+ @Mock private ParcelFileDescriptor mParcelFileDescriptor;
+ @Mock private ChunkHasher mChunkHasher;
+ @Mock private FullRestoreToFileTask mFullRestoreToFileTask;
+ @Mock private BackupFileDecryptorTask mBackupFileDecryptorTask;
+
+ private EncryptedKvRestoreTask task;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(mChunkHasher.computeHash(any()))
+ .thenAnswer(invocation -> fakeHash(invocation.getArgument(0)));
+ doAnswer(invocation -> writeTestPairsToFile(invocation.getArgument(0)))
+ .when(mFullRestoreToFileTask)
+ .restoreToFile(any());
+ doAnswer(
+ invocation ->
+ readPairsFromFile(
+ invocation.getArgument(0), invocation.getArgument(1)))
+ .when(mBackupFileDecryptorTask)
+ .decryptFile(any(), any());
+
+ temporaryDirectory = temporaryFolder.newFolder();
+ task =
+ new EncryptedKvRestoreTask(
+ temporaryDirectory,
+ mChunkHasher,
+ mFullRestoreToFileTask,
+ mBackupFileDecryptorTask);
+ }
+
+ @Test
+ public void testGetRestoreData_writesPairsToOutputInOrder() throws Exception {
+ task.getRestoreData(mParcelFileDescriptor);
+
+ assertThat(ShadowBackupDataOutput.getEntities())
+ .containsExactly(
+ new DataEntity(TEST_KEY_1, TEST_VALUE_1),
+ new DataEntity(TEST_KEY_2, TEST_VALUE_2),
+ new DataEntity(TEST_KEY_3, TEST_VALUE_3))
+ .inOrder();
+ }
+
+ @Test
+ public void testGetRestoreData_exceptionDuringDecryption_throws() throws Exception {
+ doThrow(IOException.class).when(mBackupFileDecryptorTask).decryptFile(any(), any());
+ assertThrows(IOException.class, () -> task.getRestoreData(mParcelFileDescriptor));
+ }
+
+ @Test
+ public void testGetRestoreData_exceptionDuringDownload_throws() throws Exception {
+ doThrow(IOException.class).when(mFullRestoreToFileTask).restoreToFile(any());
+ assertThrows(IOException.class, () -> task.getRestoreData(mParcelFileDescriptor));
+ }
+
+ @Test
+ public void testGetRestoreData_exceptionDuringDecryption_deletesTemporaryFiles() throws Exception {
+ doThrow(InvalidKeyException.class).when(mBackupFileDecryptorTask).decryptFile(any(), any());
+ assertThrows(InvalidKeyException.class, () -> task.getRestoreData(mParcelFileDescriptor));
+ assertThat(temporaryDirectory.listFiles()).isEmpty();
+ }
+
+ @Test
+ public void testGetRestoreData_exceptionDuringDownload_deletesTemporaryFiles() throws Exception {
+ doThrow(IOException.class).when(mFullRestoreToFileTask).restoreToFile(any());
+ assertThrows(IOException.class, () -> task.getRestoreData(mParcelFileDescriptor));
+ assertThat(temporaryDirectory.listFiles()).isEmpty();
+ }
+
+ private static Void writeTestPairsToFile(File file) throws IOException {
+ // Write the pairs out of order to check the task sorts them.
+ Set<byte[]> pairs =
+ new HashSet<>(
+ Arrays.asList(
+ createPair(TEST_KEY_1, TEST_VALUE_1),
+ createPair(TEST_KEY_3, TEST_VALUE_3),
+ createPair(TEST_KEY_2, TEST_VALUE_2)));
+
+ try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
+ oos.writeObject(pairs);
+ }
+ return null;
+ }
+
+ private static Void readPairsFromFile(File file, DecryptedChunkOutput decryptedChunkOutput)
+ throws IOException, ClassNotFoundException, InvalidKeyException,
+ NoSuchAlgorithmException {
+ try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
+ DecryptedChunkOutput output = decryptedChunkOutput.open()) {
+ Set<byte[]> pairs = readPairs(ois);
+ for (byte[] pair : pairs) {
+ output.processChunk(pair, pair.length);
+ }
+ }
+
+ return null;
+ }
+
+ private static byte[] createPair(String key, byte[] value) {
+ return MessageNano.toByteArray(CryptoTestUtils.newPair(key, value));
+ }
+
+ @SuppressWarnings("unchecked") // deserialization.
+ private static Set<byte[]> readPairs(ObjectInputStream ois)
+ throws IOException, ClassNotFoundException {
+ return (Set<byte[]>) ois.readObject();
+ }
+
+ private static ChunkHash fakeHash(byte[] data) {
+ return new ChunkHash(Arrays.copyOf(data, ChunkHash.HASH_LENGTH_BYTES));
+ }
+}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/CryptoTestUtils.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/CryptoTestUtils.java
index 5dfd5ee..b0c02ba 100644
--- a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/CryptoTestUtils.java
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/CryptoTestUtils.java
@@ -16,6 +16,8 @@
package com.android.server.backup.testing;
+import android.util.Pair;
+
import com.android.server.backup.encryption.chunk.ChunkHash;
import com.android.server.backup.encryption.protos.nano.ChunksMetadataProto;
import com.android.server.backup.encryption.protos.nano.KeyValuePairProto;
@@ -23,6 +25,8 @@
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Random;
import javax.crypto.KeyGenerator;
@@ -162,4 +166,12 @@
clone.checksum = Arrays.copyOf(original.checksum, original.checksum.length);
return clone;
}
+
+ public static <K, V> Map<K, V> mapOf(Pair<K, V>... pairs) {
+ Map<K, V> map = new HashMap<>();
+ for (Pair<K, V> pair : pairs) {
+ map.put(pair.first, pair.second);
+ }
+ return map;
+ }
}
diff --git a/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowBackupDataOutput.java b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowBackupDataOutput.java
new file mode 100644
index 0000000..2302e55
--- /dev/null
+++ b/packages/BackupEncryption/test/robolectric/src/com/android/server/testing/shadows/ShadowBackupDataOutput.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 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.server.testing.shadows;
+
+import android.app.backup.BackupDataOutput;
+
+import java.io.FileDescriptor;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/** Shadow for BackupDataOutput. */
+@Implements(BackupDataOutput.class)
+public class ShadowBackupDataOutput {
+ private static final List<DataEntity> ENTRIES = new ArrayList<>();
+
+ private String mCurrentKey;
+ private int mDataSize;
+
+ public static void reset() {
+ ENTRIES.clear();
+ }
+
+ public static Set<DataEntity> getEntities() {
+ return new LinkedHashSet<>(ENTRIES);
+ }
+
+ public void __constructor__(FileDescriptor fd) {}
+
+ public void __constructor__(FileDescriptor fd, long quota) {}
+
+ public void __constructor__(FileDescriptor fd, long quota, int transportFlags) {}
+
+ @Implementation
+ public int writeEntityHeader(String key, int size) {
+ mCurrentKey = key;
+ mDataSize = size;
+ return 0;
+ }
+
+ @Implementation
+ public int writeEntityData(byte[] data, int size) {
+ Assert.assertEquals("ShadowBackupDataOutput expects size = mDataSize", size, mDataSize);
+ ENTRIES.add(new DataEntity(mCurrentKey, data, mDataSize));
+ return 0;
+ }
+}
diff --git a/packages/BackupRestoreConfirmation/res/values-fi/strings.xml b/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
index 4517410..bc9dbde 100644
--- a/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
@@ -27,7 +27,7 @@
<string name="current_password_text" msgid="8268189555578298067">"Kirjoita nykyinen varmuuskopioinnin salasana alla:"</string>
<string name="device_encryption_restore_text" msgid="1570864916855208992">"Kirjoita laitteen salauksen salasana alle."</string>
<string name="device_encryption_backup_text" msgid="5866590762672844664">"Kirjoita laitteen salauksen salasana alle. Salasanaa käytetään myös varmuuskopioarkiston salaamiseen."</string>
- <string name="backup_enc_password_text" msgid="4981585714795233099">"Anna salasana kaikkien varmuuskopiotietojen salaamiseksi. Jos tämä jätetään tyhjäksi, nykyistä varmuuskopioinnin salasanaa käytetään:"</string>
+ <string name="backup_enc_password_text" msgid="4981585714795233099">"Lisää salasana kaikkien varmuuskopiotietojen salaamiseksi. Jos tämä jätetään tyhjäksi, nykyistä varmuuskopioinnin salasanaa käytetään:"</string>
<string name="backup_enc_password_optional" msgid="1350137345907579306">"Jos haluat salata kaikki varmuuskopiotiedot, kirjoita salasana alle:"</string>
<string name="backup_enc_password_required" msgid="7889652203371654149">"Koska laite on salattu, myös varmuuskopiointi on salattava. Kirjoita salasana alle:"</string>
<string name="restore_enc_password_text" msgid="6140898525580710823">"Jos palautustiedot on salattu, anna salasana alla:"</string>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index 9a063aa..5ec1bae 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -29,6 +29,7 @@
import com.android.systemui.power.EnhancedEstimatesImpl;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
+import com.android.systemui.statusbar.car.CarStatusBar;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationData;
@@ -42,6 +43,8 @@
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
@Module
abstract class CarSystemUIModule {
@@ -94,4 +97,9 @@
@Binds
abstract SystemUIRootComponent bindSystemUIRootComponent(
CarSystemUIRootComponent systemUIRootComponent);
+
+ @Binds
+ @IntoMap
+ @ClassKey(StatusBar.class)
+ public abstract SystemUI providesStatusBar(CarStatusBar statusBar);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
index a107dd7..c205bb4 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
@@ -15,11 +15,11 @@
*/
package com.android.systemui.car;
-import android.content.Context;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -34,8 +34,8 @@
public class CarNotificationEntryManager extends NotificationEntryManager {
@Inject
- public CarNotificationEntryManager(Context context) {
- super(context);
+ public CarNotificationEntryManager(NotificationData notificationData) {
+ super(notificationData);
}
@Override
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index b0ab5b4..cc6e842 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.car;
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -34,6 +36,7 @@
import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
@@ -57,36 +60,84 @@
import com.android.car.notification.NotificationDataManager;
import com.android.car.notification.NotificationViewController;
import com.android.car.notification.PreprocessingManager;
+import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.RegisterStatusBarResult;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.CarSystemUIFactory;
import com.android.systemui.Dependency;
+import com.android.systemui.ForegroundServiceController;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
+import com.android.systemui.UiOffloadThread;
+import com.android.systemui.appops.AppOpsController;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.classifier.FalsingLog;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.car.CarQSFragment;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.car.hvac.HvacController;
import com.android.systemui.statusbar.car.hvac.TemperatureView;
+import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotifPipelineInitializer;
+import com.android.systemui.statusbar.notification.NotificationAlertingManager;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Map;
+import javax.inject.Inject;
+import javax.inject.Named;
+
/**
* A status bar (and navigation bar) tailored for the automotive use case.
*/
@@ -175,6 +226,8 @@
private boolean mHideNavBarForKeyboard;
private boolean mBottomNavBarVisible;
+ private final NavigationBarController mNavigationBarController;
+
private final CarPowerStateListener mCarPowerStateListener =
(int state) -> {
// When the car powers on, clear all notifications and mute/unread states.
@@ -189,6 +242,118 @@
}
};
+ @Inject
+ public CarStatusBar(
+ LightBarController lightBarController,
+ AutoHideController autoHideController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ StatusBarIconController statusBarIconController,
+ DozeLog dozeLog,
+ InjectionInflationController injectionInflationController,
+ PulseExpansionHandler pulseExpansionHandler,
+ NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
+ KeyguardStateController keyguardStateController,
+ HeadsUpManagerPhone headsUpManagerPhone,
+ DynamicPrivacyController dynamicPrivacyController,
+ BypassHeadsUpNotifier bypassHeadsUpNotifier,
+ @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowNotificationLongPress,
+ NotifPipelineInitializer notifPipelineInitializer,
+ FalsingManager falsingManager,
+ BroadcastDispatcher broadcastDispatcher,
+ RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
+ NotificationGutsManager notificationGutsManager,
+ NotificationLogger notificationLogger,
+ NotificationEntryManager notificationEntryManager,
+ NotificationInterruptionStateProvider notificationInterruptionStateProvider,
+ NotificationViewHierarchyManager notificationViewHierarchyManager,
+ ForegroundServiceController foregroundServiceController,
+ AppOpsController appOpsController,
+ KeyguardViewMediator keyguardViewMediator,
+ ZenModeController zenModeController,
+ NotificationAlertingManager notificationAlertingManager,
+ DisplayMetrics displayMetrics,
+ MetricsLogger metricsLogger,
+ UiOffloadThread uiOffloadThread,
+ NotificationMediaManager notificationMediaManager,
+ NotificationLockscreenUserManager lockScreenUserManager,
+ NotificationRemoteInputManager remoteInputManager,
+ UserSwitcherController userSwitcherController,
+ NetworkController networkController,
+ BatteryController batteryController,
+ SysuiColorExtractor colorExtractor,
+ ScreenLifecycle screenLifecycle,
+ WakefulnessLifecycle wakefulnessLifecycle,
+ SysuiStatusBarStateController statusBarStateController,
+ VibratorHelper vibratorHelper,
+ BubbleController bubbleController,
+ NotificationGroupManager groupManager,
+ NotificationGroupAlertTransferHelper groupAlertTransferHelper,
+ VisualStabilityManager visualStabilityManager,
+ DeviceProvisionedController deviceProvisionedController,
+ NavigationBarController navigationBarController,
+ AssistManager assistManager,
+ NotificationListener notificationListener,
+ ConfigurationController configurationController,
+ StatusBarWindowController statusBarWindowController,
+ StatusBarWindowViewController.Builder statusBarWindowViewControllerBuild) {
+ super(
+ lightBarController,
+ autoHideController,
+ keyguardUpdateMonitor,
+ statusBarIconController,
+ dozeLog,
+ injectionInflationController,
+ pulseExpansionHandler,
+ notificationWakeUpCoordinator,
+ keyguardBypassController,
+ keyguardStateController,
+ headsUpManagerPhone,
+ dynamicPrivacyController,
+ bypassHeadsUpNotifier,
+ allowNotificationLongPress,
+ notifPipelineInitializer,
+ falsingManager,
+ broadcastDispatcher,
+ remoteInputQuickSettingsDisabler,
+ notificationGutsManager,
+ notificationLogger,
+ notificationEntryManager,
+ notificationInterruptionStateProvider,
+ notificationViewHierarchyManager,
+ foregroundServiceController,
+ appOpsController,
+ keyguardViewMediator,
+ zenModeController,
+ notificationAlertingManager,
+ displayMetrics,
+ metricsLogger,
+ uiOffloadThread,
+ notificationMediaManager,
+ lockScreenUserManager,
+ remoteInputManager,
+ userSwitcherController,
+ networkController,
+ batteryController,
+ colorExtractor,
+ screenLifecycle,
+ wakefulnessLifecycle,
+ statusBarStateController,
+ vibratorHelper,
+ bubbleController,
+ groupManager,
+ groupAlertTransferHelper,
+ visualStabilityManager,
+ deviceProvisionedController,
+ navigationBarController,
+ assistManager,
+ notificationListener,
+ configurationController,
+ statusBarWindowController,
+ statusBarWindowViewControllerBuild);
+ mNavigationBarController = navigationBarController;
+ }
+
@Override
public void start() {
// get the provisioned state before calling the parent class since it's that flow that
@@ -616,7 +781,7 @@
return;
}
mStatusBarWindowController.setStatusBarFocusable(false);
- mStatusBarWindow.cancelExpandHelper();
+ mStatusBarWindowViewController.cancelExpandHelper();
mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
animateNotificationPanel(mClosingVelocity, true);
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index 827a59e..743ab47 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -23,13 +23,17 @@
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.car.userlib.CarUserManagerHelper;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.AsyncTask;
+import android.os.UserHandle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -53,13 +57,19 @@
* Displays a GridLayout with icons for the users in the system to allow switching between users.
* One of the uses of this is for the lock screen in auto.
*/
-public class UserGridRecyclerView extends RecyclerView implements
- CarUserManagerHelper.OnUsersUpdateListener {
+public class UserGridRecyclerView extends RecyclerView {
private UserSelectionListener mUserSelectionListener;
private UserAdapter mAdapter;
private CarUserManagerHelper mCarUserManagerHelper;
private Context mContext;
+ private final BroadcastReceiver mUserUpdateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onUsersUpdate();
+ }
+ };
+
public UserGridRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
@@ -75,7 +85,7 @@
@Override
public void onFinishInflate() {
super.onFinishInflate();
- mCarUserManagerHelper.registerOnUsersUpdateListener(this);
+ registerForUserEvents();
}
/**
@@ -84,7 +94,7 @@
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
- mCarUserManagerHelper.unregisterOnUsersUpdateListener(this);
+ unregisterForUserEvents();
}
/**
@@ -161,13 +171,32 @@
mUserSelectionListener = userSelectionListener;
}
- @Override
- public void onUsersUpdate() {
+ private void onUsersUpdate() {
mAdapter.clearUsers();
mAdapter.updateUsers(createUserRecords(mCarUserManagerHelper.getAllUsers()));
mAdapter.notifyDataSetChanged();
}
+ private void registerForUserEvents() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_USER_REMOVED);
+ filter.addAction(Intent.ACTION_USER_ADDED);
+ filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
+ filter.addAction(Intent.ACTION_USER_STOPPED);
+ filter.addAction(Intent.ACTION_USER_UNLOCKED);
+ mContext.registerReceiverAsUser(
+ mUserUpdateReceiver,
+ UserHandle.ALL,
+ filter,
+ /* broadcastPermission= */ null,
+ /* scheduler= */ null);
+ }
+
+ private void unregisterForUserEvents() {
+ mContext.unregisterReceiver(mUserUpdateReceiver);
+ }
+
/**
* Adapter to populate the grid layout with the available user profiles
*/
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ActivityTile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ActivityTile.java
new file mode 100644
index 0000000..06a4a45
--- /dev/null
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/ActivityTile.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 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.settingslib.drawer;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ComponentInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Description of a single dashboard tile which is generated from an activity.
+ */
+public class ActivityTile extends Tile {
+ private static final String TAG = "ActivityTile";
+
+ public ActivityTile(ComponentInfo info, String category) {
+ super(info, category);
+ setMetaData(info.metaData);
+ }
+
+ ActivityTile(Parcel in) {
+ super(in);
+ }
+
+ @Override
+ public int getId() {
+ return Objects.hash(getPackageName(), getComponentName());
+ }
+
+ @Override
+ public String getDescription() {
+ return getPackageName() + "/" + getComponentName();
+ }
+
+ @Override
+ protected CharSequence getComponentLabel(Context context) {
+ final PackageManager pm = context.getPackageManager();
+ final ComponentInfo info = getComponentInfo(context);
+ return info == null
+ ? null
+ : info.loadLabel(pm);
+ }
+
+ @Override
+ protected ComponentInfo getComponentInfo(Context context) {
+ if (mComponentInfo == null) {
+ final PackageManager pm = context.getApplicationContext().getPackageManager();
+ final Intent intent = getIntent();
+ final List<ResolveInfo> infoList =
+ pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
+ if (infoList != null && !infoList.isEmpty()) {
+ mComponentInfo = infoList.get(0).activityInfo;
+ setMetaData(mComponentInfo.metaData);
+ } else {
+ Log.e(TAG, "Cannot find package info for "
+ + intent.getComponent().flattenToString());
+ }
+ }
+ return mComponentInfo;
+ }
+}
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
index ca2d1ed..722f734 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
@@ -30,9 +30,8 @@
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ActivityInfo;
+import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Icon;
@@ -47,13 +46,11 @@
import java.util.ArrayList;
import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
/**
* Description of a single dashboard tile that the user can select.
*/
-public class Tile implements Parcelable {
+public abstract class Tile implements Parcelable {
private static final String TAG = "Tile";
@@ -64,28 +61,27 @@
@VisibleForTesting
long mLastUpdateTime;
- private final String mActivityPackage;
- private final String mActivityName;
+ private final String mComponentPackage;
+ private final String mComponentName;
private final Intent mIntent;
- private ActivityInfo mActivityInfo;
+ protected ComponentInfo mComponentInfo;
private CharSequence mSummaryOverride;
private Bundle mMetaData;
private String mCategory;
- public Tile(ActivityInfo activityInfo, String category) {
- mActivityInfo = activityInfo;
- mActivityPackage = mActivityInfo.packageName;
- mActivityName = mActivityInfo.name;
- mMetaData = activityInfo.metaData;
+ public Tile(ComponentInfo info, String category) {
+ mComponentInfo = info;
+ mComponentPackage = mComponentInfo.packageName;
+ mComponentName = mComponentInfo.name;
mCategory = category;
- mIntent = new Intent().setClassName(mActivityPackage, mActivityName);
+ mIntent = new Intent().setClassName(mComponentPackage, mComponentName);
}
Tile(Parcel in) {
- mActivityPackage = in.readString();
- mActivityName = in.readString();
- mIntent = new Intent().setClassName(mActivityPackage, mActivityName);
+ mComponentPackage = in.readString();
+ mComponentName = in.readString();
+ mIntent = new Intent().setClassName(mComponentPackage, mComponentName);
final int number = in.readInt();
for (int i = 0; i < number; i++) {
userHandle.add(UserHandle.CREATOR.createFromParcel(in));
@@ -101,8 +97,8 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mActivityPackage);
- dest.writeString(mActivityName);
+ dest.writeString(mComponentPackage);
+ dest.writeString(mComponentName);
final int size = userHandle.size();
dest.writeInt(size);
for (int i = 0; i < size; i++) {
@@ -112,16 +108,22 @@
dest.writeBundle(mMetaData);
}
- public int getId() {
- return Objects.hash(mActivityPackage, mActivityName);
- }
+ /**
+ * Unique ID of the tile
+ */
+ public abstract int getId();
- public String getDescription() {
- return mActivityPackage + "/" + mActivityName;
- }
+ /**
+ * Human-readable description of the tile
+ */
+ public abstract String getDescription();
public String getPackageName() {
- return mActivityPackage;
+ return mComponentPackage;
+ }
+
+ public String getComponentName() {
+ return mComponentName;
}
/**
@@ -154,7 +156,7 @@
}
/**
- * Check whether title has order.
+ * Check whether tile has order.
*/
public boolean hasOrder() {
return mMetaData.containsKey(META_DATA_KEY_ORDER)
@@ -170,14 +172,14 @@
final PackageManager packageManager = context.getPackageManager();
if (mMetaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
if (mMetaData.containsKey(META_DATA_PREFERENCE_TITLE_URI)) {
- // If has as uri to provide dynamic summary, skip loading here. UI will later load
+ // If has as uri to provide dynamic title, skip loading here. UI will later load
// at tile binding time.
return null;
}
if (mMetaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
try {
final Resources res =
- packageManager.getResourcesForApplication(mActivityPackage);
+ packageManager.getResourcesForApplication(mComponentPackage);
title = res.getString(mMetaData.getInt(META_DATA_PREFERENCE_TITLE));
} catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
Log.w(TAG, "Couldn't find info", e);
@@ -186,18 +188,15 @@
title = mMetaData.getString(META_DATA_PREFERENCE_TITLE);
}
}
- // Set the preference title to the activity's label if no
- // meta-data is found
+ // Set the preference title by the component if no meta-data is found
if (title == null) {
- final ActivityInfo activityInfo = getActivityInfo(context);
- if (activityInfo == null) {
- return null;
- }
- title = activityInfo.loadLabel(packageManager);
+ title = getComponentLabel(context);
}
return title;
}
+ protected abstract CharSequence getComponentLabel(Context context);
+
/**
* Overrides the summary. This can happen when injected tile wants to provide dynamic summary.
*/
@@ -225,7 +224,7 @@
if (mMetaData.get(META_DATA_PREFERENCE_SUMMARY) instanceof Integer) {
try {
final Resources res =
- packageManager.getResourcesForApplication(mActivityPackage);
+ packageManager.getResourcesForApplication(mComponentPackage);
summary = res.getString(mMetaData.getInt(META_DATA_PREFERENCE_SUMMARY));
} catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
Log.d(TAG, "Couldn't find info", e);
@@ -281,24 +280,24 @@
return null;
}
ensureMetadataNotStale(context);
- final ActivityInfo activityInfo = getActivityInfo(context);
- if (activityInfo == null) {
- Log.w(TAG, "Cannot find ActivityInfo for " + getDescription());
+ final ComponentInfo componentInfo = getComponentInfo(context);
+ if (componentInfo == null) {
+ Log.w(TAG, "Cannot find ComponentInfo for " + getDescription());
return null;
}
int iconResId = mMetaData.getInt(META_DATA_PREFERENCE_ICON);
// Set the icon
if (iconResId == 0) {
- // Only fallback to activityinfo.icon if metadata does not contain ICON_URI.
+ // Only fallback to componentInfo.icon if metadata does not contain ICON_URI.
// ICON_URI should be loaded in app UI when need the icon object. Handling IPC at this
// level is too complex because we don't have a strong threading contract for this class
if (!mMetaData.containsKey(META_DATA_PREFERENCE_ICON_URI)) {
- iconResId = activityInfo.icon;
+ iconResId = componentInfo.icon;
}
}
if (iconResId != 0) {
- final Icon icon = Icon.createWithResource(activityInfo.packageName, iconResId);
+ final Icon icon = Icon.createWithResource(componentInfo.packageName, iconResId);
if (isIconTintable(context)) {
final TypedArray a = context.obtainStyledAttributes(new int[]{
android.R.attr.colorControlNormal});
@@ -331,41 +330,26 @@
final PackageManager pm = context.getApplicationContext().getPackageManager();
try {
- final long lastUpdateTime = pm.getPackageInfo(mActivityPackage,
+ final long lastUpdateTime = pm.getPackageInfo(mComponentPackage,
PackageManager.GET_META_DATA).lastUpdateTime;
if (lastUpdateTime == mLastUpdateTime) {
// All good. Do nothing
return;
}
// App has been updated since we load metadata last time. Reload metadata.
- mActivityInfo = null;
- getActivityInfo(context);
+ mComponentInfo = null;
+ getComponentInfo(context);
mLastUpdateTime = lastUpdateTime;
} catch (PackageManager.NameNotFoundException e) {
Log.d(TAG, "Can't find package, probably uninstalled.");
}
}
- private ActivityInfo getActivityInfo(Context context) {
- if (mActivityInfo == null) {
- final PackageManager pm = context.getApplicationContext().getPackageManager();
- final Intent intent = new Intent().setClassName(mActivityPackage, mActivityName);
- final List<ResolveInfo> infoList =
- pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
- if (infoList != null && !infoList.isEmpty()) {
- mActivityInfo = infoList.get(0).activityInfo;
- mMetaData = mActivityInfo.metaData;
- } else {
- Log.e(TAG, "Cannot find package info for "
- + intent.getComponent().flattenToString());
- }
- }
- return mActivityInfo;
- }
+ protected abstract ComponentInfo getComponentInfo(Context context);
public static final Creator<Tile> CREATOR = new Creator<Tile>() {
public Tile createFromParcel(Parcel source) {
- return new Tile(source);
+ return new ActivityTile(source);
}
public Tile[] newArray(int size) {
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index aced5ef..c4df2e8 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -20,6 +20,7 @@
import android.content.IContentProvider;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
@@ -127,6 +128,7 @@
*/
public static final String META_DATA_PREFERENCE_ICON_BACKGROUND_HINT =
"com.android.settings.bg.hint";
+
/**
* Name of the meta-data item that should be set in the AndroidManifest.xml
* to specify the icon background color as raw ARGB.
@@ -220,10 +222,11 @@
public static List<DashboardCategory> getCategories(Context context,
Map<Pair<String, String>, Tile> cache) {
final long startTime = System.currentTimeMillis();
- boolean setup = Global.getInt(context.getContentResolver(), Global.DEVICE_PROVISIONED, 0)
- != 0;
- ArrayList<Tile> tiles = new ArrayList<>();
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ final boolean setup =
+ Global.getInt(context.getContentResolver(), Global.DEVICE_PROVISIONED, 0) != 0;
+ final ArrayList<Tile> tiles = new ArrayList<>();
+ final UserManager userManager = (UserManager) context.getSystemService(
+ Context.USER_SERVICE);
for (UserHandle user : userManager.getUserProfiles()) {
// TODO: Needs much optimization, too many PM queries going on here.
if (user.getIdentifier() == ActivityManager.getCurrentUser()) {
@@ -240,7 +243,7 @@
}
}
- HashMap<String, DashboardCategory> categoryMap = new HashMap<>();
+ final HashMap<String, DashboardCategory> categoryMap = new HashMap<>();
for (Tile tile : tiles) {
final String categoryKey = tile.getCategory();
DashboardCategory category = categoryMap.get(categoryKey);
@@ -255,7 +258,7 @@
}
category.addTile(tile);
}
- ArrayList<DashboardCategory> categories = new ArrayList<>(categoryMap.values());
+ final ArrayList<DashboardCategory> categories = new ArrayList<>(categoryMap.values());
for (DashboardCategory category : categories) {
category.sortTiles();
}
@@ -275,63 +278,90 @@
if (requireSettings) {
intent.setPackage(SETTING_PKG);
}
+ getActivityTiles(context, user, addedCache, defaultCategory, outTiles, intent);
+ }
+
+ private static void getActivityTiles(Context context,
+ UserHandle user, Map<Pair<String, String>, Tile> addedCache,
+ String defaultCategory, List<Tile> outTiles, Intent intent) {
final PackageManager pm = context.getPackageManager();
- List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
+ final List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
PackageManager.GET_META_DATA, user.getIdentifier());
for (ResolveInfo resolved : results) {
if (!resolved.system) {
// Do not allow any app to add to settings, only system ones.
continue;
}
- ActivityInfo activityInfo = resolved.activityInfo;
- Bundle metaData = activityInfo.metaData;
- String categoryKey = defaultCategory;
-
- // Load category
- if ((metaData == null || !metaData.containsKey(EXTRA_CATEGORY_KEY))
- && categoryKey == null) {
- Log.w(LOG_TAG, "Found " + resolved.activityInfo.name + " for intent "
- + intent + " missing metadata "
- + (metaData == null ? "" : EXTRA_CATEGORY_KEY));
- continue;
- } else {
- categoryKey = metaData.getString(EXTRA_CATEGORY_KEY);
- }
-
- Pair<String, String> key = new Pair<>(activityInfo.packageName, activityInfo.name);
- Tile tile = addedCache.get(key);
- if (tile == null) {
- tile = new Tile(activityInfo, categoryKey);
- addedCache.put(key, tile);
- } else {
- tile.setMetaData(metaData);
- }
-
- if (!tile.userHandle.contains(user)) {
- tile.userHandle.add(user);
- }
- if (!outTiles.contains(tile)) {
- outTiles.add(tile);
- }
+ final ActivityInfo activityInfo = resolved.activityInfo;
+ final Bundle metaData = activityInfo.metaData;
+ getTile(user, addedCache, defaultCategory, outTiles, intent, metaData, activityInfo);
}
}
+ private static void getTile(UserHandle user, Map<Pair<String, String>, Tile> addedCache,
+ String defaultCategory, List<Tile> outTiles, Intent intent, Bundle metaData,
+ ComponentInfo componentInfo) {
+ String categoryKey = defaultCategory;
+ // Load category
+ if ((metaData == null || !metaData.containsKey(EXTRA_CATEGORY_KEY))
+ && categoryKey == null) {
+ Log.w(LOG_TAG, "Found " + componentInfo.name + " for intent "
+ + intent + " missing metadata "
+ + (metaData == null ? "" : EXTRA_CATEGORY_KEY));
+ return;
+ } else {
+ categoryKey = metaData.getString(EXTRA_CATEGORY_KEY);
+ }
+
+ final Pair<String, String> key = new Pair<>(componentInfo.packageName, componentInfo.name);
+ Tile tile = addedCache.get(key);
+ if (tile == null) {
+ tile = new ActivityTile(componentInfo, categoryKey);
+ addedCache.put(key, tile);
+ } else {
+ tile.setMetaData(metaData);
+ }
+
+ if (!tile.userHandle.contains(user)) {
+ tile.userHandle.add(user);
+ }
+ if (!outTiles.contains(tile)) {
+ outTiles.add(tile);
+ }
+ }
+
+ /**
+ * Returns the complete uri from the meta data key of the tile.
+
+ * @param tile Tile which contains meta data
+ * @param metaDataKey Key mapping to the uri in meta data
+ * @return Uri associated with the key
+ */
+ public static Uri getCompleteUri(Tile tile, String metaDataKey) {
+ final String uriString = tile.getMetaData().getString(metaDataKey);
+ if (TextUtils.isEmpty(uriString)) {
+ return null;
+ }
+
+ return Uri.parse(uriString);
+ }
+
/**
* Gets the icon package name and resource id from content provider.
*
* @param context context
* @param packageName package name of the target activity
- * @param uriString URI for the content provider
+ * @param uri URI for the content provider
* @param providerMap Maps URI authorities to providers
* @return package name and resource id of the icon specified
*/
public static Pair<String, Integer> getIconFromUri(Context context, String packageName,
- String uriString, Map<String, IContentProvider> providerMap) {
- Bundle bundle = getBundleFromUri(context, uriString, providerMap);
+ Uri uri, Map<String, IContentProvider> providerMap) {
+ final Bundle bundle = getBundleFromUri(context, uri, providerMap, null);
if (bundle == null) {
return null;
}
- String iconPackageName = bundle.getString(EXTRA_PREFERENCE_ICON_PACKAGE);
+ final String iconPackageName = bundle.getString(EXTRA_PREFERENCE_ICON_PACKAGE);
if (TextUtils.isEmpty(iconPackageName)) {
return null;
}
@@ -342,7 +372,7 @@
// Icon can either come from the target package or from the Settings app.
if (iconPackageName.equals(packageName)
|| iconPackageName.equals(context.getPackageName())) {
- return Pair.create(iconPackageName, bundle.getInt(META_DATA_PREFERENCE_ICON, 0));
+ return Pair.create(iconPackageName, resId);
}
return null;
}
@@ -351,34 +381,33 @@
* Gets text associated with the input key from the content provider.
*
* @param context context
- * @param uriString URI for the content provider
+ * @param uri URI for the content provider
* @param providerMap Maps URI authorities to providers
* @param key Key mapping to the text in bundle returned by the content provider
* @return Text associated with the key, if returned by the content provider
*/
- public static String getTextFromUri(Context context, String uriString,
+ public static String getTextFromUri(Context context, Uri uri,
Map<String, IContentProvider> providerMap, String key) {
- Bundle bundle = getBundleFromUri(context, uriString, providerMap);
+ final Bundle bundle = getBundleFromUri(context, uri, providerMap, null);
return (bundle != null) ? bundle.getString(key) : null;
}
- private static Bundle getBundleFromUri(Context context, String uriString,
- Map<String, IContentProvider> providerMap) {
- if (TextUtils.isEmpty(uriString)) {
+ private static Bundle getBundleFromUri(Context context, Uri uri,
+ Map<String, IContentProvider> providerMap, Bundle bundle) {
+ if (uri == null) {
return null;
}
- Uri uri = Uri.parse(uriString);
- String method = getMethodFromUri(uri);
+ final String method = getMethodFromUri(uri);
if (TextUtils.isEmpty(method)) {
return null;
}
- IContentProvider provider = getProviderFromUri(context, uri, providerMap);
+ final IContentProvider provider = getProviderFromUri(context, uri, providerMap);
if (provider == null) {
return null;
}
try {
return provider.call(context.getPackageName(), uri.getAuthority(),
- method, uriString, null);
+ method, uri.toString(), bundle);
} catch (RemoteException e) {
return null;
}
@@ -389,7 +418,7 @@
if (uri == null) {
return null;
}
- String authority = uri.getAuthority();
+ final String authority = uri.getAuthority();
if (TextUtils.isEmpty(authority)) {
return null;
}
@@ -400,7 +429,7 @@
}
/** Returns the first path segment of the uri if it exists as the method, otherwise null. */
- static String getMethodFromUri(Uri uri) {
+ private static String getMethodFromUri(Uri uri) {
if (uri == null) {
return null;
}
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 4cedc93..245ca14 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet kan binnekort afgaan (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Toestel kan binnekort afgaan (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> oor tot vol gelaai"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol gelaai"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> oor tot battery gelaai is"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot battery gelaai is"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laai"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"laai tans"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 3b7abdb..bfd3196 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ጡባዊው በቅርቡ ሊዘጋ ይችላል (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"መሣሪያው በቅርቡ ሊዘጋ ይችላል (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ሙሉ ኃይል እስኪሞላ ድረስ <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ሙሉ ለሙሉ እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> ኃይል እስከሚሞላ ድረስ ይቀራል"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ኃይል እስከሚሞላ ድረስ"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ያልታወቀ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ኃይል በመሙላት ላይ"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ኃይል በመሙላት ላይ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index df1ec30..8b67b0b 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"قد يتم إغلاق الجهاز اللوحي بعد قليل (<xliff:g id="LEVEL">%1$s</xliff:g>)."</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"قد يتم إغلاق الجهاز بعد قليل (<xliff:g id="LEVEL">%1$s</xliff:g>)."</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"يتبقى <xliff:g id="TIME">%1$s</xliff:g> لشحن البطارية بالكامل"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى يكتمل الشحن"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> إلى أن يتم شحن الجهاز بالكامل"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> إلى أن يتم شحن الجهاز بالكامل"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"غير معروف"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"جارٍ الشحن"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"جارٍ الشحن"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 9c25b66..f3ca337 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"টেবলেটটো সোনকালেই বন্ধ হ\'ব পাৰে (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ডিভাইচটো সোনকালেই বন্ধ হ\'ব পাৰে (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"সম্পূৰ্ণকৈ চ্চাৰ্জ হ\'বলৈ <xliff:g id="TIME">%1$s</xliff:g> বাকী"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> সম্পূৰ্ণৰূপে চ্চাৰ্জ হোৱা পৰ্যন্ত"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"চাৰ্জ হ’বলৈ <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> চাৰ্জ হ\'বলৈ"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"অজ্ঞাত"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"চাৰ্জ কৰি থকা হৈছে"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"চ্চাৰ্জ হৈ আছে"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 3a6d301..d35dfe8 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Planşet tezliklə sönə bilər (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Cihaz tezliklə sönə bilər (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tam enerji yığmağına <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tam enerji yığana kimi"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Enerjinin dolmasına <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - Enerjinin dolmasına <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Naməlum"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Enerji doldurma"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"enerji yığır"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index a8808fa..448de4b 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet će se uskoro isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Uređaj će se uskoro isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> do potpunog punjenja"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpunog punjenja"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Napuniće se za <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – napuniće se za <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Puni se"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"puni se"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 05d9a5d..d68c0f3 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Узровень зараду батарэі: <xliff:g id="LEVEL">%1$s</xliff:g>. Планшэт хутка спыніць працу."</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Узровень зараду батарэі: <xliff:g id="LEVEL">%1$s</xliff:g>. Прылада хутка спыніць працу."</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Да поўнай зарадкі засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Засталося <xliff:g id="TIME">%1$s</xliff:g> да поўнай зарадкі"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Невядома"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарадка"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ідзе зарадка"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 7fa5b06..cb99f64 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Възможно е таблетът да се изключи скоро (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Възможно е устройството да се изключи скоро (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Оставащо време до пълно зареждане: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Оставащо време до пълно зареждане: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарежда се"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"зарежда се"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index f1fc9f9..f2f4f52 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ট্যাবলেটটি শীঘ্রই বন্ধ হয়ে যেতে পারে (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ডিভাইসটি শীঘ্রই বন্ধ হয়ে যেতে পারে (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%1$s</xliff:g> বাকি"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%2$s</xliff:g> লাগবে"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"সম্পূর্ণ চার্জ হতে <xliff:g id="TIME">%1$s</xliff:g> বাকি আছে"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>-এ সম্পূর্ণ চার্জ হয়ে যাবে"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"অজানা"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"চার্জ হচ্ছে"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"চার্জ হচ্ছে"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 02b2a8b..45b8dd9 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet će se uskoro isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Uređaj će se uskoro isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Još <xliff:g id="TIME">%1$s</xliff:g> do potpune napunjenosti"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Napunit će se za <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – napunit će se za <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"punjenje"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 2649544..bd1ed6a 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"És possible que la tauleta s\'apagui aviat (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"És possible que el dispositiu s\'apagui aviat (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> per completar la càrrega"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> per completar la càrrega"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconegut"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"S\'està carregant"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"s\'està carregant"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 5256399..042e12a 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet se brzy vypne (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Zařízení se brzy vypne (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Plně se nabije za <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – plně se nabije za <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Do nabití zbývá: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do nabití"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Neznámé"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjí se"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nabíjení"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 1884f64..4723293 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Denne tablet lukker muligvis snart ned (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Enheden lukker muligvis snart ned (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"fuldt opladet om <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – fuldt opladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Opladet om <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – opladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ukendt"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Oplader"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"oplader"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index d8da638..4f5a965 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet wird eventuell bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Gerät wird eventuell bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> bis zur vollständigen Aufladung"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis vollständig geladen"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Noch <xliff:g id="TIME">%1$s</xliff:g> bis zur Aufladung"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis zur Aufladung"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unbekannt"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Wird aufgeladen"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"wird aufgeladen..."</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index b1b1be6..753dea8 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Το tablet μπορεί να απενεργοποιηθεί σύντομα (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Η συσκευή μπορεί να απενεργοποιηθεί σύντομα (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Απομένουν <xliff:g id="TIME">%1$s</xliff:g> έως την πλήρη φόρτιση"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Απομένουν <xliff:g id="TIME">%1$s</xliff:g> για ολοκλήρωση της φόρτισης"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για την ολοκλήρωση της φόρτισης"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Άγνωστο"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Φόρτιση"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"φόρτιση"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 63463b1..dd3d278 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Device may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> left until charged"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until charged"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 63463b1..dd3d278 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Device may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> left until charged"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until charged"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 63463b1..dd3d278 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Device may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> left until charged"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until charged"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 63463b1..dd3d278 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Device may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> left until charged"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until charged"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index e5a0bda..d9f61d8 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Device may shutdown soon (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> left until fully charged"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until fully charged"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> left until charged"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until charged"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 7874aeb..30cb0a1 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Es posible que pronto se apague la tablet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Es posible que pronto se apague el dispositivo (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> para completar la carga"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> para completar la carga)"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> para completar la carga"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 8baf7a2..32905df 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Es posible que el tablet se apague pronto (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Es posible que el dispositivo se apague pronto (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tiempo restante hasta carga completa: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> hasta que termine de cargarse"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> hasta que termine de cargarse)"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 090b28d..79b8a84 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tahvelarvuti võib peagi välja lülituda (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Seade võib peagi välja lülituda (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> täislaadimiseni"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Täislaadimiseni on jäänud <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täislaadimiseni"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tundmatu"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laadimine"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"laadimine"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index fd3936d..bab4cde 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Baliteke tableta laster itzaltzea (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Baliteke gailua laster itzaltzea (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> falta dira guztiz kargatu arte"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ezezaguna"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Kargatzen"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"kargatzen"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 352c276..9d84090 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ممکن است رایانه لوحی بهزودی خاموش شود (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ممکن است دستگاه بهزودی خاموش شود (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> تا شارژ شدن کامل باقی مانده است"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> مانده تا شارژ کامل"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> مانده تا شارژ کامل"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ناشناس"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"در حال شارژ شدن"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"درحال شارژ شدن"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 0d522c4..929e101 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tabletti voi pian sammua (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Laite voi pian sammua (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> kunnes täynnä"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> jäljellä täyteen lataukseen"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> täyteen lataukseen"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tuntematon"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Ladataan"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ladataan"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 1dde863..d3bfc96 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Il se peut que la tablette s\'éteigne bientôt (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Il se peut que l\'appareil s\'éteigne bientôt (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à la charge complète"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à la charge complète"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> : <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Charge en cours…"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"en cours de charge"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index cf4ee13..b5706ce 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Il est possible que la tablette s\'éteigne bientôt (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Il est possible que l\'appareil s\'éteigne bientôt (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> avant charge complète"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à ce que la batterie soit chargée"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la charge complète"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"en charge…"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index b998a74..2aa1604 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"É posible que a tableta se apague en breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"É posible que o dispositivo se apague en breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo que queda para completar a carga: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> para completar a carga"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar a carga"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Descoñecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index cf0e201..c2cc4c5 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ટૅબ્લેટ થોડીક જ વારમાં બંધ થઈ શકે છે (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ઉપકરણ થોડીક જ વારમાં બંધ થઈ શકે છે (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"સંપૂર્ણપણે ચાર્જ થવામાં <xliff:g id="TIME">%1$s</xliff:g> બાકી"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - સંપૂર્ણપણે ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"ચાર્જ થવામાં <xliff:g id="TIME">%1$s</xliff:g> બાકી છે"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જ થવા માટે <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"અજાણ્યું"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ચાર્જ થઈ રહ્યું છે"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ચાર્જ થઈ રહ્યું છે"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 3a20d04..61e1997 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"टैबलेट जल्दी ही बंद हो सकता है (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"डिवाइस जल्दी ही बंद हो सकता है (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूरी तरह से चार्ज होने में <xliff:g id="TIME">%1$s</xliff:g> शेष"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूरी तरह से चार्ज होने तक"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"चार्ज पूरा होने में <xliff:g id="TIME">%1$s</xliff:g> बचा है"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> में पूरा चार्ज हो जाएगा"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हो रही है"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"चार्ज किया जा रहा है"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 6d957dc..0fc16f8 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet bi se uskoro mogao isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Uređaj bi se uskoro mogao isključiti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Još <xliff:g id="TIME">%1$s</xliff:g> do potpune napunjenosti"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Napunit će se za <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – napunit će se za <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"punjenje"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 39b5da2..45cd379 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Előfordulhat, hogy a táblagép hamarosan leáll (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Előfordulhat, hogy az eszköz hamarosan leáll (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> a teljes töltöttségig"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> van hátra a feltöltésig"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a feltöltésig"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ismeretlen"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Töltés"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"töltés"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 16d7ea4..2145adb 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Պլանշետը շուտով կանջատվի (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Սարքը շուտով կանջատվի (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Մինչև լրիվ լիցքավորումը մնացել է <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> մինչև լիցքավորումը"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լիցքավորումը"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Անհայտ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Լիցքավորում"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"լիցքավորում"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 02c4c8c..15b6da5 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet mungkin segera dimatikan (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Perangkat mungkin segera dimatikan (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> lagi hingga terisi penuh"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Sisa <xliff:g id="TIME">%1$s</xliff:g> hingga terisi penuh"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi terisi penuh"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Mengisi daya"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"mengisi daya baterai"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 11d69571..eede117 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Spjaldtölvan gæti slökkt á sér fljótlega (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Tækið gæti slökkt á sér fljótlega (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> þar til hleðslu er lokið"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> þar til fullri hleðslu er náð"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> að fullri hleðslu"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> að fullri hleðslu"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Óþekkt"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Í hleðslu"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"í hleðslu"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index a43e8d6..2c64ec2 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Il tablet potrebbe spegnersi a breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Il dispositivo potrebbe spegnersi a breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo rimanente alla carica completa: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Tempo rimanente alla carica completa: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Sconosciuta"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"In carica"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"in carica"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index a3e049c..30d6a4a 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ייתכן שהטאבלט ייכבה בקרוב (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ייתכן שהמכשיר ייכבה בקרוב (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> עד לטעינה מלאה"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד לטעינה מלאה"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"נשארו <xliff:g id="TIME">%1$s</xliff:g> עד הטעינה"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד הטעינה"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"לא ידוע"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"בטעינה"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"בטעינה"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 50543d8..6cb5514 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"タブレットの電源がもうすぐ切れます(<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"デバイスの電源がもうすぐ切れます(<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"フル充電まであと <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"充電完了まであと <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電完了まで <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"充電しています"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 8b9b6b6..4c78a38 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ტაბლეტი შეიძლება მალე გაითიშოს (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"მოწყობილობა შეიძლება მალე გაითიშოს (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"სრულ დატენვამდე დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> — სრულ დატენვამდე დარჩა <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"დატენვამდე დარჩა <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> დატენვამდე"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"უცნობი"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"იტენება"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"იტენება"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 246e3eb..ce08657 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Планшет көп ұзамай өшуі мүмкін (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Құрылғы көп ұзамай өшуі мүмкін (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Толық зарядталуына <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Зарядталғанға дейін <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Белгісіз"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядталуда"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"зарядталуда"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 36cf2d4..43c9282 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ថេប្លេតអាចនឹងបិទក្នុងពេលបន្តិចទៀត (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ឧបករណ៍អាចនឹងបិទក្នុងពេលបន្តិចទៀត (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបសាកថ្មពេញ"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើបសាកថ្មពេញ"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបត្រូវសាក"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើបត្រូវសាក"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"មិនស្គាល់"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"កំពុងបញ្ចូលថ្ម"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"កំពុងសាកថ្ម"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 97eed0f..3fe9855 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ಟ್ಯಾಬ್ಲೆಟ್ ಶೀಘ್ರದಲ್ಲೇ ಶಟ್ ಡೌನ್ ಆಗಬಹುದು (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ಸಾಧನವು ಶೀಘ್ರದಲ್ಲೇ ಶಟ್ ಡೌನ್ ಆಗಬಹುದು (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಸಂಪೂರ್ಣ ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%1$s</xliff:g> ಸಮಯ ಬಾಕಿ ಇದೆ"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಚಾರ್ಜ್ ಆಗಲು <xliff:g id="TIME">%2$s</xliff:g> ಸಮಯ ಬೇಕು"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ಅಪರಿಚಿತ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 8f8bbc1..ac44c0d 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"태블릿이 곧 종료될 수 있음(<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"기기가 곧 종료될 수 있음(<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"충전 완료까지 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"충전 완료까지 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 완료까지 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"알 수 없음"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"충전 중"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"충전 중"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 435ce53..72b2159 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Планшет бир аздан кийин өчүп калышы мүмкүн (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Түзмөк бир аздан кийин өчүп калышы мүмкүн (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Батарея толгонго чейин калган убакыт: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> кийин кубатталат"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> кийин кубатталат"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Белгисиз"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Кубатталууда"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"кубатталууда"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 1cee8fb..28e8111 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ແທັບເລັດອາດຈະປິດໃນໄວໆນີ້ (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ອຸປະກອນອາດຈະປິດໃນໄວໆນີ້ (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈົນກວ່າຈະສາກເຕັມ"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ບໍ່ຮູ້ຈັກ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ກຳລັງສາກໄຟ"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ກຳລັງສາກໄຟ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index c10bd00..93fcaa7 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Planšetinis kompiuteris netrukus gali būti išjungtas (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Įrenginys netrukus gali būti išjungtas (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Iki visiškos įkrovos liko <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Iki visiškos įkrovos liko <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – iki visiškos įkrovos liko <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nežinomas"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Kraunasi..."</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"įkraunama"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 96aebc5..c12d097 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Iespējams, planšetdators drīz izslēgsies (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Iespējams, ierīce drīz izslēgsies (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Atlikušais laiks līdz pilnai uzlādei: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> līdz pilnīgai uzlādei"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Vēl <xliff:g id="TIME">%1$s</xliff:g> līdz pilnai uzlādei"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai uzlādei"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nezināms"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Uzlāde"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"notiek uzlāde"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index d93304f..9a76a0a 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Таблетот може да се исклучи наскоро (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Уредот може да се исклучи наскоро (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Преостануваат <xliff:g id="TIME">%1$s</xliff:g> дури се наполни целосно"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> дури се наполни целосно"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Уште <xliff:g id="TIME">%1$s</xliff:g> до целосно полнење"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> до целосно полнење"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Се полни"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"се полни"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 7016b7f..bb76295 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ടാബ്ലെറ്റ് ഉടൻ ഷട്ട് ഡൗൺ ആയേക്കാം (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ഉപകരണം ഉടൻ ഷട്ട്ഡൗൺ ആയേക്കാം (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"മുഴുവൻ ചാർജാകാൻ <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഫുൾ ചാർജാകാൻ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"പൂർണ്ണമായി ചാർജാവാൻ <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമായി ചാർജാവാൻ <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"അജ്ഞാതം"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ചാർജ് ചെയ്യുന്നു"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ചാർജ് ചെയ്യുന്നു"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 80e78a3..65a8ca6 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Таблет удахгүй унтарна (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Төхөөрөмж удахгүй унтарна (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Бүрэн цэнэглэх хүртэл <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"бүрэн цэнэглэх хүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Цэнэглэх хүртэл үлдсэн <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - цэнэглэх хүртэл <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Тодорхойгүй"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Цэнэглэж байна"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"цэнэглэж байна"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 54723a8..3d75ad6 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"टॅबलेट लवकरच बंद होऊ शकतो (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"डिव्हाइस लवकरच बंद पडू शकते (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूर्णपणे चार्ज होण्यास <xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्णपणे चार्ज होण्यात <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> पर्यंत पूर्ण चार्ज होईल"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पर्यंत पूर्ण चार्ज होईल"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज होत आहे"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"चार्ज होत आहे"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 3841a3b..0b2a4b0 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet mungkin ditutup tidak lama lagi (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Peranti mungkin ditutup tidak lama lagi (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> lagi sehingga dicas penuh"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas penuh"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> lagi sehingga dicas penuh"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga dicas"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Mengecas"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"mengecas"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 38f128a..6fde69a 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"မကြာမီ တက်ဘလက် ပိတ်သွားနိုင်သည် (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"မကြာမီ စက်ပိတ်သွားနိုင်သည် (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"အားပြည့်ရန် <xliff:g id="TIME">%1$s</xliff:g> လိုပါသည်"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> − အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"အားပြည့်ရန် <xliff:g id="TIME">%1$s</xliff:g> ကျန်သည်"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> ကျန်သည်"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"မသိ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"အားသွင်းနေပါသည်"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"အားသွင်းနေပါသည်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 144d4c2..66ad20e 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Nettbrettet slås kanskje av snart (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Enheten slås kanskje av snart (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> til det er fulladet"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fulladet"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> til batteriet er fulladet"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til batteriet er fulladet"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ukjent"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Lader"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"lader"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index b2e1cd6..860e9bf 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ट्याब्लेट चाँडै बन्द हुन सक्छ (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"यन्त्र चाँडै बन्द हुन सक्छ (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्णरूपमा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> बाँकी"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"पूर्ण चार्ज हुन <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"पूर्ण चार्ज हुन <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> लाग्छ"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हुँदै"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"चार्ज हुँदै"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index c50b43a..2fff3283 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet wordt binnenkort mogelijk uitgeschakeld (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Apparaat wordt binnenkort mogelijk uitgeschakeld (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Nog <xliff:g id="TIME">%1$s</xliff:g> tot volledig opgeladen"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot volledig opgeladen"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Nog <xliff:g id="TIME">%1$s</xliff:g> tot opgeladen"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot opgeladen"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Opladen"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"opladen"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index f9e0d39..ff2a534 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ଖୁବ୍ ଶୀଘ୍ର ଟାବଲେଟ୍ଟି ବନ୍ଦ ହୋଇଯାଇପାରେ (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ଖୁବ୍ ଶୀଘ୍ର ଡିଭାଇସ୍ଟି ବନ୍ଦ ହୋଇଯାଇପାରେ(<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ସମ୍ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବାପାଇଁ <xliff:g id="TIME">%1$s</xliff:g> ବାକି ଅଛି"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ପୂର୍ଣ୍ଣ ଚାର୍ଜ ହେବା ପର୍ଯ୍ୟନ୍ତ"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"ଚାର୍ଜ ହେବା ପାଇଁ <xliff:g id="TIME">%1$s</xliff:g> ବାକି ଅଛି"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ଚାର୍ଜ ହେବା ପର୍ଯ୍ୟନ୍ତ"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ଅଜ୍ଞାତ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ଚାର୍ଜ ହେଉଛି"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ଚାର୍ଜ ହେଉଛି"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index b5acd8e..0cf95753 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ਟੈਬਲੈੱਟ ਛੇਤੀ ਹੀ ਬੰਦ ਹੋ ਸਕਦਾ ਹੈ (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ਡੀਵਾਈਸ ਛੇਤੀ ਹੀ ਬੰਦ ਹੋ ਸਕਦਾ ਹੈ (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਲਈ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਤੱਕ ਚਾਰਜ ਹੋ ਜਾਵੇਗੀ"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ਅਗਿਆਤ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 60a4c53..caed8c3 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet może się wkrótce wyłączyć (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Urządzenie może się wkrótce wyłączyć (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> do pełnego naładowania"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Do naładowania <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – do naładowania <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Nieznane"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Ładowanie"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ładowanie"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index dd0a75b..04a24f1 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"O tablet pode ser desligado em breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"O dispositivo pode ser desligado em breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> restante(s) até a carga completa"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Tempo restante até a carga completa: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"carregando"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index c076d32..a206d1a 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"O tablet poderá ser encerrado em breve (<xliff:g id="LEVEL">%1$s</xliff:g>)."</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"O dispositivo poderá ser encerrado em breve (<xliff:g id="LEVEL">%1$s</xliff:g>)."</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Falta(m) <xliff:g id="TIME">%1$s</xliff:g> para concluir o carregamento"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar totalmente carregada"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Falta(m) <xliff:g id="TIME">%1$s</xliff:g> até ficar carregada"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar carregada"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"A carregar"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"a carregar…"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index dd0a75b..04a24f1 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"O tablet pode ser desligado em breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"O dispositivo pode ser desligado em breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> restante(s) até a carga completa"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Tempo restante até a carga completa: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> até a carga completa"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"carregando"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index fb020e2..76a56e5 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tableta se poate închide în curând (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Dispozitivul se poate închide în curând (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Timp rămas până la încărcarea completă: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcarea completă"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Au mai rămas <xliff:g id="TIME">%1$s</xliff:g> până la încărcare"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> până la încărcare"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Necunoscut"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Se încarcă"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"se încarcă"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 806be6e..3e3768a 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Уровень заряда батареи: <xliff:g id="LEVEL">%1$s</xliff:g>. Планшет скоро завершит работу."</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Уровень заряда батареи: <xliff:g id="LEVEL">%1$s</xliff:g>. Устройство скоро завершит работу."</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Ещё <xliff:g id="TIME">%1$s</xliff:g> до полной зарядки"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> до полной зарядки"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Идет зарядка"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"заряжается"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 925d5b4..186c23a 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ටැබ්ලටය ඉක්මනින් වැසිය හැකිය (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"උපාංගය ඉක්මනින් වැසිය හැකිය (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"පූර්ණව ආරෝපණය වන තෙක් <xliff:g id="TIME">%1$s</xliff:g> ඉතිරියි"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පූර්ණයෙන් ආරෝපණය වන තෙක්"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"ආරෝපණය වන තෙක් <xliff:g id="TIME">%1$s</xliff:g> ඇත"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආරෝපණය වන තෙක් <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"නොදනී"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ආරෝපණය වෙමින්"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ආරෝපණය වේ"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index d77e1eb..9559975 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet sa môže čoskoro vypnúť (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Zariadenie sa môže čoskoro vypnúť (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> do úplného nabitia"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Zostávajúci čas do úplného nabitia: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Neznáme"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíja sa"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nabíja sa"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 263b4d0..62e4ad1 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablični računalnik se bo morda kmalu zaustavil (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Naprava se bo morda kmalu zaustavila (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Še <xliff:g id="TIME">%1$s</xliff:g> do polne napolnjenosti"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Še <xliff:g id="TIME">%1$s</xliff:g> do polne napolnjenosti"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do polne napolnjenosti"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Neznano"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Polnjenje"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"polnjenje"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 7a054bb..0498f31 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tableti mund të fiket së shpejti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Pajisja mund të fiket së shpejti (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura deri në ngarkimin e plotë"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet plotësisht"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura për karikimin"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të karikohen"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"I panjohur"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Po karikohet"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"po karikohet"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 0edc985..3157dee 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Таблет ће се ускоро искључити (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Уређај ће се ускоро искључити (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> до потпуног пуњења"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до потпуног пуњења"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Напуниће се за <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – напуниће се за <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Пуни се"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"пуни се"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 862fc6c..31517b8 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Surfplattan kan stängas av snart (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Enheten kan stängas av snart (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Batteriet är fulladdat om <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tills det är fulladdat"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> kvar till full laddning"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till full laddning"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Okänd"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Laddar"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"laddas"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 12922ca..d73084f 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Kompyuta kibao inakaribia kuzimika (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Kifaa kinakaribia kuzimika (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Imebaki <xliff:g id="TIME">%1$s</xliff:g> chaji ijae"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g> hadi ijae chaji"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hadi ijae chaji"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Haijulikani"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Inachaji"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"inachaji"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 8f72ab6..de70d08 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -138,8 +138,8 @@
<string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"கடவுச்சொல் தேவைப்படாத திறந்த நெட்வொர்க்"</string>
<string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"கடவுச்சொல் தேவைப்படும் பாதுகாப்பான நெட்வொர்க்"</string>
<string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
- <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"அகற்றப்பட்ட பயன்பாடுகள்"</string>
- <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"அகற்றப்பட்ட பயன்பாடுகள் மற்றும் பயனர்கள்"</string>
+ <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"அகற்றப்பட்ட ஆப்ஸ்"</string>
+ <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"அகற்றப்பட்ட ஆப்ஸ் மற்றும் பயனர்கள்"</string>
<string name="data_usage_ota" msgid="5377889154805560860">"சிஸ்டம் புதுப்பிப்புகள்"</string>
<string name="tether_settings_title_usb" msgid="6688416425801386511">"USB டெதெரிங்"</string>
<string name="tether_settings_title_wifi" msgid="3277144155960302049">"போர்ட்டபிள் ஹாட்ஸ்பாட்"</string>
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"டேப்லெட் விரைவில் ஆஃப் ஆகக்கூடும் (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"சாதனம் விரைவில் ஆஃப் ஆகக்கூடும் (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"முழு சார்ஜாக <xliff:g id="TIME">%1$s</xliff:g>ம் ஆகும்"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - முழு சார்ஜாக <xliff:g id="TIME">%2$s</xliff:g> ஆகும்"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"முழு சார்ஜாக <xliff:g id="TIME">%1$s</xliff:g> ஆகும்"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - முழு சார்ஜாக <xliff:g id="TIME">%2$s</xliff:g> ஆகும்"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"அறியப்படாத"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"சார்ஜ் ஆகிறது"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"சார்ஜ் ஆகிறது"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index e591121..3591670 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"టాబ్లెట్ షట్డౌన్ కావచ్చు (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"పరికరం త్వరలో షట్డౌన్ కావచ్చు (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"పూర్తిగా ఛార్జ్ కావడానికి <xliff:g id="TIME">%1$s</xliff:g> పడుతుంది"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"ఛార్జ్ అవ్వడానికి <xliff:g id="TIME">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - ఛార్జ్ అవ్వడానికి <xliff:g id="TIME">%2$s</xliff:g> పడుతుంది"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"తెలియదు"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"ఛార్జ్ అవుతోంది"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ఛార్జ్ అవుతోంది"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index b3bef9d..1cfe45e 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"แท็บเล็ตอาจปิดเครื่องในไม่ช้า (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"อุปกรณ์อาจปิดเครื่องในไม่ช้า (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"อีก <xliff:g id="TIME">%1$s</xliff:g> จึงจะชาร์จเต็ม"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>จนกว่าจะชาร์จเต็ม"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"เหลือ <xliff:g id="TIME">%1$s</xliff:g> จนกว่าจะชาร์จ"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะชาร์จ"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"ไม่ทราบ"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"กำลังชาร์จ"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"กำลังชาร์จ"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 85b6438..8b3118b 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Malapit nang mag-shutdown ang tablet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Malapit nang mag-shut down ang device (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> ang natitira bago makumpleto ang charge"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang sa makumpleto ang charge"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> ang natitira bago matapos mag-charge"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hanggang matapos mag-charge"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Hindi Kilala"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Nagcha-charge"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"nagcha-charge"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 6031eca..5891c79 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet kısa süre içinde kapanabilir (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Cihaz kısa süre içinde kapanabilir (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tam olarak şarj olmasına <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Şarj olmaya <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - şarj olmaya <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Bilinmiyor"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Şarj oluyor"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"şarj oluyor"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 5f3c6a6..0bca307 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Планшет може невдовзі вимкнутися (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Пристрій може невдовзі вимкнутися (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"До повного зарядження залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> до повного заряду"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Невідомо"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Заряджається"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"заряджається"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 82d9b3f..1e27b48 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ٹیبلیٹ جلد ہی بند ہو سکتا ہے (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"آلہ جلد ہی بند ہو سکتا ہے (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"پوری طرح چارج ہونے میں <xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> پوری طرح چارج ہونے تک"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"چارج ہونے میں <xliff:g id="TIME">%1$s</xliff:g> باقی"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> چارج ہونے تک"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"نامعلوم"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"چارج ہو رہا ہے"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"چارج ہو رہا ہے"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 0d3e8de..487100c 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Planshet tez orada o‘chib qolishi mumkin (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Qurilma tez orada o‘chib qolishi mumkin (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"To‘lishiga <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> ichida to‘ladi"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> ichida toʻliq quvvat oladi"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> ichida toʻliq quvvat oladi"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Noma’lum"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Quvvat olmoqda"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"quvvat olmoqda"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 003c457..c247617 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Máy tính bảng có thể sắp tắt (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Thiết bị có thể sắp tắt (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> nữa sẽ được sạc đầy"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> nữa sẽ được sạc đầy"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"Còn <xliff:g id="TIME">%1$s</xliff:g> nữa là sạc xong"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> nữa là sạc xong"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Không xác định"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Đang sạc"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"đang sạc"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index bcf1f2d..dddc107 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"平板电脑可能即将关机 (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"设备可能即将关机 (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"还需 <xliff:g id="TIME">%1$s</xliff:g>充满电"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需 <xliff:g id="TIME">%2$s</xliff:g>充满"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"还剩 <xliff:g id="TIME">%1$s</xliff:g>充满电"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>后充满电"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"正在充电"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"正在充电"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 286765d..8560e22 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"平板電腦可能即將關機 (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"裝置可能即將關機 (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g>後就能充滿電"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能充滿電"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"還需 <xliff:g id="TIME">%1$s</xliff:g>才能充滿電"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - 還需 <xliff:g id="TIME">%2$s</xliff:g>才能充滿電"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"正在充電"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index c641302..404aa19 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"平板電腦可能即將關機 (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"裝置可能即將關機 (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"再過 <xliff:g id="TIME">%1$s</xliff:g>就能完成充電"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g>後充飽電"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽電"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"充電中"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 1bfbf07..542332f 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -402,8 +402,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Ithebhulethi ingacisha maduze (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Idivayisi ingacisha maduze (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> kushiywe ishaja"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze ligcwale ngokuphelele"</string>
+ <string name="power_remaining_charging_duration_only" msgid="6672239353042034265">"<xliff:g id="TIME">%1$s</xliff:g> esele ize ishaje"</string>
+ <string name="power_charging_duration" msgid="5850751284103249125">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ize igcwale"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Akwaziwa"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Iyashaja"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"iyashaja"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java
index ea39317..81ca9ea 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java
@@ -111,8 +111,9 @@
for (int op : LOCATION_OPS) {
final String permission = AppOpsManager.opToPermission(op);
final int permissionFlags = pm.getPermissionFlags(permission, packageName, user);
- if (PermissionChecker.checkPermission(mContext, permission, -1, uid, packageName)
- == PermissionChecker.PERMISSION_GRANTED) {
+ if (PermissionChecker.checkPermissionForPreflight(mContext, permission,
+ PermissionChecker.PID_UNKNOWN, uid, packageName)
+ == PermissionChecker.PERMISSION_GRANTED) {
if ((permissionFlags
& PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) == 0) {
showApp = false;
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
index 60c9984..104cc8f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
@@ -110,9 +110,9 @@
final String permission = AppOpsManager.opToPermission(op);
final int permissionFlags = pm.getPermissionFlags(permission, packageName,
user);
- if (PermissionChecker.checkPermission(mContext, permission, -1, uid,
- packageName)
- == PermissionChecker.PERMISSION_GRANTED) {
+ if (PermissionChecker.checkPermissionForPreflight(mContext, permission,
+ PermissionChecker.PID_UNKNOWN, uid, packageName)
+ == PermissionChecker.PERMISSION_GRANTED) {
if ((permissionFlags
& PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED)
== 0) {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
index 5da6205..2664ecd 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
@@ -23,7 +23,6 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class TileTest {
@@ -41,7 +40,7 @@
mActivityInfo.name = "abc";
mActivityInfo.icon = com.android.internal.R.drawable.ic_plus;
mActivityInfo.metaData = new Bundle();
- mTile = new Tile(mActivityInfo, "category");
+ mTile = new ActivityTile(mActivityInfo, "category");
}
@Test
@@ -70,7 +69,7 @@
@Test
public void getIcon_noContextOrMetadata_returnNull() {
mActivityInfo.metaData = null;
- final Tile tile = new Tile(mActivityInfo, "category");
+ final Tile tile = new ActivityTile(mActivityInfo, "category");
assertThat(tile.getIcon(null)).isNull();
assertThat(tile.getIcon(RuntimeEnvironment.application)).isNull();
}
@@ -100,7 +99,7 @@
@Test
public void isIconTintable_hasMetadata_shouldReturnIconTintableMetadata() {
- final Tile tile = new Tile(mActivityInfo, "category");
+ final Tile tile = new ActivityTile(mActivityInfo, "category");
mActivityInfo.metaData.putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, false);
assertThat(tile.isIconTintable(RuntimeEnvironment.application)).isFalse();
@@ -111,14 +110,14 @@
@Test
public void isIconTintable_noIcon_shouldReturnFalse() {
- final Tile tile = new Tile(mActivityInfo, "category");
+ final Tile tile = new ActivityTile(mActivityInfo, "category");
assertThat(tile.isIconTintable(RuntimeEnvironment.application)).isFalse();
}
@Test
public void isIconTintable_noTintableMetadata_shouldReturnFalse() {
- final Tile tile = new Tile(mActivityInfo, "category");
+ final Tile tile = new ActivityTile(mActivityInfo, "category");
mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON, android.R.drawable.ic_info);
assertThat(tile.isIconTintable(RuntimeEnvironment.application)).isFalse();
@@ -126,7 +125,7 @@
@Test
public void getPriority_noMetadata_return0() {
- final Tile tile = new Tile(mActivityInfo, "category");
+ final Tile tile = new ActivityTile(mActivityInfo, "category");
assertThat(tile.getOrder()).isEqualTo(0);
}
@@ -135,7 +134,7 @@
public void getPriority_badMetadata_return0() {
mActivityInfo.metaData.putString(META_DATA_KEY_ORDER, "1");
- final Tile tile = new Tile(mActivityInfo, "category");
+ final Tile tile = new ActivityTile(mActivityInfo, "category");
assertThat(tile.getOrder()).isEqualTo(0);
}
@@ -144,7 +143,7 @@
public void getPriority_validMetadata_returnMetadataValue() {
mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, 1);
- final Tile tile = new Tile(mActivityInfo, "category");
+ final Tile tile = new ActivityTile(mActivityInfo, "category");
assertThat(tile.getOrder()).isEqualTo(1);
}
@@ -157,7 +156,7 @@
spm.addResolveInfoForIntent(
new Intent().setClassName(mActivityInfo.packageName, mActivityInfo.name), info);
- final Tile tile = new Tile(mActivityInfo, "category");
+ final Tile tile = new ActivityTile(mActivityInfo, "category");
final long staleTimeStamp = -10000;
tile.mLastUpdateTime = staleTimeStamp;
@@ -173,8 +172,8 @@
final ShadowPackageManager spm = Shadow.extract(mContext.getPackageManager());
spm.removePackage(mActivityInfo.packageName);
- final Tile tile = new Tile(mActivityInfo, "category");
- ReflectionHelpers.setField(tile, "mActivityInfo", null);
+ final Tile tile = new ActivityTile(mActivityInfo, "category");
+ tile.mComponentInfo = null;
assertThat(tile.getTitle(RuntimeEnvironment.application)).isNull();
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java
index ed6b9b0..6cbae05 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java
@@ -37,6 +37,7 @@
import android.os.Bundle;
import com.android.settingslib.R;
+import com.android.settingslib.drawer.ActivityTile;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.Tile;
@@ -84,7 +85,7 @@
@Test
public void setBackgroundColor_externalTileWithBackgroundColorRawValue_shouldUpdateIcon() {
- final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
+ final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000);
doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
.when(tile).getIcon(mContext);
@@ -97,7 +98,7 @@
@Test
public void setBackgroundColor_tileWithoutBackgroundColor_shouldSetDefaultBackgroundColor() {
- final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
+ final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
.when(tile).getIcon(mContext);
final AdaptiveIcon icon = new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK));
@@ -110,7 +111,7 @@
@Test
public void onBindTile_externalTileWithBackgroundColorHint_shouldUpdateIcon() {
- final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
+ final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE));
mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT,
R.color.bt_outline_color);
doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update))
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 8c2e431..67062b7 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -100,8 +100,6 @@
Settings.Secure.DOZE_PICK_UP_GESTURE,
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
- Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
- Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED,
@@ -114,7 +112,6 @@
Settings.Secure.ASSIST_GESTURE_WAKE_ENABLED,
Settings.Secure.VR_DISPLAY_MODE,
Settings.Secure.NOTIFICATION_BADGING,
- Settings.Secure.NOTIFICATION_BUBBLES,
Settings.Secure.NOTIFICATION_DISMISS_RTL,
Settings.Secure.QS_AUTO_ADDED_TILES,
Settings.Secure.SCREENSAVER_ENABLED,
@@ -145,12 +142,9 @@
Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK,
Settings.Secure.UI_NIGHT_MODE,
Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST,
- Settings.Secure.SKIP_GESTURE,
Settings.Secure.SKIP_DIRECTION,
- Settings.Secure.SILENCE_GESTURE,
Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
Settings.Secure.NAVIGATION_MODE,
- Settings.Secure.AWARE_ENABLED,
Settings.Secure.SKIP_GESTURE_COUNT,
Settings.Secure.SKIP_TOUCH_COUNT,
Settings.Secure.SILENCE_ALARMS_GESTURE_COUNT,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index f160edc6..976f336 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -157,7 +157,6 @@
VALIDATORS.put(Secure.ASSIST_GESTURE_WAKE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.VR_DISPLAY_MODE, new DiscreteValueValidator(new String[] {"0", "1"}));
VALIDATORS.put(Secure.NOTIFICATION_BADGING, BOOLEAN_VALIDATOR);
- VALIDATORS.put(Secure.NOTIFICATION_BUBBLES, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.NOTIFICATION_DISMISS_RTL, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.QS_AUTO_ADDED_TILES, TILE_LIST_VALIDATOR);
VALIDATORS.put(Secure.SCREENSAVER_ENABLED, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 720266a..16c96e6 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -4385,8 +4385,7 @@
if (currentVersion == 182) {
// Remove secure bubble settings.
- getSecureSettingsLocked(userId).deleteSettingLocked(
- Secure.NOTIFICATION_BUBBLES);
+ getSecureSettingsLocked(userId).deleteSettingLocked("notification_bubbles");
// Add global bubble settings.
getGlobalSettingsLocked().insertSettingLocked(Global.NOTIFICATION_BUBBLES,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 86625fa..ebb9e86 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -720,6 +720,11 @@
Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED,
Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED,
Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED,
+ Settings.Secure.AWARE_ENABLED,
+ Settings.Secure.SKIP_GESTURE,
+ Settings.Secure.SILENCE_GESTURE,
+ Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
+ Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
Settings.Secure.FACE_UNLOCK_RE_ENROLL);
@Test
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 2a41aa6..d71d009 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -375,15 +375,16 @@
}
}
+ private static String getFileName(BugreportInfo info, String suffix) {
+ return String.format("%s-%s%s", info.baseName, info.name, suffix);
+ }
+
private final class BugreportCallbackImpl extends BugreportCallback {
private final BugreportInfo mInfo;
- BugreportCallbackImpl(String name, @Nullable String title, @Nullable String description,
- @BugreportParams.BugreportMode int type) {
- // pid not used in this workflow, so setting default = 0
- mInfo = new BugreportInfo(mContext, 0 /* pid */, name,
- 100 /* max progress*/, title, description, type);
+ BugreportCallbackImpl(BugreportInfo info) {
+ mInfo = info;
}
@Override
@@ -409,7 +410,8 @@
@Override
public void onFinished() {
// TODO: Make all callback functions lock protected.
- trackInfoWithId();
+ mInfo.renameBugreportFile();
+ mInfo.renameScreenshots(mScreenshotsDir);
sendBugreportFinishedBroadcast();
}
@@ -429,16 +431,15 @@
}
private void sendBugreportFinishedBroadcast() {
- final String bugreportFileName = mInfo.name + ".zip";
- final File bugreportFile = new File(BUGREPORT_DIR, bugreportFileName);
- final String bugreportFilePath = bugreportFile.getAbsolutePath();
- if (bugreportFile.length() == 0) {
+ final String bugreportFilePath = mInfo.bugreportFile.getAbsolutePath();
+ if (mInfo.bugreportFile.length() == 0) {
Log.e(TAG, "Bugreport file empty. File path = " + bugreportFilePath);
return;
}
if (mInfo.type == BugreportParams.BUGREPORT_MODE_REMOTE) {
- sendRemoteBugreportFinishedBroadcast(bugreportFilePath, bugreportFile);
+ sendRemoteBugreportFinishedBroadcast(bugreportFilePath, mInfo.bugreportFile);
} else {
+ trackInfoWithId();
cleanupOldFiles(MIN_KEEP_COUNT, MIN_KEEP_AGE);
final Intent intent = new Intent(INTENT_BUGREPORT_FINISHED);
intent.putExtra(EXTRA_BUGREPORT, bugreportFilePath);
@@ -466,10 +467,10 @@
}
private void addScreenshotToIntent(Intent intent) {
- final String screenshotFileName = mInfo.name + ".png";
- final File screenshotFile = new File(BUGREPORT_DIR, screenshotFileName);
- final String screenshotFilePath = screenshotFile.getAbsolutePath();
- if (screenshotFile.length() > 0) {
+ final File screenshotFile = mInfo.screenshotFiles.isEmpty()
+ ? null : mInfo.screenshotFiles.get(0);
+ if (screenshotFile != null && screenshotFile.length() > 0) {
+ final String screenshotFilePath = screenshotFile.getAbsolutePath();
intent.putExtra(EXTRA_SCREENSHOT, screenshotFilePath);
}
return;
@@ -670,34 +671,44 @@
}
}
- private String getBugreportName() {
+ private String getBugreportBaseName(@BugreportParams.BugreportMode int type) {
String buildId = SystemProperties.get("ro.build.id", "UNKNOWN_BUILD");
String deviceName = SystemProperties.get("ro.product.name", "UNKNOWN_DEVICE");
- String currentTimestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
- return String.format("bugreport-%s-%s-%s", deviceName, buildId, currentTimestamp);
+ String typeSuffix = null;
+ if (type == BugreportParams.BUGREPORT_MODE_WIFI) {
+ typeSuffix = "wifi";
+ } else if (type == BugreportParams.BUGREPORT_MODE_TELEPHONY) {
+ typeSuffix = "telephony";
+ } else {
+ return String.format("bugreport-%s-%s", deviceName, buildId);
+ }
+ return String.format("bugreport-%s-%s-%s", deviceName, buildId, typeSuffix);
}
private void startBugreportAPI(Intent intent) {
mUsingBugreportApi = true;
- String bugreportName = getBugreportName();
+ String shareTitle = intent.getStringExtra(EXTRA_TITLE);
+ String shareDescription = intent.getStringExtra(EXTRA_DESCRIPTION);
+ int bugreportType = intent.getIntExtra(EXTRA_BUGREPORT_TYPE,
+ BugreportParams.BUGREPORT_MODE_INTERACTIVE);
+ String baseName = getBugreportBaseName(bugreportType);
+ String name = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
- ParcelFileDescriptor bugreportFd = createReadWriteFile(BUGREPORT_DIR,
- bugreportName + ".zip");
+ // pid not used in this workflow, so setting default = 0
+ BugreportInfo info = new BugreportInfo(mContext, 0 /* pid */, baseName, name,
+ 100 /* max progress*/, shareTitle, shareDescription, bugreportType,
+ mUsingBugreportApi);
+
+ ParcelFileDescriptor bugreportFd = info.createBugreportFd();
if (bugreportFd == null) {
Log.e(TAG, "Bugreport parcel file descriptor is null.");
return;
}
- int bugreportType = intent.getIntExtra(EXTRA_BUGREPORT_TYPE,
- BugreportParams.BUGREPORT_MODE_INTERACTIVE);
- String shareTitle = intent.getStringExtra(EXTRA_TITLE);
- String shareDescription = intent.getStringExtra(EXTRA_DESCRIPTION);
-
- ParcelFileDescriptor screenshotFd = createReadWriteFile(BUGREPORT_DIR,
- bugreportName + ".png");
+ ParcelFileDescriptor screenshotFd = info.createScreenshotFd();
if (screenshotFd == null) {
Log.e(TAG, "Screenshot parcel file descriptor is null. Deleting bugreport file");
FileUtils.closeQuietly(bugreportFd);
- new File(BUGREPORT_DIR, String.format("%s.zip", bugreportName)).delete();
+ info.bugreportFile.delete();
return;
}
mBugreportManager = (BugreportManager) mContext.getSystemService(
@@ -708,8 +719,7 @@
+ " bugreport file fd: " + bugreportFd
+ " screenshot file fd: " + screenshotFd);
- BugreportCallbackImpl bugreportCallback = new BugreportCallbackImpl(bugreportName,
- shareTitle, shareDescription, bugreportType);
+ BugreportCallbackImpl bugreportCallback = new BugreportCallbackImpl(info);
try {
mBugreportManager.startBugreport(bugreportFd, screenshotFd,
new BugreportParams(bugreportType), executor, bugreportCallback);
@@ -722,14 +732,13 @@
}
}
- private ParcelFileDescriptor createReadWriteFile(String dirName, String fileName) {
+ private static ParcelFileDescriptor createReadWriteFile(File file) {
try {
- File f = new File(dirName, fileName);
- f.createNewFile();
- f.setReadable(true, true);
- f.setWritable(true, true);
+ file.createNewFile();
+ file.setReadable(true, true);
+ file.setWritable(true, true);
- ParcelFileDescriptor fd = ParcelFileDescriptor.open(f,
+ ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_APPEND);
return fd;
} catch (IOException e) {
@@ -1088,15 +1097,19 @@
*/
private void onBugreportFinished(int id) {
BugreportInfo info = getInfo(id);
- final File bugreportFile = new File(BUGREPORT_DIR, info.name + ".zip");
+ final File bugreportFile = info.bugreportFile;
final int max = -1; // this is to log metrics for dumpstate duration.
- File screenshotFile = new File(BUGREPORT_DIR, info.name + ".png");
+ File screenshotFile = info.screenshotFiles.isEmpty()
+ ? null : info.screenshotFiles.get(0);
// If the screenshot file did not get populated implies this type of bugreport does not
// need the screenshot file; setting the file to null so that empty file doesnt get shared
- if (screenshotFile.length() == 0) {
+ if (screenshotFile != null && screenshotFile.length() == 0) {
if (screenshotFile.delete()) {
Log.d(TAG, "screenshot file deleted successfully.");
}
+ info.screenshotFiles.remove(0);
+ // TODO(b/136066578): Will soon stop using the below variable as it is a no-op in
+ // API flow and the screenshotFile value is read from info.screenshotFiles
screenshotFile = null;
}
// TODO: Since we are passing id to the function, it should be able to find the info linked
@@ -1120,10 +1133,18 @@
DumpstateListener dumpstateListener = new DumpstateListener(info);
mBugreportInfos.put(id, info);
}
- info.renameScreenshots(mScreenshotsDir);
- info.bugreportFile = bugreportFile;
- if (screenshotFile != null) {
- info.addScreenshot(screenshotFile);
+ if (!mUsingBugreportApi) {
+ // Rename in API flow happens before sending the broadcast for remote bugreport (to
+ // handle renaming before sending broadcasts)
+ info.renameScreenshots(mScreenshotsDir);
+ // API workflow already has the bugreport file. This was required in legacy flow, when
+ // FINISHED broadcast would send the final bugreport files.
+ // TODO(b/136066578): Change function definition to not include bugreport/screenshot
+ // file in params
+ info.bugreportFile = bugreportFile;
+ if (screenshotFile != null) {
+ info.addScreenshot(screenshotFile);
+ }
}
if (max != -1) {
@@ -1784,7 +1805,7 @@
if (hasFocus) {
return;
}
- sanitizeName();
+ sanitizeName(info);
}
});
@@ -1803,9 +1824,13 @@
MetricsLogger.action(context,
MetricsEvent.ACTION_BUGREPORT_DETAILS_CANCELED);
if (!mTempName.equals(mSavedName)) {
- // Must restore dumpstate's name since it was changed
+ // Must restore bugreport's name since it was changed
// before user clicked OK.
- setBugreportNameProperty(mPid, mSavedName);
+ if (mUsingBugreportApi) {
+ info.name = mSavedName;
+ } else {
+ setBugreportNameProperty(mPid, mSavedName);
+ }
}
}
})
@@ -1854,7 +1879,7 @@
@Override
public void onClick(View view) {
MetricsLogger.action(context, MetricsEvent.ACTION_BUGREPORT_DETAILS_SAVED);
- sanitizeName();
+ sanitizeName(info);
final String name = mInfoName.getText().toString();
final String title = mInfoTitle.getText().toString();
final String description = mInfoDescription.getText().toString();
@@ -1870,7 +1895,7 @@
* Sanitizes the user-provided value for the {@code name} field, automatically replacing
* invalid characters if necessary.
*/
- private void sanitizeName() {
+ private void sanitizeName(BugreportInfo info) {
String name = mInfoName.getText().toString();
if (name.equals(mTempName)) {
if (DEBUG) Log.v(TAG, "name didn't change, no need to sanitize: " + name);
@@ -1892,23 +1917,15 @@
name = safeName.toString();
mInfoName.setText(name);
}
- if (mUsingBugreportApi) {
- File prevFile = new File(BUGREPORT_DIR, mTempName + ".zip");
- File newFile = new File(BUGREPORT_DIR, name + ".zip");
- if (!prevFile.renameTo(newFile)) {
- Log.e(TAG, "File rename from : " + mTempName
- + " to : " + name + " from the UI failed.");
- } else {
- Log.d(TAG, "File rename from : " + mTempName
- + " to : " + name + " from the UI succeeded.");
- }
- }
mTempName = name;
-
- // Must update system property for the cases where dumpstate finishes
- // while the user is still entering other fields (like title or
- // description)
- setBugreportNameProperty(mPid, name);
+ if (mUsingBugreportApi) {
+ info.name = name;
+ } else {
+ // Must update system property for the cases where dumpstate finishes
+ // while the user is still entering other fields (like title or
+ // description)
+ setBugreportNameProperty(mPid, name);
+ }
}
/**
@@ -1944,14 +1961,23 @@
/**
* {@code pid} of the {@code dumpstate} process generating the bugreport.
+ * pid is unused in the API flow
+ * TODO(b/136066578): Remove pid
*/
final int pid;
/**
- * Name of the bugreport, will be used to rename the final files.
- * <p>
- * Initial value is the bugreport filename reported by {@code dumpstate}, but user can
- * change it later to a more meaningful name.
+ * Prefix name of the bugreport, this is uneditable.
+ * The baseName consists of the string "bugreport" + deviceName + buildID
+ * This will end with the string "wifi"/"telephony" for wifi/telephony bugreports.
+ * Bugreport zip file name = "<baseName>-<name>.zip"
+ * Bugreport png file name = "<baseName>-<name>.png"
+ */
+ String baseName;
+
+ /**
+ * Suffix name of the bugreport/screenshot, is set to timestamp initially. User can make
+ * modifications to this using interface.
*/
String name;
@@ -2021,6 +2047,12 @@
boolean finished;
/**
+ * Whether this bugreport is using API workflow.
+ * TODO(b/136066578): Remove when legacy bugreport methods are removed
+ */
+ boolean usingApi;
+
+ /**
* Whether the details entries have been added to the bugreport yet.
*/
boolean addingDetailsToZip;
@@ -2051,15 +2083,17 @@
// onFinished() callback method is the only function where type is used.
// Set type to -1 as it is unused in this workflow.
// This constructor will soon be removed.
- this(context, pid, name, max, null, null, -1);
+ this(context, pid, "" /* dumpstate handles basename */, name, max, null, null, -1,
+ false);
this.id = id;
}
/**
* Constructor for tracked bugreports - typically called upon receiving BUGREPORT_REQUESTED.
*/
- BugreportInfo(Context context, int pid, String name, int max, @Nullable String shareTitle,
- @Nullable String shareDescription, int type) {
+ BugreportInfo(Context context, int pid, String baseName, String name, int max,
+ @Nullable String shareTitle, @Nullable String shareDescription,
+ @BugreportParams.BugreportMode int type, boolean usingApi) {
this.context = context;
this.pid = pid;
this.name = name;
@@ -2067,6 +2101,8 @@
this.shareTitle = shareTitle == null ? "" : shareTitle;
this.shareDescription = shareDescription == null ? "" : shareDescription;
this.type = type;
+ this.baseName = baseName;
+ this.usingApi = usingApi;
}
/**
@@ -2078,6 +2114,17 @@
this.finished = true;
}
+ ParcelFileDescriptor createBugreportFd() {
+ bugreportFile = new File(BUGREPORT_DIR, getFileName(this, ".zip"));
+ return createReadWriteFile(bugreportFile);
+ }
+
+ ParcelFileDescriptor createScreenshotFd() {
+ File screenshotFile = new File(BUGREPORT_DIR, getFileName(this, ".png"));
+ addScreenshot(screenshotFile);
+ return createReadWriteFile(screenshotFile);
+ }
+
/**
* Gets the name for next screenshot file.
*/
@@ -2103,7 +2150,12 @@
final List<File> renamedFiles = new ArrayList<>(screenshotFiles.size());
for (File oldFile : screenshotFiles) {
final String oldName = oldFile.getName();
- final String newName = oldName.replaceFirst(Integer.toString(pid), name);
+ final String newName;
+ if (usingApi) {
+ newName = getFileName(this, ".png");
+ } else {
+ newName = oldName.replaceFirst(Integer.toString(pid), name);
+ }
final File newFile;
if (!newName.equals(oldName)) {
final File renamedFile = new File(screenshotDir, newName);
@@ -2118,6 +2170,18 @@
screenshotFiles = renamedFiles;
}
+ /**
+ * Rename bugreport file to include the name given by user via UI
+ */
+ void renameBugreportFile() {
+ File newBugreportFile = new File(BUGREPORT_DIR, getFileName(this, ".zip"));
+ if (!newBugreportFile.getPath().equals(bugreportFile.getPath())) {
+ if (bugreportFile.renameTo(newBugreportFile)) {
+ bugreportFile = newBugreportFile;
+ }
+ }
+ }
+
String getFormattedLastUpdate() {
if (context == null) {
// Restored from Parcel
@@ -2136,8 +2200,10 @@
final StringBuilder builder = new StringBuilder()
.append("\tid: ").append(id)
.append(", pid: ").append(pid)
+ .append(", baseName: ").append(baseName)
.append(", name: ").append(name)
.append(", finished: ").append(finished)
+ .append(", usingApi: ").append(usingApi)
.append("\n\ttitle: ").append(title)
.append("\n\tdescription: ");
if (description == null) {
@@ -2169,6 +2235,7 @@
context = null;
id = in.readInt();
pid = in.readInt();
+ baseName = in.readString();
name = in.readString();
title = in.readString();
description = in.readString();
@@ -2186,6 +2253,7 @@
}
finished = in.readInt() == 1;
+ usingApi = in.readInt() == 1;
screenshotCounter = in.readInt();
shareDescription = in.readString();
shareTitle = in.readString();
@@ -2195,6 +2263,7 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeInt(pid);
+ dest.writeString(baseName);
dest.writeString(name);
dest.writeString(title);
dest.writeString(description);
@@ -2212,6 +2281,7 @@
}
dest.writeInt(finished ? 1 : 0);
+ dest.writeInt(usingApi ? 1 : 0);
dest.writeInt(screenshotCounter);
dest.writeString(shareDescription);
dest.writeString(shareTitle);
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index a8ce196..a3d420e 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -104,12 +104,6 @@
Shows the drag handle for the divider between two apps when in split screen
mode.
-### [com.android.systemui.SystemBars](/packages/SystemUI/src/com/android/systemui/SystemBars.java)
-
-This is a proxy to the actual SystemUI for the status bar. This loads from
-config_statusBarComponent which defaults to StatusBar. (maybe this should be
-removed and copy how config_systemUiVendorServiceComponent works)
-
### [com.android.systemui.status.phone.StatusBar](/packages/SystemUI/src/com/android/systemui/status/phone/StatusBar.java)
This shows the UI for the status bar and the notification shade it contains.
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index 11bcc88..b9122d2 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Voer jou wagwoord in"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Verkeerde PIN-kode."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Ongeldige kaart."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Volgelaai"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Gelaai"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laai tans draadloos"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laai tans"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laai tans vinnig"</string>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index 4feb9f1..4cabaca 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"ይለፍ ቃልዎን ያስገቡ"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ትክክል ያልሆነ ፒን ኮድ።"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"ልክ ያልሆነ ካርድ።"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"ሙሉ በሙሉ ኃይል ተሞልቷል"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"ባትሪ ሞልቷል"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • በገመድ አልባ ኃይል በመሙላት ላይ"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ኃይል በመሙላት ላይ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • በፍጥነት ኃይልን በመሙላት ላይ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 4e163a2..d017953 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"أدخل كلمة المرور"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"رمز رقم التعريف الشخصي غير صحيح."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"بطاقة غير صالحة."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"تم شحن البطارية بالكامل"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"تم الشحن"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن لاسلكيًا"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن سريعًا"</string>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index e225675..0c7dec3 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"আপোনাৰ পাছৱর্ড দিয়ক"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ভুল পিন ক\'ড।"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"ব্যৱহাৰৰ অযোগ্য ছিম কাৰ্ড"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"পূৰ্ণৰূপে চ্চাৰ্জ হৈছে"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"চ্চার্জ কৰা হ’ল"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • বেতাঁৰৰ জৰিয়তে চাৰ্জ কৰি থকা হৈছে"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চ্চার্জ কৰি থকা হৈছে"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • দ্ৰুত গতিৰে চ্চাৰ্জ কৰি থকা হৈছে"</string>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index c0cf129..8cdf2f0 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Şifrənizi daxil edin"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Yanlış PIN kod."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Yanlış Kart."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Tam dolub"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Enerji yığdı"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Simsiz şəkildə batareya yığır"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Enerji yığır"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sürətlə enerji yığır"</string>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index 88ca77b..eeda7ce 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Unesite lozinku"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kôd je netačan."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Nevažeća kartica."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Napunjena je u potpunosti"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Napunjena je"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bežično punjenje"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Puni se"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Brzo se puni"</string>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index a897fb2..09cda6b 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Увядзіце пароль"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Няправільны PIN-код."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Несапраўдная картка."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Акумулятар поўнасцю зараджаны"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Зараджаны"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе бесправадная зарадка"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе зарадка"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе хуткая зарадка"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index eebdb9e..75942ea 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Въведете паролата си"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Неправилен ПИН код."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Картата е невалидна."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Напълно заредено"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Заредена"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се безжично"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарежда се бързо"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index b544c14..0e8189f 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"পাসওয়ার্ড লিখুন"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ভুল পিন কোড দেওয়া হয়েছে।"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"ভুল কার্ড।"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"সম্পূর্ণ চার্জ আছে"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"চার্জ হয়েছে"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ওয়্যারলেস পদ্ধতিতে চার্জ হচ্ছে"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চার্জ হচ্ছে"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • দ্রুত চার্জ হচ্ছে"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 8547bc8..33fe43f 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Unesite lozinku"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Pogrešan PIN."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Nevažeća kartica."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Potpuno napunjen"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Napunjeno"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bežično punjenje"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Brzo punjenje"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index ccde138..6c85fd3 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Introdueix la contrasenya"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"El codi PIN no és correcte."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"La targeta no és vàlida."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Completament carregada"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Bateria carregada"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant sense fil"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant ràpidament"</string>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index 3adc279..e944312 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Zadejte heslo"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Nesprávný kód PIN."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Neplatná karta."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Plně nabito"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Nabito"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bezdrátové nabíjení"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíjení"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Rychlé nabíjení"</string>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index 0e6a1f3..ac1791b 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Angiv din adgangskode"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Forkert pinkode."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Ugyldigt kort."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Fuldt opladet"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Opladet"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Trådløs opladning"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader hurtigt"</string>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index d44bfbc..0607c8a 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Passwort eingeben"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Falscher PIN-Code."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Ungültige Karte."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Vollständig aufgeladen"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Aufgeladen"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kabelloses Laden"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird geladen"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird schnell geladen"</string>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 46b1d30..6997b16 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Εισαγάγετε κωδικό πρόσβασης"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Λανθασμένος κωδικός PIN."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Μη έγκυρη κάρτα."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Πλήρως φορτισμένη"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Φορτίστηκε"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ασύρματη φόρτιση"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Φόρτιση"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Γρήγορη φόρτιση"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index 5640b6d..19dd191 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Enter your password"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Incorrect PIN code."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Invalid card."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Fully charged"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Charged"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging wirelessly"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
index 5836b72..acfb7e2 100644
--- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Enter your password"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Incorrect PIN code."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Invalid card."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Fully charged"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Charged"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging wirelessly"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index 5640b6d..19dd191 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Enter your password"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Incorrect PIN code."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Invalid card."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Fully charged"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Charged"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging wirelessly"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index 5640b6d..19dd191 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Enter your password"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Incorrect PIN code."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Invalid card."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Fully charged"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Charged"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging wirelessly"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
index fb968b7..b29bd60 100644
--- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Enter your password"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Incorrect PIN code."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Invalid Card."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Fully charged"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Charged"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging wirelessly"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Charging rapidly"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index 727cbad..aa5c4e0 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Ingresa tu contraseña"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorrecto"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Tarjeta no válida"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Carga completa"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Cargada"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando de manera inalámbrica"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rápidamente"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index 870741e..5f9a456 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Introduce tu contraseña"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"El código PIN es incorrecto."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Tarjeta no válida."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Carga completa"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Cargada"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando sin cables"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rápidamente"</string>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index b6cac13..c555ced 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Sisestage parool"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Vale PIN-kood."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Kehtetu kaart."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Täielikult laetud"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Laetud"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Juhtmeta laadimine"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laadimine"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kiirlaadimine"</string>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 8ad942b..612b2de 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Idatzi pasahitza"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kode hori ez da zuzena."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Txartelak ez du balio."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Erabat kargatuta"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Kargatuta"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hari gabe kargatzen"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kargatzen"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Bizkor kargatzen"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index 9c9de22..0bf01d9 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"گذرواژهتان را وارد کنید"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"کد پین اشتباه است."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"کارت نامعتبر"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"شارژ کامل است"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"شارژ کامل شد"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ بیسیم"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ شدن"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ سریع"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index 66f1de5..9b727a4 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Kirjoita salasana"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Väärä PIN-koodi"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Virheellinen kortti"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Täyteen ladattu"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Ladattu"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan langattomasti"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan nopeasti"</string>
@@ -74,7 +74,7 @@
<string name="kg_sim_pin_instructions_multi" msgid="1643757228644271861">"Anna operaattorin <xliff:g id="CARRIER">%1$s</xliff:g> SIM-kortin PIN-koodi."</string>
<string name="kg_sim_lock_esim_instructions" msgid="4416732549172148542">"<xliff:g id="PREVIOUS_MSG">%1$s</xliff:g> Poista eSIM käytöstä, jos haluat käyttää laitetta ilman mobiililiittymää."</string>
<string name="kg_pin_instructions" msgid="4069609316644030034">"Anna PIN-koodi."</string>
- <string name="kg_password_instructions" msgid="136952397352976538">"Anna salasana"</string>
+ <string name="kg_password_instructions" msgid="136952397352976538">"Lisää salasana"</string>
<string name="kg_puk_enter_puk_hint" msgid="2288964170039899277">"SIM-kortti on nyt poistettu käytöstä. Jatka antamalla PUK-koodi. Saat lisätietoja ottamalla yhteyttä operaattoriin."</string>
<string name="kg_puk_enter_puk_hint_multi" msgid="1373131883510840794">"Operaattorin <xliff:g id="CARRIER">%1$s</xliff:g> SIM-kortti on nyt lukittu. Jatka antamalla PUK-koodi. Saat lisätietoja operaattoriltasi."</string>
<string name="kg_puk_enter_pin_hint" msgid="3137789674920391087">"Anna haluamasi PIN-koodi."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index 66c7c86..a86cdbe 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Entrez votre mot de passe"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"NIP erroné."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Cette carte n\'est pas valide."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Complètement chargé"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Chargé"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • En recharge sans fil"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"En recharge : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"En recharge rapide : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index d6aa5d2..70075ec 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Saisissez votre mot de passe"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Le code est incorrect."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Carte non valide."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Complètement chargée"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Chargé"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge sans fil"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge…"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge rapide…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index e6b10a0..9504a3e 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Introduce o contrasinal"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorrecto"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"A tarxeta non é válida."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Batería totalmente cargada"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Cargada"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando sen fíos"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rapidamente"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index 025462e..a2370d0 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"તમારો પાસવર્ડ દાખલ કરો"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ખોટો પિન કોડ."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"અમાન્ય કાર્ડ."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"સંપૂર્ણપણે ચાર્જ થયેલ"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"ચાર્જ થઈ ગયું"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • વાયરલેસથી ચાર્જિંગ"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ઝડપથી ચાર્જિંગ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index 2de75e4..f8e99a6 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"अपना पासवर्ड डालें"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"गलत पिन कोड."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"गलत कार्ड."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"पूरी तरह चार्ज हो गया"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"चार्ज हो गई है"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • वायरलेस तरीके से चार्ज हो रहा है"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज हो रहा है"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • तेज़ चार्ज हो रहा है"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index c4f7bba..1c9396a 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Unesite zaporku"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kôd nije točan."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Nevažeća kartica."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Potpuno napunjena baterija"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Napunjeno"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • bežično punjenje"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • punjenje"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • brzo punjenje"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index 06142bc..ea5ab94 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Adja meg jelszavát"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Helytelen PIN-kód."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Érvénytelen kártya."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Teljesen feltöltve"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Feltöltve"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Vezeték nélküli töltés"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Töltés"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Gyors töltés"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index f501fcc..b34eced 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Մուտքագրեք գաղտնաբառը"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN կոդը սխալ է։"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Սխալ քարտ"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Ամբողջությամբ լիցքավորված է"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Լիցքավորված է"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Անլար լիցքավորում"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Լիցքավորում"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Արագ լիցքավորում"</string>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index 64f396e..3dd6c91 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Masukkan sandi"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Kode PIN salah."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Kartu Tidak Valid"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Terisi penuh"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Terisi"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya secara nirkabel"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya dengan cepat"</string>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index aa33215..c09dcc6 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Sláðu inn aðgangsorðið þitt"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Rangt PIN-númer."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Ógilt kort."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Fullhlaðin"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Fullhlaðin"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Í þráðlausri hleðslu"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Í hleðslu"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hröð hleðsla"</string>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index 761640c..3f5cfbb 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Inserisci la password"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Codice PIN errato."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Scheda non valida."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Completamente carica"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Carico"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • In carica wireless"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • In carica"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica veloce"</string>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index e72c808..95caf91 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"יש להזין סיסמה"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"קוד הגישה שגוי"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"כרטיס לא חוקי."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"טעונה במלואה"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"הסוללה טעונה"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה אלחוטית"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • בטעינה מהירה"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 27adb8c..9872a07 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"パスワードを入力してください"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN コードが無効です。"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"無効なカードです。"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"充電完了"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"充電が完了しました"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ワイヤレス充電中"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電中"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 急速充電中"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index d165230..c3b5047 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"შეიყვანეთ პაროლი"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN-კოდი არასწორია."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"ბარათი არასწორია."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"ბოლომდე დატენილი"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"დატენილია"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • იტენება უსადენოდ"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • იტენება"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • სწრაფად იტენება"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 8522346..e8741f9 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Құпия сөзді енгізіңіз"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN коды қате"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Жарамсыз карта."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Толық зарядталды"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Зарядталды"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Сымсыз зарядталуда"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядталуда"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Жылдам зарядталуда"</string>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index 7b4266a..d48de15 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"បញ្ចូលពាក្យសម្ងាត់របស់អ្នក"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"កូដ PIN មិនត្រឹមត្រូវទេ។"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"បណ្ណមិនត្រឹមត្រូវទេ។"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"បានសាកថ្មពេញ"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"បានសាកថ្ម"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • កំពុងសាកថ្មឥតខ្សែ"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • កំពុងសាកថ្ម"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • កំពុងសាកថ្មយ៉ាងឆាប់រហ័ស"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index eaaa829..7a6a0bf 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸಿ"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ತಪ್ಪಾದ ಪಿನ್ ಕೋಡ್."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"ಅಮಾನ್ಯ ಕಾರ್ಡ್."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"ಪೂರ್ಣವಾಗಿ ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ವೈರ್ಲೆಸ್ ಆಗಿ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ಚಾರ್ಜ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ವೇಗವಾಗಿ ಚಾರ್ಜ್ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index ca84937..9c1ffc8 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"비밀번호 입력"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"잘못된 PIN 코드입니다."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"유효하지 않은 카드"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"충전 완료"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"충전됨"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 무선 충전 중"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 충전 중"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 고속 충전 중"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 805a567..a106000 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Сырсөзүңүздү киргизиңиз"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN-код туура эмес."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"SIM-карта жараксыз."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Толук кубатталды"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Кубатталды"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зымсыз кубатталууда"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Кубатталууда"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Тез кубатталууда"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index 1418d27..e4d66a7 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"ປ້ອນລະຫັດຜ່ານຂອງທ່ານ"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"ບັດບໍ່ຖືກຕ້ອງ."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"ສາກເຕັມແລ້ວ"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"ສາກເຕັມແລ້ວ."</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກໄຟໄຮ້ສາຍ"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກແບບດ່ວນ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index bbd25b2..30e7cad 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Įveskite slaptažodį"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Netinkamas PIN kodas."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Netinkama kortelė."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Visiškai įkrautas"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Įkrauta"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kraunama be laidų"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Įkraunama"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Greitai įkraunama"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index 58ca8ce..8cafcd3 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Ievadiet paroli"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kods nav pareizs."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Nederīga karte."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Pilnībā uzlādēts"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Akumulators uzlādēts"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek bezvadu uzlāde"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek uzlāde"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek ātrā uzlāde"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index 1ffd8a4..e2ab170 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Внесете ја лозинката"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Погрешен PIN-код."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Неважечка картичка."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Целосно полна"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Полна"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Се полни безжично"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Се полни"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Брзо полнење"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index 1f60c73..33765b4 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"നിങ്ങളുടെ പാസ്വേഡ് നല്കുക"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"പിൻ കോഡ് തെറ്റാണ്."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"അസാധുവായ കാർഡ്."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"പൂർണ്ണമായി ചാർജ് ചെയ്തു"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"ചാർജായി"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • വയർലെസ്സ് ആയി ചാർജ് ചെയ്യുന്നു"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ചാർജ് ചെയ്യുന്നു"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • വേഗത്തിൽ ചാർജ് ചെയ്യുന്നു"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index 55dd70c..3451fb8 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Нууц үгээ оруулна уу"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ПИН код буруу байна."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Карт хүчингүй байна."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Бүрэн цэнэглэсэн"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Цэнэглэсэн"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Утасгүй цэнэглэж байна"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Цэнэглэж байна"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Хурдан цэнэглэж байна"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 0ba82e0..e86fa10 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"तुमचा पासवर्ड एंटर करा"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"चुकीचा पिन कोड."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"अवैध कार्ड."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"पूर्णपणे चार्ज"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"चार्ज झाली"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • वायरलेस पद्धतीने चार्ज करत आहे"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज होत आहे"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • वेगाने चार्ज होत आहे"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index 17e1056..80ccd3e 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Masukkan kata laluan anda"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Kod PIN salah."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Kad Tidak Sah."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Dicas penuh"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Sudah dicas"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengecas secara wayarles"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengecas"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengecas dengan cepat"</string>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index 28fe2b2..c1fa6be 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"သင့်စကားဝှက် ထည့်ပါ"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ပင်နံပါတ် မှားနေသည်။"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"ကတ် မမှန်ကန်ပါ။"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"အားအပြည့်သွင်းထားသည်"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"အားသွင်းပြီးပါပြီ"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ကြိုးမဲ့ အားသွင်းနေသည်"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • အားသွင်းနေသည်"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • အမြန်အားသွင်းနေသည်"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index 692dcad..af99aa7 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Skriv inn passordet ditt"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Feil PIN-kode."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Ugyldig kort."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Fulladet"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Oppladet"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader trådløst"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader raskt"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index 8102021..82a4a19 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"आफ्नो पासवर्ड प्रविष्ट गर्नु…"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN कोड गलत छ।"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"अमान्य कार्ड।"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"पूर्ण चार्ज भएको"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"चार्ज भयो"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • तारविनै चार्ज गर्दै"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज गरिँदै"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • द्रुत गतिमा चार्ज गरिँदै"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index c79f2f7..c533956 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Geef je wachtwoord op"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Onjuiste pincode."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Ongeldige kaart."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Volledig opgeladen"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Opgeladen"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Draadloos opladen"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Opladen"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Snel opladen"</string>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index c28561a..258c2a8 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"ନିଜ ପାସ୍ୱର୍ଡ ଲେଖନ୍ତୁ"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ଭୁଲ PIN କୋଡ୍।"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"ଅମାନ୍ୟ କାର୍ଡ।"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"ସମ୍ପୂର୍ଣ୍ଣ ଭାବରେ ଚାର୍ଜ ହୋଇଗଲା"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"ଚାର୍ଜ ହୋଇଗଲା"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"ୱାୟାର୍ଲେସ୍ଭାବରେ <xliff:g id="PERCENTAGE">%s</xliff:g> • ଚାର୍ଜ ହୋଇଛି"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ଚାର୍ଜ ହେଉଛି"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ଦ୍ରୁତ ଭାବେ ଚାର୍ଜ ହେଉଛି"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 01b5d8e..2c3f64e 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"ਆਪਣਾ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"ਗਲਤ ਪਿੰਨ ਕੋਡ।"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"ਅਵੈਧ ਕਾਰਡ।"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"ਪੂਰਾ ਚਾਰਜ"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"ਚਾਰਜ ਹੋ ਗਿਆ"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਬਿਨਾਂ ਤਾਰ ਤੋਂ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਤੇਜ਼ੀ ਨਾਲ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index f86a082..b88440f 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Wpisz hasło"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Nieprawidłowy kod PIN."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Nieprawidłowa karta."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Bateria w pełni naładowana"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Naładowana"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ładowanie bezprzewodowe"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ładowanie"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Szybkie ładowanie"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index 436dd55..ed552d4 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Digite sua senha"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorreto."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Cartão inválido."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Carga completa"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Carregada"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando sem fio"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando rapidamente"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index 2ba4268..5dd0beb 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Introduza a palavra-passe."</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorreto."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Cartão inválido."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Totalmente carregada"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Carregada"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar sem fios"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar…"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar rapidamente…"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index 436dd55..ed552d4 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Digite sua senha"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Código PIN incorreto."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Cartão inválido."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Carga completa"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Carregada"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando sem fio"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregando rapidamente"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index 6fdc958..13e15e3 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Introduceți parola"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Cod PIN incorect."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Card nevalid"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Complet încărcată"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Încărcată"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă wireless"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă rapid"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index f9bd05b..781a3e4 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Введите пароль"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Неверный PIN-код."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Ошибка SIM-карты."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Аккумулятор полностью заряжен"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Батарея заряжена"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Беспроводная зарядка"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"Идет зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"Идет быстрая зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index e40be05..e51aa96 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"ඔබේ මුරපදය ඇතුළු කරන්න"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"වැරදි PIN කේතයකි."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"වලංගු නොවන කාඩ්පත."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"සම්පූර්ණයෙන් ආරෝපණය වී ඇත"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"අරෝපිතයි"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • නොරැහැන්ව ආරෝපණ කෙරේ"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ආරෝපණය වෙමින්"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • වේගයෙන් ආරෝපණය වෙමින්"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index e7800e9..4fe1e4f 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Zadajte heslo"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Nesprávny kód PIN."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Neplatná karta."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Úplne nabité"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Nabité"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíja sa bezdrôtovo"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíja sa"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nabíja sa rýchlo"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index cce3a31..822e162 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Vnesite geslo"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Napačna koda PIN."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Neveljavna kartica"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Popolnoma napolnjen"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Akumulator napolnjen"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • brezžično polnjenje"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • polnjenje"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • hitro polnjenje"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index e4b37d0..4636e6a 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Fut fjalëkalimin"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Kodi PIN është i pasaktë."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Karta e pavlefshme."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"I ngarkuar plotësisht"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"I ngarkuar"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet me valë"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet me shpejtësi"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index 1e6de94..033e93b 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Унесите лозинку"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN кôд је нетачан."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Неважећа картица."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Напуњена је у потпуности"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Напуњена је"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Бежично пуњење"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуни се"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Брзо се пуни"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index 4cca176..8d7be97 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Ange ditt lösenord"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Fel pinkod."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Ogiltigt kort."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Fulladdad"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Laddat"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas trådlöst"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas snabbt"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index df51859..5ab4d07 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Weka nenosiri lako"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Nambari ya PIN si sahihi."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Kadi si Sahihi."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Imejaa chaji"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Betri imejaa"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji bila kutumia waya"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji kwa kasi"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 9aa1972..fa75b4d 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"கடவுச்சொல்லை உள்ளிடுக"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"தவறான பின் குறியீடு."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"செல்லாத சிம் கார்டு."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"முழுவதுமாகச் சார்ஜ் ஆகிவிட்டது"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"சார்ஜ் செய்யப்பட்டது"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • வயர்லெஸ் முறையில் சார்ஜாகிறது"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • சார்ஜாகிறது"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • வேகமாகச் சார்ஜாகிறது"</string>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 925d673..ad89ba7 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"మీ పాస్వర్డ్ను నమోదు చేయండి"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"పిన్ కోడ్ తప్పు."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"చెల్లని కార్డ్."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"పూర్తిగా ఛార్జ్ చేయబడింది"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"ఛార్జ్ చేయబడింది"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • వైర్ లేకుండా ఛార్జ్ అవుతోంది"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ఛార్జ్ అవుతోంది"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • వేగంగా ఛార్జ్ అవుతోంది"</string>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index c439c32..caa60f3 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"ป้อนรหัสผ่าน"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"รหัส PIN ไม่ถูกต้อง"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"การ์ดไม่ถูกต้อง"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"ชาร์จเต็มแล้ว"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"ชาร์จแล้ว"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • กำลังชาร์จแบบไร้สาย"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • กำลังชาร์จ"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • กำลังชาร์จอย่างเร็ว"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index a9ca1b6..65b87e3 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Ilagay ang iyong password"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Mali ang PIN code."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Di-wasto ang Card."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Puno na ang baterya"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Tapos nang mag-charge"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wireless na nagcha-charge"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Nagcha-charge"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mabilis na nagcha-charge"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index 4e81505..c35e99e 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Şifrenizi girin"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Yanlış PIN kodu."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Geçersiz Kart."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Tamamen şarj edildi"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Şarj oldu"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kablosuz olarak şarj ediliyor"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj oluyor"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hızlı şarj oluyor"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index c683e32..c2b9419 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Введіть пароль"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Неправильний PIN-код."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Недійсна картка."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Повністю заряджений"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Заряджено"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Бездротове заряджання"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Заряджання"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Швидке заряджання"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index 96b949b..8a74093 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"اپنا پاس ورڈ درج کریں"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"غلط PIN کوڈ۔"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"غلط کارڈ۔"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"مکمل طور پر چارج ہو گيا"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"چارج ہوگئی"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • وائرلیس طریقے سے چارج ہو رہا ہے"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • چارج ہو رہا ہے"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • تیزی سے چارج ہو رہا ہے"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index 80509ac..5bf38ec 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -33,9 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Parolni kiriting"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN kodi xato."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"SIM karta yaroqsiz."</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for keyguard_charged (3316115607283493413) -->
- <skip />
+ <string name="keyguard_charged" msgid="2222329688813033109">"Batareya quvvati to‘ldi"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Simsiz quvvatlanyapti"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Quvvat olmoqda"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Tezkor quvvat olmoqda"</string>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index b8c1998..c50891e 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Nhập mật khẩu của bạn"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Mã PIN không chính xác."</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Thẻ không hợp lệ."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Đã sạc đầy"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Đã sạc đầy"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc không dây"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc nhanh"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index 88fc363..e4438f9 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"输入您的密码"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN 码有误。"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"SIM 卡无效。"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"充电完成"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"已充满电"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在无线充电"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在充电"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在快速充电"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index 2d84106..4134527 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"請輸入密碼"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN 碼不正確。"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"SIM 卡無效。"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"充電完成"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"已完成充電"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 無線充電中"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在充電"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 正在快速充電"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index 18b9479..fd95559 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"輸入密碼"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"PIN 碼不正確。"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"卡片無效。"</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"充電完成"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"充電完成"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 無線充電"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電中"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 快速充電中"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index 6a7f647..f60599d 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -33,7 +33,7 @@
<string name="keyguard_enter_your_password" msgid="5397328359341314506">"Faka iphasiwedi yakho"</string>
<string name="keyguard_password_wrong_pin_code" msgid="6535018036285012028">"Ikhodi ye-PIN engalungile!"</string>
<string name="keyguard_sim_error_message_short" msgid="592109500618448312">"Ikhadi elingavumelekile."</string>
- <string name="keyguard_charged" msgid="3316115607283493413">"Ishaje ngokuphelele"</string>
+ <string name="keyguard_charged" msgid="2222329688813033109">"Kushajiwe"</string>
<string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Iyashaja ngaphandle kwentambo"</string>
<string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Iyashaja"</string>
<string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ishaja kaningi"</string>
diff --git a/packages/SystemUI/res/drawable/auth_dialog_lock.xml b/packages/SystemUI/res/drawable/auth_dialog_lock.xml
new file mode 100644
index 0000000..8146c16
--- /dev/null
+++ b/packages/SystemUI/res/drawable/auth_dialog_lock.xml
@@ -0,0 +1,27 @@
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="32dp"
+ android:height="32dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="?android:attr/colorAccent"
+ android:pathData="M12,15m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
+ <path
+ android:fillColor="?android:attr/colorAccent"
+ android:pathData="M18,8h-1.5V5.5C16.5,3.01 14.49,1 12,1S7.5,3.01 7.5,5.5V8H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9.5,5.5C9.5,4.12 10.62,3 12,3c1.38,0 2.5,1.12 2.5,2.5V8h-5V5.5zM18,20H6V10h1.5h9H18V20z"/>
+</vector>
diff --git a/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml b/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml
new file mode 100644
index 0000000..c3fa39e
--- /dev/null
+++ b/packages/SystemUI/res/layout-land/auth_credential_pattern_view.xml
@@ -0,0 +1,113 @@
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<com.android.systemui.biometrics.AuthCredentialPatternView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:elevation="@dimen/biometric_dialog_elevation">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+ <ImageView
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:background="@drawable/auth_dialog_lock"/>
+
+ <TextView
+ android:id="@+id/title"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="12dp"
+ android:textSize="20sp"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+ <TextView
+ android:id="@+id/subtitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="8dp"
+ android:textSize="16sp"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+ <TextView
+ android:id="@+id/description"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="8dp"
+ android:gravity="center"
+ android:textSize="16sp"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+ <TextView
+ android:id="@+id/error"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:textSize="16sp"
+ android:gravity="center"
+ android:textColor="?android:attr/colorError"/>
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <com.android.internal.widget.LockPatternView
+ android:id="@+id/lockPattern"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="40dp"
+ android:layout_marginRight="40dp"
+ android:layout_gravity="center"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ style="@style/LockPatternStyleBiometricPrompt"/>
+
+ </LinearLayout>
+
+</com.android.systemui.biometrics.AuthCredentialPatternView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/auth_container_view.xml b/packages/SystemUI/res/layout/auth_container_view.xml
index 23199aa..3db01a4 100644
--- a/packages/SystemUI/res/layout/auth_container_view.xml
+++ b/packages/SystemUI/res/layout/auth_container_view.xml
@@ -34,7 +34,7 @@
android:elevation="@dimen/biometric_dialog_elevation"/>
<ScrollView
- android:id="@+id/scrollview"
+ android:id="@+id/biometric_scrollview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
diff --git a/packages/SystemUI/res/layout/auth_credential_password_view.xml b/packages/SystemUI/res/layout/auth_credential_password_view.xml
new file mode 100644
index 0000000..4aed033
--- /dev/null
+++ b/packages/SystemUI/res/layout/auth_credential_password_view.xml
@@ -0,0 +1,101 @@
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<com.android.systemui.biometrics.AuthCredentialPasswordView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center_horizontal"
+ android:elevation="@dimen/biometric_dialog_elevation">
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+ <ImageView
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:background="@drawable/auth_dialog_lock"/>
+
+ <TextView
+ android:id="@+id/title"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="12dp"
+ android:textSize="20sp"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+ <TextView
+ android:id="@+id/subtitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="8dp"
+ android:textSize="16sp"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+ <TextView
+ android:id="@+id/description"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="8dp"
+ android:gravity="center"
+ android:textSize="16sp"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+ <TextView
+ android:id="@+id/error"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:textSize="16sp"
+ android:gravity="center"
+ android:textColor="?android:attr/colorError"/>
+
+ <EditText
+ android:id="@+id/lockPassword"
+ android:layout_marginBottom="20dp"
+ android:layout_marginLeft="100dp"
+ android:layout_marginRight="100dp"
+ android:layout_width="208dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:inputType="textPassword"
+ android:maxLength="500"
+ android:textSize="16sp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:imeOptions="flagForceAscii"
+ style="@style/LockPatternStyleBiometricPrompt"/>
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="5"/>
+
+</com.android.systemui.biometrics.AuthCredentialPasswordView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/auth_credential_pattern_view.xml b/packages/SystemUI/res/layout/auth_credential_pattern_view.xml
new file mode 100644
index 0000000..c9edcd6
--- /dev/null
+++ b/packages/SystemUI/res/layout/auth_credential_pattern_view.xml
@@ -0,0 +1,97 @@
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<com.android.systemui.biometrics.AuthCredentialPatternView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center_horizontal"
+ android:elevation="@dimen/biometric_dialog_elevation">
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+ <ImageView
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:background="@drawable/auth_dialog_lock"/>
+
+ <TextView
+ android:id="@+id/title"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="12dp"
+ android:textSize="20sp"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+ <TextView
+ android:id="@+id/subtitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="8dp"
+ android:textSize="16sp"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+ <TextView
+ android:id="@+id/description"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginTop="8dp"
+ android:gravity="center"
+ android:textSize="16sp"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="3"/>
+
+ <TextView
+ android:id="@+id/error"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="24dp"
+ android:textSize="16sp"
+ android:gravity="center"
+ android:textColor="?android:attr/colorError"/>
+
+ <com.android.internal.widget.LockPatternView
+ android:id="@+id/lockPattern"
+ android:layout_marginBottom="20dp"
+ android:layout_marginLeft="40dp"
+ android:layout_marginRight="40dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ style="@style/LockPatternStyleBiometricPrompt"/>
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
+</com.android.systemui.biometrics.AuthCredentialPatternView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index e7c6b25..0e59a41 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -17,14 +17,9 @@
*/
-->
-<com.android.systemui.statusbar.phone.NotificationPanelView
+<merge
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:id="@+id/notification_panel"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@android:color/transparent" >
-
+ xmlns:systemui="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:id="@+id/big_clock_container"
android:layout_width="match_parent"
@@ -112,5 +107,4 @@
android:background="@drawable/qs_navbar_scrim" />
<include layout="@layout/status_bar_expanded_plugin_frame"/>
-
-</com.android.systemui.statusbar.phone.NotificationPanelView>
+</merge>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 9716a00..57834da 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -64,7 +64,7 @@
sysui:ignoreRightInset="true"
/>
- <include layout="@layout/status_bar_expanded"
+ <ViewStub android:id="@+id/status_bar_expanded"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 4d451bc..b0b4615 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Stel invoer metodes op"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fisiese sleutelbord"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Gee <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Gee <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Maak <xliff:g id="APPLICATION">%1$s</xliff:g> oop om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te hanteer?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Maak <xliff:g id="APPLICATION">%1$s</xliff:g> oop om <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> te hanteer?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bevestig"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tik op Bevestig om te voltooi"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Gestaaf"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Raak die vingerafdruksensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Vingerafdrukikoon"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Soek tans vir jou …"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Kennisgewings"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Flitslig"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiele data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Datagebruik"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Oorblywende data"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 4d0a62e..e423c6a 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"የግቤት ስልቶችን አዘጋጅ"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"የሚዳሰስ የቁልፍ ሰሌዳ"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_DEVICE">%2$s</xliff:g>ን እንዲደርስበት ይፈቀድለት?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ን እንዲደርስበት ይፈቀድለት?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ን እንዲይዘው <xliff:g id="APPLICATION">%1$s</xliff:g> ይክፈት?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ን እንዲይዘው <xliff:g id="APPLICATION">%1$s</xliff:g> ይክፈት?"</string>
@@ -108,7 +110,7 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"ስልክ"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"የድምጽ እርዳታ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ክፈት"</string>
- <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"አሻራን በመጠባበቅ ላይ"</string>
+ <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"የጣት አሻራን በመጠባበቅ ላይ"</string>
<string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"የጣት አሻራዎን ሳይጠቀሙ ይክፈቱ"</string>
<string name="accessibility_scanning_face" msgid="769545173211758586">"የቅኝት ፊት"</string>
<string name="accessibility_send_smart_reply" msgid="7766727839703044493">"ላክ"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ተረጋግጧል"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ለማጠናቀቅ አረጋግጥን መታ ያድርጉ"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"የተረጋገጠ"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"የጣት አሻራ ዳሳሹን ይንኩ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"የጣት አሻራ አዶ"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"እርስዎን በመፈለግ ላይ…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"ማሳወቂያዎች"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"የባትሪ ብርሃን"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"የተንቀሳቃሽ ስልክ ውሂብ"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"የውሂብ አጠቃቀም"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ቀሪ ውሂብ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 787fc8d..3b145105 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"إعداد أسلوب الإدخال"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"لوحة مفاتيح فعلية"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"هل تريد السماح لتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى <xliff:g id="USB_DEVICE">%2$s</xliff:g>؟"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"هل تريد السماح لتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>؟"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"هل تريد فتح <xliff:g id="APPLICATION">%1$s</xliff:g> للتعامل مع <xliff:g id="USB_DEVICE">%2$s</xliff:g>؟"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"هل تريد فتح تطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> للتعامل مع <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>؟"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"تمّ التأكيد."</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"يمكنك النقر على \"تأكيد\" لإكمال المهمة."</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"مصادقة"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"المس زر استشعار بصمة الإصبع"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"رمز بصمة الإصبع"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"جارٍ البحث عن وجهك…"</string>
@@ -372,6 +388,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"الإشعارات"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"الفلاش"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"بيانات الجوّال"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"استخدام البيانات"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"البيانات المتبقية"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index d7feb0c..c3ca88a 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ইনপুট পদ্ধতি ছেট আপ কৰক"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"বাস্তৱিক কীব\'ৰ্ড"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ত প্ৰৱেশ কৰিবলৈ <xliff:g id="APPLICATION">%1$s</xliff:g>ক অনুমতি দিবনে?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g>ক <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ত প্ৰৱেশ কৰিবলৈ অনুমতি দিবনে?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ক ব্যৱহাৰ কৰিবলৈ <xliff:g id="APPLICATION">%1$s</xliff:g>ক খোলেনে?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ক ব্যৱহাৰ কৰিবলৈ <xliff:g id="APPLICATION">%1$s</xliff:g>ক খোলেনে?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"নিশ্চিত কৰিলে"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"সম্পূৰ্ণ কৰিবলৈ নিশ্চিত কৰক-ত টিপক"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো স্পৰ্শ কৰক"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ফিংগাৰপ্ৰিণ্ট আইকন"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"আপোনাৰ মুখমণ্ডল বিচাৰি আছে…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"জাননীসমূহ"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ফ্লাশ্বলাইট"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ম’বাইল ডেটা"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ডেটা ব্যৱহাৰ"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"বাকী থকা ডেটা"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index f6cd5dc..67e24c5 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Daxiletmə metodlarını ayarlayın"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fiziki klaviatura"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına giriş icazəsi verilsin?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqinə <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> cihazına giriş icazəsi verilsin?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazını idarə etmək üçün <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqi açılsın?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> cihazını idarə etmək üçün <xliff:g id="APPLICATION">%1$s</xliff:g> tətbiqi açılsın?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Təsdiqləndi"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tamamlamaq üçün \"Təsdiq edin\" seçiminə toxunun"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Doğrulandı"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Barmaq izi sensoruna klikləyin"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Barmaq izi ikonası"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Siz axtarılırsınız…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Bildirişlər"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"İşartı"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobil data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Data istifadəsi"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Qalan data"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 2196c15..3def744 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Podesi metode unosa"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fizička tastatura"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Želite li da dozvolite da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Želite li da dozvolite da <xliff:g id="APPLICATION">%1$s</xliff:g> pristupa uređaju <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> da biste koristili uređaj <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Želite li da otvorite aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> da biste koristili uređaj <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potvrđeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Dodirnite Potvrdi da biste završili"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Identitet je potvrđen"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dodirnite senzor za otisak prsta"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otiska prsta"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Tražimo vas…"</string>
@@ -366,6 +382,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obaveštenja"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampa"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilni podaci"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Potrošnja podataka"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Preostala količina podataka"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 06ee3e1..cdb4ddb 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Налада метадаў уводу"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Фізічная клавіятура"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Дазволіць праграме <xliff:g id="APPLICATION">%1$s</xliff:g> доступ да прылады <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Дазволіць праграме <xliff:g id="APPLICATION">%1$s</xliff:g> доступ да прылады <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Адкрыць праграму <xliff:g id="APPLICATION">%1$s</xliff:g> для працы з прыладай <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Адкрыць праграму <xliff:g id="APPLICATION">%1$s</xliff:g> для працы з прыладай <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Пацверджана"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Націсніце \"Пацвердзіць\", каб завяршыць"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Распазнана"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Дакраніцеся да сканера адбіткаў пальцаў"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок адбіткаў пальцаў"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ідзе пошук вашага твару…"</string>
@@ -370,6 +386,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Апавяшчэнні"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Ліхтарык"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мабільная перадача даных"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Выкарыстанне трафіка"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Засталося трафіку"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 6f37a75..cd22290 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Методи на въвеждане: Настройка"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Физическа клавиатура"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Да се разреши ли на <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Да се разреши ли на <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Да се използва ли <xliff:g id="APPLICATION">%1$s</xliff:g> за работата с/ъс <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Да се използва ли <xliff:g id="APPLICATION">%1$s</xliff:g> за работата с/ъс <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Потвърдено"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Докоснете „Потвърждаване“ за завършване"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Удостоверено"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Докоснете сензора за отпечатъци"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона за отпечатък"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Търсим ви…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Известия"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Фенерче"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобилни данни"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Пренос на данни"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Оставащи данни"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 9c33f2b..11a6e90 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ইনপুট পদ্ধতিগুলি সেট-আপ করুন"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ফিজিক্যাল কীবোর্ড"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> কে <xliff:g id="USB_DEVICE">%2$s</xliff:g> অ্যাক্সেস করতে দেবেন?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> কে <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> অ্যাক্সেস করতে দেবেন?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ব্যবহার করার জন্য <xliff:g id="APPLICATION">%1$s</xliff:g> চালু করবেন?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ব্যবহার করার জন্য <xliff:g id="APPLICATION">%1$s</xliff:g> চালু করবেন?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"কনফার্ম করা হয়েছে"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"সম্পূর্ণ করতে \'কনফার্ম করুন\' বোতামে ট্যাপ করুন"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"প্রমাণীকৃত"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"আঙ্গুলের ছাপের সেন্সর স্পর্শ করুন"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"আঙ্গুলের ছাপের আইকন"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"আপনার জন্য খোঁজা হচ্ছে…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"বিজ্ঞপ্তি"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ফ্ল্যাশলাইট"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"মোবাইল ডেটা"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ডেটার ব্যবহার"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"অবশিষ্ট ডেটা"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 2d77626..7eaa9c4 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Postavljanje načina unosa"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fizička tastatura"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Dozvoliti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Dozvoliti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup dodatku: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Otvoriti aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> za upravljanje uređajem: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Otvoriti aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> za upravljanje dodatkom: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potvrđeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Dodirnite Potvrdi da završite"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autentificirano"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dodirnite senzor za otisak prsta"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona za otisak prsta"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Tražimo vas…"</string>
@@ -366,6 +382,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obavještenja"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Svjetiljka"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Prijenos podataka na mobilnoj mreži"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Prijenos podataka"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Preostala količina podataka"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index ee16c58..3bd72b3 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configura els mètodes d\'entrada"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Teclat físic"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Vols permetre que <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Vols permetre que <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Vols obrir <xliff:g id="APPLICATION">%1$s</xliff:g> per gestionar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Vols obrir <xliff:g id="APPLICATION">%1$s</xliff:g> per gestionar <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmat"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toca Confirma per completar"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autenticat"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor d\'empremtes digitals"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona d\'empremta digital"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"S\'està cercant la teva cara…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificacions"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Llanterna"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Dades mòbils"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Ús de dades"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Dades restants"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index bed63db..b3a8596 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavit metody zadávání"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fyzická klávesnice"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Otevřít aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> ke správě zařízení <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Otevřít aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> ke správě zařízení <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potvrzeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Ověření dokončíte klepnutím na Potvrdit"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Ověřeno"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotkněte se snímače otisků prstů"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otisku prstu"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Hledáme vás…"</string>
@@ -368,6 +384,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Oznámení"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Svítilna"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilní data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Využití dat"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Zbývající data"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 45ef5b1..f0e5898 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inputmetoder"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fysisk tastatur"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Vil du give <xliff:g id="APPLICATION">%1$s</xliff:g> adgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Vil du give <xliff:g id="APPLICATION">%1$s</xliff:g> adgang til <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Vil du åbne <xliff:g id="APPLICATION">%1$s</xliff:g> til håndtering af <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Vil du åbne <xliff:g id="APPLICATION">%1$s</xliff:g> til håndtering af <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bekræftet"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tryk på Bekræft for at udføre"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Godkendt"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sæt fingeren på fingeraftrykslæseren"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon for fingeraftryk"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Forsøger at finde dig…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifikationer"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lommelygte"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobildata"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Dataforbrug"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Resterende data"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 1deceb1..f32c577 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Eingabemethoden festlegen"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physische Tastatur"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> den Zugriff auf <xliff:g id="USB_DEVICE">%2$s</xliff:g> gewähren?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> den Zugriff auf <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> gewähren?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Für <xliff:g id="USB_DEVICE">%2$s</xliff:g> <xliff:g id="APPLICATION">%1$s</xliff:g> öffnen?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Für <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> <xliff:g id="APPLICATION">%1$s</xliff:g> öffnen?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bestätigt"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Zum Abschließen auf \"Bestätigen\" tippen"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Authentifiziert"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Berühre den Fingerabdrucksensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerabdruck-Symbol"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Wir suchen nach dir…"</string>
@@ -368,6 +384,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Benachrichtigungen"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Taschenlampe"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobile Daten"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Datennutzung"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Verbleibende Daten"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 2b57ab5..ce693ee 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Ρύθμιση μεθόδων εισαγωγής"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Φυσικό πληκτρολόγιο"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Να επιτρέπεται η πρόσβαση της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> στη συσκευή <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Να επιτρέπεται η πρόσβαση της εφαρμογής <xliff:g id="APPLICATION">%1$s</xliff:g> στο αξεσουάρ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>;"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Να ανοίγει η εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> για τη διαχείριση της συσκευής <xliff:g id="USB_DEVICE">%2$s</xliff:g>;"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Να ανοίγει η εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> για τη διαχείριση του αξεσουάρ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>;"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Επιβεβαιώθηκε"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Πατήστε Επιβεβαίωση για ολοκλήρωση"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Ολοκληρώθηκε ο έλεγχος ταυτότητας"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Αγγίξτε τον αισθητήρα δακτυλικών αποτυπωμάτων"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Αναζήτηση για εσάς…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Ειδοποιήσεις"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Φακός"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Δεδομένα κινητής τηλεφωνίας"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Χρήση δεδομένων"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Υπολειπόμενα δεδομένα"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 7a6271f..013b4cb 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -47,6 +47,7 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Set up input methods"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physical keyboard"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_device_permission_prompt_warn" msgid="1842558472039505091">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +127,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tap Confirm to complete"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Authenticated"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
@@ -364,6 +379,7 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Torch"</string>
+ <string name="quick_settings_flashlight_camera_in_use" msgid="6120370795890963385">"Camera in use"</string>
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobile data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Data usage"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Remaining data"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index fe19e7c..a21ecb49 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -47,6 +47,7 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Set up input methods"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physical keyboard"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_device_permission_prompt_warn" msgid="1842558472039505091">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +127,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tap Confirm to complete"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Authenticated"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
@@ -364,6 +379,7 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Flashlight"</string>
+ <string name="quick_settings_flashlight_camera_in_use" msgid="6120370795890963385">"Camera in use"</string>
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobile data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Data usage"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Remaining data"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 7a6271f..013b4cb 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -47,6 +47,7 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Set up input methods"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physical keyboard"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_device_permission_prompt_warn" msgid="1842558472039505091">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +127,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tap Confirm to complete"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Authenticated"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
@@ -364,6 +379,7 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Torch"</string>
+ <string name="quick_settings_flashlight_camera_in_use" msgid="6120370795890963385">"Camera in use"</string>
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobile data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Data usage"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Remaining data"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 7a6271f..013b4cb 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -47,6 +47,7 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Set up input methods"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physical keyboard"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_device_permission_prompt_warn" msgid="1842558472039505091">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +127,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tap Confirm to complete"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Authenticated"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
@@ -364,6 +379,7 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Torch"</string>
+ <string name="quick_settings_flashlight_camera_in_use" msgid="6120370795890963385">"Camera in use"</string>
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobile data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Data usage"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Remaining data"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 32469f2..d8cfb30 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -47,6 +47,7 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Set up input methods"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physical keyboard"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <string name="usb_device_permission_prompt_warn" msgid="1842558472039505091">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device."</string>
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Allow <xliff:g id="APPLICATION">%1$s</xliff:g> to access <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Open <xliff:g id="APPLICATION">%1$s</xliff:g> to handle <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +127,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmed"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tap Confirm to complete"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Authenticated"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
@@ -364,6 +379,7 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Flashlight"</string>
+ <string name="quick_settings_flashlight_camera_in_use" msgid="6120370795890963385">"Camera in use"</string>
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobile data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Data usage"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Remaining data"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index f29aa1e..4b2943c 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de intro."</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Teclado físico"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"¿Deseas permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"¿Deseas permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"¿Deseas abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para usar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"¿Deseas abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para usar <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmado"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Presiona Confirmar para completarla"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autenticado"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor de huellas digitales"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícono de huella digital"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Autenticando tu rostro…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificaciones"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Linterna"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Datos móviles"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Uso de datos"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Datos restantes"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 3088098..903c50a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de entrada"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Teclado físico"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"¿Quieres permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"¿Quieres permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"¿Quieres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para utilizar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"¿Quieres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para utilizar <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toca Confirmar para completar la acción"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Se ha autenticado"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor de huellas digitales"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icono de huella digital"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Buscando tu cara…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificaciones"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Linterna"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Datos móviles"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Uso de datos"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Datos restantes"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 51226ab..113b207 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Seadista sisestusmeetodeid"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Füüsiline klaviatuur"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Kas lubada rakendusele <xliff:g id="APPLICATION">%1$s</xliff:g> juurdepääs seadmele <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Kas lubada rakendusele <xliff:g id="APPLICATION">%1$s</xliff:g> juurdepääs seadmele <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Kas avada rakendus <xliff:g id="APPLICATION">%1$s</xliff:g> seadme <xliff:g id="USB_DEVICE">%2$s</xliff:g> kasutamiseks?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Kas avada rakendus <xliff:g id="APPLICATION">%1$s</xliff:g> seadme <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> kasutamiseks?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Kinnitatud"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Lõpuleviimiseks puudutage nuppu Kinnita"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autenditud"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Puudutage sõrmejäljeandurit"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Sõrmejälje ikoon"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Otsitakse teid …"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Märguanded"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Taskulamp"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiilne andmeside"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Andmeside kasutus"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Järelejäänud andmemaht"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 0d2863e..e541329 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfiguratu idazketa-metodoak"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Teklatu fisikoa"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> atzitzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> atzitzeko baimena eman nahi diozu <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioari?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="APPLICATION">%1$s</xliff:g> ireki nahi duzu <xliff:g id="USB_DEVICE">%2$s</xliff:g> kudeatzeko?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="APPLICATION">%1$s</xliff:g> ireki nahi duzu <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> kudeatzeko?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Berretsita"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Amaitzeko, sakatu \"Berretsi\""</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autentifikatuta"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sakatu hatz-marken sentsorea"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Hatz-markaren ikonoa"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Zure bila…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Jakinarazpenak"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Linterna"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Datu-konexioa"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Datuen erabilera"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Geratzen diren datuak"</string>
@@ -897,7 +915,7 @@
<string name="mobile_data_disable_message" msgid="4756541658791493506">"<xliff:g id="CARRIER">%s</xliff:g> erabilita ezingo dituzu erabili datuak edo Internet. Wifi-sare baten bidez soilik konektatu ahal izango zara Internetera."</string>
<string name="mobile_data_disable_message_default_carrier" msgid="6078110473451946831">"Uneko operadorea"</string>
<string name="touch_filtered_warning" msgid="8671693809204767551">"Aplikazio bat baimen-eskaera oztopatzen ari denez, ezarpenek ezin dute egiaztatu erantzuna."</string>
- <string name="slice_permission_title" msgid="7465009437851044444">"<xliff:g id="APP_0">%1$s</xliff:g> aplikazioari <xliff:g id="APP_2">%2$s</xliff:g> aplikazioaren zatiak erakusteko baimena eman nahi diozu?"</string>
+ <string name="slice_permission_title" msgid="7465009437851044444">"<xliff:g id="APP_2">%2$s</xliff:g> aplikazioaren zatiak erakusteko baimena eman nahi diozu <xliff:g id="APP_0">%1$s</xliff:g> aplikazioari?"</string>
<string name="slice_permission_text_1" msgid="3514586565609596523">"- <xliff:g id="APP">%1$s</xliff:g> aplikazioaren informazioa irakur dezake."</string>
<string name="slice_permission_text_2" msgid="3146758297471143723">"- <xliff:g id="APP">%1$s</xliff:g> aplikazioan ekintzak gauza ditzake."</string>
<string name="slice_permission_checkbox" msgid="7986504458640562900">"Baimendu <xliff:g id="APP">%1$s</xliff:g> aplikazioari edozein aplikazioren zatiak erakustea"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index e649d80..232f7a2 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"تنظیم روشهای ورودی"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"صفحهکلید فیزیکی"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"به <xliff:g id="APPLICATION">%1$s</xliff:g> برای دسترسی به <xliff:g id="USB_DEVICE">%2$s</xliff:g> اجازه داده شود؟"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"به <xliff:g id="APPLICATION">%1$s</xliff:g> برای دسترسی به <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> اجازه داده شود؟"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"برای استفاده از <xliff:g id="USB_DEVICE">%2$s</xliff:g>، <xliff:g id="APPLICATION">%1$s</xliff:g> باز شود؟"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"برای استفاده از <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>، <xliff:g id="APPLICATION">%1$s</xliff:g> باز شود؟"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"تأیید شد"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"برای تکمیل، روی تأیید ضربه بزنید"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"راستیآزماییشده"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"حسگر اثر انگشت را لمس کنید"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"نماد اثر انگشت"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"درحال جستجوی شما…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"اعلانها"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"چراغ قوه"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"داده تلفن همراه"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"مصرف داده"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"دادههای باقیمانده"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index e195754..5767c3c 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Määritä syöttötavat"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fyysinen näppäimistö"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Saako <xliff:g id="APPLICATION">%1$s</xliff:g> käyttöoikeuden (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Saako <xliff:g id="APPLICATION">%1$s</xliff:g> käyttöoikeuden (<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>)?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Avataanko <xliff:g id="APPLICATION">%1$s</xliff:g>, jotta <xliff:g id="USB_DEVICE">%2$s</xliff:g> voidaan ottaa käyttöön?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Avataanko <xliff:g id="APPLICATION">%1$s</xliff:g>, jotta <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> voidaan ottaa käyttöön?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Vahvistettu"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Valitse lopuksi Vahvista"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Todennettu"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Kosketa sormenjälkitunnistinta"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Sormenjälkikuvake"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Etsitään kasvoja…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Ilmoitukset"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Taskulamppu"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiilidata"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Datakäyttö"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Käytettävissä"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 4f28efa..04138c0 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurer les modes de saisie"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Clavier physique"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -56,7 +58,7 @@
<string name="always_use_device" msgid="4015357883336738417">"Toujours ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> lorsque <xliff:g id="USB_DEVICE">%2$s</xliff:g> est connecté"</string>
<string name="always_use_accessory" msgid="3257892669444535154">"Toujours ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> lorsque <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> est connecté"</string>
<string name="usb_debugging_title" msgid="4513918393387141949">"Autoriser le débogage USB?"</string>
- <string name="usb_debugging_message" msgid="2220143855912376496">"Empreinte numérique de la clé RSA de l\'ordinateur : \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+ <string name="usb_debugging_message" msgid="2220143855912376496">"Empreinte digitale numérique de la clé RSA de l\'ordinateur : \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"Toujours autoriser sur cet ordinateur"</string>
<string name="usb_debugging_allow" msgid="2272145052073254852">"Autoriser"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Débogage USB non autorisé"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmé"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Touchez Confirmer pour terminer"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Authentifié"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touchez le capteur d\'empreintes digitales"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icône d\'empreinte digitale"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Recherche de votre visage…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampe de poche"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Données cellulaires"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Utilisation de données"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Données restantes"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index a51ebb1..7191426 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurer les modes de saisie"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Clavier physique"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_DEVICE">%2$s</xliff:g> ?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmé"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Appuyez sur \"Confirmer\" pour terminer"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Authentifié"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Appuyez sur le lecteur d\'empreinte digitale"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icône d\'empreinte digitale"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Recherche de votre visage…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifications"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampe de poche"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Données mobiles"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Conso des données"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Données restantes"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 7a7ebf2..4262d88 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de entrada"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Teclado físico"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Queres permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Queres permitir que <xliff:g id="APPLICATION">%1$s</xliff:g> acceda a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Queres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para utilizar <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Queres abrir <xliff:g id="APPLICATION">%1$s</xliff:g> para utilizar <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toca Confirmar para completar o proceso"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autenticado"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca o sensor de impresión dixital"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona de impresión dixital"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Buscándote…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificacións"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lanterna"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Datos móbiles"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Uso de datos"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Datos restantes"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 10aba24..66f9a7a 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ઇનપુટ પદ્ધતિઓ સેટ કરો"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ભૌતિક કીબોર્ડ"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ના ઍક્સેસ માટે <xliff:g id="APPLICATION">%1$s</xliff:g>ને મંજૂરી આપીએ?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ના ઍક્સેસ માટે <xliff:g id="APPLICATION">%1$s</xliff:g>ને મંજૂરી આપીએ?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ને હૅન્ડલ કરવા માટે <xliff:g id="APPLICATION">%1$s</xliff:g>ને ખોલીએ?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ને હૅન્ડલ કરવા માટે <xliff:g id="APPLICATION">%1$s</xliff:g>ને ખોલીએ?"</string>
@@ -56,7 +58,7 @@
<string name="always_use_device" msgid="4015357883336738417">"જ્યારે <xliff:g id="USB_DEVICE">%2$s</xliff:g> કનેક્ટેડ હોય ત્યારે <xliff:g id="APPLICATION">%1$s</xliff:g>ને હંમેશા ખોલો"</string>
<string name="always_use_accessory" msgid="3257892669444535154">"જ્યારે <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> કનેક્ટેડ હોય ત્યારે <xliff:g id="APPLICATION">%1$s</xliff:g>ને હંમેશા ખોલો"</string>
<string name="usb_debugging_title" msgid="4513918393387141949">"USB ડિબગિંગને મંજૂરી આપીએ?"</string>
- <string name="usb_debugging_message" msgid="2220143855912376496">"કમ્પ્યુટરની RSA મુખ્ય ફિંગરપ્રિંટ આ છે:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+ <string name="usb_debugging_message" msgid="2220143855912376496">"કમ્પ્યુટરની RSA મુખ્ય ફિંગરપ્રિન્ટ આ છે:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"હંમેશા આ કમ્પ્યુટરથી મંજૂરી આપો"</string>
<string name="usb_debugging_allow" msgid="2272145052073254852">"મંજૂરી આપો"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ડીબગિંગની મંજૂરી નથી"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"પુષ્ટિ કરી"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"પરીક્ષણ પૂર્ણ કરવા કન્ફર્મ કરોને ટૅપ કરો"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"પ્રમાણિત"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ફિંગરપ્રિન્ટના સેન્સરને સ્પર્શ કરો"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ફિંગરપ્રિન્ટનું આઇકન"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"તમારા માટે શોધી રહ્યાં છે..."</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"નોટિફિકેશનો"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ફ્લેશલાઇટ"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"મોબાઇલ ડેટા"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ડેટા વપરાશ"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"બાકી ડેટા"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 9ce8e7d..c49cae4 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"इनपुट का तरीका सेट करें"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"सामान्य कीबोर्ड"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> को <xliff:g id="USB_DEVICE">%2$s</xliff:g> के ऐक्सेस की अनुमति दें?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> को <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> के ऐक्सेस की अनुमति दें?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> के लिए <xliff:g id="APPLICATION">%1$s</xliff:g> खोलें?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> के लिए <xliff:g id="APPLICATION">%1$s</xliff:g> खोलें?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"पुष्टि हो गई"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"\'पुष्टि करें\' पर टैप करके पूरा करें"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"पुष्टि हो गई"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"फ़िंगरप्रिंट सेंसर को छुएं"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फ़िंगरप्रिंट आइकॉन"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"आपको पहचान रहा है…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"सूचनाएं"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"फ़्लैशलाइट"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"मोबाइल डेटा"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"डेटा खर्च"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"शेष डेटा"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 9c9b0b0..6086764 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Postavljanje načina unosa"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fizička tipkovnica"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Želite li dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Želite li dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup uređaju <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Želite li otvoriti aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> radi upravljanja uređajem <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Želite li otvoriti aplikaciju <xliff:g id="APPLICATION">%1$s</xliff:g> radi upravljanja uređajem <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potvrđeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Dodirnite Potvrdi za dovršetak"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autentičnost provjerena"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dodirnite senzor otiska prsta"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otiska prsta"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Tražimo vas…"</string>
@@ -366,6 +382,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obavijesti"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Svjetiljka"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilni podaci"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Potrošnja podataka"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Preostali podaci"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 99a049e..be039c7 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Beviteli módok beállítása"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fizikai billentyűzet"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Engedélyezi a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> számára, hogy hozzáférjen a következőhöz: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Engedélyezi a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> számára, hogy hozzáférjen a következőhöz: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Megnyitja a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazást a(z) <xliff:g id="USB_DEVICE">%2$s</xliff:g> kezeléséhez?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Megnyitja a(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazást a(z) <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> kezeléséhez?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Megerősítve"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Koppintson a Megerősítés lehetőségre"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Hitelesítve"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Érintse meg az ujjlenyomat-érzékelőt"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ujjlenyomat ikonja"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Keresem az Ön arcát…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Értesítések"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Zseblámpa"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiladatok"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Adathasználat"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Fennmaradó adatmennyiség"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 9ac0afb..0f84b50 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Կարգավորել մուտքագրման եղանակները"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Ֆիզիկական ստեղնաշար"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Թույլատրե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին օգտագործել <xliff:g id="USB_DEVICE">%2$s</xliff:g> լրասարքը։"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Թույլատրե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածին օգտագործել <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> լրասարքը։"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Բացե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածը <xliff:g id="USB_DEVICE">%2$s</xliff:g> լրասարքը մշակելու համար։"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Բացե՞լ <xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածը <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> լրասարքը մշակելու համար։"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Հաստատվեց"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Ավարտելու համար հպեք «Հաստատել»"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Նույնականացված է"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Հպեք մատնահետքի սկաներին"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Մատնահետքի պատկերակ"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Դեմքի ճանաչում…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Ծանուցումներ"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Լապտեր"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Բջջային ինտերնետ"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Տվյալների օգտագործումը"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Մնացած տվյալները"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 443e3b3..0b3ef70 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Menyiapkan metode masukan"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Keyboard fisik"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Izinkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Izinkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk menangani <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk menangani <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Dikonfirmasi"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Ketuk Konfirmasi untuk menyelesaikan"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Diautentikasi"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sentuh sensor sidik jari"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon sidik jari"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Mencari wajah Anda…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifikasi"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampu senter"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Data seluler"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Penggunaan kuota"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Data tersisa"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index f481e48..7a8d290 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Setja upp innsláttaraðferðir"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Vélbúnaðarlyklaborð"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Viltu veita <xliff:g id="APPLICATION">%1$s</xliff:g> aðgang að <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Viltu veita <xliff:g id="APPLICATION">%1$s</xliff:g> aðgang að <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Viltu opna <xliff:g id="APPLICATION">%1$s</xliff:g> til að sjá um <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Viltu opna <xliff:g id="APPLICATION">%1$s</xliff:g> til að sjá um <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Staðfest"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Ýttu á „Staðfesta“ til að ljúka"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Auðkennt"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Snertu fingrafaralesarann"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingrafaratákn"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Leitar að þér ..."</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Tilkynningar"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Vasaljós"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Farsímagögn"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Gagnanotkun"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Gögn eftir"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 718608a..cc053be 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configura metodi di immissione"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Tastiera fisica"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Consentire a <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Consentire a <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere a <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Vuoi aprire <xliff:g id="APPLICATION">%1$s</xliff:g> per gestire <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Vuoi aprire <xliff:g id="APPLICATION">%1$s</xliff:g> per gestire <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -56,7 +58,7 @@
<string name="always_use_device" msgid="4015357883336738417">"Apri sempre <xliff:g id="APPLICATION">%1$s</xliff:g> quando si collega <xliff:g id="USB_DEVICE">%2$s</xliff:g>"</string>
<string name="always_use_accessory" msgid="3257892669444535154">"Apri sempre <xliff:g id="APPLICATION">%1$s</xliff:g> quando si collega <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>"</string>
<string name="usb_debugging_title" msgid="4513918393387141949">"Consentire debug USB?"</string>
- <string name="usb_debugging_message" msgid="2220143855912376496">"Fingerprint della chiave RSA del computer: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+ <string name="usb_debugging_message" msgid="2220143855912376496">"Impronta della chiave RSA del computer: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"Consenti sempre da questo computer"</string>
<string name="usb_debugging_allow" msgid="2272145052073254852">"Consenti"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Debug USB non consentito"</string>
@@ -108,8 +110,8 @@
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefono"</string>
<string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Sblocca"</string>
- <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"In attesa dell\'impronta digitale"</string>
- <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Sblocca senza utilizzare l\'impronta digitale"</string>
+ <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"In attesa dell\'impronta"</string>
+ <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Sblocca senza utilizzare l\'impronta"</string>
<string name="accessibility_scanning_face" msgid="769545173211758586">"Scansione del viso"</string>
<string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Invia"</string>
<string name="accessibility_manage_notification" msgid="2026361503393549753">"Gestisci notifiche"</string>
@@ -126,8 +128,22 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confermato"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tocca Conferma per completare"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autenticazione eseguita"</string>
- <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Tocca il sensore di impronte digitali"</string>
- <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona dell\'impronta digitale"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
+ <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Tocca il sensore di impronte"</string>
+ <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona dell\'impronta"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"In attesa del volto…"</string>
<string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Icona volto"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Pulsante zoom compatibilità."</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifiche"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Torcia"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Dati mobili"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Utilizzo dati"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Dati rimanenti"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 606a097..09e4f0e 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"הגדר שיטות קלט"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"מקלדת פיזית"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"האם לתת לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"האם לתת לאפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> גישה אל <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"האם לפתוח את <xliff:g id="APPLICATION">%1$s</xliff:g> כדי לעבוד עם <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"האם לפתוח את <xliff:g id="APPLICATION">%1$s</xliff:g> כדי לעבוד עם <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"מאושר"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"יש להקיש על \'אישור\' לסיום"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"מאומת"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"יש לגעת בחיישן טביעות האצבע"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"סמל טביעת אצבע"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"מחפש אותך…"</string>
@@ -368,6 +384,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"התראות"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"פנס"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"חבילת גלישה"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"שימוש בנתונים"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"מכסת נתונים נותרת"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 0bc500c..3dc9fb7 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"入力方法をセットアップ"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"物理キーボード"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> に <xliff:g id="USB_DEVICE">%2$s</xliff:g> へのアクセスを許可しますか?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> に <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> へのアクセスを許可しますか?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="APPLICATION">%1$s</xliff:g> を起動して <xliff:g id="USB_DEVICE">%2$s</xliff:g> を処理しますか?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="APPLICATION">%1$s</xliff:g> を起動して <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> を処理しますか?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"確認しました"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"完了するには [確認] をタップしてください"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"認証済み"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"指紋認証センサーをタップしてください"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋アイコン"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"顔を認証しています…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"通知"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ライト"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"モバイルデータ"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"データ使用量"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"残りのデータ"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index b3c7de7..24db256 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"შეყვანის მეთოდების დაყენება"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ფიზიკური კლავიატურა"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"მიეცეს <xliff:g id="APPLICATION">%1$s</xliff:g>-ს <xliff:g id="USB_DEVICE">%2$s</xliff:g>-ზე წვდომის უფლება?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"მიეცეს <xliff:g id="APPLICATION">%1$s</xliff:g>-ს <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>-ზე წვდომის უფლება?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"გსურთ, გახსნათ <xliff:g id="APPLICATION">%1$s</xliff:g>, <xliff:g id="USB_DEVICE">%2$s</xliff:g>-ის გამოსაყენებლად?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"გსურთ, გახსნათ <xliff:g id="APPLICATION">%1$s</xliff:g>, <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>-ის გამოსაყენებლად?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"დადასტურებული"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"დასასრულებლად შეეხეთ „დადასტურებას“"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"ავტორიზებულია"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"შეეხეთ თითის ანაბეჭდის სენსორს"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"თითის ანაბეჭდის ხატულა"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"მიმდინარეობს თქვენი ძიება…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"შეტყობინებები"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ფანარი"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"მობილური ინტერნეტი"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"მონაცემთა მოხმარება"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"დარჩენილი მონაცემები"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index e1fa4b2b..ff1b9fc 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Енгізу әдістерін орнату"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Физикалық пернетақта"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына <xliff:g id="USB_DEVICE">%2$s</xliff:g> құрылғысына кіруге рұқсат берілсін бе?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> қолданбасына <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> жабдығына кіруге рұқсат берілсін бе?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> жабдығын басқару үшін <xliff:g id="APPLICATION">%1$s</xliff:g> ашылсын ба?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> жабдығын басқару үшін <xliff:g id="APPLICATION">%1$s</xliff:g> ашылсын ба?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Расталды"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Аяқтау үшін \"Растау\" түймесін түртіңіз."</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Аутентификацияланған"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Саусақ ізін оқу сканерін түртіңіз"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Саусақ ізі белгішесі"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Бет ізделуде…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Хабарландырулар"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Қалта шам"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобильдік деректер"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Дерек шығыны"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Қалған деректер"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index db93aa9..323138c 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"រៀបចំវិធីសាស្ត្របញ្ចូល"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ក្ដារចុចពិតប្រាកដ"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"អនុញ្ញាត <xliff:g id="APPLICATION">%1$s</xliff:g> ឱ្យចូលប្រើ <xliff:g id="USB_DEVICE">%2$s</xliff:g> មែនទេ?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"អនុញ្ញាត <xliff:g id="APPLICATION">%1$s</xliff:g> ឱ្យចូលប្រើ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> មែនទេ?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"បើក <xliff:g id="APPLICATION">%1$s</xliff:g> ដើម្បីគ្រប់គ្រង <xliff:g id="USB_DEVICE">%2$s</xliff:g> មែនទេ?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"បើក <xliff:g id="APPLICATION">%1$s</xliff:g> ដើម្បីគ្រប់គ្រង <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> មែនទេ?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"បានបញ្ជាក់"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ចុច \"បញ្ជាក់\" ដើម្បីបញ្ចប់"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"បានផ្ទៀងផ្ទាត់"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ប៉ះឧបករណ៍ចាប់ស្នាមម្រាមដៃ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"រូបតំណាងស្នាមម្រាមដៃ"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"កំពុងស្វែងរកអ្នក…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"ការជូនដំណឹង"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ពិល"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ទិន្នន័យទូរសព្ទចល័ត"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ការប្រើទិន្នន័យ"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ទិន្នន័យនៅសល់"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 98589ad..ac593e8 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ಇನ್ಪುಟ್ ವಿಧಾನಗಳನ್ನು ಹೊಂದಿಸು"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ಪ್ರವೇಶಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ಗೆ ಪ್ರವೇಶಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯುವುದೇ?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು <xliff:g id="APPLICATION">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯುವುದೇ?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ಪೂರ್ಣಗೊಳಿಸಲು ದೃಢೀಕರಿಸಿ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಐಕಾನ್"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ನಿಮಗಾಗಿ ಹುಡುಕಲಾಗುತ್ತಿದೆ…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"ಅಧಿಸೂಚನೆಗಳು"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ಫ್ಲಾಶ್ಲೈಟ್"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ಮೊಬೈಲ್ ಡೇಟಾ"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ಡೇಟಾ ಬಳಕೆ"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ಉಳಿದಿರುವ ಡೇಟಾ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 03c277e..f37ec00 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"입력 방법 설정"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"물리적 키보드"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱이 <xliff:g id="USB_DEVICE">%2$s</xliff:g>에 액세스하도록 허용하시겠습니까?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱이 <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>에 액세스하도록 허용하시겠습니까?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱을 열어 <xliff:g id="USB_DEVICE">%2$s</xliff:g>을(를) 처리하시겠습니까?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱을 열어 <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>을(를) 처리하시겠습니까?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"확인함"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"완료하려면 확인을 탭하세요."</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"인증됨"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"지문 센서를 터치하세요."</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"지문 아이콘"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"찾는 중..."</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"알림"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"손전등"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"모바일 데이터"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"데이터 사용"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"잔여 데이터"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index c82e5b0..beb2b02 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Киргизүү ыкмасын тууралоо"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Аппараттык тергич"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүн колдоно берсинби?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> кабелин колдоно берсинби?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> түзмөгүнө туташуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу ачылсынбы?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> кабелине туташуу үчүн <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу ачылсынбы?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Ырасталды"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Бүтүрүү үчүн \"Ырастоо\" баскычын басыңыз"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Аныктыгы текшерилди"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Манжа изинин сенсорун басыңыз"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Манжа изинин сүрөтчөсү"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Жүзүңүз изделүүдө…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Билдирмелер"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Кол чырак"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобилдик Интернет"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Дайындардын өткөрүлүшү"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Калган дайындар"</string>
@@ -902,7 +920,7 @@
<string name="slice_permission_text_2" msgid="3146758297471143723">"- <xliff:g id="APP">%1$s</xliff:g> колдонмосунда аракеттерди аткарат"</string>
<string name="slice_permission_checkbox" msgid="7986504458640562900">"<xliff:g id="APP">%1$s</xliff:g> бардык колдонмолордун үлгүлөрүн көрсөтүүгө уруксат берүү"</string>
<string name="slice_permission_allow" msgid="2340244901366722709">"Уруксат берүү"</string>
- <string name="slice_permission_deny" msgid="7683681514008048807">"Жок"</string>
+ <string name="slice_permission_deny" msgid="7683681514008048807">"Тыюу салынат"</string>
<string name="auto_saver_title" msgid="1217959994732964228">"Батареяны үнөмдөгүчтүн тартибин жөндөө үчүн басыңыз"</string>
<string name="auto_saver_text" msgid="2563289953551438248">"Батареянын кубаты түгөнүп калганда, күйгүзүлсүн"</string>
<string name="no_auto_saver_action" msgid="8086002101711328500">"Жок, рахмат"</string>
@@ -926,7 +944,7 @@
<string name="bubbles_settings_button_description" msgid="2970630476657287189">"<xliff:g id="APP_NAME">%1$s</xliff:g> көбүктөрүнүн жөндөөлөрү"</string>
<string name="bubbles_prompt" msgid="8807968030159469710">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунун калкып чыкма билдирмелерине уруксат бересизби?"</string>
<string name="manage_bubbles_text" msgid="7027739766859191408">"Башкаруу"</string>
- <string name="no_bubbles" msgid="337101288173078247">"Жок"</string>
+ <string name="no_bubbles" msgid="337101288173078247">"Тыюу салынат"</string>
<string name="yes_bubbles" msgid="668809525728633841">"Уруксат берүү"</string>
<string name="ask_me_later_bubbles" msgid="2147688438402939029">"Кийинчерээк суралсын"</string>
<string name="bubble_content_description_single" msgid="1184462974339387516">"<xliff:g id="APP_NAME">%2$s</xliff:g> колдонмосунан <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 4f4d291..68c9951 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ຕັ້ງຄ່າວິທີການປ້ອນຂໍ້ມູນ"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ແປ້ນພິມແທ້"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"ອະນຸຍາດໃຫ້ <xliff:g id="APPLICATION">%1$s</xliff:g> ເຂົ້າເຖິງ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ໄດ້ບໍ?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"ອະນຸຍາດໃຫ້ <xliff:g id="APPLICATION">%1$s</xliff:g> ເຂົ້າເຖິງ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ໄດ້ບໍ?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"ເປີດ <xliff:g id="APPLICATION">%1$s</xliff:g> ເພື່ອໃຊ້ກັບ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ບໍ?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"ເປີດ <xliff:g id="APPLICATION">%1$s</xliff:g> ເພື່ອໃຊ້ກັບ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ບໍ?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ຢືນຢັນແລ້ວ"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ແຕະຢືນຢັນເພື່ອສຳເລັດ"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"ຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ແຕະໃສ່ເຊັນເຊີລາຍນິ້ວມື"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ໄອຄອນລາຍນິ້ວມື"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ກຳລັງຊອກຫາທ່ານ…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"ການແຈ້ງເຕືອນ"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ໄຟສາຍ"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ອິນເຕີເນັດມືຖື"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ການນຳໃຊ້ຂໍ້ມູນ"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ຂໍ້ມູນທີ່ຍັງເຫຼືອ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index ca7c89e..230194d 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nustatyti įvesties metodus"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fizinė klaviatūra"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Leisti „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti įrenginį (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Leisti „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti įrenginį (<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>)?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Atidaryti „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kad būtų galima tvarkyti įrenginį (<xliff:g id="USB_DEVICE">%2$s</xliff:g>)?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Atidaryti „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kad būtų galima tvarkyti įrenginį (<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>)?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Patvirtinta"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Paliesk. „Patvirtinti“, kad užbaigtumėte"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autentifikuota"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Palieskite piršto antspaudo jutiklį"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Piršto antspaudo piktograma"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ieškoma jūsų…"</string>
@@ -368,6 +384,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Pranešimai"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Žibintuvėlis"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiliojo ryšio duomenys"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Duomenų naudojimas"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Likę duomenys"</string>
@@ -466,7 +484,7 @@
<string name="media_projection_remember_text" msgid="3103510882172746752">"Daugiau neberodyti"</string>
<string name="clear_all_notifications_text" msgid="814192889771462828">"Viską išvalyti"</string>
<string name="manage_notifications_text" msgid="2386728145475108753">"Tvarkyti"</string>
- <string name="notification_section_header_gentle" msgid="4372438504154095677">"Tylūs pranešimai"</string>
+ <string name="notification_section_header_gentle" msgid="4372438504154095677">"Tylieji pranešimai"</string>
<string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Išvalyti visus tylius pranešimus"</string>
<string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Pranešimai pristabdyti naudojant netrukdymo režimą"</string>
<string name="media_projection_action_text" msgid="8470872969457985954">"Pradėti dabar"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 424e104..e1905f5 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Iestatīt ievades metodes"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fiziskā tastatūra"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Vai atļaut lietotnei <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šai ierīcei: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Vai atļaut lietotnei <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šim piederumam: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Vai atvērt lietotni <xliff:g id="APPLICATION">%1$s</xliff:g>, lai izmantotu šo ierīci: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Vai atvērt lietotni <xliff:g id="APPLICATION">%1$s</xliff:g>, lai izmantotu šo piederumu: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Apstiprināts"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Lai pabeigtu, pieskarieties Apstiprināt"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autentifikācija veikta"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Pieskarieties pirksta nospieduma sensoram"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Pirksta nospieduma ikona"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Notiek jūsu sejas meklēšana…"</string>
@@ -366,6 +382,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Paziņojumi"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Zibspuldze"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilie dati"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Datu lietojums"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Atlikušie dati"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index dd86ede..300dff5 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Постави методи на внес."</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Физичка тастатура"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Ќе дозволите <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапува до <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Ќе дозволите <xliff:g id="APPLICATION">%1$s</xliff:g> да пристапува до <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Да се отвори <xliff:g id="APPLICATION">%1$s</xliff:g> за да управува со <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Да се отвори <xliff:g id="APPLICATION">%1$s</xliff:g> за да управува со <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Потврдено"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Допрете „Потврди“ за да се заврши"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Проверена"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Допрете го сензорот за отпечатоци"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона за отпечатоци"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ве бараме вас…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Известувања"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Светилка"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобилен интернет"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Потрошен интернет"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Преостанати податоци"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 859e65b..0a06b2c 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ടൈപ്പുചെയ്യൽ രീതികൾ സജ്ജീകരിക്കുക"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ഫിസിക്കൽ കീബോഡ്"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ആക്സസ് ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g>-നെ അനുവദിക്കണോ?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ആക്സസ് ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g>-നെ അനുവദിക്കണോ?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> കൈകാര്യം ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g> തുറക്കണോ?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> കൈകാര്യം ചെയ്യാൻ <xliff:g id="APPLICATION">%1$s</xliff:g> തുറക്കണോ?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"സ്ഥിരീകരിച്ചു"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"പൂർത്തിയാക്കാൻ സ്ഥിരീകരിക്കുക ടാപ്പ് ചെയ്യൂ"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"പരിശോധിച്ചുറപ്പിച്ചു"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"വിരലടയാള സെൻസർ സ്പർശിക്കുക"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"വിരലടയാള ഐക്കൺ"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"നിങ്ങൾക്കായി തിരയുന്നു…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"അറിയിപ്പുകൾ"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ടോർച്ച്"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"മൊബൈൽ ഡാറ്റ"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ഡാറ്റാ ഉപയോഗം"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ശേഷിക്കുന്ന ഡാറ്റ"</string>
@@ -377,7 +395,7 @@
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"സൂര്യോദയം വരെ"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>-ന്"</string>
<string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> വരെ"</string>
- <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ഇരുണ്ട തീം"</string>
+ <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ഡാർക്ക് തീം"</string>
<string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ഇരുണ്ട തീം\nബാറ്ററി ലാഭിക്കൽ"</string>
<string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
<string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC പ്രവർത്തനരഹിതമാക്കി"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 3363af7..0298d20 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Оруулах аргыг тохируулах"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Бодит гар"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g>-г <xliff:g id="USB_DEVICE">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g>-г <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>-г зохицуулахын тулд <xliff:g id="APPLICATION">%1$s</xliff:g>-г нээх үү?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>-г зохицуулахын тулд <xliff:g id="APPLICATION">%1$s</xliff:g>-г нээх үү?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Баталгаажсан"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Дуусгахын тулд баталгаажуулахыг товших"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Баталгаажуулагдсан"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Хурууны хээ мэдрэгчид хүрэх"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Хурууны хээний дүрс тэмдэг"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Таныг хайж байна…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Мэдэгдэл"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Гар чийдэн"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобайл дата"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Дата ашиглалт"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Үлдсэн дата"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index f785fe9..07b985f 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"इनपुट पद्धती सेट करा"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"वास्तविक कीबोर्ड"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_DEVICE">%2$s</xliff:g> अॅक्सेस करण्याची अनुमती द्यायची का?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> अॅक्सेस करण्याची अनुमती द्यायची का?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> हाताळण्यासाठी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडायचे का?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> हाताळण्यासाठी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडायचे का?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"निश्चित केले"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"पूर्ण करण्यासाठी खात्री करा वर टॅप करा"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"ऑथेंटिकेशन केलेले"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"फिंगरप्रिंट सेन्सरला स्पर्श करा"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फिंगरप्रिंट आयकन"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"तुमच्यासाठी शोधत आहे…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"सूचना"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"फ्लॅशलाइट"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"मोबाइल डेटा"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"डेटा वापर"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"शिल्लक डेटा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 352c376..f696ee3 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Sediakan kaedah input"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Papan kekunci fizikal"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Benarkan <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk mengendalikan <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Buka <xliff:g id="APPLICATION">%1$s</xliff:g> untuk mengendalikan <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Disahkan"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Ketik Sahkan untuk menyelesaikan"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Disahkan"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sentuh penderia cap jari"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon cap jari"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Mencari anda…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Pemberitahuan"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lampu suluh"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Data mudah alih"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Penggunaan data"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Baki data"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index d136042..eb73df7 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ထည့်သွင်းနည်းများ သတ်မှတ်ခြင်း"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ခလုတ်ပါဝင်သော ကီးဘုတ်"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> အား ဝင်သုံးရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ခွင့်ပြုပါသလား။"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> အား ဝင်သုံးရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ခွင့်ပြုပါသလား။"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ဆောင်ရွက်ရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ဖွင့်လိုပါသလား။"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ဆောင်ရွက်ရန် <xliff:g id="APPLICATION">%1$s</xliff:g> ကို ဖွင့်လိုပါသလား။"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"အတည်ပြုပြီးပြီ"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"အပြီးသတ်ရန်အတွက် \'အတည်ပြုရန်\' ကို တို့ပါ"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"အထောက်အထားစိစစ်ပြီးပြီ"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"လက်ဗွေအာရုံခံကိရိယာကို တို့ပါ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"လက်ဗွေ သင်္ကေတ"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"သင့်ကို ရှာဖွေနေသည်…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"အကြောင်းကြားချက်များ"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ဖလက်ရှ်မီး"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"မိုဘိုင်းဒေတာ"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ဒေတာ သုံးစွဲမှု"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ကျန်ရှိ ဒေတာ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 86f0b38..9e1c5db 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inndatametoder"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fysisk tastatur"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Vil du gi <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Vil du gi <xliff:g id="APPLICATION">%1$s</xliff:g> tilgang til <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Vil du åpne <xliff:g id="APPLICATION">%1$s</xliff:g> for å behandle <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Vil du åpne <xliff:g id="APPLICATION">%1$s</xliff:g> for å behandle <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bekreftet"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Trykk på Bekreft for å fullføre"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autentisert"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Trykk på fingeravtrykkssensoren"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon for fingeravtrykk"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ser etter deg …"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Varsler"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lommelykt"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobildata"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Databruk"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Gjenværende data"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 4c17904..5a00002 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"इनपुट विधिहरू सेटअप गर्नुहोस्"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"वास्तविक किबोर्ड"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_DEVICE">%2$s</xliff:g> माथि पहुँच राख्ने अनुमति दिने हो?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> लाई <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> माथि पहुँच राख्ने अनुमति दिने हो?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> को व्यवस्थापन गर्न <xliff:g id="APPLICATION">%1$s</xliff:g> खोल्ने हो?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> को व्यवस्थापन गर्न <xliff:g id="APPLICATION">%1$s</xliff:g> खोल्ने हो?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"पुष्टि भयो"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"पूरा गर्नका लागि पुष्टि गर्नुहोस् नामक विकल्पमा ट्याप गर्नुहोस्"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"प्रमाणीकरण गरियो"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"फिंगरप्रिन्ट सेन्सरमा छुनुहोस्"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फिंगरप्रिन्ट जनाउने आइकन"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"तपाईंलाई खोज्दै…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"अधिसूचनाहरू"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"फ्ल्यासलाइट"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"मोबाइल डेटा"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"डेटाको प्रयोग"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"बाँकी डेटा"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index c62c579..dacbd53 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Invoermethoden instellen"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fysiek toetsenbord"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> toegang geven tot <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="APPLICATION">%1$s</xliff:g> openen om <xliff:g id="USB_DEVICE">%2$s</xliff:g> te verwerken?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="APPLICATION">%1$s</xliff:g> openen om <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> te verwerken?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bevestigd"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tik op Bevestigen om te voltooien"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Geverifieerd"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Raak de vingerafdruksensor aan"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Vingerafdrukpictogram"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Jouw gezicht zoeken…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Meldingen"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Zaklamp"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobiele data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Datagebruik"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Resterende gegevens"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index d295925..2720abf 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ଇନପୁଟ୍ ପଦ୍ଧତି ସେଟ୍ କରନ୍ତୁ"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ଫିଜିକଲ୍ କୀ’ବୋର୍ଡ୍"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ଆକ୍ସେସ୍ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ଆକ୍ସେସ୍ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ନିୟନ୍ତ୍ରଣ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g> ଖୋଲିବେ?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ନିୟନ୍ତ୍ରଣ କରିବାକୁ <xliff:g id="APPLICATION">%1$s</xliff:g> ଖୋଲିବେ?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ସୁନିଶ୍ଚିତ କରାଯାଇଛି"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ସୁନିଶ୍ଚିତ କରନ୍ତୁରେ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ଟିପଚିହ୍ନ ସେନସର୍କୁ ଛୁଅଁନ୍ତୁ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ଆଙ୍ଗୁଠି ଚିହ୍ନ ଆଇକନ୍"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ଆପଣଙ୍କୁ ଚିହ୍ନଟ କରୁଛି…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"ବିଜ୍ଞପ୍ତି"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ଫ୍ଲାସ୍ଲାଇଟ୍"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ମୋବାଇଲ୍ ଡାଟା"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ଡାଟାର ବ୍ୟବହାର"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ଅବଶିଷ୍ଟ ଡାଟା"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index b75deb9..805a580 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ਇਨਪੁਟ ਵਿਧੀਆਂ ਸੈਟ ਅਪ ਕਰੋ"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ਫਿਜੀਕਲ ਕੀ-ਬੋਰਡ"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"ਕੀ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ਤੱਕ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"ਕੀ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ਤੱਕ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨੂੰ ਪਹੁੰਚ ਕਰਨ ਦੇਣੀ ਹੈ?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"ਕੀ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ਨੂੰ ਵਰਤਣ ਲਈ <xliff:g id="APPLICATION">%1$s</xliff:g> ਖੋਲ੍ਹਣੀ ਹੈ?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"ਕੀ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ਨੂੰ ਵਰਤਣ ਲਈ <xliff:g id="APPLICATION">%1$s</xliff:g> ਖੋਲ੍ਹਣੀ ਹੈ?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ਪੁਸ਼ਟੀ ਕੀਤੀ ਗਈ"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ਪੂਰਾ ਕਰਨ ਲਈ ਪੁਸ਼ਟੀ ਕਰੋ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਪ੍ਰਤੀਕ"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ਤੁਹਾਡੀ ਪਛਾਣ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"ਸੂਚਨਾਵਾਂ"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ਫਲੈਸ਼ਲਾਈਟ"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ਮੋਬਾਈਲ ਡਾਟਾ"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ਡਾਟਾ ਵਰਤੋਂ"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ਬਾਕੀ ਡਾਟਾ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index d372b3d..16dfff3 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfiguruj metody wprowadzania"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Klawiatura fizyczna"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Otworzyć aplikację <xliff:g id="APPLICATION">%1$s</xliff:g> do obsługi urządzenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Otworzyć aplikację <xliff:g id="APPLICATION">%1$s</xliff:g> do obsługi urządzenia <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potwierdzono"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Aby zakończyć, kliknij Potwierdź"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Uwierzytelniono"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotknij czytnika linii papilarnych"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona odcisku palca"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Szukam Cię…"</string>
@@ -370,6 +386,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Powiadomienia"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Latarka"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilna transmisja danych"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Użycie danych"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Pozostały limit"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 2b76157..25ca226 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de entrada"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Teclado físico"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Abrir o app <xliff:g id="APPLICATION">%1$s</xliff:g> para lidar com o <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Abrir o app <xliff:g id="APPLICATION">%1$s</xliff:g> para lidar com o <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toque em \"Confirmar\" para concluir"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autenticado"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toque no sensor de impressão digital"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Procurando você…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificações"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lanterna"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Dados móveis"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Uso de dados"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Dados restantes"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 17cc86f..fdb98fa 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos introdução"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Teclado físico"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Pretende permitir que a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao dispositivo <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Pretende permitir que a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao acessório <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Pretende abrir a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> para controlar o acessório <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Pretende abrir a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> para controlar o acessório <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -68,7 +70,7 @@
<string name="learn_more" msgid="5000517160980853569">"Saiba mais"</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Zoom para preencher o ecrã"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Esticar p. caber em ec. int."</string>
- <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de ecrã"</string>
+ <string name="global_action_screenshot" msgid="8329831278085426283">"Capt. ecrã"</string>
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"A guardar captura de ecrã..."</string>
<string name="screenshot_saving_title" msgid="8242282144535555697">"A guardar captura de ecrã..."</string>
<string name="screenshot_saved_title" msgid="5637073968117370753">"Captura de ecrã guardada"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmado"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toque em Confirmar para concluir."</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autenticado"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toque no sensor de impressões digitais."</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"À sua procura…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificações"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lanterna"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Dados móveis"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Utilização de dados"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Dados restantes"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 2b76157..25ca226 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de entrada"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Teclado físico"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Abrir o app <xliff:g id="APPLICATION">%1$s</xliff:g> para lidar com o <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Abrir o app <xliff:g id="APPLICATION">%1$s</xliff:g> para lidar com o <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmada"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toque em \"Confirmar\" para concluir"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autenticado"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toque no sensor de impressão digital"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Procurando você…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificações"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lanterna"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Dados móveis"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Uso de dados"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Dados restantes"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index db8f87d..171ca9a 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Setați metode introducere text"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Tastatură fizică"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Permiteți <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Permiteți <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Deschideți <xliff:g id="APPLICATION">%1$s</xliff:g> ca să gestioneze <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Deschideți <xliff:g id="APPLICATION">%1$s</xliff:g> ca să gestioneze <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -56,7 +58,7 @@
<string name="always_use_device" msgid="4015357883336738417">"Deschideți întotdeauna <xliff:g id="APPLICATION">%1$s</xliff:g> când este conectat <xliff:g id="USB_DEVICE">%2$s</xliff:g>"</string>
<string name="always_use_accessory" msgid="3257892669444535154">"Deschideți întotdeauna <xliff:g id="APPLICATION">%1$s</xliff:g> când este conectat <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>"</string>
<string name="usb_debugging_title" msgid="4513918393387141949">"Permiteți remedierea erorilor prin USB?"</string>
- <string name="usb_debugging_message" msgid="2220143855912376496">"Amprenta digitală din cheia RSA a computerului este:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+ <string name="usb_debugging_message" msgid="2220143855912376496">"Amprenta din cheia RSA a computerului este:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"Permiteți întotdeauna de pe acest computer"</string>
<string name="usb_debugging_allow" msgid="2272145052073254852">"Permiteți"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Remedierea erorilor prin USB nu este permisă"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmat"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Atingeți Confirmați pentru a finaliza"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autentificat"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Atingeți senzorul de amprente"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Pictograma amprentă"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Vă căutăm…"</string>
@@ -366,6 +382,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificări"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lanternă"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Date mobile"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Utilizarea datelor"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Date rămase"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index f7527d9..1d7f6c8 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Настройка способов ввода"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Физическая клавиатура"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Предоставить приложению \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ к устройству \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Предоставить приложению \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ к устройству \"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>\"?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Открыть приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" для управления устройством \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Открыть приложение \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" для управления устройством \"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>\"?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Подтверждено"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Нажмите \"Подтвердить\""</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Аутентификация выполнена"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Прикоснитесь к сканеру отпечатков пальцев."</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок отпечатка пальца"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Поиск лица…"</string>
@@ -368,6 +384,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Уведомления"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Фонарик"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобильный Интернет"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Передача данных"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Остается данных"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index c87ef5a..fa1c109 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ආදාන ක්රම සකසන්න"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"භෞතික යතුරු පුවරුව"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> හට <xliff:g id="USB_DEVICE">%2$s</xliff:g> වෙත පිවිසීමට ඉඩ දෙන්නද?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> හට <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> වෙත පිවිසීමට ඉඩ දෙන්නද?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> හැසිරවීමට <xliff:g id="APPLICATION">%1$s</xliff:g> විවෘත කරන්නද?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> හැසිරවීමට <xliff:g id="APPLICATION">%1$s</xliff:g> විවෘත කරන්නද?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"තහවුරු කළා"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"සම්පූර්ණ කිරීමට තහවුරු කරන්න තට්ටු කර."</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"සත්යාපනය විය"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ඇඟිලි සලකුණු නිරූපකය"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ඔබව සොයමින්…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"දැනුම්දීම්"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"සැණෙළි ආලෝකය"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"ජංගම දත්ත"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"දත්ත භාවිතය"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ඉතිරි ඇති දත්ත"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 1e171a1..ddb0ed4 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavenie metód vstupu"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fyzická klávesnica"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Otvoriť aplikáciu <xliff:g id="APPLICATION">%1$s</xliff:g> na použitie zariadenia <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Otvoriť aplikáciu <xliff:g id="APPLICATION">%1$s</xliff:g> na použitie zariadenia <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potvrdené"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Overenie dokončíte klepnutím na Potvrdiť"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Overené"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotknite sa senzora odtlačkov prstov"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona odtlačku prsta"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Hľadáme vás…"</string>
@@ -368,6 +384,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Upozornenia"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Baterka"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobilné dáta"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Spotreba dát"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Zostávajúce údaje"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index b342ce6..1af84fe 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavi načine vnosa"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fizična tipkovnica"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Ali aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> dovolite dostop do dodatka USB <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Ali aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> dovolite dostop do dodatka USB <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Želite odpreti aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g> za upravljanje dodatka USB <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Želite odpreti aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g> za upravljanje dodatka USB <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potrjeno"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Za dokončanje se dotaknite »Potrdite«"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Preverjena pristnost"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotaknite se tipala prstnih odtisov"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona prstnih odtisov"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Preverjanje vašega obraza …"</string>
@@ -368,6 +384,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obvestila"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Svetilka"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Prenos podatkov v mobilnem omrežju"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Poraba podatkov"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Preostala količina podatkov"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 4fba770..344aae3 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfiguro metodat e hyrjes"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Tastierë fizike"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Të lejohet <xliff:g id="APPLICATION">%1$s</xliff:g> të ketë qasje te <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Të lejohet <xliff:g id="APPLICATION">%1$s</xliff:g> të ketë qasje te <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Të hapet <xliff:g id="APPLICATION">%1$s</xliff:g> për të përdorur <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Të hapet <xliff:g id="APPLICATION">%1$s</xliff:g> për të përdorur <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -56,7 +58,7 @@
<string name="always_use_device" msgid="4015357883336738417">"Hap gjithmonë <xliff:g id="APPLICATION">%1$s</xliff:g> kur lidhet <xliff:g id="USB_DEVICE">%2$s</xliff:g>"</string>
<string name="always_use_accessory" msgid="3257892669444535154">"Hap gjithmonë <xliff:g id="APPLICATION">%1$s</xliff:g> kur lidhet <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>"</string>
<string name="usb_debugging_title" msgid="4513918393387141949">"Të lejohet korrigjimi i USB-së?"</string>
- <string name="usb_debugging_message" msgid="2220143855912376496">"Shenja e gishtit të tastit \"RSA\" së kompjuterit është:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+ <string name="usb_debugging_message" msgid="2220143855912376496">"Gjurma e gishtit të tastit \"RSA\" së kompjuterit është:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"Lejo gjithmonë nga ky kompjuter"</string>
<string name="usb_debugging_allow" msgid="2272145052073254852">"Lejo"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Korrigjimi i USB-së nuk lejohet"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Konfirmuar"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Trokit \"Konfirmo\" për ta përfunduar"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"U vërtetua"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Prek sensorin e gjurmës së gishtit"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona e gjurmës së gishtit"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Po të kërkojmë…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Njoftimet"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Elektriku"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Të dhënat celulare"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Përdorimi i të dhënave"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Të dhënat e mbetura"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 310fc6f..b36b9dc 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Подеси методе уноса"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Физичка тастатура"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Желите ли да дозволите да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Желите ли да дозволите да <xliff:g id="APPLICATION">%1$s</xliff:g> приступа уређају <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> да бисте користили уређај <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Желите ли да отворите апликацију <xliff:g id="APPLICATION">%1$s</xliff:g> да бисте користили уређај <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Потврђено"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Додирните Потврди да бисте завршили"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Идентитет је потврђен"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Додирните сензор за отисак прста"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона отиска прста"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Тражимо вас…"</string>
@@ -366,6 +382,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Обавештења"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Лампа"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобилни подаци"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Потрошња података"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Преостала количина података"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 54769cd..24e0b1e 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurera inmatningsmetoder"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fysiskt tangentbord"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Vill du ge <xliff:g id="APPLICATION">%1$s</xliff:g> åtkomst till <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Vill du ge <xliff:g id="APPLICATION">%1$s</xliff:g> åtkomst till <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Vill du öppna <xliff:g id="APPLICATION">%1$s</xliff:g> och hantera <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Vill du öppna <xliff:g id="APPLICATION">%1$s</xliff:g> och hantera <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bekräftat"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Slutför genom att trycka på Bekräfta"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Autentiserad"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Tryck på fingeravtryckssensorn"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon för fingeravtryck"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Håller utkik efter dig …"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Aviseringar"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Ficklampa"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobildata"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Dataanvändning"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Återstående data"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 3f9278a..93f5b7d 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Weka mbinu za ingizo"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Kibodi halisi"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Ungependa kuruhusu <xliff:g id="APPLICATION">%1$s</xliff:g> ifikie <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Ungependa kufungua <xliff:g id="APPLICATION">%1$s</xliff:g> ili itumie <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Ungependa kufungua <xliff:g id="APPLICATION">%1$s</xliff:g> ili itumie <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Imethibitishwa"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Gusa Thibitisha ili ukamilishe"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Umethibitishwa"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Gusa kitambua alama ya kidole"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Aikoni ya alama ya kidole"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Inakutafuta…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Arifa"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Tochi"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Data ya simu"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Matumizi ya data"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Data iliyosalia"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 0f36889..a5aa91d 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"உள்ளீட்டு முறைகளை அமை"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"கைமுறை விசைப்பலகை"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ஐ அணுக, <xliff:g id="APPLICATION">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ஐ அணுக, <xliff:g id="APPLICATION">%1$s</xliff:g> ஆப்ஸை அனுமதிக்கவா?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ஐக் கையாள, <xliff:g id="APPLICATION">%1$s</xliff:g> பயன்பாட்டைத் திறக்கவா?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ஐக் கையாள, <xliff:g id="APPLICATION">%1$s</xliff:g> பயன்பாட்டைத் திறக்கவா?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"உறுதிப்படுத்தப்பட்டது"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"முடிக்க \'உறுதிப்படுத்து\' என்பதை தட்டவும்"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"அங்கீகரிக்கப்பட்டது"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"கைரேகை சென்சாரைத் தொடவும்"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"கைரேகை ஐகான்"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"உங்கள் முகத்தைத் தேடுகிறது…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"அறிவிப்புகள்"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"டார்ச் லைட்"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"மொபைல் டேட்டா"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"டேட்டா உபயோகம்"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"மீதமுள்ள தரவு"</string>
@@ -498,29 +516,29 @@
<string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"உங்கள் நிறுவனம், பணிக் கணக்கில் சான்றிதழ் அங்கீகாரத்தை நிறுவியுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
<string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"இந்தச் சாதனத்தில் சான்றிதழ் அங்கீகாரம் நிறுவப்பட்டுள்ளது. உங்களின் பாதுகாப்பான நெட்வொர்க் ட்ராஃபிக் கண்காணிக்கப்படலாம் அல்லது மாற்றப்படலாம்."</string>
<string name="monitoring_description_management_network_logging" msgid="7184005419733060736">"உங்கள் நிர்வாகி, நெட்வொர்க் பதிவெடுத்தலை இயக்கியுள்ளார். இது சாதனத்தில் ட்ராஃபிக்கைக் கண்காணிக்கும்."</string>
- <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள்."</string>
- <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="VPN_APP_0">%1$s</xliff:g> மற்றும் <xliff:g id="VPN_APP_1">%2$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள்."</string>
- <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் உங்கள் பணிக் கணக்கு இணைக்கப்பட்டுள்ளது."</string>
- <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் உங்களின் தனிப்பட்ட சுயவிவரம் இணைக்கப்பட்டுள்ளது."</string>
+ <string name="monitoring_description_named_vpn" msgid="7403457334088909254">"மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள்."</string>
+ <string name="monitoring_description_two_named_vpns" msgid="4198511413729213802">"மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="VPN_APP_0">%1$s</xliff:g> மற்றும் <xliff:g id="VPN_APP_1">%2$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள்."</string>
+ <string name="monitoring_description_managed_profile_named_vpn" msgid="1427905889862420559">"மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் உங்கள் பணிக் கணக்கு இணைக்கப்பட்டுள்ளது."</string>
+ <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="VPN_APP">%1$s</xliff:g> உடன் உங்களின் தனிப்பட்ட சுயவிவரம் இணைக்கப்பட்டுள்ளது."</string>
<string name="monitoring_description_do_header_generic" msgid="96588491028288691">"உங்கள் சாதனத்தை நிர்வகிப்பது: <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
<string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"உங்கள் சாதனத்தை நிர்வகிக்க, <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> ஆப்ஸை <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> பயன்படுத்தும்."</string>
<string name="monitoring_description_do_body" msgid="3639594537660975895">"உங்கள் நிர்வாகியால் அமைப்புகள், நிறுவன அணுகல், ஆப்ஸ், சாதனத்துடன் தொடர்புடைய டேட்டா, சாதன இருப்பிடத் தகவல் ஆகியவற்றைக் கண்காணிக்கவும் நிர்வகிக்கவும் முடியும்."</string>
<string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
<string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"மேலும் அறிக"</string>
- <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"<xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள். இந்த ஆப்ஸால் மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்."</string>
+ <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"<xliff:g id="VPN_APP">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள். இந்த ஆப்ஸால் மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்."</string>
<string name="monitoring_description_vpn_settings_separator" msgid="1933186756733474388">" "</string>
<string name="monitoring_description_vpn_settings" msgid="6434859242636063861">"VPN அமைப்புகளைத் திற"</string>
<string name="monitoring_description_ca_cert_settings_separator" msgid="4987350385906393626">" "</string>
<string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"நம்பகமான அனுமதிச் சான்றுகளைத் திற"</string>
<string name="monitoring_description_network_logging" msgid="7223505523384076027">"உங்கள் நிர்வாகி நெட்வொர்க் பதிவெடுத்தலை இயக்கியுள்ளார், இது சாதனத்தில் ட்ராஃபிக்கைக் கண்காணிக்கும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
- <string name="monitoring_description_vpn" msgid="4445150119515393526">"VPN இணைப்பை அமைக்க, பயன்பாட்டிற்கு அனுமதி வழங்கியுள்ளீர்கள்.\n\nஇந்த ஆப்ஸால் மின்னஞ்சல்கள், பயன்பாடுகள் மற்றும் இணையதளங்கள் உட்பட, உங்கள் சாதனத்தையும் நெட்வொர்க் செயல்பாட்டையும் கண்காணிக்க முடியும்."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"உங்கள் பணிக் கணக்கை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது.\n\nஉங்கள் நிர்வாகியால் பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்.\n\nஉங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய VPN உடனும் இணைக்கப்பட்டுள்ளீர்கள்."</string>
+ <string name="monitoring_description_vpn" msgid="4445150119515393526">"VPN இணைப்பை அமைக்க, பயன்பாட்டிற்கு அனுமதி வழங்கியுள்ளீர்கள்.\n\nஇந்த ஆப்ஸால் மின்னஞ்சல்கள், ஆப்ஸ் மற்றும் இணையதளங்கள் உட்பட, உங்கள் சாதனத்தையும் நெட்வொர்க் செயல்பாட்டையும் கண்காணிக்க முடியும்."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"உங்கள் பணிக் கணக்கை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது.\n\nஉங்கள் நிர்வாகியால் ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்.\n\nமேலும் தகவலுக்கு, உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்.\n\nஉங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய VPN உடனும் இணைக்கப்பட்டுள்ளீர்கள்."</string>
<string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
- <string name="monitoring_description_app" msgid="1828472472674709532">"மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள்."</string>
- <string name="monitoring_description_app_personal" msgid="484599052118316268">"<xliff:g id="APPLICATION">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள். இந்த ஆப்ஸால், மின்னஞ்சல்கள், பயன்பாடுகள் மற்றும் இணையதளங்கள் உட்பட உங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்."</string>
- <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள். இந்த ஆப்ஸால் மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்."</string>
- <string name="monitoring_description_app_work" msgid="4612997849787922906">"உங்கள் பணிக் கணக்கை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது. மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் பணி நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION">%2$s</xliff:g> உடன் அது இணைக்கப்பட்டுள்ளது.\n\nமேலும் தகவலுக்கு, நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
- <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"உங்கள் பணிக் கணக்கை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது. மின்னஞ்சல்கள், பயன்பாடுகள், இணையதளங்கள் உட்பட உங்கள் பணி நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> உடன் அது இணைக்கப்பட்டுள்ளது.\n\nஉங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> உடனும் இணைக்கப்பட்டுள்ளீர்கள்."</string>
+ <string name="monitoring_description_app" msgid="1828472472674709532">"மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள்."</string>
+ <string name="monitoring_description_app_personal" msgid="484599052118316268">"<xliff:g id="APPLICATION">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள். இந்த ஆப்ஸால், மின்னஞ்சல்கள், ஆப்ஸ் மற்றும் இணையதளங்கள் உட்பட உங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்."</string>
+ <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"<xliff:g id="APPLICATION">%1$s</xliff:g> உடன் இணைக்கப்பட்டுள்ளீர்கள். இந்த ஆப்ஸால் மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்க முடியும்."</string>
+ <string name="monitoring_description_app_work" msgid="4612997849787922906">"உங்கள் பணிக் கணக்கை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது. மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் பணி நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION">%2$s</xliff:g> உடன் அது இணைக்கப்பட்டுள்ளது.\n\nமேலும் தகவலுக்கு, நிர்வாகியைத் தொடர்புகொள்ளவும்."</string>
+ <string name="monitoring_description_app_personal_work" msgid="5664165460056859391">"உங்கள் பணிக் கணக்கை <xliff:g id="ORGANIZATION">%1$s</xliff:g> நிர்வகிக்கிறது. மின்னஞ்சல்கள், ஆப்ஸ், இணையதளங்கள் உட்பட உங்கள் பணி நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> உடன் அது இணைக்கப்பட்டுள்ளது.\n\nஉங்கள் தனிப்பட்ட நெட்வொர்க் செயல்பாட்டைக் கண்காணிக்கக்கூடிய <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> உடனும் இணைக்கப்பட்டுள்ளீர்கள்."</string>
<string name="keyguard_indication_trust_unlocked" msgid="2712865815371519117">"TrustAgent இதைத் திறந்தே வைத்துள்ளது"</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"நீங்கள் கைமுறையாகத் திறக்கும் வரை, சாதனம் பூட்டப்பட்டிருக்கும்"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"விரைவாக அறிவிப்புகளைப் பெறுதல்"</string>
@@ -846,7 +864,7 @@
<string name="pip_skip_to_prev" msgid="1955311326688637914">"முந்தையதற்குச் செல்"</string>
<string name="thermal_shutdown_title" msgid="4458304833443861111">"வெப்பத்தினால் ஃபோன் ஆஃப் செய்யப்பட்டது"</string>
<string name="thermal_shutdown_message" msgid="9006456746902370523">"இப்போது உங்கள் ஃபோன் இயல்புநிலையில் இயங்குகிறது"</string>
- <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"உங்கள் ஃபோன் அதிகமாகச் சூடானதால், அதன் சூட்டைக் குறைக்க, ஆஃப் செய்யப்பட்டது. இப்போது உங்கள் ஃபோன் இயல்புநிலையில் இயங்குகிறது.\n\nபின்வருவனவற்றைச் செய்தால், ஃபோன் சூடாகலாம்:\n • அதிகளவு தரவைப் பயன்படுத்தும் ஆப்ஸை (எ.கா: கேமிங், வீடியோ (அ) வழிகாட்டுதல் பயன்பாடுகள்) பயன்படுத்துவது\n • பெரிய கோப்புகளைப் பதிவிறக்குவது/பதிவேற்றுவது\n • அதிக வெப்பநிலையில் ஃபோனைப் பயன்படுத்துவது"</string>
+ <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"உங்கள் ஃபோன் அதிகமாகச் சூடானதால், அதன் சூட்டைக் குறைக்க, ஆஃப் செய்யப்பட்டது. இப்போது உங்கள் ஃபோன் இயல்புநிலையில் இயங்குகிறது.\n\nபின்வருவனவற்றைச் செய்தால், ஃபோன் சூடாகலாம்:\n • அதிகளவு தரவைப் பயன்படுத்தும் ஆப்ஸை (எ.கா: கேமிங், வீடியோ (அ) வழிகாட்டுதல் ஆப்ஸ்) பயன்படுத்துவது\n • பெரிய கோப்புகளைப் பதிவிறக்குவது/பதிவேற்றுவது\n • அதிக வெப்பநிலையில் ஃபோனைப் பயன்படுத்துவது"</string>
<string name="high_temp_title" msgid="4589508026407318374">"மொபைல் சூடாகிறது"</string>
<string name="high_temp_notif_message" msgid="5642466103153429279">"மொபைலின் வெப்ப அளவு குறையும் போது, சில அம்சங்களைப் பயன்படுத்த முடியாது"</string>
<string name="high_temp_dialog_message" msgid="6840700639374113553">"உங்கள் மொபைலின் வெப்ப அளவு தானாகவே குறையும். தொடர்ந்து நீங்கள் மொபைலைப் பயன்படுத்தலாம், ஆனால் அதன் வேகம் குறைவாக இருக்கக்கூடும்.\n\nமொபைலின் வெப்ப அளவு குறைந்தவுடன், அது இயல்பு நிலையில் இயங்கும்."</string>
@@ -891,7 +909,7 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> வரை"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"வைத்திரு"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"மாற்று"</string>
- <string name="running_foreground_services_title" msgid="381024150898615683">"பின்னணியில் இயங்கும் பயன்பாடுகள்"</string>
+ <string name="running_foreground_services_title" msgid="381024150898615683">"பின்னணியில் இயங்கும் ஆப்ஸ்"</string>
<string name="running_foreground_services_msg" msgid="6326247670075574355">"பேட்டரி மற்றும் டேட்டா உபயோக விவரங்களைக் காண, தட்டவும்"</string>
<string name="mobile_data_disable_title" msgid="1068272097382942231">"மொபைல் டேட்டாவை ஆஃப் செய்யவா?"</string>
<string name="mobile_data_disable_message" msgid="4756541658791493506">"<xliff:g id="CARRIER">%s</xliff:g> மூலம் டேட்டா அல்லது இணையத்தை உங்களால் பயன்படுத்த முடியாது. வைஃபை வழியாக மட்டுமே இணையத்தைப் பயன்படுத்த முடியும்."</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 62fe95b..c6b2bb7 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ఇన్పుట్ పద్ధతులను సెటప్ చేయండి"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"భౌతిక కీబోర్డ్"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ని యాక్సెస్ చేయడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ని అనుమతించాలా?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ని యాక్సెస్ చేయడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ని అనుమతించాలా?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g>ని నిర్వహించడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ని తెరవాలా?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>ని నిర్వహించడానికి <xliff:g id="APPLICATION">%1$s</xliff:g>ని తెరవాలా?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"నిర్ధారించబడింది"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"పూర్తి చేయడానికి \"నిర్ధారించు\" నొక్కండి"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"ప్రామాణీకరించబడింది"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"వేలిముద్ర సెన్సార్ను తాకండి"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"వేలిముద్ర చిహ్నం"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"మీ కోసం చూస్తోంది…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"నోటిఫికేషన్లు"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ఫ్లాష్లైట్"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"మొబైల్ డేటా"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"డేటా వినియోగం"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"మిగిలిన డేటా"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index eb6810a0..2907524 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ตั้งค่าวิธีการป้อนข้อมูล"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"แป้นพิมพ์บนเครื่อง"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_DEVICE">%2$s</xliff:g> ไหม"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"อนุญาตให้ <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึง <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ไหม"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"เปิด <xliff:g id="APPLICATION">%1$s</xliff:g> เพื่อจัดการ <xliff:g id="USB_DEVICE">%2$s</xliff:g> ไหม"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"เปิด <xliff:g id="APPLICATION">%1$s</xliff:g> เพื่อจัดการ <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ไหม"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ยืนยันแล้ว"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"แตะยืนยันเพื่อดำเนินการให้เสร็จสมบูรณ์"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"ตรวจสอบสิทธิ์แล้ว"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"แตะเซ็นเซอร์ลายนิ้วมือ"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ไอคอนลายนิ้วมือ"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"กำลังหาใบหน้าคุณ…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"การแจ้งเตือน"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"ไฟฉาย"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"เน็ตมือถือ"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"การใช้อินเทอร์เน็ต"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ข้อมูลที่เหลืออยู่"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index f6abdcb..ce8c88b 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"I-set up paraan ng pag-input"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Aktwal na keyboard"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Payagan ang <xliff:g id="APPLICATION">%1$s</xliff:g> na ma-access ang <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Payagan ang <xliff:g id="APPLICATION">%1$s</xliff:g> na ma-access ang <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Buksan ang <xliff:g id="APPLICATION">%1$s</xliff:g> upang pamahalaan ang <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Buksan ang <xliff:g id="APPLICATION">%1$s</xliff:g> upang pamahalaan ang <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Nakumpirma"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"I-tap ang Kumpirmahin para kumpletuhin"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Na-authenticate"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Pindutin ang fingerprint sensor"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icon ng fingerprint"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Hinahanap ka…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Mga Notification"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Flashlight"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobile data"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Paggamit ng data"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Natitirang data"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index b5e1702..7976014 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Giriş yöntemlerini ayarla"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fiziksel klavye"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının <xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazına erişmesine izin verilsin mi?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> aksesuarına erişmesine izin verilsin mi?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> cihazını işlemek için <xliff:g id="APPLICATION">%1$s</xliff:g> uygulaması açılsın mı?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> aksesuarını işlemek için <xliff:g id="APPLICATION">%1$s</xliff:g> uygulaması açılsın mı?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Onaylandı"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tamamlamak için Onayla\'ya dokunun"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Kimliği Doğrulandı"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Parmak izi sensörüne dokunun"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Parmak izi simgesi"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Yüzünüz tanınmaya çalışılıyor…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Bildirimler"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Fener"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobil veri"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Veri kullanımı"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Kalan veri"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 36bec1e..ea2f376 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Налаштувати методи введення"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Фізична клавіатура"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Надати додатку <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до такого аксесуара: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Надати додатку <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до такого аксесуара: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Відкрити додаток <xliff:g id="APPLICATION">%1$s</xliff:g>, щоб використовувати такий аксесуар: <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Відкрити додаток <xliff:g id="APPLICATION">%1$s</xliff:g>, щоб використовувати такий аксесуар: <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Підтверджено"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Щоб завершити, натисніть \"Підтвердити\""</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Автентифіковано"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Торкніться сканера відбитків пальців"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок відбитка пальця"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Пошук обличчя…"</string>
@@ -368,6 +384,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Сповіщення"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Ліхтарик"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Мобільне передавання даних"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Використання даних"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Залишилося даних"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 5fceabe..1c28431 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ان پٹ کے طریقوں کو ترتیب دیں"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"طبعی کی بورڈ"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> کو <xliff:g id="USB_DEVICE">%2$s</xliff:g> تک رسائی حاصل کرنے کی اجازت دیں؟"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> کو <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> تک رسائی حاصل کرنے کی اجازت دیں؟"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> ہینڈل کرنے کیلئے <xliff:g id="APPLICATION">%1$s</xliff:g> کھولیں؟"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> ہینڈل کرنے کیلئے <xliff:g id="APPLICATION">%1$s</xliff:g> کھولیں؟"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"تصدیق شدہ"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"مکمل کرنے کیلئے \'تصدیق کریں\' تھپتھپائیں"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"تصدیق کردہ"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"فنگر پرنٹ سینسر پر ٹچ کریں"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"فنگر پرنٹ آئیکن"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"آپ کے لیے تلاش کیا جا رہا ہے…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"اطلاعات"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"فلیش لائٹ"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"موبائل ڈیٹا"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ڈیٹا کا استعمال"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"باقی ڈیٹا"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 37651a5..c3e39e5 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Kiritish usullarini moslash"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Tashqi tugmatag"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasiga <xliff:g id="USB_DEVICE">%2$s</xliff:g> qurilmasidan foydalanishga ruxsat berilsinmi?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> ilovasiga <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> qurilmasidan foydalanishga ruxsat berilsinmi?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> bilan ishlash uchun <xliff:g id="APPLICATION">%1$s</xliff:g> ochilsinmi?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> bilan ishlash uchun <xliff:g id="APPLICATION">%1$s</xliff:g> ochilsinmi?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Tasdiqlangan"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tasdiqlash uchun tegining"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Tasdiqlandi"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Barmoq izi skaneriga tegining"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Barmoq izi belgisi"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Yuzingiz tekshirilmoqda…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Bildirishnomalar"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Fonar"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Mobil internet"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Trafik sarfi"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Qolgan trafik"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index f678265..d2da39b 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Thiết lập phương thức nhập"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Bàn phím vật lý"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Cho phép <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Cho phép <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Mở <xliff:g id="APPLICATION">%1$s</xliff:g> để điều khiển <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Mở <xliff:g id="APPLICATION">%1$s</xliff:g> để điều khiển <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -56,7 +58,7 @@
<string name="always_use_device" msgid="4015357883336738417">"Luôn mở <xliff:g id="APPLICATION">%1$s</xliff:g> khi kết nối <xliff:g id="USB_DEVICE">%2$s</xliff:g>"</string>
<string name="always_use_accessory" msgid="3257892669444535154">"Luôn mở <xliff:g id="APPLICATION">%1$s</xliff:g> khi kết nối <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>"</string>
<string name="usb_debugging_title" msgid="4513918393387141949">"Cho phép gỡ lỗi qua USB?"</string>
- <string name="usb_debugging_message" msgid="2220143855912376496">"Tệp tham chiếu khóa RSA của máy tính là:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+ <string name="usb_debugging_message" msgid="2220143855912376496">"Vân tay khóa RSA của máy tính là:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"Luôn cho phép từ máy tính này"</string>
<string name="usb_debugging_allow" msgid="2272145052073254852">"Cho phép"</string>
<string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Không cho phép chế độ gỡ lỗi qua USB"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Ðã xác nhận"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Nhấn vào Xác nhận để hoàn tất"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Đã xác thực"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Chạm vào cảm biến vân tay"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Biểu tượng vân tay"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Đang tìm kiếm bạn…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Thông báo"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Đèn pin"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Dữ liệu di động"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Sử dụng dữ liệu"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Dữ liệu còn lại"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 05509f6..551e54e 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"设置输入法"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"物理键盘"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"要允许<xliff:g id="APPLICATION">%1$s</xliff:g>访问<xliff:g id="USB_DEVICE">%2$s</xliff:g>吗?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"要允许<xliff:g id="APPLICATION">%1$s</xliff:g>访问<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>吗?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"要打开<xliff:g id="APPLICATION">%1$s</xliff:g>来处理<xliff:g id="USB_DEVICE">%2$s</xliff:g>吗?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"要打开<xliff:g id="APPLICATION">%1$s</xliff:g>来处理<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>吗?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"已确认"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"点按“确认”即可完成"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"已经过身份验证"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"请触摸指纹传感器"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指纹图标"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"正在查找您的面孔…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"通知"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"手电筒"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"移动数据"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"流量使用情况"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"剩余流量"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index b57e61f..206fcfc 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"設定輸入法"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"實體鍵盤"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>」嗎?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」處理「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」處理「<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>」嗎?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"已確認"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"輕按 [確定] 以完成"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"驗證咗"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"請輕觸指紋感應器"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋圖示"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"正在搜尋您的臉孔…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"通知"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"電筒"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"流動數據"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"數據用量"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"剩餘資料"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 14fedbb..c1f299d 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"設定輸入法"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"實體鍵盤"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"要允許「<xliff:g id="APPLICATION">%1$s</xliff:g>」存取「<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>」嗎?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」處理「<xliff:g id="USB_DEVICE">%2$s</xliff:g>」嗎?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"要開啟「<xliff:g id="APPLICATION">%1$s</xliff:g>」處理「<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>」嗎?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"確認完畢"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"輕觸 [確認] 完成驗證設定"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"已通過驗證"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"請輕觸指紋感應器"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋圖示"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"正在尋找你的臉孔…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"通知"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"手電筒"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"行動數據"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"數據用量"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"剩餘資料"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index c158c77..37eca51 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -47,6 +47,8 @@
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Izilungiselelo zezindlela zokufakwayo"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Ukwakheka kwekhibhodi"</string>
<string name="usb_device_permission_prompt" msgid="1825685909587559679">"Vumela i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukufinyelela i-<xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
+ <!-- no translation found for usb_device_permission_prompt_warn (1842558472039505091) -->
+ <skip />
<string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"Vumela i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukufinyelela i-<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
<string name="usb_device_confirm_prompt" msgid="7440562274256843905">"Vula i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukuze uphath i-<xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
<string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"Vula i-<xliff:g id="APPLICATION">%1$s</xliff:g> ukuze uphath i-<xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
@@ -126,6 +128,20 @@
<string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Kuqinisekisiwe"</string>
<string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Thepha okuthi Qinisekisa ukuze uqedele"</string>
<string name="biometric_dialog_authenticated" msgid="5918352844999713693">"Kugunyaziwe"</string>
+ <!-- no translation found for biometric_dialog_use_pin (2506187927478996039) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_pattern (4721877831431699442) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_use_password (3426428493718969343) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pin (4600590473629948574) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_pattern (4808369401645512099) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_wrong_password (2343518162282889518) -->
+ <skip />
+ <!-- no translation found for biometric_dialog_credential_too_many_attempts (1556206869468265728) -->
+ <skip />
<string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Thinta inzwa yesigxivizo somunwe"</string>
<string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Isithonjana sezigxivizo zeminwe"</string>
<string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Kufunwa wena…"</string>
@@ -364,6 +380,8 @@
</plurals>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Izaziso"</string>
<string name="quick_settings_flashlight_label" msgid="2133093497691661546">"I-Flashlight"</string>
+ <!-- no translation found for quick_settings_flashlight_camera_in_use (6120370795890963385) -->
+ <skip />
<string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"Idatha yeselula"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Ukusetshenziswa kwedatha"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Idatha esele"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 61210d3..105b27e 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -279,7 +279,7 @@
<item>com.android.systemui.recents.Recents</item>
<item>com.android.systemui.volume.VolumeUI</item>
<item>com.android.systemui.stackdivider.Divider</item>
- <item>com.android.systemui.SystemBars</item>
+ <item>com.android.systemui.statusbar.phone.StatusBar</item>
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item>
<item>com.android.systemui.media.RingtonePlayer</item>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1079206..d722d61 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1009,10 +1009,15 @@
<!-- Biometric Dialog values -->
<dimen name="biometric_dialog_biometric_icon_size">64dp</dimen>
<dimen name="biometric_dialog_corner_size">4dp</dimen>
+ <!-- Y translation when showing/dismissing the dialog-->
<dimen name="biometric_dialog_animation_translation_offset">350dp</dimen>
<dimen name="biometric_dialog_border_padding">4dp</dimen>
<dimen name="biometric_dialog_elevation">1dp</dimen>
<dimen name="biometric_dialog_icon_padding">16dp</dimen>
+ <!-- Y translation for biometric contents when transitioning to device credential UI -->
+ <dimen name="biometric_dialog_medium_to_large_translation_offset">100dp</dimen>
+ <!-- Y translation for credential contents when animating in -->
+ <dimen name="biometric_dialog_credential_translation_offset">60dp</dimen>
<!-- Wireless Charging Animation values -->
<dimen name="wireless_charging_dots_radius_start">0dp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 3727181..04640f4 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -141,5 +141,8 @@
<!-- Global Actions Menu -->
<item type="id" name="global_actions_view" />
+
+ <!-- NotificationPanelView -->
+ <item type="id" name="notification_panel" />
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 97e2f0f..8335c11 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -118,10 +118,13 @@
<string name="status_bar_use_physical_keyboard">Physical keyboard</string>
<!-- Prompt for the USB device permission dialog [CHAR LIMIT=80] -->
- <string name="usb_device_permission_prompt">Allow <xliff:g id="application">%1$s</xliff:g> to access <xliff:g id="usb_device">%2$s</xliff:g>?</string>
+ <string name="usb_device_permission_prompt">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_device" example="USB Headphones">%2$s</xliff:g>?</string>
+
+ <!-- Checkbox label for USB device dialogs with warning text for USB device dialogs. [CHAR LIMIT=200]-->
+ <string name="usb_device_permission_prompt_warn">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_device" example="USB Headphones">%2$s</xliff:g>?\nThis app has not been granted record permission but could capture audio through this USB device.</string>
<!-- Prompt for the USB accessory permission dialog [CHAR LIMIT=80] -->
- <string name="usb_accessory_permission_prompt">Allow <xliff:g id="application">%1$s</xliff:g> to access <xliff:g id="usb_accessory">%2$s</xliff:g>?</string>
+ <string name="usb_accessory_permission_prompt">Allow <xliff:g id="application" example= "Usb Mega Player">%1$s</xliff:g> to access <xliff:g id="usb_accessory" example="USB Dock">%2$s</xliff:g>?</string>
<!-- Prompt for the USB device confirm dialog [CHAR LIMIT=80] -->
<string name="usb_device_confirm_prompt">Open <xliff:g id="application">%1$s</xliff:g> to handle <xliff:g id="usb_device">%2$s</xliff:g>?</string>
@@ -308,6 +311,21 @@
<!-- Talkback string when a biometric is authenticated [CHAR LIMIT=NONE] -->
<string name="biometric_dialog_authenticated">Authenticated</string>
+ <!-- Button text shown on BiometricPrompt giving the user the option to use an alternate form of authentication (Pin) [CHAR LIMIT=30] -->
+ <string name="biometric_dialog_use_pin">Use PIN</string>
+ <!-- Button text shown on BiometricPrompt giving the user the option to use an alternate form of authentication (Pattern) [CHAR LIMIT=30] -->
+ <string name="biometric_dialog_use_pattern">Use pattern</string>
+ <!-- Button text shown on BiometricPrompt giving the user the option to use an alternate form of authentication (Pass) [CHAR LIMIT=30] -->
+ <string name="biometric_dialog_use_password">Use password</string>
+ <!-- Error string shown when the user enters an incorrect PIN [CHAR LIMIT=40]-->
+ <string name="biometric_dialog_wrong_pin">Wrong PIN</string>
+ <!-- Error string shown when the user enters an incorrect pattern [CHAR LIMIT=40]-->
+ <string name="biometric_dialog_wrong_pattern">Wrong pattern</string>
+ <!-- Error string shown when the user enters an incorrect password [CHAR LIMIT=40]-->
+ <string name="biometric_dialog_wrong_password">Wrong password</string>
+ <!-- Error string shown when the user enters too many incorrect attempts [CHAR LIMIT=120]-->
+ <string name="biometric_dialog_credential_too_many_attempts">Too many incorrect attempts.\nTry again in <xliff:g id="number">%d</xliff:g> seconds.</string>
+
<!-- Message shown when the system-provided fingerprint dialog is shown, asking for authentication -->
<string name="fingerprint_dialog_touch_sensor">Touch the fingerprint sensor</string>
<!-- Content description of the fingerprint icon when the system-provided fingerprint dialog is showing, for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -860,6 +878,8 @@
<string name="quick_settings_notifications_label">Notifications</string>
<!-- QuickSettings: Flashlight [CHAR LIMIT=NONE] -->
<string name="quick_settings_flashlight_label">Flashlight</string>
+ <!-- QuickSettings: Flashlight, used when it's not available due to camera in use [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_flashlight_camera_in_use">Camera in use</string>
<!-- QuickSettings: Cellular detail panel title [CHAR LIMIT=NONE] -->
<string name="quick_settings_cellular_detail_title">Mobile data</string>
<!-- QuickSettings: Cellular detail panel, data usage title [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 6374191..96fbcbb 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -314,6 +314,12 @@
<item name="*android:errorColor">?android:attr/colorError</item>
</style>
+ <style name="LockPatternStyleBiometricPrompt">
+ <item name="*android:regularColor">?android:attr/colorForeground</item>
+ <item name="*android:successColor">?android:attr/colorForeground</item>
+ <item name="*android:errorColor">?android:attr/colorError</item>
+ </style>
+
<style name="qs_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
<item name="lightIconTheme">@style/QSIconTheme</item>
<item name="darkIconTheme">@style/QSIconTheme</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index e1b723e..ef9538d 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -35,6 +35,7 @@
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.internal.telephony.IccCardConstants;
@@ -57,6 +58,7 @@
private static final String TAG = "CarrierTextController";
private final boolean mIsEmergencyCallCapable;
+ private final Handler mMainHandler;
private boolean mTelephonyCapable;
private boolean mShowMissingSim;
private boolean mShowAirplaneMode;
@@ -65,6 +67,7 @@
private WifiManager mWifiManager;
private boolean[] mSimErrorState;
private final int mSimSlotsNumber;
+ @Nullable // Check for nullability before dispatching
private CarrierTextCallback mCarrierTextCallback;
private Context mContext;
private CharSequence mSeparator;
@@ -73,12 +76,12 @@
new WakefulnessLifecycle.Observer() {
@Override
public void onFinishedWakingUp() {
- mCarrierTextCallback.finishedWakingUp();
+ if (mCarrierTextCallback != null) mCarrierTextCallback.finishedWakingUp();
}
@Override
public void onStartedGoingToSleep() {
- mCarrierTextCallback.startedGoingToSleep();
+ if (mCarrierTextCallback != null) mCarrierTextCallback.startedGoingToSleep();
}
};
@@ -167,8 +170,9 @@
mSeparator = separator;
mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
mSimSlotsNumber = ((TelephonyManager) context.getSystemService(
- Context.TELEPHONY_SERVICE)).getPhoneCount();
+ Context.TELEPHONY_SERVICE)).getMaxPhoneCount();
mSimErrorState = new boolean[mSimSlotsNumber];
+ mMainHandler = Dependency.get(Dependency.MAIN_HANDLER);
}
/**
@@ -227,7 +231,12 @@
if (whitelistIpcs(() -> ConnectivityManager.from(mContext).isNetworkSupported(
ConnectivityManager.TYPE_MOBILE))) {
mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
- mKeyguardUpdateMonitor.registerCallback(mCallback);
+ // Keyguard update monitor expects callbacks from main thread
+ mMainHandler.post(() -> {
+ if (mKeyguardUpdateMonitor != null) {
+ mKeyguardUpdateMonitor.registerCallback(mCallback);
+ }
+ });
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
telephonyManager.listen(mPhoneStateListener,
LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
@@ -239,7 +248,12 @@
} else {
mCarrierTextCallback = null;
if (mKeyguardUpdateMonitor != null) {
- mKeyguardUpdateMonitor.removeCallback(mCallback);
+ // Keyguard update monitor expects callbacks from main thread
+ mMainHandler.post(() -> {
+ if (mKeyguardUpdateMonitor != null) {
+ mKeyguardUpdateMonitor.removeCallback(mCallback);
+ }
+ });
mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
}
telephonyManager.listen(mPhoneStateListener, LISTEN_NONE);
@@ -364,10 +378,9 @@
@VisibleForTesting
protected void postToCallback(CarrierTextCallbackInfo info) {
- Handler handler = Dependency.get(Dependency.MAIN_HANDLER);
final CarrierTextCallback callback = mCarrierTextCallback;
if (callback != null) {
- handler.post(() -> callback.updateCarrierInfo(info));
+ mMainHandler.post(() -> callback.updateCarrierInfo(info));
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 8d167e8..b9fe933 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -76,7 +76,7 @@
// How much you need to drag the bouncer to trigger an auth retry (in dps.)
private static final float MIN_DRAG_SIZE = 10;
// How much to scale the default slop by, to avoid accidental drags.
- private static final float SLOP_SCALE = 2f;
+ private static final float SLOP_SCALE = 4f;
private KeyguardSecurityModel mSecurityModel;
private LockPatternUtils mLockPatternUtils;
@@ -128,7 +128,7 @@
public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mSecurityModel = new KeyguardSecurityModel(context);
+ mSecurityModel = Dependency.get(KeyguardSecurityModel.class);
mLockPatternUtils = new LockPatternUtils(context);
mUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
index bb89959..1395fd9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -25,6 +25,10 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.Dependency;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
public class KeyguardSecurityModel {
/**
@@ -46,6 +50,7 @@
private LockPatternUtils mLockPatternUtils;
+ @Inject
KeyguardSecurityModel(Context context) {
mContext = context;
mLockPatternUtils = new LockPatternUtils(context);
@@ -57,7 +62,7 @@
mLockPatternUtils = utils;
}
- SecurityMode getSecurityMode(int userId) {
+ public SecurityMode getSecurityMode(int userId) {
KeyguardUpdateMonitor monitor = Dependency.get(KeyguardUpdateMonitor.class);
if (mIsPukScreenAvailable && SubscriptionManager.isValidSubscriptionId(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 63da533..5a1c997 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -22,7 +22,6 @@
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Handler;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -135,7 +134,7 @@
super(context, attrs, defStyle);
mIActivityManager = ActivityManager.getService();
mLockPatternUtils = new LockPatternUtils(getContext());
- mHandler = new Handler(Looper.myLooper());
+ mHandler = new Handler();
onDensityOrFontScaleChanged();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a6b3be2..dc8ee16 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -58,6 +58,7 @@
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
@@ -329,6 +330,7 @@
private SparseBooleanArray mUserIsUnlocked = new SparseBooleanArray();
private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
+ private SparseBooleanArray mUserTrustIsUsuallyManaged = new SparseBooleanArray();
private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
private SparseBooleanArray mUserFaceAuthenticated = new SparseBooleanArray();
private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
@@ -472,6 +474,7 @@
public void onTrustManagedChanged(boolean managed, int userId) {
checkIsHandlerThread();
mUserTrustIsManaged.put(userId, managed);
+ mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -925,6 +928,14 @@
return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
}
+ /**
+ * Cached version of {@link TrustManager#isTrustUsuallyManaged(int)}.
+ */
+ public boolean isTrustUsuallyManaged(int userId) {
+ checkIsHandlerThread();
+ return mUserTrustIsUsuallyManaged.get(userId);
+ }
+
public boolean isUnlockingWithBiometricAllowed() {
return mStrongAuthTracker.isUnlockingWithBiometricAllowed();
}
@@ -1474,9 +1485,11 @@
mUserIsUnlocked.put(userId, mUserManager.isUserUnlocked(userId));
}
- private void handleUserRemoved(int userId) {
+ @VisibleForTesting
+ void handleUserRemoved(int userId) {
checkIsHandlerThread();
mUserIsUnlocked.delete(userId);
+ mUserTrustIsUsuallyManaged.delete(userId);
}
@VisibleForTesting
@@ -1662,7 +1675,7 @@
e.rethrowAsRuntimeException();
}
- mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
+ mTrustManager = context.getSystemService(TrustManager.class);
mTrustManager.registerTrustListener(this);
mLockPatternUtils = new LockPatternUtils(context);
mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
@@ -1697,6 +1710,11 @@
mUserIsUnlocked.put(user, mUserManager.isUserUnlocked(user));
mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
+ List<UserInfo> allUsers = mUserManager.getUsers();
+ for (UserInfo userInfo : allUsers) {
+ mUserTrustIsUsuallyManaged.put(userInfo.id,
+ mTrustManager.isTrustUsuallyManaged(userInfo.id));
+ }
updateAirplaneModeState();
TelephonyManager telephony =
@@ -2048,6 +2066,7 @@
*/
private void handleUserSwitching(int userId, IRemoteCallback reply) {
checkIsHandlerThread();
+ mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 37bb54c..07bfa71 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -30,6 +30,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.Preconditions;
+import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.clock.ClockManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -316,6 +317,7 @@
@Inject Lazy<FalsingManager> mFalsingManager;
@Inject Lazy<SysUiState> mSysUiStateFlagsContainer;
@Inject Lazy<AlarmManager> mAlarmManager;
+ @Inject Lazy<KeyguardSecurityModel> mKeyguardSecurityModel;
@Inject
public Dependency() {
@@ -501,6 +503,7 @@
mProviders.put(FalsingManager.class, mFalsingManager::get);
mProviders.put(SysUiState.class, mSysUiStateFlagsContainer::get);
mProviders.put(AlarmManager.class, mAlarmManager::get);
+ mProviders.put(KeyguardSecurityModel.class, mKeyguardSecurityModel::get);
// TODO(b/118592525): to support multi-display , we start to add something which is
// per-display, while others may be global. I think it's time to add
diff --git a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java
index 818b5e1..f9f0f1b 100644
--- a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java
@@ -30,6 +30,7 @@
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
import com.android.systemui.statusbar.phone.ManagedProfileController;
import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
@@ -199,6 +200,12 @@
/**
*/
@Binds
+ public abstract SysuiStatusBarStateController providesSysuiStatusBarStateController(
+ StatusBarStateControllerImpl statusBarStateControllerImpl);
+
+ /**
+ */
+ @Binds
public abstract StatusBarIconController provideStatusBarIconController(
StatusBarIconControllerImpl controllerImpl);
diff --git a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
index 239cbfe..0d24321 100644
--- a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
@@ -40,6 +40,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.widget.LockPatternUtils;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.plugins.PluginInitializerImpl;
import com.android.systemui.shared.plugins.PluginManager;
@@ -238,4 +239,10 @@
public AlarmManager provideAlarmManager(Context context) {
return context.getSystemService(AlarmManager.class);
}
+
+ /** */
+ @Provides
+ public LockPatternUtils provideLockPatternUtils(Context context) {
+ return new LockPatternUtils(context);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java
index 0e079e3..5c561e5 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java
@@ -83,7 +83,9 @@
}
}
};
- mHandler.postDelayed(r, MIN_FGS_TIME_MS);
+ long delayAmt = MIN_FGS_TIME_MS
+ - (System.currentTimeMillis() - entry.notification.getPostTime());
+ mHandler.postDelayed(r, delayAmt);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemBars.java b/packages/SystemUI/src/com/android/systemui/SystemBars.java
deleted file mode 100644
index c4c0fd6..0000000
--- a/packages/SystemUI/src/com/android/systemui/SystemBars.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui;
-
-import android.util.Log;
-
-import com.android.systemui.statusbar.phone.StatusBar;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Ensure a single status bar service implementation is running at all times, using the in-process
- * implementation according to the product config.
- */
-public class SystemBars extends SystemUI {
- private static final String TAG = "SystemBars";
- private static final boolean DEBUG = false;
- private static final int WAIT_FOR_BARS_TO_DIE = 500;
-
- // in-process fallback implementation, per the product config
- private SystemUI mStatusBar;
-
- @Override
- public void start() {
- if (DEBUG) Log.d(TAG, "start");
- createStatusBarFromConfig();
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mStatusBar != null) {
- mStatusBar.dump(fd, pw, args);
- }
- }
-
- @Override
- public void onBootCompleted() {
- if (mStatusBar != null) {
- mStatusBar.onBootCompleted();
- }
- }
-
- private void createStatusBarFromConfig() {
- if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
- final String clsName = mContext.getString(R.string.config_statusBarComponent);
- if (clsName == null || clsName.length() == 0) {
- throw andLog("No status bar component configured", null);
- }
- Class<?> cls = null;
- try {
- cls = mContext.getClassLoader().loadClass(clsName);
- } catch (Throwable t) {
- throw andLog("Error loading status bar component: " + clsName, t);
- }
- try {
- mStatusBar = (SystemUI) cls.newInstance();
- } catch (Throwable t) {
- throw andLog("Error creating status bar component: " + clsName, t);
- }
- mStatusBar.mContext = mContext;
- mStatusBar.mComponents = mComponents;
- if (mStatusBar instanceof StatusBar) {
- SystemUIFactory.getInstance().getRootComponent()
- .getStatusBarInjector()
- .createStatusBar((StatusBar) mStatusBar);
- }
- mStatusBar.start();
- if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
- }
-
- private RuntimeException andLog(String msg, Throwable t) {
- Log.w(TAG, msg, t);
- throw new RuntimeException(msg, t);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java
index ba2dec0..785038f 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java
@@ -44,7 +44,7 @@
@ClassKey(PowerUI.class)
public abstract SystemUI bindPowerUI(PowerUI sysui);
- /** Inject into StatusBar. */
+ /** Inject into Recents. */
@Binds
@IntoMap
@ClassKey(Recents.class)
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
index 262b5ec..176bcbf 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
@@ -19,8 +19,6 @@
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
-import android.content.Context;
-
import androidx.annotation.Nullable;
import com.android.systemui.dock.DockManager;
@@ -40,6 +38,8 @@
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
/**
* A dagger module for injecting default implementations of components of System UI that may be
@@ -70,11 +70,13 @@
abstract NotificationData.KeyguardEnvironment bindKeyguardEnvironment(
KeyguardEnvironmentImpl keyguardEnvironment);
- @Singleton
- @Provides
- static ShadeController provideShadeController(Context context) {
- return SysUiServiceProvider.getComponent(context, StatusBar.class);
- }
+ @Binds
+ abstract ShadeController provideShadeController(StatusBar statusBar);
+
+ @Binds
+ @IntoMap
+ @ClassKey(StatusBar.class)
+ public abstract SystemUI providesStatusBar(StatusBar statusBar);
@Singleton
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/EdgeLight.java b/packages/SystemUI/src/com/android/systemui/assist/ui/EdgeLight.java
index 9ae02c5..baa3a4a 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/EdgeLight.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/EdgeLight.java
@@ -16,6 +16,8 @@
package com.android.systemui.assist.ui;
+import android.util.Log;
+
import androidx.annotation.ColorInt;
/**
@@ -29,9 +31,12 @@
* counter-clockwise.
*/
public final class EdgeLight {
+
+ private static final String TAG = "EdgeLight";
+
@ColorInt
private int mColor;
- private float mOffset;
+ private float mStart;
private float mLength;
/** Copies a list of EdgeLights. */
@@ -45,13 +50,13 @@
public EdgeLight(@ColorInt int color, float offset, float length) {
mColor = color;
- mOffset = offset;
+ mStart = offset;
mLength = length;
}
public EdgeLight(EdgeLight sourceLight) {
mColor = sourceLight.getColor();
- mOffset = sourceLight.getOffset();
+ mStart = sourceLight.getStart();
mLength = sourceLight.getLength();
}
@@ -77,23 +82,41 @@
}
/**
- * Returns the current offset, in units of the total device perimeter and measured from the
- * bottom-left corner (see class description).
+ * Sets the endpoints of the edge light, both measured from the bottom-left corner (see class
+ * description). This is a convenience method to avoid separate setStart and setLength calls.
*/
- public float getOffset() {
- return mOffset;
+ public void setEndpoints(float start, float end) {
+ if (start > end) {
+ Log.e(TAG, String.format("Endpoint must be >= start (add 1 if necessary). Got [%f, %f]",
+ start, end));
+ return;
+ }
+ mStart = start;
+ mLength = end - start;
+ }
+
+ /**
+ * Returns the current starting position, in units of the total device perimeter and measured
+ * from the bottom-left corner (see class description).
+ */
+ public float getStart() {
+ return mStart;
}
/**
* Sets the current offset, in units of the total device perimeter and measured from the
* bottom-left corner (see class description).
*/
- public void setOffset(float offset) {
- mOffset = offset;
+ public void setStart(float start) {
+ mStart = start;
+ }
+
+ public float getEnd() {
+ return mStart + mLength;
}
/** Returns the center, measured from the bottom-left corner (see class description). */
public float getCenter() {
- return mOffset + (mLength / 2.f);
+ return mStart + (mLength / 2.f);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
index bb3bd78..570b911 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
@@ -140,10 +140,10 @@
float rightStart = mGuide.getRegionWidth(PerimeterPathGuide.Region.BOTTOM)
+ (cornerLengthNormalized - arcOffsetNormalized) * (1 - progress);
- setLight(0, leftStart, lightLength);
- setLight(1, leftStart + lightLength, lightLength);
- setLight(2, rightStart - (lightLength * 2), lightLength);
- setLight(3, rightStart - lightLength, lightLength);
+ setLight(0, leftStart, leftStart + lightLength);
+ setLight(1, leftStart + lightLength, leftStart + lightLength * 2);
+ setLight(2, rightStart - (lightLength * 2), rightStart - lightLength);
+ setLight(3, rightStart - lightLength, rightStart);
setVisibility(View.VISIBLE);
}
invalidate();
@@ -155,7 +155,7 @@
public void hide() {
setVisibility(GONE);
for (EdgeLight light : mAssistInvocationLights) {
- light.setLength(0);
+ light.setEndpoints(0, 0);
}
attemptUnregisterNavBarListener();
}
@@ -235,12 +235,11 @@
}
}
- protected void setLight(int index, float offset, float length) {
+ protected void setLight(int index, float start, float end) {
if (index < 0 || index >= 4) {
Log.w(TAG, "invalid invocation light index: " + index);
}
- mAssistInvocationLights.get(index).setOffset(offset);
- mAssistInvocationLights.get(index).setLength(length);
+ mAssistInvocationLights.get(index).setEndpoints(start, end);
}
/**
@@ -268,9 +267,11 @@
}
private void renderLight(EdgeLight light, Canvas canvas) {
- mGuide.strokeSegment(mPath, light.getOffset(), light.getOffset() + light.getLength());
- mPaint.setColor(light.getColor());
- canvas.drawPath(mPath, mPaint);
+ if (light.getLength() > 0) {
+ mGuide.strokeSegment(mPath, light.getStart(), light.getStart() + light.getLength());
+ mPaint.setColor(light.getColor());
+ canvas.drawPath(mPath, mPaint);
+ }
}
private void attemptRegisterNavBarListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index 73bbce9..d20cd72 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -16,8 +16,6 @@
package com.android.systemui.biometrics;
-import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -25,6 +23,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.hardware.biometrics.BiometricPrompt;
import android.os.Bundle;
@@ -34,7 +33,7 @@
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
+import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
import android.widget.Button;
import android.widget.ImageView;
@@ -42,10 +41,13 @@
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.R;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
/**
* Contains the Biometric views (title, subtitle, icon, buttons, etc) and its controllers.
@@ -97,6 +99,7 @@
int ACTION_BUTTON_NEGATIVE = 3;
int ACTION_BUTTON_TRY_AGAIN = 4;
int ACTION_ERROR = 5;
+ int ACTION_USE_DEVICE_CREDENTIAL = 6;
/**
* When an action has occurred. The caller will only invoke this when the callback should
@@ -145,6 +148,14 @@
public int getDelayAfterError() {
return BiometricPrompt.HIDE_DIALOG_DELAY;
}
+
+ public int getMediumToLargeAnimationDurationMs() {
+ return AuthDialog.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS;
+ }
+
+ public int getAnimateCredentialStartDelayMs() {
+ return AuthDialog.ANIMATE_CREDENTIAL_START_DELAY_MS;
+ }
}
private final Injector mInjector;
@@ -154,8 +165,9 @@
private final int mTextColorHint;
private AuthPanelController mPanelController;
- private Bundle mBundle;
+ private Bundle mBiometricPromptBundle;
private boolean mRequireConfirmation;
+ private int mUserId;
@AuthDialog.DialogSize int mSize = AuthDialog.SIZE_UNKNOWN;
private TextView mTitleView;
@@ -212,6 +224,9 @@
} else if (mSize == AuthDialog.SIZE_SMALL) {
Log.w(TAG, "Ignoring background click during small dialog");
return;
+ } else if (mSize == AuthDialog.SIZE_LARGE) {
+ Log.w(TAG, "Ignoring background click during large dialog");
+ return;
}
mCallback.onAction(Callback.ACTION_USER_CANCELED);
};
@@ -256,7 +271,7 @@
}
public void setBiometricPromptBundle(Bundle bundle) {
- mBundle = bundle;
+ mBiometricPromptBundle = bundle;
}
public void setCallback(Callback callback) {
@@ -267,6 +282,10 @@
backgroundView.setOnClickListener(mBackgroundClickListener);
}
+ public void setUserId(int userId) {
+ mUserId = userId;
+ }
+
public void setRequireConfirmation(boolean requireConfirmation) {
mRequireConfirmation = requireConfirmation;
}
@@ -287,7 +306,7 @@
final int newHeight = mIconView.getHeight() + 2 * (int) iconPadding;
mPanelController.updateForContentDimensions(mMediumWidth, newHeight,
- false /* animate */);
+ 0 /* animateDurationMs */);
mSize = newSize;
} else if (mSize == AuthDialog.SIZE_SMALL && newSize == AuthDialog.SIZE_MEDIUM) {
@@ -305,10 +324,8 @@
// Animate the text
final ValueAnimator opacityAnimator = ValueAnimator.ofFloat(0, 1);
- opacityAnimator.setDuration(AuthDialog.ANIMATE_DURATION_MS);
opacityAnimator.addUpdateListener((animation) -> {
final float opacity = (float) animation.getAnimatedValue();
-
mTitleView.setAlpha(opacity);
mIndicatorView.setAlpha(opacity);
mNegativeButton.setAlpha(opacity);
@@ -324,7 +341,7 @@
// Choreograph together
final AnimatorSet as = new AnimatorSet();
- as.setDuration(AuthDialog.ANIMATE_DURATION_MS);
+ as.setDuration(AuthDialog.ANIMATE_SMALL_TO_MEDIUM_DURATION_MS);
as.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
@@ -355,11 +372,73 @@
as.start();
// Animate the panel
mPanelController.updateForContentDimensions(mMediumWidth, mMediumHeight,
- true /* animate */);
+ AuthDialog.ANIMATE_SMALL_TO_MEDIUM_DURATION_MS);
} else if (newSize == AuthDialog.SIZE_MEDIUM) {
mPanelController.updateForContentDimensions(mMediumWidth, mMediumHeight,
- false /* animate */);
+ 0 /* animateDurationMs */);
mSize = newSize;
+ } else if (newSize == AuthDialog.SIZE_LARGE) {
+ final boolean isManagedProfile = Utils.isManagedProfile(mContext, mUserId);
+
+ // If it's a managed profile, animate the contents and panel down, since the credential
+ // contents will be shown on the same "layer" as the background. If it's not a managed
+ // profile, animate the contents up and expand the panel to full-screen - the credential
+ // contents will be shown on the same "layer" as the panel.
+ final float translationY = isManagedProfile ?
+ -getResources().getDimension(
+ R.dimen.biometric_dialog_animation_translation_offset)
+ : getResources().getDimension(
+ R.dimen.biometric_dialog_medium_to_large_translation_offset);
+ final AuthBiometricView biometricView = this;
+
+ // Translate at full duration
+ final ValueAnimator translationAnimator = ValueAnimator.ofFloat(
+ biometricView.getY(), biometricView.getY() - translationY);
+ translationAnimator.setDuration(mInjector.getMediumToLargeAnimationDurationMs());
+ translationAnimator.addUpdateListener((animation) -> {
+ final float translation = (float) animation.getAnimatedValue();
+ biometricView.setTranslationY(translation);
+ });
+ translationAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ if (biometricView.getParent() != null) {
+ ((ViewGroup) biometricView.getParent()).removeView(biometricView);
+ }
+ mSize = newSize;
+ }
+ });
+
+ // Opacity to 0 in half duration
+ final ValueAnimator opacityAnimator = ValueAnimator.ofFloat(1, 0);
+ opacityAnimator.setDuration(mInjector.getMediumToLargeAnimationDurationMs() / 2);
+ opacityAnimator.addUpdateListener((animation) -> {
+ final float opacity = (float) animation.getAnimatedValue();
+ biometricView.setAlpha(opacity);
+ });
+
+ if (!isManagedProfile) {
+ mPanelController.setUseFullScreen(true);
+ mPanelController.updateForContentDimensions(
+ mPanelController.getContainerWidth(),
+ mPanelController.getContainerHeight(),
+ mInjector.getMediumToLargeAnimationDurationMs());
+ }
+
+ // Start the animations together
+ AnimatorSet as = new AnimatorSet();
+ List<Animator> animators = new ArrayList<>();
+ animators.add(translationAnimator);
+ animators.add(opacityAnimator);
+ if (isManagedProfile) {
+ animators.add(mPanelController.getTranslationAnimator(translationY));
+ animators.add(mPanelController.getAlphaAnimator(0));
+ }
+ as.playTogether(animators);
+ as.setDuration(isManagedProfile ? mInjector.getMediumToLargeAnimationDurationMs()
+ : mInjector.getMediumToLargeAnimationDurationMs() * 2 / 3);
+ as.start();
} else {
Log.e(TAG, "Unknown transition from: " + mSize + " to: " + newSize);
}
@@ -528,7 +607,11 @@
if (mState == STATE_PENDING_CONFIRMATION) {
mCallback.onAction(Callback.ACTION_USER_CANCELED);
} else {
- mCallback.onAction(Callback.ACTION_BUTTON_NEGATIVE);
+ if (isDeviceCredentialAllowed()) {
+ startTransitionToCredentialUI();
+ } else {
+ mCallback.onAction(Callback.ACTION_BUTTON_NEGATIVE);
+ }
}
});
@@ -544,6 +627,16 @@
});
}
+ /**
+ * Kicks off the animation process and invokes the callback.
+ */
+ void startTransitionToCredentialUI() {
+ updateSize(AuthDialog.SIZE_LARGE);
+ mHandler.postDelayed(() -> {
+ mCallback.onAction(Callback.ACTION_USE_DEVICE_CREDENTIAL);
+ }, mInjector.getAnimateCredentialStartDelayMs());
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -556,11 +649,37 @@
*/
@VisibleForTesting
void onAttachedToWindowInternal() {
- setText(mTitleView, mBundle.getString(BiometricPrompt.KEY_TITLE));
- setText(mNegativeButton, mBundle.getString(BiometricPrompt.KEY_NEGATIVE_TEXT));
+ setText(mTitleView, mBiometricPromptBundle.getString(BiometricPrompt.KEY_TITLE));
- setTextOrHide(mSubtitleView, mBundle.getString(BiometricPrompt.KEY_SUBTITLE));
- setTextOrHide(mDescriptionView, mBundle.getString(BiometricPrompt.KEY_DESCRIPTION));
+ final String negativeText;
+ if (isDeviceCredentialAllowed()) {
+
+ final @Utils.CredentialType int credentialType =
+ Utils.getCredentialType(mContext, mUserId);
+ switch(credentialType) {
+ case Utils.CREDENTIAL_PIN:
+ negativeText = getResources().getString(R.string.biometric_dialog_use_pin);
+ break;
+ case Utils.CREDENTIAL_PATTERN:
+ negativeText = getResources().getString(R.string.biometric_dialog_use_pattern);
+ break;
+ case Utils.CREDENTIAL_PASSWORD:
+ negativeText = getResources().getString(R.string.biometric_dialog_use_password);
+ break;
+ default:
+ negativeText = getResources().getString(R.string.biometric_dialog_use_password);
+ break;
+ }
+
+ } else {
+ negativeText = mBiometricPromptBundle.getString(BiometricPrompt.KEY_NEGATIVE_TEXT);
+ }
+ setText(mNegativeButton, negativeText);
+
+ setTextOrHide(mSubtitleView,
+ mBiometricPromptBundle.getString(BiometricPrompt.KEY_SUBTITLE));
+ setTextOrHide(mDescriptionView,
+ mBiometricPromptBundle.getString(BiometricPrompt.KEY_DESCRIPTION));
if (mSavedState == null) {
updateState(STATE_AUTHENTICATING_ANIMATING_IN);
@@ -655,4 +774,8 @@
}
}
}
+
+ private boolean isDeviceCredentialAllowed() {
+ return Utils.isDeviceCredentialAllowed(mBiometricPromptBundle);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 6555c75..a9359d4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -24,7 +24,9 @@
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
+import android.hardware.biometrics.Authenticator;
import android.hardware.biometrics.BiometricAuthenticator;
+import android.hardware.biometrics.BiometricPrompt;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -36,6 +38,7 @@
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Interpolator;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
@@ -72,17 +75,20 @@
@interface ContainerState {}
final Config mConfig;
+ private final Injector mInjector;
private final IBinder mWindowToken = new Binder();
private final WindowManager mWindowManager;
private final AuthPanelController mPanelController;
private final Interpolator mLinearOutSlowIn;
@VisibleForTesting final BiometricCallback mBiometricCallback;
+ private final CredentialCallback mCredentialCallback;
- private final ViewGroup mContainerView;
- private final AuthBiometricView mBiometricView;
+ @VisibleForTesting final FrameLayout mFrameLayout;
+ @VisibleForTesting @Nullable AuthBiometricView mBiometricView;
+ @VisibleForTesting @Nullable AuthCredentialView mCredentialView;
private final ImageView mBackgroundView;
- private final ScrollView mScrollView;
+ @VisibleForTesting final ScrollView mBiometricScrollView;
private final View mPanelView;
private final float mTranslationY;
@@ -145,7 +151,31 @@
public AuthContainerView build(int modalityMask) {
mConfig.mModalityMask = modalityMask;
- return new AuthContainerView(mConfig);
+ return new AuthContainerView(mConfig, new Injector());
+ }
+ }
+
+ public static class Injector {
+ ScrollView getBiometricScrollView(FrameLayout parent) {
+ return parent.findViewById(R.id.biometric_scrollview);
+ }
+
+ FrameLayout inflateContainerView(LayoutInflater factory, ViewGroup root) {
+ return (FrameLayout) factory.inflate(
+ R.layout.auth_container_view, root, false /* attachToRoot */);
+ }
+
+ AuthPanelController getPanelController(Context context, View panelView,
+ boolean isManagedProfile) {
+ return new AuthPanelController(context, panelView, isManagedProfile);
+ }
+
+ ImageView getBackgroundView(FrameLayout parent) {
+ return parent.findViewById(R.id.background);
+ }
+
+ View getPanelView(FrameLayout parent) {
+ return parent.findViewById(R.id.panel);
}
}
@@ -155,7 +185,7 @@
public void onAction(int action) {
switch (action) {
case AuthBiometricView.Callback.ACTION_AUTHENTICATED:
- animateAway(AuthDialogCallback.DISMISSED_AUTHENTICATED);
+ animateAway(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED);
break;
case AuthBiometricView.Callback.ACTION_USER_CANCELED:
animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
@@ -169,17 +199,30 @@
case AuthBiometricView.Callback.ACTION_ERROR:
animateAway(AuthDialogCallback.DISMISSED_ERROR);
break;
+ case AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL:
+ mConfig.mCallback.onDeviceCredentialPressed();
+ addCredentialView(false /* animatePanel */, true /* animateContents */);
+ break;
default:
Log.e(TAG, "Unhandled action: " + action);
}
}
}
+ final class CredentialCallback implements AuthCredentialView.Callback {
+ @Override
+ public void onCredentialMatched() {
+ animateAway(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED);
+ }
+ }
+
@VisibleForTesting
- AuthContainerView(Config config) {
+ AuthContainerView(Config config, Injector injector) {
super(config.mContext);
mConfig = config;
+ mInjector = injector;
+
mWindowManager = mContext.getSystemService(WindowManager.class);
mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
@@ -187,51 +230,48 @@
.getDimension(R.dimen.biometric_dialog_animation_translation_offset);
mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
mBiometricCallback = new BiometricCallback();
+ mCredentialCallback = new CredentialCallback();
final LayoutInflater factory = LayoutInflater.from(mContext);
- mContainerView = (ViewGroup) factory.inflate(
- R.layout.auth_container_view, this, false /* attachToRoot */);
+ mFrameLayout = mInjector.inflateContainerView(factory, this);
- mPanelView = mContainerView.findViewById(R.id.panel);
- mPanelController = new AuthPanelController(mContext, mPanelView);
+ final boolean isManagedProfile = Utils.isManagedProfile(mContext, mConfig.mUserId);
- // TODO: Update with new controllers if multi-modal authentication can occur simultaneously
- if (config.mModalityMask == BiometricAuthenticator.TYPE_FINGERPRINT) {
- mBiometricView = (AuthBiometricFingerprintView)
- factory.inflate(R.layout.auth_biometric_fingerprint_view, null, false);
- } else if (config.mModalityMask == BiometricAuthenticator.TYPE_FACE) {
- mBiometricView = (AuthBiometricFaceView)
- factory.inflate(R.layout.auth_biometric_face_view, null, false);
- } else {
- Log.e(TAG, "Unsupported modality mask: " + config.mModalityMask);
- mBiometricView = null;
- mBackgroundView = null;
- mScrollView = null;
- return;
+ mPanelView = mInjector.getPanelView(mFrameLayout);
+ mPanelController = mInjector.getPanelController(mContext, mPanelView, isManagedProfile);
+
+ // Inflate biometric view only if necessary.
+ if (Utils.isBiometricAllowed(mConfig.mBiometricPromptBundle)) {
+ if (config.mModalityMask == BiometricAuthenticator.TYPE_FINGERPRINT) {
+ mBiometricView = (AuthBiometricFingerprintView)
+ factory.inflate(R.layout.auth_biometric_fingerprint_view, null, false);
+ } else if (config.mModalityMask == BiometricAuthenticator.TYPE_FACE) {
+ mBiometricView = (AuthBiometricFaceView)
+ factory.inflate(R.layout.auth_biometric_face_view, null, false);
+ } else {
+ Log.e(TAG, "Unsupported biometric modality: " + config.mModalityMask);
+ mBiometricView = null;
+ mBackgroundView = null;
+ mBiometricScrollView = null;
+ return;
+ }
}
- mBackgroundView = mContainerView.findViewById(R.id.background);
+ mBiometricScrollView = mInjector.getBiometricScrollView(mFrameLayout);
+ mBackgroundView = mInjector.getBackgroundView(mFrameLayout);
- UserManager userManager = mContext.getSystemService(UserManager.class);
- DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
- if (userManager.isManagedProfile(mConfig.mUserId)) {
+
+ if (isManagedProfile) {
final Drawable image = getResources().getDrawable(R.drawable.work_challenge_background,
mContext.getTheme());
+ final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
image.setColorFilter(dpm.getOrganizationColorForUser(mConfig.mUserId),
PorterDuff.Mode.DARKEN);
mBackgroundView.setScaleType(ImageView.ScaleType.CENTER_CROP);
mBackgroundView.setImageDrawable(image);
}
- mBiometricView.setRequireConfirmation(mConfig.mRequireConfirmation);
- mBiometricView.setPanelController(mPanelController);
- mBiometricView.setBiometricPromptBundle(config.mBiometricPromptBundle);
- mBiometricView.setCallback(mBiometricCallback);
- mBiometricView.setBackgroundView(mBackgroundView);
-
- mScrollView = mContainerView.findViewById(R.id.scrollview);
- mScrollView.addView(mBiometricView);
- addView(mContainerView);
+ addView(mFrameLayout);
setOnKeyListener((v, keyCode, event) -> {
if (keyCode != KeyEvent.KEYCODE_BACK) {
@@ -248,6 +288,53 @@
}
@Override
+ public boolean isAllowDeviceCredentials() {
+ return Utils.isDeviceCredentialAllowed(mConfig.mBiometricPromptBundle);
+ }
+
+ private void addBiometricView() {
+ mBiometricView.setRequireConfirmation(mConfig.mRequireConfirmation);
+ mBiometricView.setPanelController(mPanelController);
+ mBiometricView.setBiometricPromptBundle(mConfig.mBiometricPromptBundle);
+ mBiometricView.setCallback(mBiometricCallback);
+ mBiometricView.setBackgroundView(mBackgroundView);
+ mBiometricView.setUserId(mConfig.mUserId);
+ mBiometricScrollView.addView(mBiometricView);
+ }
+
+ /**
+ * Adds the credential view. When going from biometric to credential view, the biometric
+ * view starts the panel expansion animation. If the credential view is being shown first,
+ * it should own the panel expansion.
+ * @param animatePanel if the credential view needs to own the panel expansion animation
+ */
+ private void addCredentialView(boolean animatePanel, boolean animateContents) {
+ final LayoutInflater factory = LayoutInflater.from(mContext);
+ final int credentialType = Utils.getCredentialType(mContext, mConfig.mUserId);
+ switch (credentialType) {
+ case Utils.CREDENTIAL_PATTERN:
+ mCredentialView = (AuthCredentialView) factory.inflate(
+ R.layout.auth_credential_pattern_view, null, false);
+ break;
+ case Utils.CREDENTIAL_PIN:
+ case Utils.CREDENTIAL_PASSWORD:
+ mCredentialView = (AuthCredentialView) factory.inflate(
+ R.layout.auth_credential_password_view, null, false);
+ break;
+ default:
+ throw new IllegalStateException("Unknown credential type: " + credentialType);
+ }
+
+ mCredentialView.setContainerView(this);
+ mCredentialView.setUser(mConfig.mUserId);
+ mCredentialView.setCallback(mCredentialCallback);
+ mCredentialView.setBiometricPromptBundle(mConfig.mBiometricPromptBundle);
+ mCredentialView.setPanelController(mPanelController, animatePanel);
+ mCredentialView.setShouldAnimateContents(animateContents);
+ mFrameLayout.addView(mCredentialView);
+ }
+
+ @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mPanelController.setContainerDimensions(getMeasuredWidth(), getMeasuredHeight());
@@ -256,8 +343,22 @@
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
+ onAttachedToWindowInternal();
+ }
+
+ @VisibleForTesting
+ void onAttachedToWindowInternal() {
mWakefulnessLifecycle.addObserver(this);
+ if (Utils.isBiometricAllowed(mConfig.mBiometricPromptBundle)) {
+ addBiometricView();
+ } else if (Utils.isDeviceCredentialAllowed(mConfig.mBiometricPromptBundle)) {
+ addCredentialView(true /* animatePanel */, false /* animateContents */);
+ } else {
+ throw new IllegalStateException("Unknown configuration: "
+ + Utils.getAuthenticators(mConfig.mBiometricPromptBundle));
+ }
+
if (mConfig.mSkipIntro) {
mContainerState = STATE_SHOWING;
} else {
@@ -265,7 +366,7 @@
// The background panel and content are different views since we need to be able to
// animate them separately in other places.
mPanelView.setY(mTranslationY);
- mScrollView.setY(mTranslationY);
+ mBiometricScrollView.setY(mTranslationY);
setAlpha(0f);
postOnAnimation(() -> {
@@ -276,12 +377,21 @@
.withLayer()
.withEndAction(this::onDialogAnimatedIn)
.start();
- mScrollView.animate()
+ mBiometricScrollView.animate()
.translationY(0)
.setDuration(ANIMATION_DURATION_SHOW_MS)
.setInterpolator(mLinearOutSlowIn)
.withLayer()
.start();
+ if (mCredentialView != null && mCredentialView.isAttachedToWindow()) {
+ mCredentialView.setY(mTranslationY);
+ mCredentialView.animate()
+ .translationY(0)
+ .setDuration(ANIMATION_DURATION_SHOW_MS)
+ .setInterpolator(mLinearOutSlowIn)
+ .withLayer()
+ .start();
+ }
animate()
.alpha(1f)
.setDuration(ANIMATION_DURATION_SHOW_MS)
@@ -305,7 +415,9 @@
@Override
public void show(WindowManager wm, @Nullable Bundle savedState) {
- mBiometricView.restoreState(savedState);
+ if (mBiometricView != null) {
+ mBiometricView.restoreState(savedState);
+ }
wm.addView(this, getLayoutParams(mWindowToken));
}
@@ -346,7 +458,15 @@
@Override
public void onSaveState(@NonNull Bundle outState) {
outState.putInt(AuthDialog.KEY_CONTAINER_STATE, mContainerState);
- mBiometricView.onSaveState(outState);
+ // In the case where biometric and credential are both allowed, we can assume that
+ // biometric isn't showing if credential is showing since biometric is shown first.
+ outState.putBoolean(AuthDialog.KEY_BIOMETRIC_SHOWING,
+ mBiometricView != null && mCredentialView == null);
+ outState.putBoolean(AuthDialog.KEY_CREDENTIAL_SHOWING, mCredentialView != null);
+
+ if (mBiometricView != null) {
+ mBiometricView.onSaveState(outState);
+ }
}
@Override
@@ -354,6 +474,11 @@
return mConfig.mOpPackageName;
}
+ @Override
+ public void animateToCredentialUI() {
+ mBiometricView.startTransitionToCredentialUI();
+ }
+
@VisibleForTesting
void animateAway(int reason) {
animateAway(true /* sendReason */, reason);
@@ -391,12 +516,20 @@
.withLayer()
.withEndAction(endActionRunnable)
.start();
- mScrollView.animate()
+ mBiometricScrollView.animate()
.translationY(mTranslationY)
.setDuration(ANIMATION_DURATION_AWAY_MS)
.setInterpolator(mLinearOutSlowIn)
.withLayer()
.start();
+ if (mCredentialView != null && mCredentialView.isAttachedToWindow()) {
+ mCredentialView.animate()
+ .translationY(mTranslationY)
+ .setDuration(ANIMATION_DURATION_AWAY_MS)
+ .setInterpolator(mLinearOutSlowIn)
+ .withLayer()
+ .start();
+ }
animate()
.alpha(0f)
.setDuration(ANIMATION_DURATION_AWAY_MS)
@@ -431,7 +564,9 @@
return;
}
mContainerState = STATE_SHOWING;
- mBiometricView.onDialogAnimatedIn();
+ if (mBiometricView != null) {
+ mBiometricView.onDialogAnimatedIn();
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index d10a3fe..4c2afb0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -23,6 +23,8 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
+import android.hardware.biometrics.Authenticator;
+import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
import android.os.Bundle;
@@ -105,6 +107,15 @@
}
@Override
+ public void onDeviceCredentialPressed() {
+ try {
+ mReceiver.onDeviceCredentialPressed();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException when handling credential button", e);
+ }
+ }
+
+ @Override
public void onDismissed(@DismissedReason int reason) {
switch (reason) {
case AuthDialogCallback.DISMISSED_USER_CANCELED:
@@ -116,11 +127,12 @@
break;
case AuthDialogCallback.DISMISSED_BUTTON_POSITIVE:
- sendResultAndCleanUp(BiometricPrompt.DISMISSED_REASON_CONFIRMED);
+ sendResultAndCleanUp(BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED);
break;
- case AuthDialogCallback.DISMISSED_AUTHENTICATED:
- sendResultAndCleanUp(BiometricPrompt.DISMISSED_REASON_CONFIRM_NOT_REQUIRED);
+ case AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED:
+ sendResultAndCleanUp(
+ BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED);
break;
case AuthDialogCallback.DISMISSED_ERROR:
@@ -131,6 +143,10 @@
sendResultAndCleanUp(BiometricPrompt.DISMISSED_REASON_SERVER_REQUESTED);
break;
+ case AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED:
+ sendResultAndCleanUp(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED);
+ break;
+
default:
Log.e(TAG, "Unhandled reason: " + reason);
break;
@@ -185,16 +201,19 @@
}
@Override
- public void showBiometricDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver,
- int type, boolean requireConfirmation, int userId, String opPackageName) {
+ public void showAuthenticationDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver,
+ int biometricModality, boolean requireConfirmation, int userId, String opPackageName) {
+ final int authenticators = Utils.getAuthenticators(bundle);
+
if (DEBUG) {
- Log.d(TAG, "showBiometricDialog, type: " + type
+ Log.d(TAG, "showAuthenticationDialog, authenticators: " + authenticators
+ + ", biometricModality: " + biometricModality
+ ", requireConfirmation: " + requireConfirmation);
}
SomeArgs args = SomeArgs.obtain();
args.arg1 = bundle;
args.arg2 = receiver;
- args.argi1 = type;
+ args.argi1 = biometricModality;
args.arg3 = requireConfirmation;
args.argi2 = userId;
args.arg4 = opPackageName;
@@ -204,6 +223,7 @@
Log.w(TAG, "mCurrentDialog: " + mCurrentDialog);
skipAnimation = true;
}
+
showDialog(args, skipAnimation, null /* savedState */);
}
@@ -227,14 +247,21 @@
}
@Override
- public void onBiometricError(String error) {
- if (DEBUG) Log.d(TAG, "onBiometricError: " + error);
- mCurrentDialog.onError(error);
+ public void onBiometricError(int errorCode, String error) {
+ if (DEBUG) Log.d(TAG, "onBiometricError: " + errorCode + ", " + error);
+
+ final boolean isLockout = errorCode == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT
+ || errorCode == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
+ if (mCurrentDialog.isAllowDeviceCredentials() && isLockout) {
+ mCurrentDialog.animateToCredentialUI();
+ } else {
+ mCurrentDialog.onError(error);
+ }
}
@Override
- public void hideBiometricDialog() {
- if (DEBUG) Log.d(TAG, "hideBiometricDialog");
+ public void hideAuthenticationDialog() {
+ if (DEBUG) Log.d(TAG, "hideAuthenticationDialog");
mCurrentDialog.dismissFromSystemServer();
}
@@ -262,7 +289,7 @@
}
if (DEBUG) {
- Log.d(TAG, "showDialog, "
+ Log.d(TAG, "showDialog: " + args
+ " savedState: " + savedState
+ " mCurrentDialog: " + mCurrentDialog
+ " newDialog: " + newDialog
@@ -306,6 +333,15 @@
// to send its pending callback immediately.
if (savedState.getInt(AuthDialog.KEY_CONTAINER_STATE)
!= AuthContainerView.STATE_ANIMATING_OUT) {
+ final boolean credentialShowing =
+ savedState.getBoolean(AuthDialog.KEY_CREDENTIAL_SHOWING);
+ if (credentialShowing) {
+ // TODO: Clean this up
+ Bundle bundle = (Bundle) mCurrentDialogArgs.arg1;
+ bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED,
+ Authenticator.TYPE_CREDENTIAL);
+ }
+
showDialog(mCurrentDialogArgs, true /* skipAnimation */, savedState);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
new file mode 100644
index 0000000..8df072e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2019 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.systemui.biometrics;
+
+import android.content.Context;
+import android.text.InputType;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.android.internal.widget.LockPatternChecker;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.R;
+
+/**
+ * Pin and Password UI
+ */
+public class AuthCredentialPasswordView extends AuthCredentialView
+ implements TextView.OnEditorActionListener {
+
+ private static final String TAG = "BiometricPrompt/AuthCredentialPasswordView";
+
+ private final InputMethodManager mImm;
+ private EditText mPasswordField;
+
+ public AuthCredentialPasswordView(Context context,
+ AttributeSet attrs) {
+ super(context, attrs);
+ mImm = mContext.getSystemService(InputMethodManager.class);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mPasswordField = findViewById(R.id.lockPassword);
+ mPasswordField.setOnEditorActionListener(this);
+ mPasswordField.setOnKeyListener((v, keyCode, event) -> {
+ if (keyCode != KeyEvent.KEYCODE_BACK) {
+ return false;
+ }
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ mContainerView.animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
+ }
+ return true;
+ });
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ if (mCredentialType == Utils.CREDENTIAL_PIN) {
+ mPasswordField.setInputType(
+ InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
+ }
+
+ // Wait a bit to focus the field so the focusable flag on the window is already set then.
+ post(() -> {
+ mPasswordField.requestFocus();
+ mImm.showSoftInput(mPasswordField, InputMethodManager.SHOW_IMPLICIT);
+ });
+ }
+
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ // Check if this was the result of hitting the enter key
+ final boolean isSoftImeEvent = event == null
+ && (actionId == EditorInfo.IME_NULL
+ || actionId == EditorInfo.IME_ACTION_DONE
+ || actionId == EditorInfo.IME_ACTION_NEXT);
+ final boolean isKeyboardEnterKey = event != null
+ && KeyEvent.isConfirmKey(event.getKeyCode())
+ && event.getAction() == KeyEvent.ACTION_DOWN;
+ if (isSoftImeEvent || isKeyboardEnterKey) {
+ checkPasswordAndUnlock();
+ return true;
+ }
+ return false;
+ }
+
+ private void checkPasswordAndUnlock() {
+ final byte[] password = LockPatternUtils.charSequenceToByteArray(mPasswordField.getText());
+ if (password == null || password.length == 0) {
+ return;
+ }
+
+ mPendingLockCheck = LockPatternChecker.checkPassword(mLockPatternUtils,
+ password, mUserId, this::onCredentialChecked);
+ }
+
+ @Override
+ protected void onCredentialChecked(boolean matched, int timeoutMs) {
+ super.onCredentialChecked(matched, timeoutMs);
+
+ if (matched) {
+ mImm.hideSoftInputFromWindow(getWindowToken(), 0 /* flags */);
+ } else {
+ mPasswordField.setText("");
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
new file mode 100644
index 0000000..6c36f82
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPatternView.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2019 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.systemui.biometrics;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.android.internal.widget.LockPatternChecker;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.LockPatternView;
+import com.android.systemui.R;
+
+import java.util.List;
+
+/**
+ * Pattern UI
+ */
+public class AuthCredentialPatternView extends AuthCredentialView {
+
+ private LockPatternView mLockPatternView;
+
+ private class UnlockPatternListener implements LockPatternView.OnPatternListener {
+
+ @Override
+ public void onPatternStart() {
+
+ }
+
+ @Override
+ public void onPatternCleared() {
+
+ }
+
+ @Override
+ public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {
+
+ }
+
+ @Override
+ public void onPatternDetected(List<LockPatternView.Cell> pattern) {
+ if (mPendingLockCheck != null) {
+ mPendingLockCheck.cancel(false);
+ }
+
+ mLockPatternView.setEnabled(false);
+
+ if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
+ // Pattern size is less than the minimum, do not count it as a failed attempt.
+ onPatternChecked(false /* matched */, 0 /* timeoutMs */);
+ return;
+ }
+
+ mPendingLockCheck = LockPatternChecker.checkPattern(
+ mLockPatternUtils,
+ pattern,
+ mUserId,
+ this::onPatternChecked);
+ }
+
+ private void onPatternChecked(boolean matched, int timeoutMs) {
+ AuthCredentialPatternView.this.onCredentialChecked(matched, timeoutMs);
+ if (timeoutMs > 0) {
+ mLockPatternView.setEnabled(false);
+ } else {
+ mLockPatternView.setEnabled(true);
+ }
+ }
+ }
+
+ @Override
+ protected void onErrorTimeoutFinish() {
+ super.onErrorTimeoutFinish();
+ mLockPatternView.setEnabled(true);
+ }
+
+ public AuthCredentialPatternView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mLockPatternView = findViewById(R.id.lockPattern);
+ mLockPatternView.setOnPatternListener(new UnlockPatternListener());
+ mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(mUserId));
+ mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
new file mode 100644
index 0000000..8c8611e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialView.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2019 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.systemui.biometrics;
+
+import android.content.Context;
+import android.hardware.biometrics.BiometricPrompt;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.CountDownTimer;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.Interpolators;
+import com.android.systemui.R;
+
+/**
+ * Abstract base class for Pin, Pattern, or Password authentication, for
+ * {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)}
+ */
+public abstract class AuthCredentialView extends LinearLayout {
+
+ private static final String TAG = "BiometricPrompt/AuthCredentialView";
+ private static final int ERROR_DURATION_MS = 3000;
+
+ private final AccessibilityManager mAccessibilityManager;
+
+ protected final Handler mHandler;
+
+ private Bundle mBiometricPromptBundle;
+ private AuthPanelController mPanelController;
+ private boolean mShouldAnimatePanel;
+ private boolean mShouldAnimateContents;
+
+ private TextView mTitleView;
+ private TextView mSubtitleView;
+ private TextView mDescriptionView;
+ protected TextView mErrorView;
+
+ protected @Utils.CredentialType int mCredentialType;
+ protected final LockPatternUtils mLockPatternUtils;
+ protected AuthContainerView mContainerView;
+ protected Callback mCallback;
+ protected AsyncTask<?, ?, ?> mPendingLockCheck;
+ protected int mUserId;
+ protected ErrorTimer mErrorTimer;
+
+ interface Callback {
+ void onCredentialMatched();
+ }
+
+ protected static class ErrorTimer extends CountDownTimer {
+ private final TextView mErrorView;
+ private final Context mContext;
+
+ /**
+ * @param millisInFuture The number of millis in the future from the call
+ * to {@link #start()} until the countdown is done and {@link
+ * #onFinish()}
+ * is called.
+ * @param countDownInterval The interval along the way to receive
+ * {@link #onTick(long)} callbacks.
+ */
+ public ErrorTimer(Context context, long millisInFuture, long countDownInterval,
+ TextView errorView) {
+ super(millisInFuture, countDownInterval);
+ mErrorView = errorView;
+ mContext = context;
+ }
+
+ @Override
+ public void onTick(long millisUntilFinished) {
+ final int secondsCountdown = (int) (millisUntilFinished / 1000);
+ mErrorView.setText(mContext.getString(
+ R.string.biometric_dialog_credential_too_many_attempts, secondsCountdown));
+ }
+
+ @Override
+ public void onFinish() {
+ mErrorView.setText("");
+ }
+ }
+
+ protected final Runnable mClearErrorRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mErrorView.setText("");
+ }
+ };
+
+ public AuthCredentialView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ mLockPatternUtils = new LockPatternUtils(mContext);
+ mHandler = new Handler(Looper.getMainLooper());
+ mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
+ }
+
+ protected void showError(String error) {
+ mHandler.removeCallbacks(mClearErrorRunnable);
+ mErrorView.setText(error);
+ mHandler.postDelayed(mClearErrorRunnable, ERROR_DURATION_MS);
+ }
+
+ private void setTextOrHide(TextView view, String string) {
+ if (TextUtils.isEmpty(string)) {
+ view.setVisibility(View.GONE);
+ } else {
+ view.setText(string);
+ }
+
+ Utils.notifyAccessibilityContentChanged(mAccessibilityManager, this);
+ }
+
+ private void setText(TextView view, String string) {
+ view.setText(string);
+ }
+
+ void setUser(int user) {
+ mUserId = user;
+ }
+
+ void setCallback(Callback callback) {
+ mCallback = callback;
+ }
+
+ void setBiometricPromptBundle(Bundle bundle) {
+ mBiometricPromptBundle = bundle;
+ }
+
+ void setPanelController(AuthPanelController panelController, boolean animatePanel) {
+ mPanelController = panelController;
+ mShouldAnimatePanel = animatePanel;
+ }
+
+ void setShouldAnimateContents(boolean animateContents) {
+ mShouldAnimateContents = animateContents;
+ }
+
+ void setContainerView(AuthContainerView containerView) {
+ mContainerView = containerView;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ mCredentialType = Utils.getCredentialType(mContext, mUserId);
+
+ setText(mTitleView, mBiometricPromptBundle.getString(BiometricPrompt.KEY_TITLE));
+ setTextOrHide(mSubtitleView,
+ mBiometricPromptBundle.getString(BiometricPrompt.KEY_SUBTITLE));
+ setTextOrHide(mDescriptionView,
+ mBiometricPromptBundle.getString(BiometricPrompt.KEY_DESCRIPTION));
+
+ // Only animate this if we're transitioning from a biometric view.
+ if (mShouldAnimateContents) {
+ setTranslationY(getResources()
+ .getDimension(R.dimen.biometric_dialog_credential_translation_offset));
+ setAlpha(0);
+
+ postOnAnimation(() -> {
+ animate().translationY(0)
+ .setDuration(AuthDialog.ANIMATE_CREDENTIAL_INITIAL_DURATION_MS)
+ .alpha(1.f)
+ .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
+ .withLayer()
+ .start();
+ });
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mErrorTimer != null) {
+ mErrorTimer.cancel();
+ }
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mTitleView = findViewById(R.id.title);
+ mSubtitleView = findViewById(R.id.subtitle);
+ mDescriptionView = findViewById(R.id.description);
+ mErrorView = findViewById(R.id.error);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+
+ if (mShouldAnimatePanel) {
+ // Credential view is always full screen.
+ mPanelController.setUseFullScreen(true);
+ mPanelController.updateForContentDimensions(mPanelController.getContainerWidth(),
+ mPanelController.getContainerHeight(), 0 /* animateDurationMs */);
+ mShouldAnimatePanel = false;
+ }
+ }
+
+ protected void onErrorTimeoutFinish() {}
+
+ protected void onCredentialChecked(boolean matched, int timeoutMs) {
+ if (matched) {
+ mClearErrorRunnable.run();
+ mCallback.onCredentialMatched();
+ } else {
+ if (timeoutMs > 0) {
+ mHandler.removeCallbacks(mClearErrorRunnable);
+ long deadline = mLockPatternUtils.setLockoutAttemptDeadline(mUserId, timeoutMs);
+ mErrorTimer = new ErrorTimer(mContext,
+ deadline - SystemClock.elapsedRealtime(),
+ LockPatternUtils.FAILED_ATTEMPT_COUNTDOWN_INTERVAL_MS,
+ mErrorView) {
+ @Override
+ public void onFinish() {
+ onErrorTimeoutFinish();
+ mClearErrorRunnable.run();
+ }
+ };
+ mErrorTimer.start();
+ } else {
+ final int error;
+ switch (mCredentialType) {
+ case Utils.CREDENTIAL_PIN:
+ error = R.string.biometric_dialog_wrong_pin;
+ break;
+ case Utils.CREDENTIAL_PATTERN:
+ error = R.string.biometric_dialog_wrong_pattern;
+ break;
+ case Utils.CREDENTIAL_PASSWORD:
+ error = R.string.biometric_dialog_wrong_password;
+ break;
+ default:
+ error = R.string.biometric_dialog_wrong_password;
+ break;
+ }
+ showError(getResources().getString(error));
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
index edb2953..ca95f9d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
@@ -31,6 +31,8 @@
public interface AuthDialog {
String KEY_CONTAINER_STATE = "container_state";
+ String KEY_BIOMETRIC_SHOWING = "biometric_showing";
+ String KEY_CREDENTIAL_SHOWING = "credential_showing";
String KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY = "try_agian_visibility";
String KEY_BIOMETRIC_STATE = "state";
@@ -40,17 +42,38 @@
String KEY_BIOMETRIC_DIALOG_SIZE = "size";
int SIZE_UNKNOWN = 0;
+ /**
+ * Minimal UI, showing only biometric icon.
+ */
int SIZE_SMALL = 1;
+ /**
+ * Normal-sized biometric UI, showing title, icon, buttons, etc.
+ */
int SIZE_MEDIUM = 2;
+ /**
+ * Full-screen credential UI.
+ */
int SIZE_LARGE = 3;
@Retention(RetentionPolicy.SOURCE)
@IntDef({SIZE_UNKNOWN, SIZE_SMALL, SIZE_MEDIUM, SIZE_LARGE})
@interface DialogSize {}
/**
- * Animation duration, e.g. small to medium dialog, icon translation, etc.
+ * Animation duration, from small to medium dialog, including back panel, icon translation, etc
*/
- int ANIMATE_DURATION_MS = 150;
+ int ANIMATE_SMALL_TO_MEDIUM_DURATION_MS = 150;
+ /**
+ * Animation duration from medium to large dialog, including biometric fade out, back panel, etc
+ */
+ int ANIMATE_MEDIUM_TO_LARGE_DURATION_MS = 450;
+ /**
+ * Delay before notifying {@link AuthCredentialView} to start animating in.
+ */
+ int ANIMATE_CREDENTIAL_START_DELAY_MS = ANIMATE_MEDIUM_TO_LARGE_DURATION_MS * 2 / 3;
+ /**
+ * Animation duration when sliding in credential UI
+ */
+ int ANIMATE_CREDENTIAL_INITIAL_DURATION_MS = 150;
/**
* Show the dialog.
@@ -101,4 +124,14 @@
* Get the client's package name
*/
String getOpPackageName();
+
+ /**
+ * Animate to credential UI. Typically called after biometric is locked out.
+ */
+ void animateToCredentialUI();
+
+ /**
+ * @return true if device credential is allowed.
+ */
+ boolean isAllowDeviceCredentials();
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
index 70752f5..12bb122 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
@@ -27,17 +27,18 @@
int DISMISSED_USER_CANCELED = 1;
int DISMISSED_BUTTON_NEGATIVE = 2;
int DISMISSED_BUTTON_POSITIVE = 3;
-
- int DISMISSED_AUTHENTICATED = 4;
+ int DISMISSED_BIOMETRIC_AUTHENTICATED = 4;
int DISMISSED_ERROR = 5;
int DISMISSED_BY_SYSTEM_SERVER = 6;
+ int DISMISSED_CREDENTIAL_AUTHENTICATED = 7;
@IntDef({DISMISSED_USER_CANCELED,
DISMISSED_BUTTON_NEGATIVE,
DISMISSED_BUTTON_POSITIVE,
- DISMISSED_AUTHENTICATED,
+ DISMISSED_BIOMETRIC_AUTHENTICATED,
DISMISSED_ERROR,
- DISMISSED_BY_SYSTEM_SERVER})
+ DISMISSED_BY_SYSTEM_SERVER,
+ DISMISSED_CREDENTIAL_AUTHENTICATED})
@interface DismissedReason {}
/**
@@ -50,4 +51,9 @@
* Invoked when the "try again" button is clicked
*/
void onTryAgainPressed();
+
+ /**
+ * Invoked when the "use password" button is clicked
+ */
+ void onDeviceCredentialPressed();
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
index 55ba049..2b8b586 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthPanelController.java
@@ -16,15 +16,17 @@
package com.android.systemui.biometrics;
+import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.graphics.Color;
import android.graphics.Outline;
import android.util.Log;
import android.view.View;
import android.view.ViewOutlineProvider;
+import android.view.animation.AccelerateDecelerateInterpolator;
import com.android.systemui.R;
-import com.android.systemui.biometrics.AuthDialog;
/**
* Controls the back panel and its animations for the BiometricPrompt UI.
@@ -36,8 +38,9 @@
private final Context mContext;
private final View mPanelView;
- private final float mCornerRadius;
- private final int mBiometricMargin;
+ private final boolean mIsManagedProfile;
+
+ private boolean mUseFullScreen;
private int mContainerWidth;
private int mContainerHeight;
@@ -45,14 +48,23 @@
private int mContentWidth;
private int mContentHeight;
+ private float mCornerRadius;
+ private int mMargin;
+
@Override
public void getOutline(View view, Outline outline) {
final int left = (mContainerWidth - mContentWidth) / 2;
final int right = mContainerWidth - left;
+
+ // If the content fits within the container, shrink the height to wrap the content.
+ // Otherwise, set the outline to be the display size minus the margin - the content within
+ // is scrollable.
final int top = mContentHeight < mContainerHeight
- ? mContainerHeight - mContentHeight - mBiometricMargin
- : mBiometricMargin;
- final int bottom = mContainerHeight - mBiometricMargin;
+ ? mContainerHeight - mContentHeight - mMargin
+ : mMargin;
+
+ // TODO(b/139954942) Likely don't need to "+1" after we resolve the navbar styling.
+ final int bottom = mContainerHeight - mMargin + 1;
outline.setRoundRect(left, top, right, bottom, mCornerRadius);
}
@@ -64,11 +76,34 @@
mContainerHeight = containerHeight;
}
- public void updateForContentDimensions(int contentWidth, int contentHeight, boolean animate) {
+ public void setUseFullScreen(boolean fullScreen) {
+ mUseFullScreen = fullScreen;
+ }
+
+ public ValueAnimator getTranslationAnimator(float relativeTranslationY) {
+ final ValueAnimator animator = ValueAnimator.ofFloat(
+ mPanelView.getY(), mPanelView.getY() - relativeTranslationY);
+ animator.addUpdateListener(animation -> {
+ final float translation = (float) animation.getAnimatedValue();
+ mPanelView.setTranslationY(translation);
+ });
+ return animator;
+ }
+
+ public ValueAnimator getAlphaAnimator(float alpha) {
+ final ValueAnimator animator = ValueAnimator.ofFloat(mPanelView.getAlpha(), alpha);
+ animator.addUpdateListener(animation -> {
+ mPanelView.setAlpha((float) animation.getAnimatedValue());
+ });
+ return animator;
+ }
+
+ public void updateForContentDimensions(int contentWidth, int contentHeight,
+ int animateDurationMs) {
if (DEBUG) {
Log.v(TAG, "Content Width: " + contentWidth
+ " Height: " + contentHeight
- + " Animate: " + animate);
+ + " Animate: " + animateDurationMs);
}
if (mContainerWidth == 0 || mContainerHeight == 0) {
@@ -76,27 +111,86 @@
return;
}
- if (animate) {
+ final int margin = mUseFullScreen ? 0 : (int) mContext.getResources()
+ .getDimension(R.dimen.biometric_dialog_border_padding);
+ final float cornerRadius = mUseFullScreen ? 0 : mContext.getResources()
+ .getDimension(R.dimen.biometric_dialog_corner_size);
+
+ // When going to full-screen for managed profiles, fade away so the managed profile
+ // background behind this view becomes visible.
+ final boolean shouldFadeAway = mUseFullScreen && mIsManagedProfile;
+ final int alpha = shouldFadeAway ? 0 : 255;
+ final float elevation = shouldFadeAway ? 0 :
+ mContext.getResources().getDimension(R.dimen.biometric_dialog_elevation);
+
+ if (animateDurationMs > 0) {
+ // Animate margin
+ ValueAnimator marginAnimator = ValueAnimator.ofInt(mMargin, margin);
+ marginAnimator.addUpdateListener((animation) -> {
+ mMargin = (int) animation.getAnimatedValue();
+ });
+
+ // Animate corners
+ ValueAnimator cornerAnimator = ValueAnimator.ofFloat(mCornerRadius, cornerRadius);
+ cornerAnimator.addUpdateListener((animation) -> {
+ mCornerRadius = (float) animation.getAnimatedValue();
+ });
+
+ // Animate height
ValueAnimator heightAnimator = ValueAnimator.ofInt(mContentHeight, contentHeight);
- heightAnimator.setDuration(AuthDialog.ANIMATE_DURATION_MS);
heightAnimator.addUpdateListener((animation) -> {
mContentHeight = (int) animation.getAnimatedValue();
mPanelView.invalidateOutline();
});
heightAnimator.start();
+
+ // Animate width
+ ValueAnimator widthAnimator = ValueAnimator.ofInt(mContentWidth, contentWidth);
+ widthAnimator.addUpdateListener((animation) -> {
+ mContentWidth = (int) animation.getAnimatedValue();
+ });
+
+ // Animate background
+ ValueAnimator alphaAnimator = ValueAnimator.ofInt(
+ mPanelView.getBackground().getAlpha(), alpha);
+ alphaAnimator.addUpdateListener((animation) -> {
+ if (shouldFadeAway) {
+ mPanelView.getBackground().setAlpha((int) animation.getAnimatedValue());
+ }
+ });
+
+ // Play together
+ AnimatorSet as = new AnimatorSet();
+ as.setDuration(animateDurationMs);
+ as.setInterpolator(new AccelerateDecelerateInterpolator());
+ as.playTogether(cornerAnimator, widthAnimator, marginAnimator, alphaAnimator);
+ as.start();
+
} else {
+ mMargin = margin;
+ mCornerRadius = cornerRadius;
mContentWidth = contentWidth;
mContentHeight = contentHeight;
+ mPanelView.getBackground().setAlpha(alpha);
mPanelView.invalidateOutline();
}
}
- AuthPanelController(Context context, View panelView) {
+ int getContainerWidth() {
+ return mContainerWidth;
+ }
+
+ int getContainerHeight() {
+ return mContainerHeight;
+ }
+
+ AuthPanelController(Context context, View panelView, boolean isManagedProfile) {
mContext = context;
mPanelView = panelView;
+ mIsManagedProfile = isManagedProfile;
mCornerRadius = context.getResources()
.getDimension(R.dimen.biometric_dialog_corner_size);
- mBiometricMargin = (int) context.getResources()
+ mMargin = (int) context.getResources()
.getDimension(R.dimen.biometric_dialog_border_padding);
mPanelView.setOutlineProvider(this);
mPanelView.setClipToOutline(true);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
index e00cf6a..d6f830d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
@@ -18,14 +18,36 @@
import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
+import android.annotation.IntDef;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.hardware.biometrics.Authenticator;
+import android.hardware.biometrics.BiometricPrompt;
+import android.os.Bundle;
+import android.os.UserManager;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.R;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
public class Utils {
+
+ public static final int CREDENTIAL_PIN = 1;
+ public static final int CREDENTIAL_PATTERN = 2;
+ public static final int CREDENTIAL_PASSWORD = 3;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD})
+ @interface CredentialType {}
+
+
static float dpToPixels(Context context, float dp) {
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi
/ DisplayMetrics.DENSITY_DEFAULT);
@@ -46,4 +68,41 @@
view.sendAccessibilityEventUnchecked(event);
view.notifySubtreeAccessibilityStateChanged(view, view, CONTENT_CHANGE_TYPE_SUBTREE);
}
+
+ static boolean isDeviceCredentialAllowed(Bundle biometricPromptBundle) {
+ final int authenticators = getAuthenticators(biometricPromptBundle);
+ return (authenticators & Authenticator.TYPE_CREDENTIAL) != 0;
+ }
+
+ static boolean isBiometricAllowed(Bundle biometricPromptBundle) {
+ final int authenticators = getAuthenticators(biometricPromptBundle);
+ return (authenticators & Authenticator.TYPE_BIOMETRIC) != 0;
+ }
+
+ static int getAuthenticators(Bundle biometricPromptBundle) {
+ return biometricPromptBundle.getInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED);
+ }
+
+ static @CredentialType int getCredentialType(Context context, int userId) {
+ final LockPatternUtils lpu = new LockPatternUtils(context);
+ switch (lpu.getKeyguardStoredPasswordQuality(userId)) {
+ case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
+ return CREDENTIAL_PATTERN;
+ case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
+ return CREDENTIAL_PIN;
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+ case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
+ return CREDENTIAL_PASSWORD;
+ default:
+ return CREDENTIAL_PASSWORD;
+ }
+ }
+
+ static boolean isManagedProfile(Context context, int userId) {
+ final UserManager userManager = context.getSystemService(UserManager.class);
+ return userManager.isManagedProfile(userId);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java
index cb7c998..8105c6a 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java
@@ -37,7 +37,7 @@
* adb shell setprop debug.falsing_log true
*
* The log gets dumped as part of the SystemUI services. To dump on demand:
- * adb shell dumpsys activity service com.android.systemui SystemBars | grep -A 999 FALSING | less
+ * adb shell dumpsys activity service com.android.systemui StatusBar | grep -A 999 FALSING | less
*
* To dump into logcat:
* adb shell setprop debug.falsing_logcat true
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d2a9c75..a8027c0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -100,6 +100,7 @@
import java.util.ArrayList;
import javax.inject.Inject;
+import javax.inject.Singleton;
/**
* Mediates requests related to the keyguard. This includes queries about the
@@ -142,6 +143,7 @@
* directly to the keyguard UI is posted to a {@link android.os.Handler} to ensure it is taken on the UI
* thread of the keyguard.
*/
+@Singleton
public class KeyguardViewMediator extends SystemUI {
private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
private static final long KEYGUARD_DONE_PENDING_TIMEOUT_MS = 3000;
@@ -232,7 +234,7 @@
*/
private PowerManager.WakeLock mShowKeyguardWakeLock;
- private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
// these are protected by synchronized (this)
@@ -315,7 +317,7 @@
* the keyguard.
*/
private boolean mWaitingUntilKeyguardVisible = false;
- private LockPatternUtils mLockPatternUtils;
+ private final LockPatternUtils mLockPatternUtils;
private boolean mKeyguardDonePending = false;
private boolean mHideAnimationRun = false;
private boolean mHideAnimationRunning = false;
@@ -648,29 +650,26 @@
@Override
public int getBouncerPromptReason() {
- // TODO(b/140053364)
- return whitelistIpcs(() -> {
- int currentUser = ActivityManager.getCurrentUser();
- boolean trust = mTrustManager.isTrustUsuallyManaged(currentUser);
- boolean biometrics = mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser);
- boolean any = trust || biometrics;
- KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
- mUpdateMonitor.getStrongAuthTracker();
- int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser);
+ int currentUser = KeyguardUpdateMonitor.getCurrentUser();
+ boolean trust = mUpdateMonitor.isTrustUsuallyManaged(currentUser);
+ boolean biometrics = mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser);
+ boolean any = trust || biometrics;
+ KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
+ mUpdateMonitor.getStrongAuthTracker();
+ int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser);
- if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
- return KeyguardSecurityView.PROMPT_REASON_RESTART;
- } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
- } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
- } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
- } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
- }
- return KeyguardSecurityView.PROMPT_REASON_NONE;
- });
+ if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
+ return KeyguardSecurityView.PROMPT_REASON_RESTART;
+ } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
+ } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
+ } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
+ } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
+ }
+ return KeyguardSecurityView.PROMPT_REASON_NONE;
}
@Override
@@ -682,10 +681,21 @@
};
@Inject
- public KeyguardViewMediator(FalsingManager falsingManager) {
+ public KeyguardViewMediator(
+ Context context,
+ FalsingManager falsingManager,
+ LockPatternUtils lockPatternUtils) {
super();
+ mContext = context;
mFalsingManager = falsingManager;
+
+ mLockPatternUtils = lockPatternUtils;
+ mStatusBarKeyguardViewManager =
+ SystemUIFactory.getInstance().createStatusBarKeyguardViewManager(
+ mContext,
+ mViewMediatorCallback,
+ mLockPatternUtils);
}
public void userActivity() {
@@ -699,7 +709,7 @@
private void setupLocked() {
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+ mTrustManager = mContext.getSystemService(TrustManager.class);
mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
mShowKeyguardWakeLock.setReferenceCounted(false);
@@ -723,7 +733,6 @@
mUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
- mLockPatternUtils = new LockPatternUtils(mContext);
KeyguardUpdateMonitor.setCurrentUser(ActivityManager.getCurrentUser());
// Assume keyguard is showing (unless it's disabled) until we know for sure, unless Keyguard
@@ -737,9 +746,6 @@
setShowingLocked(false /* showing */, true /* forceCallbacks */);
}
- mStatusBarKeyguardViewManager =
- SystemUIFactory.getInstance().createStatusBarKeyguardViewManager(mContext,
- mViewMediatorCallback, mLockPatternUtils);
final ContentResolver cr = mContext.getContentResolver();
mDeviceInteractive = mPM.isInteractive();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index 2755e98..dafdd89 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -101,11 +101,15 @@
state.slash = new SlashState();
}
state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
+ state.secondaryLabel = "";
if (!mFlashlightController.isAvailable()) {
state.icon = mIcon;
state.slash.isSlashed = true;
+ state.secondaryLabel = mContext.getString(
+ R.string.quick_settings_flashlight_camera_in_use);
state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_flashlight_unavailable);
+ R.string.accessibility_quick_settings_flashlight_unavailable)
+ + ", " + state.secondaryLabel;
state.state = Tile.STATE_UNAVAILABLE;
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 134d4b8..36e04fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -270,12 +270,13 @@
default void onRotationProposal(int rotation, boolean isValid) { }
- default void showBiometricDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver,
- int type, boolean requireConfirmation, int userId, String opPackageName) { }
+ default void showAuthenticationDialog(Bundle bundle,
+ IBiometricServiceReceiverInternal receiver, int biometricModality,
+ boolean requireConfirmation, int userId, String opPackageName) { }
default void onBiometricAuthenticated(boolean authenticated, String failureReason) { }
default void onBiometricHelp(String message) { }
- default void onBiometricError(String error) { }
- default void hideBiometricDialog() { }
+ default void onBiometricError(int errorCode, String error) { }
+ default void hideAuthenticationDialog() { }
/**
* @see IStatusBar#onDisplayReady(int)
@@ -740,13 +741,13 @@
}
@Override
- public void showBiometricDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver,
- int type, boolean requireConfirmation, int userId, String opPackageName) {
+ public void showAuthenticationDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver,
+ int biometricModality, boolean requireConfirmation, int userId, String opPackageName) {
synchronized (mLock) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = bundle;
args.arg2 = receiver;
- args.argi1 = type;
+ args.argi1 = biometricModality;
args.arg3 = requireConfirmation;
args.argi2 = userId;
args.arg4 = opPackageName;
@@ -773,14 +774,14 @@
}
@Override
- public void onBiometricError(String error) {
+ public void onBiometricError(int errorCode, String error) {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, error).sendToTarget();
+ mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, errorCode, 0, error).sendToTarget();
}
}
@Override
- public void hideBiometricDialog() {
+ public void hideAuthenticationDialog() {
synchronized (mLock) {
mHandler.obtainMessage(MSG_BIOMETRIC_HIDE).sendToTarget();
}
@@ -1032,10 +1033,10 @@
mHandler.removeMessages(MSG_BIOMETRIC_AUTHENTICATED);
SomeArgs someArgs = (SomeArgs) msg.obj;
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).showBiometricDialog(
+ mCallbacks.get(i).showAuthenticationDialog(
(Bundle) someArgs.arg1,
(IBiometricServiceReceiverInternal) someArgs.arg2,
- someArgs.argi1 /* type */,
+ someArgs.argi1 /* biometricModality */,
(boolean) someArgs.arg3 /* requireConfirmation */,
someArgs.argi2 /* userId */,
(String) someArgs.arg4 /* opPackageName */);
@@ -1060,12 +1061,12 @@
break;
case MSG_BIOMETRIC_ERROR:
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onBiometricError((String) msg.obj);
+ mCallbacks.get(i).onBiometricError(msg.arg1, (String) msg.obj);
}
break;
case MSG_BIOMETRIC_HIDE:
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).hideBiometricDialog();
+ mCallbacks.get(i).hideAuthenticationDialog();
}
break;
case MSG_SHOW_CHARGING_ANIMATION:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
index 09f8045..16cdfaa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
@@ -237,6 +237,7 @@
/** @return {@link AssistHandleViewController} (only on the default display). */
public AssistHandleViewController getAssistHandlerViewController() {
- return getDefaultNavigationBarFragment().getAssistHandlerViewController();
+ NavigationBarFragment navBar = getDefaultNavigationBarFragment();
+ return navBar == null ? null : navBar.getAssistHandlerViewController();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index 13c6f27..9b31234 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -38,7 +38,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.NotificationPanelView;
-import com.android.systemui.statusbar.phone.StatusBarWindowView;
+import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
/**
* A class that allows activities to be launched in a seamless way where the notification
@@ -55,8 +55,8 @@
private static final long LAUNCH_TIMEOUT = 500;
private final NotificationPanelView mNotificationPanel;
private final NotificationListContainer mNotificationContainer;
- private final StatusBarWindowView mStatusBarWindow;
private final float mWindowCornerRadius;
+ private final StatusBarWindowViewController mStatusBarWindowViewController;
private Callback mCallback;
private final Runnable mTimeoutRunnable = () -> {
setAnimationPending(false);
@@ -66,16 +66,17 @@
private boolean mAnimationRunning;
private boolean mIsLaunchForActivity;
- public ActivityLaunchAnimator(StatusBarWindowView statusBarWindow,
+ public ActivityLaunchAnimator(
+ StatusBarWindowViewController statusBarWindowViewController,
Callback callback,
NotificationPanelView notificationPanel,
NotificationListContainer container) {
mNotificationPanel = notificationPanel;
mNotificationContainer = container;
- mStatusBarWindow = statusBarWindow;
+ mStatusBarWindowViewController = statusBarWindowViewController;
mCallback = callback;
mWindowCornerRadius = ScreenDecorationsUtils
- .getWindowCornerRadius(statusBarWindow.getResources());
+ .getWindowCornerRadius(mStatusBarWindowViewController.getView().getResources());
}
public RemoteAnimationAdapter getLaunchAnimation(
@@ -112,11 +113,11 @@
private void setAnimationPending(boolean pending) {
mAnimationPending = pending;
- mStatusBarWindow.setExpandAnimationPending(pending);
+ mStatusBarWindowViewController.setExpandAnimationPending(pending);
if (pending) {
- mStatusBarWindow.postDelayed(mTimeoutRunnable, LAUNCH_TIMEOUT);
+ mStatusBarWindowViewController.getView().postDelayed(mTimeoutRunnable, LAUNCH_TIMEOUT);
} else {
- mStatusBarWindow.removeCallbacks(mTimeoutRunnable);
+ mStatusBarWindowViewController.getView().removeCallbacks(mTimeoutRunnable);
}
}
@@ -246,7 +247,7 @@
private void setExpandAnimationRunning(boolean running) {
mNotificationPanel.setLaunchingNotification(running);
mSourceNotification.setExpandAnimationRunning(running);
- mStatusBarWindow.setExpandAnimationRunning(running);
+ mStatusBarWindowViewController.setExpandAnimationRunning(running);
mNotificationContainer.setExpandingNotification(running ? mSourceNotification : null);
mAnimationRunning = running;
if (!running) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 90301c5..148a1a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -20,7 +20,6 @@
import android.annotation.Nullable;
import android.app.Notification;
-import android.content.Context;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
@@ -124,8 +123,8 @@
}
@Inject
- public NotificationEntryManager(Context context) {
- mNotificationData = new NotificationData(context);
+ public NotificationEntryManager(NotificationData notificationData) {
+ mNotificationData = notificationData;
}
/** Adds a {@link NotificationEntryListener}. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
new file mode 100644
index 0000000..480cb78
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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.systemui.statusbar.notification
+
+import android.content.Context
+import android.provider.DeviceConfig
+
+import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
+import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
+import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE
+import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
+import com.android.systemui.util.DeviceConfigProxy
+
+import javax.inject.Inject
+
+private var sUsePeopleFiltering: Boolean? = null
+
+/**
+ * Feature controller for the NOTIFICATIONS_USE_PEOPLE_FILTERING config.
+ */
+class NotificationSectionsFeatureManager @Inject constructor(
+ val proxy: DeviceConfigProxy,
+ val context: Context
+) {
+
+ fun isFilteringEnabled(): Boolean {
+ return usePeopleFiltering(proxy)
+ }
+
+ fun getNotificationBuckets(): IntArray {
+ return when {
+ isFilteringEnabled() ->
+ intArrayOf(BUCKET_PEOPLE, BUCKET_ALERTING, BUCKET_SILENT)
+ NotificationUtils.useNewInterruptionModel(context) ->
+ intArrayOf(BUCKET_ALERTING, BUCKET_SILENT)
+ else ->
+ intArrayOf(BUCKET_ALERTING)
+ }
+ }
+
+ fun getNumberOfBuckets(): Int {
+ return getNotificationBuckets().size
+ }
+
+ @VisibleForTesting
+ fun clearCache() {
+ sUsePeopleFiltering = null
+ }
+}
+
+private fun usePeopleFiltering(proxy: DeviceConfigProxy): Boolean {
+ if (sUsePeopleFiltering == null) {
+ sUsePeopleFiltering = proxy.getBoolean(
+ DeviceConfig.NAMESPACE_SYSTEMUI, NOTIFICATIONS_USE_PEOPLE_FILTERING, false)
+ }
+
+ return sUsePeopleFiltering!!
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
index dfbbf98..1af47dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
@@ -36,7 +36,6 @@
private static final int[] sLocationOffset = new int[2];
@Nullable private static Boolean sUseNewInterruptionModel = null;
- @Nullable private static Boolean sUsePeopleFiltering = null;
public static boolean isGrayscale(ImageView v, ContrastColorUtil colorUtil) {
Object isGrayscale = v.getTag(R.id.icon_is_grayscale);
@@ -88,17 +87,4 @@
}
return sUseNewInterruptionModel;
}
-
- /**
- * Caches and returns the value of the people filtering setting. Cannot change except through
- * process restarts.
- */
- public static boolean usePeopleFiltering(Context context) {
- if (sUsePeopleFiltering == null) {
- sUsePeopleFiltering = context.getResources().getBoolean(
- R.bool.config_usePeopleFiltering);
- }
-
- return sUsePeopleFiltering;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
index aacb2dd..cf0fbbb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
@@ -24,7 +24,6 @@
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Person;
-import android.content.Context;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.SnoozeCriterion;
@@ -35,7 +34,7 @@
import com.android.systemui.Dependency;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.notification.NotificationFilter;
-import com.android.systemui.statusbar.notification.NotificationUtils;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -46,6 +45,8 @@
import java.util.List;
import java.util.Objects;
+import javax.inject.Inject;
+
/**
* The list of currently displaying notifications.
*/
@@ -73,8 +74,9 @@
private final Ranking mTmpRanking = new Ranking();
private final boolean mUsePeopleFiltering;
- public NotificationData(Context context) {
- mUsePeopleFiltering = NotificationUtils.usePeopleFiltering(context);
+ @Inject
+ public NotificationData(NotificationSectionsFeatureManager sectionsFeatureManager) {
+ mUsePeopleFiltering = sectionsFeatureManager.isFilteringEnabled();
}
public void setHeadsUpManager(HeadsUpManager headsUpManager) {
@@ -483,19 +485,6 @@
}
/**
- * Get the current set of buckets for notification entries, as defined here
- */
- public static int[] getNotificationBuckets(Context context) {
- if (NotificationUtils.usePeopleFiltering(context)) {
- return new int[]{BUCKET_PEOPLE, BUCKET_ALERTING, BUCKET_SILENT};
- } else if (NotificationUtils.useNewInterruptionModel(context)) {
- return new int[]{BUCKET_ALERTING, BUCKET_SILENT};
- } else {
- return new int[]{BUCKET_ALERTING};
- }
- }
-
- /**
* Provides access to keyguard state and user settings dependent data.
*/
public interface KeyguardEnvironment {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
index 4700baa..18d436f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
@@ -421,7 +421,7 @@
}
/** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */
- private static class AnimateCloseListener extends AnimatorListenerAdapter {
+ private class AnimateCloseListener extends AnimatorListenerAdapter {
final View mView;
private final GutsContent mGutsContent;
@@ -433,8 +433,10 @@
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
- mView.setVisibility(View.GONE);
- mGutsContent.onFinishedClosing();
+ if (!isExposed()) {
+ mView.setVisibility(View.GONE);
+ mGutsContent.onFinishedClosing();
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 9d0dd6b..2b7deec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -100,6 +100,7 @@
protected String mKeyToRemoveOnGutsClosed;
private StatusBar mStatusBar;
+ private Runnable mOpenRunnable;
@Inject
public NotificationGutsManager(
@@ -343,6 +344,7 @@
public void closeAndSaveGuts(boolean removeLeavebehinds, boolean force, boolean removeControls,
int x, int y, boolean resetMenu) {
if (mNotificationGutsExposed != null) {
+ mNotificationGutsExposed.removeCallbacks(mOpenRunnable);
mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force);
}
if (resetMenu) {
@@ -445,7 +447,7 @@
// ensure that it's laid but not visible until actually laid out
guts.setVisibility(View.INVISIBLE);
// Post to ensure the the guts are properly laid out.
- guts.post(new Runnable() {
+ mOpenRunnable = new Runnable() {
@Override
public void run() {
if (row.getWindowToken() == null) {
@@ -470,7 +472,8 @@
mListContainer.onHeightChanged(row, true /* needsAnimation */);
mGutsMenuItem = menuItem;
}
- });
+ };
+ guts.post(mOpenRunnable);
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index ec0c634..b4f7b59 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -16,10 +16,9 @@
package com.android.systemui.statusbar.notification.stack;
-import android.content.Context;
import android.util.MathUtils;
-import com.android.systemui.statusbar.notification.collection.NotificationData;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -52,8 +51,8 @@
@Inject
NotificationRoundnessManager(
KeyguardBypassController keyguardBypassController,
- Context context) {
- int numberOfSections = NotificationData.getNotificationBuckets(context).length;
+ NotificationSectionsFeatureManager sectionsFeatureManager) {
+ int numberOfSections = sectionsFeatureManager.getNumberOfBuckets();
mFirstInSectionViews = new ActivatableNotificationView[numberOfSections];
mLastInSectionViews = new ActivatableNotificationView[numberOfSections];
mTmpFirstInSectionViews = new ActivatableNotificationView[numberOfSections];
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index a67018e..f5705c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -109,11 +109,11 @@
import com.android.systemui.statusbar.notification.FakeShadowView;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.ShadeViewRefactor;
import com.android.systemui.statusbar.notification.ShadeViewRefactor.RefactorComponent;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -517,7 +517,8 @@
StatusBarStateController statusBarStateController,
HeadsUpManagerPhone headsUpManager,
KeyguardBypassController keyguardBypassController,
- FalsingManager falsingManager) {
+ FalsingManager falsingManager,
+ NotificationSectionsFeatureManager sectionsFeatureManager) {
super(context, attrs, 0, 0);
Resources res = getResources();
@@ -531,7 +532,7 @@
mKeyguardBypassController = keyguardBypassController;
mFalsingManager = falsingManager;
- int[] buckets = NotificationData.getNotificationBuckets(context);
+ int[] buckets = sectionsFeatureManager.getNotificationBuckets();
mSectionsManager =
new NotificationSectionsManager(
this,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 68eca8d6..cac3304 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -117,6 +117,9 @@
private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
+ private final boolean mShowLeftAffordance;
+ private final boolean mShowCameraAffordance;
+
private KeyguardAffordanceView mRightAffordanceView;
private KeyguardAffordanceView mLeftAffordanceView;
private ViewGroup mIndicationArea;
@@ -184,6 +187,9 @@
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+ mShowLeftAffordance = getResources().getBoolean(R.bool.config_keyguardShowLeftAffordance);
+ mShowCameraAffordance = getResources()
+ .getBoolean(R.bool.config_keyguardShowCameraAffordance);
}
private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
@@ -371,8 +377,8 @@
// Things are not set up yet; reply hazy, ask again later
return;
}
- mRightAffordanceView.setVisibility(!mDozing && mRightButton.getIcon().isVisible
- ? View.VISIBLE : View.GONE);
+ mRightAffordanceView.setVisibility(!mDozing && mShowCameraAffordance
+ && mRightButton.getIcon().isVisible ? View.VISIBLE : View.GONE);
}
/**
@@ -384,8 +390,12 @@
}
private void updateLeftAffordanceIcon() {
+ if (!mShowLeftAffordance || mDozing) {
+ mLeftAffordanceView.setVisibility(GONE);
+ return;
+ }
IconState state = mLeftButton.getIcon();
- mLeftAffordanceView.setVisibility(!mDozing && state.isVisible ? View.VISIBLE : View.GONE);
+ mLeftAffordanceView.setVisibility(state.isVisible ? View.VISIBLE : View.GONE);
if (state.drawable != mLeftAffordanceView.getDrawable()
|| state.tint != mLeftAffordanceView.shouldTint()) {
mLeftAffordanceView.setImageDrawable(state.drawable, state.tint);
@@ -767,10 +777,8 @@
@Override
public IconState getIcon() {
mLeftIsVoiceAssist = canLaunchVoiceAssist();
- final boolean showAffordance =
- getResources().getBoolean(R.bool.config_keyguardShowLeftAffordance);
if (mLeftIsVoiceAssist) {
- mIconState.isVisible = mUserSetupComplete && showAffordance;
+ mIconState.isVisible = mUserSetupComplete && mShowLeftAffordance;
if (mLeftAssistIcon == null) {
mIconState.drawable = mContext.getDrawable(R.drawable.ic_mic_26dp);
} else {
@@ -779,7 +787,8 @@
mIconState.contentDescription = mContext.getString(
R.string.accessibility_voice_assist_button);
} else {
- mIconState.isVisible = mUserSetupComplete && showAffordance && isPhoneVisible();
+ mIconState.isVisible = mUserSetupComplete && mShowLeftAffordance
+ && isPhoneVisible();
mIconState.drawable = mContext.getDrawable(
com.android.internal.R.drawable.ic_phone);
mIconState.contentDescription = mContext.getString(
@@ -802,7 +811,7 @@
public IconState getIcon() {
boolean isCameraDisabled = (mStatusBar != null) && !mStatusBar.isCameraAllowedByAdmin();
mIconState.isVisible = !isCameraDisabled
- && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
+ && mShowCameraAffordance
&& mUserSetupComplete
&& resolveCameraIntent() != null;
mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index c3de843..f34c15c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.phone;
import static com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import android.content.Context;
@@ -38,11 +37,13 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardHostView;
+import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardSecurityView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.DejankUtils;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.FalsingManager;
@@ -461,15 +462,9 @@
* notifications on Keyguard, like SIM PIN/PUK.
*/
public boolean needsFullscreenBouncer() {
- // TODO(b/140059518)
- return whitelistIpcs(() -> {
- ensureView();
- if (mKeyguardView != null) {
- SecurityMode mode = mKeyguardView.getSecurityMode();
- return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
- }
- return false;
- });
+ SecurityMode mode = Dependency.get(KeyguardSecurityModel.class).getSecurityMode(
+ KeyguardUpdateMonitor.getCurrentUser());
+ return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index cee1d5d..c7fe4a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -408,14 +408,11 @@
.setDuration(200)
.setAnimationFinishListener(mAnimatorListenerAdapter)
.setCustomInterpolator(PANEL_ALPHA.getProperty(), Interpolators.ALPHA_IN);
- private final NotificationEntryManager mEntryManager =
- Dependency.get(NotificationEntryManager.class);
+ private final NotificationEntryManager mEntryManager;
private final CommandQueue mCommandQueue;
- private final NotificationLockscreenUserManager mLockscreenUserManager =
- Dependency.get(NotificationLockscreenUserManager.class);
- private final ShadeController mShadeController =
- Dependency.get(ShadeController.class);
+ private final NotificationLockscreenUserManager mLockscreenUserManager;
+ private final ShadeController mShadeController;
private int mDisplayId;
/**
@@ -461,6 +458,9 @@
KeyguardBypassController bypassController,
FalsingManager falsingManager,
PluginManager pluginManager,
+ ShadeController shadeController,
+ NotificationLockscreenUserManager notificationLockscreenUserManager,
+ NotificationEntryManager notificationEntryManager,
DozeLog dozeLog) {
super(context, attrs, falsingManager, dozeLog);
setWillNotDraw(!DEBUG);
@@ -495,6 +495,11 @@
mBottomAreaShadeAlphaAnimator.setDuration(160);
mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT);
mPluginManager = pluginManager;
+ mShadeController = shadeController;
+ mLockscreenUserManager = notificationLockscreenUserManager;
+ mEntryManager = notificationEntryManager;
+
+ setBackgroundColor(Color.TRANSPARENT);
}
/**
@@ -509,9 +514,10 @@
mKeyguardBottomArea.setStatusBar(mStatusBar);
}
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
+ /**
+ * Call after this view has been fully inflated and had its children attached.
+ */
+ public void onChildrenAttached() {
mKeyguardStatusBar = findViewById(R.id.keyguard_header);
mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
@@ -554,7 +560,7 @@
}
});
- Dependency.get(PluginManager.class).addPluginListener(
+ mPluginManager.addPluginListener(
new PluginListener<HomeControlsPlugin>() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 3817197..5ba19cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -41,6 +41,7 @@
import com.android.internal.util.function.TriConsumer;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.DejankUtils;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
@@ -311,10 +312,12 @@
// Docking pulses may take a long time, wallpapers should also fade away after a while.
mWallpaperVisibilityTimedOut = false;
if (shouldFadeAwayWallpaper()) {
- mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
- AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
+ DejankUtils.postAfterTraversal(() -> {
+ mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
+ AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
+ });
} else {
- mTimeTicker.cancel();
+ DejankUtils.postAfterTraversal(mTimeTicker::cancel);
}
if (mKeyguardUpdateMonitor.needsSlowUnlockTransition() && mState == ScrimState.UNLOCKED) {
@@ -430,8 +433,10 @@
// and docking.
if (mWallpaperVisibilityTimedOut) {
mWallpaperVisibilityTimedOut = false;
- mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
- AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
+ DejankUtils.postAfterTraversal(() -> {
+ mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
+ AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
+ });
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 5fc2d9b..6ce6dfa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -25,7 +25,6 @@
import static android.app.StatusBarManager.windowStateToString;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
-import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import static com.android.systemui.Dependency.BG_HANDLER;
import static com.android.systemui.Dependency.MAIN_HANDLER;
@@ -244,9 +243,11 @@
import javax.inject.Inject;
import javax.inject.Named;
+import javax.inject.Singleton;
import dagger.Subcomponent;
+@Singleton
public class StatusBar extends SystemUI implements DemoMode,
ActivityStarter, KeyguardStateController.Callback,
OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
@@ -347,21 +348,20 @@
private BrightnessMirrorController mBrightnessMirrorController;
private boolean mBrightnessMirrorVisible;
protected BiometricUnlockController mBiometricUnlockController;
- private LightBarController mLightBarController;
+ private final LightBarController mLightBarController;
protected LockscreenWallpaper mLockscreenWallpaper;
- @VisibleForTesting
- protected AutoHideController mAutoHideController;
+ private final AutoHideController mAutoHideController;
private int mNaturalBarHeight = -1;
private final Point mCurrentDisplaySize = new Point();
+ protected StatusBarWindowViewController mStatusBarWindowViewController;
protected StatusBarWindowView mStatusBarWindow;
protected PhoneStatusBarView mStatusBarView;
private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
protected StatusBarWindowController mStatusBarWindowController;
- @VisibleForTesting
- KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@VisibleForTesting
DozeServiceHost mDozeServiceHost = new DozeServiceHost();
private boolean mWakeUpComingFromTouch;
@@ -369,38 +369,22 @@
private final Object mQueueLock = new Object();
- protected StatusBarIconController mIconController;
- @Inject
- DozeLog mDozeLog;
- @Inject
- InjectionInflationController mInjectionInflater;
- @Inject
- PulseExpansionHandler mPulseExpansionHandler;
- @Inject
- NotificationWakeUpCoordinator mWakeUpCoordinator;
- @Inject
- KeyguardBypassController mKeyguardBypassController;
- @Inject
- KeyguardStateController mKeyguardStateController;
- @Inject
- protected HeadsUpManagerPhone mHeadsUpManager;
- @Inject
- DynamicPrivacyController mDynamicPrivacyController;
- @Inject
- BypassHeadsUpNotifier mBypassHeadsUpNotifier;
- @Nullable
- @Inject
- protected KeyguardLiftController mKeyguardLiftController;
- @Inject
- @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
- boolean mAllowNotificationLongPress;
- @Inject
- protected NotifPipelineInitializer mNotifPipelineInitializer;
- @Inject
- protected FalsingManager mFalsingManager;
-
- @VisibleForTesting
- BroadcastDispatcher mBroadcastDispatcher;
+ private final StatusBarIconController mIconController;
+ private final DozeLog mDozeLog;
+ private final InjectionInflationController mInjectionInflater;
+ private final PulseExpansionHandler mPulseExpansionHandler;
+ private final NotificationWakeUpCoordinator mWakeUpCoordinator;
+ private final KeyguardBypassController mKeyguardBypassController;
+ private final KeyguardStateController mKeyguardStateController;
+ private final HeadsUpManagerPhone mHeadsUpManager;
+ private final DynamicPrivacyController mDynamicPrivacyController;
+ private final BypassHeadsUpNotifier mBypassHeadsUpNotifier;
+ private final boolean mAllowNotificationLongPress;
+ private final NotifPipelineInitializer mNotifPipelineInitializer;
+ private final FalsingManager mFalsingManager;
+ private final BroadcastDispatcher mBroadcastDispatcher;
+ private final ConfigurationController mConfigurationController;
+ private final StatusBarWindowViewController.Builder mStatusBarWindowViewControllerBuilder;
// expanded notifications
protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -413,8 +397,7 @@
// RemoteInputView to be activated after unlock
private View mPendingRemoteInputView;
- private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler =
- Dependency.get(RemoteInputQuickSettingsDisabler.class);
+ private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
private View mReportRejectedTouch;
@@ -423,18 +406,17 @@
private final int[] mAbsPos = new int[2];
private final ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
- private NotificationGutsManager mGutsManager;
- protected NotificationLogger mNotificationLogger;
- protected NotificationEntryManager mEntryManager;
+ private final NotificationGutsManager mGutsManager;
+ private final NotificationLogger mNotificationLogger;
+ private final NotificationEntryManager mEntryManager;
private NotificationListController mNotificationListController;
- private NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
- protected NotificationViewHierarchyManager mViewHierarchyManager;
- protected ForegroundServiceController mForegroundServiceController;
- protected AppOpsController mAppOpsController;
- protected KeyguardViewMediator mKeyguardViewMediator;
- private ZenModeController mZenController;
- private final NotificationAlertingManager mNotificationAlertingManager =
- Dependency.get(NotificationAlertingManager.class);
+ private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
+ private final NotificationViewHierarchyManager mViewHierarchyManager;
+ private final ForegroundServiceController mForegroundServiceController;
+ private final AppOpsController mAppOpsController;
+ private final KeyguardViewMediator mKeyguardViewMediator;
+ private final ZenModeController mZenController;
+ private final NotificationAlertingManager mNotificationAlertingManager;
// for disabling the status bar
private int mDisabled1 = 0;
@@ -445,7 +427,7 @@
private final Rect mLastFullscreenStackBounds = new Rect();
private final Rect mLastDockedStackBounds = new Rect();
- private final DisplayMetrics mDisplayMetrics = Dependency.get(DisplayMetrics.class);
+ private final DisplayMetrics mDisplayMetrics;
// XXX: gesture research
private final GestureRecorder mGestureRec = DEBUG_GESTURES
@@ -454,7 +436,7 @@
private ScreenPinningRequest mScreenPinningRequest;
- private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
+ private final MetricsLogger mMetricsLogger;
// ensure quick settings is disabled until the current user makes it through the setup wizard
@VisibleForTesting
@@ -491,14 +473,14 @@
private ViewMediatorCallback mKeyguardViewMediatorCallback;
protected ScrimController mScrimController;
protected DozeScrimController mDozeScrimController;
- private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
+ private final UiOffloadThread mUiOffloadThread;
protected boolean mDozing;
private boolean mDozingRequested;
- private NotificationMediaManager mMediaManager;
- protected NotificationLockscreenUserManager mLockscreenUserManager;
- protected NotificationRemoteInputManager mRemoteInputManager;
+ private final NotificationMediaManager mMediaManager;
+ private final NotificationLockscreenUserManager mLockscreenUserManager;
+ private final NotificationRemoteInputManager mRemoteInputManager;
private boolean mWallpaperSupported;
private final BroadcastReceiver mWallpaperChangedReceiver = new BroadcastReceiver() {
@@ -569,18 +551,18 @@
};
private KeyguardUserSwitcher mKeyguardUserSwitcher;
- protected UserSwitcherController mUserSwitcherController;
- private NetworkController mNetworkController;
- private BatteryController mBatteryController;
+ private final UserSwitcherController mUserSwitcherController;
+ private final NetworkController mNetworkController;
+ private final BatteryController mBatteryController;
protected boolean mPanelExpanded;
private UiModeManager mUiModeManager;
protected boolean mIsKeyguard;
private LogMaker mStatusBarStateLog;
protected NotificationIconAreaController mNotificationIconAreaController;
@Nullable private View mAmbientIndicationContainer;
- private SysuiColorExtractor mColorExtractor;
- private ScreenLifecycle mScreenLifecycle;
- @VisibleForTesting WakefulnessLifecycle mWakefulnessLifecycle;
+ private final SysuiColorExtractor mColorExtractor;
+ private final ScreenLifecycle mScreenLifecycle;
+ private final WakefulnessLifecycle mWakefulnessLifecycle;
private final View.OnClickListener mGoToLockedShadeListener = v -> {
if (mState == StatusBarState.KEYGUARD) {
@@ -589,8 +571,7 @@
}
};
private boolean mNoAnimationOnNextBarModeChange;
- private final SysuiStatusBarStateController mStatusBarStateController =
- (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class);
+ private final SysuiStatusBarStateController mStatusBarStateController;
private final KeyguardUpdateMonitorCallback mUpdateCallback =
new KeyguardUpdateMonitorCallback() {
@@ -611,19 +592,14 @@
private HeadsUpAppearanceController mHeadsUpAppearanceController;
private boolean mVibrateOnOpening;
- private VibratorHelper mVibratorHelper;
+ private final VibratorHelper mVibratorHelper;
private ActivityLaunchAnimator mActivityLaunchAnimator;
protected StatusBarNotificationPresenter mPresenter;
private NotificationActivityStarter mNotificationActivityStarter;
private boolean mPulsing;
- protected BubbleController mBubbleController;
- private final BubbleController.BubbleExpandListener mBubbleExpandListener =
- (isExpanding, key) -> {
- mEntryManager.updateNotifications();
- updateScrimController();
- };
+ private final BubbleController mBubbleController;
+ private final BubbleController.BubbleExpandListener mBubbleExpandListener;
private ActivityIntentHelper mActivityIntentHelper;
- private ShadeController mShadeController;
@Override
public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
@@ -639,43 +615,131 @@
AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION};
+ @Inject
+ public StatusBar(
+ LightBarController lightBarController,
+ AutoHideController autoHideController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ StatusBarIconController statusBarIconController,
+ DozeLog dozeLog,
+ InjectionInflationController injectionInflationController,
+ PulseExpansionHandler pulseExpansionHandler,
+ NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
+ KeyguardStateController keyguardStateController,
+ HeadsUpManagerPhone headsUpManagerPhone,
+ DynamicPrivacyController dynamicPrivacyController,
+ BypassHeadsUpNotifier bypassHeadsUpNotifier,
+ @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowNotificationLongPress,
+ NotifPipelineInitializer notifPipelineInitializer,
+ FalsingManager falsingManager,
+ BroadcastDispatcher broadcastDispatcher,
+ RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
+ NotificationGutsManager notificationGutsManager,
+ NotificationLogger notificationLogger,
+ NotificationEntryManager notificationEntryManager,
+ NotificationInterruptionStateProvider notificationInterruptionStateProvider,
+ NotificationViewHierarchyManager notificationViewHierarchyManager,
+ ForegroundServiceController foregroundServiceController,
+ AppOpsController appOpsController,
+ KeyguardViewMediator keyguardViewMediator,
+ ZenModeController zenModeController,
+ NotificationAlertingManager notificationAlertingManager,
+ DisplayMetrics displayMetrics,
+ MetricsLogger metricsLogger,
+ UiOffloadThread uiOffloadThread,
+ NotificationMediaManager notificationMediaManager,
+ NotificationLockscreenUserManager lockScreenUserManager,
+ NotificationRemoteInputManager remoteInputManager,
+ UserSwitcherController userSwitcherController,
+ NetworkController networkController,
+ BatteryController batteryController,
+ SysuiColorExtractor colorExtractor,
+ ScreenLifecycle screenLifecycle,
+ WakefulnessLifecycle wakefulnessLifecycle,
+ SysuiStatusBarStateController statusBarStateController,
+ VibratorHelper vibratorHelper,
+ BubbleController bubbleController,
+ NotificationGroupManager groupManager,
+ NotificationGroupAlertTransferHelper groupAlertTransferHelper,
+ VisualStabilityManager visualStabilityManager,
+ DeviceProvisionedController deviceProvisionedController,
+ NavigationBarController navigationBarController,
+ AssistManager assistManager,
+ NotificationListener notificationListener,
+ ConfigurationController configurationController,
+ StatusBarWindowController statusBarWindowController,
+ StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder) {
+ mLightBarController = lightBarController;
+ mAutoHideController = autoHideController;
+ mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ mIconController = statusBarIconController;
+ mDozeLog = dozeLog;
+ mInjectionInflater = injectionInflationController;
+ mPulseExpansionHandler = pulseExpansionHandler;
+ mWakeUpCoordinator = notificationWakeUpCoordinator;
+ mKeyguardBypassController = keyguardBypassController;
+ mKeyguardStateController = keyguardStateController;
+ mHeadsUpManager = headsUpManagerPhone;
+ mDynamicPrivacyController = dynamicPrivacyController;
+ mBypassHeadsUpNotifier = bypassHeadsUpNotifier;
+ mAllowNotificationLongPress = allowNotificationLongPress;
+ mNotifPipelineInitializer = notifPipelineInitializer;
+ mFalsingManager = falsingManager;
+ mBroadcastDispatcher = broadcastDispatcher;
+ mRemoteInputQuickSettingsDisabler = remoteInputQuickSettingsDisabler;
+ mGutsManager = notificationGutsManager;
+ mNotificationLogger = notificationLogger;
+ mEntryManager = notificationEntryManager;
+ mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
+ mViewHierarchyManager = notificationViewHierarchyManager;
+ mForegroundServiceController = foregroundServiceController;
+ mAppOpsController = appOpsController;
+ mKeyguardViewMediator = keyguardViewMediator;
+ mZenController = zenModeController;
+ mNotificationAlertingManager = notificationAlertingManager;
+ mDisplayMetrics = displayMetrics;
+ mMetricsLogger = metricsLogger;
+ mUiOffloadThread = uiOffloadThread;
+ mMediaManager = notificationMediaManager;
+ mLockscreenUserManager = lockScreenUserManager;
+ mRemoteInputManager = remoteInputManager;
+ mUserSwitcherController = userSwitcherController;
+ mNetworkController = networkController;
+ mBatteryController = batteryController;
+ mColorExtractor = colorExtractor;
+ mScreenLifecycle = screenLifecycle;
+ mWakefulnessLifecycle = wakefulnessLifecycle;
+ mStatusBarStateController = statusBarStateController;
+ mVibratorHelper = vibratorHelper;
+ mBubbleController = bubbleController;
+ mGroupManager = groupManager;
+ mGroupAlertTransferHelper = groupAlertTransferHelper;
+ mVisualStabilityManager = visualStabilityManager;
+ mDeviceProvisionedController = deviceProvisionedController;
+ mNavigationBarController = navigationBarController;
+ mAssistManager = assistManager;
+ mNotificationListener = notificationListener;
+ mConfigurationController = configurationController;
+ mStatusBarWindowController = statusBarWindowController;
+ mStatusBarWindowViewControllerBuilder = statusBarWindowViewControllerBuilder;
+
+ mBubbleExpandListener =
+ (isExpanding, key) -> {
+ mEntryManager.updateNotifications();
+ updateScrimController();
+ };
+ }
+
@Override
public void start() {
- mGroupManager = Dependency.get(NotificationGroupManager.class);
- mGroupAlertTransferHelper = Dependency.get(NotificationGroupAlertTransferHelper.class);
- mVisualStabilityManager = Dependency.get(VisualStabilityManager.class);
- mNotificationLogger = Dependency.get(NotificationLogger.class);
- mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class);
- mNotificationListener = Dependency.get(NotificationListener.class);
mNotificationListener.registerAsSystemService();
- mNetworkController = Dependency.get(NetworkController.class);
- mUserSwitcherController = Dependency.get(UserSwitcherController.class);
- mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
mScreenLifecycle.addObserver(mScreenObserver);
- mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
- mBatteryController = Dependency.get(BatteryController.class);
- mAssistManager = Dependency.get(AssistManager.class);
mUiModeManager = mContext.getSystemService(UiModeManager.class);
- mLockscreenUserManager = Dependency.get(NotificationLockscreenUserManager.class);
- mGutsManager = Dependency.get(NotificationGutsManager.class);
- mMediaManager = Dependency.get(NotificationMediaManager.class);
- mEntryManager = Dependency.get(NotificationEntryManager.class);
mBypassHeadsUpNotifier.setUp(mEntryManager);
- mNotificationInterruptionStateProvider =
- Dependency.get(NotificationInterruptionStateProvider.class);
- mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class);
- mForegroundServiceController = Dependency.get(ForegroundServiceController.class);
- mAppOpsController = Dependency.get(AppOpsController.class);
- mZenController = Dependency.get(ZenModeController.class);
- mKeyguardViewMediator = getComponent(KeyguardViewMediator.class);
- mColorExtractor = Dependency.get(SysuiColorExtractor.class);
- mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
- mNavigationBarController = Dependency.get(NavigationBarController.class);
- mBubbleController = Dependency.get(BubbleController.class);
mBubbleController.setExpandListener(mBubbleExpandListener);
mActivityIntentHelper = new ActivityIntentHelper(mContext);
- mBroadcastDispatcher = Dependency.get(BroadcastDispatcher.class);
KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance();
if (sliceProvider != null) {
sliceProvider.initDependencies(mMediaManager, mStatusBarStateController,
@@ -698,7 +762,6 @@
mVibrateOnOpening = mContext.getResources().getBoolean(
R.bool.config_vibrateOnIconAnimation);
- mVibratorHelper = Dependency.get(VibratorHelper.class);
DateTimeView.setReceiverHandler(Dependency.get(Dependency.TIME_TICK_HANDLER));
putComponent(StatusBar.class, this);
@@ -712,7 +775,6 @@
mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -806,7 +868,7 @@
Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
- Dependency.get(ConfigurationController.class).addCallback(this);
+ mConfigurationController.addCallback(this);
// set the initial view visibility
Dependency.get(InitController.class).addPostInitTask(this::updateAreThereNotifications);
@@ -826,8 +888,7 @@
updateTheme();
inflateStatusBarWindow(context);
- mStatusBarWindow.setService(this);
- mStatusBarWindow.setBypassController(mKeyguardBypassController);
+ mStatusBarWindowViewController.setService(this);
mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
// TODO: Deal with the ugliness that comes from having some of the statusbar broken out
@@ -839,6 +900,8 @@
NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
mNotificationLogger.setUpWithContainer(notifListContainer);
+ // TODO: make this injectable. Currently that would create a circular dependency between
+ // NotificationIconAreaController and StatusBar.
mNotificationIconAreaController = SystemUIFactory.getInstance()
.createNotificationIconAreaController(context, this,
mWakeUpCoordinator, mKeyguardBypassController,
@@ -893,7 +956,7 @@
mStatusBarStateController, mKeyguardBypassController,
mWakeUpCoordinator);
mHeadsUpAppearanceController.readFrom(oldController);
- mStatusBarWindow.setStatusBarView(mStatusBarView);
+ mStatusBarWindowViewController.setStatusBarView(mStatusBarView);
updateAreThereNotifications();
checkBarModes();
}).getFragmentManager()
@@ -901,10 +964,9 @@
.replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
CollapsedStatusBarFragment.TAG)
.commit();
- mIconController = Dependency.get(StatusBarIconController.class);
mHeadsUpManager.setUp(mStatusBarWindow, mGroupManager, this, mVisualStabilityManager);
- Dependency.get(ConfigurationController.class).addCallback(mHeadsUpManager);
+ mConfigurationController.addCallback(mHeadsUpManager);
mHeadsUpManager.addListener(this);
mHeadsUpManager.addListener(mNotificationPanel);
mHeadsUpManager.addListener(mGroupManager);
@@ -947,11 +1009,8 @@
}
});
- mAutoHideController = Dependency.get(AutoHideController.class);
mAutoHideController.setStatusBar(this);
- mLightBarController = Dependency.get(LightBarController.class);
-
ScrimView scrimBehind = mStatusBarWindow.findViewById(R.id.scrim_behind);
ScrimView scrimInFront = mStatusBarWindow.findViewById(R.id.scrim_in_front);
ScrimView scrimForBubble = mStatusBarWindow.findViewById(R.id.scrim_for_bubble);
@@ -964,7 +1023,7 @@
mStatusBarWindowController.setScrimsVisibility(scrimsVisible);
}
if (mStatusBarWindow != null) {
- mStatusBarWindow.onScrimVisibilityChanged(scrimsVisible);
+ mStatusBarWindowViewController.onScrimVisibilityChanged(scrimsVisible);
}
}, DozeParameters.getInstance(mContext),
mContext.getSystemService(AlarmManager.class),
@@ -987,7 +1046,7 @@
}
mNotificationPanel.setLaunchAffordanceListener(
- mStatusBarWindow::onShowingLaunchAffordanceChanged);
+ mStatusBarWindowViewController::onShowingLaunchAffordanceChanged);
// Set up the quick settings tile panel
View container = mStatusBarWindow.findViewById(R.id.qs_frame);
@@ -1042,11 +1101,10 @@
});
}
- PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- if (!pm.isScreenOn()) {
+ if (!mPowerManager.isScreenOn()) {
mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
}
- mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
+ mGestureWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
"GestureWakeLock");
mVibrator = mContext.getSystemService(Vibrator.class);
int[] pattern = mContext.getResources().getIntArray(
@@ -1094,7 +1152,7 @@
private void setUpPresenter() {
// Set up the initial notification state.
mActivityLaunchAnimator = new ActivityLaunchAnimator(
- mStatusBarWindow, this, mNotificationPanel,
+ mStatusBarWindowViewController, this, mNotificationPanel,
(NotificationListContainer) mStackScroller);
final NotificationRowBinderImpl rowBinder =
@@ -1123,7 +1181,6 @@
final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback =
(StatusBarRemoteInputCallback) Dependency.get(
NotificationRemoteInputManager.Callback.class);
- mShadeController = Dependency.get(ShadeController.class);
final ActivityStarter activityStarter = Dependency.get(ActivityStarter.class);
mNotificationActivityStarter = new StatusBarNotificationActivityStarter(mContext,
@@ -1131,7 +1188,7 @@
mHeadsUpManager, activityStarter, mActivityLaunchAnimator,
mBarService, mStatusBarStateController, mKeyguardManager, mDreamManager,
mRemoteInputManager, mStatusBarRemoteInputCallback, mGroupManager,
- mLockscreenUserManager, mShadeController, mKeyguardStateController,
+ mLockscreenUserManager, this, mKeyguardStateController,
mNotificationInterruptionStateProvider, mMetricsLogger,
new LockPatternUtils(mContext), Dependency.get(MAIN_HANDLER),
Dependency.get(BG_HANDLER), mActivityIntentHelper, mBubbleController);
@@ -1140,7 +1197,7 @@
mEntryManager.setRowBinder(rowBinder);
rowBinder.setNotificationClicker(new NotificationClicker(
- this, Dependency.get(BubbleController.class), mNotificationActivityStarter));
+ this, mBubbleController, mNotificationActivityStarter));
mGroupAlertTransferHelper.bind(mEntryManager, mGroupManager);
mNotificationListController.bind();
@@ -1170,8 +1227,8 @@
@Override
public void wakeUpIfDozing(long time, View where, String why) {
if (mDozing) {
- PowerManager pm = mContext.getSystemService(PowerManager.class);
- pm.wakeUp(time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
+ mPowerManager.wakeUp(
+ time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
mWakeUpComingFromTouch = true;
where.getLocationInWindow(mTmpInt2);
mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
@@ -1267,17 +1324,20 @@
protected void inflateStatusBarWindow(Context context) {
mStatusBarWindow = (StatusBarWindowView) mInjectionInflater.injectable(
LayoutInflater.from(context)).inflate(R.layout.super_status_bar, null);
+ mStatusBarWindowViewController = mStatusBarWindowViewControllerBuilder
+ .setStatusBarWindowView(mStatusBarWindow)
+ .setShadeController(this)
+ .build();
}
protected void startKeyguard() {
Trace.beginSection("StatusBar#startKeyguard");
- KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
mBiometricUnlockController = new BiometricUnlockController(mContext,
- mDozeScrimController, keyguardViewMediator,
+ mDozeScrimController, mKeyguardViewMediator,
mScrimController, this, mKeyguardStateController, new Handler(),
mKeyguardUpdateMonitor, mKeyguardBypassController);
putComponent(BiometricUnlockController.class, mBiometricUnlockController);
- mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
+ mStatusBarKeyguardViewManager = mKeyguardViewMediator.registerStatusBar(this,
getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
mKeyguardBypassController);
@@ -1287,7 +1347,7 @@
mRemoteInputManager.getController().addCallback(mStatusBarKeyguardViewManager);
mDynamicPrivacyController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
- mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
+ mKeyguardViewMediatorCallback = mKeyguardViewMediator.getViewMediatorCallback();
mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
Dependency.get(KeyguardDismissUtil.class).setDismissHandler(this::executeWhenUnlocked);
@@ -1773,6 +1833,16 @@
return mPresenter;
}
+ @VisibleForTesting
+ void setBarStateForTest(int state) {
+ mState = state;
+ }
+
+ @VisibleForTesting
+ void setUserSetupForTest(boolean userSetup) {
+ mUserSetup = userSetup;
+ }
+
/**
* All changes to the status bar and notifications funnel through here and are batched.
*/
@@ -1960,7 +2030,7 @@
// release focus immediately to kick off focus change transition
mStatusBarWindowController.setStatusBarFocusable(false);
- mStatusBarWindow.cancelExpandHelper();
+ mStatusBarWindowViewController.cancelExpandHelper();
mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
} else {
mBubbleController.collapseStack();
@@ -2351,8 +2421,8 @@
dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
}
pw.println(" StatusBarWindowView: ");
- if (mStatusBarWindow != null) {
- mStatusBarWindow.dump(fd, pw, args);
+ if (mStatusBarWindowViewController != null) {
+ mStatusBarWindowViewController.dump(fd, pw, args);
}
pw.println(" mMediaManager: ");
@@ -2464,7 +2534,6 @@
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
makeStatusBarView(result);
- mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
mStatusBarWindowController.add(mStatusBarWindow, getStatusBarHeight());
}
@@ -2708,7 +2777,6 @@
}
}
- // SystemUIService notifies SystemBars of configuration changes, which then calls down here
@Override
public void onConfigChanged(Configuration newConfig) {
updateResources();
@@ -3290,7 +3358,7 @@
final int themeResId = lockDarkText ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI;
if (mContext.getThemeResId() != themeResId) {
mContext.setTheme(themeResId);
- Dependency.get(ConfigurationController.class).notifyThemeChanged();
+ mConfigurationController.notifyThemeChanged();
}
}
@@ -3648,7 +3716,7 @@
mBouncerShowing = bouncerShowing;
mKeyguardBypassController.setBouncerShowing(bouncerShowing);
mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
- mStatusBarWindow.setBouncerShowingScrimmed(isBouncerShowingScrimmed());
+ mStatusBarWindowViewController.setBouncerShowingScrimmed(isBouncerShowingScrimmed());
if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
updateHideIconsForBouncer(true /* animate */);
mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
@@ -3663,7 +3731,7 @@
*/
public void collapseShade() {
if (mNotificationPanel.isTracking()) {
- mStatusBarWindow.cancelCurrentTouch();
+ mStatusBarWindowViewController.cancelCurrentTouch();
}
if (mPanelExpanded && mState == StatusBarState.SHADE) {
animateCollapsePanels();
@@ -3684,7 +3752,7 @@
updateVisibleToUser();
updateNotificationPanelTouchState();
- mStatusBarWindow.cancelCurrentTouch();
+ mStatusBarWindowViewController.cancelCurrentTouch();
if (mLaunchCameraOnFinishedGoingToSleep) {
mLaunchCameraOnFinishedGoingToSleep = false;
@@ -3837,8 +3905,7 @@
return;
}
if (!mDeviceInteractive) {
- PowerManager pm = mContext.getSystemService(PowerManager.class);
- pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH,
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH,
"com.android.systemui:CAMERA_GESTURE");
}
vibrateForCameraGesture();
@@ -3877,20 +3944,17 @@
}
boolean isCameraAllowedByAdmin() {
- // TODO(b/140060745)
- return whitelistIpcs(() -> {
- if (mDevicePolicyManager.getCameraDisabled(null,
- mLockscreenUserManager.getCurrentUserId())) {
- return false;
- } else if (mStatusBarKeyguardViewManager == null
- || (isKeyguardShowing() && isKeyguardSecure())) {
- // Check if the admin has disabled the camera specifically for the keyguard
- return (mDevicePolicyManager.getKeyguardDisabledFeatures(null,
- mLockscreenUserManager.getCurrentUserId())
- & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
- }
- return true;
- });
+ if (mDevicePolicyManager.getCameraDisabled(null,
+ mLockscreenUserManager.getCurrentUserId())) {
+ return false;
+ } else if (mStatusBarKeyguardViewManager == null
+ || (isKeyguardShowing() && isKeyguardSecure())) {
+ // Check if the admin has disabled the camera specifically for the keyguard
+ return (mDevicePolicyManager.getKeyguardDisabledFeatures(null,
+ mLockscreenUserManager.getCurrentUserId())
+ & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
+ }
+ return true;
}
private boolean isGoingToSleep() {
@@ -3906,7 +3970,8 @@
public void notifyBiometricAuthModeChanged() {
updateDozing();
updateScrimController();
- mStatusBarWindow.onBiometricAuthModeChanged(mBiometricUnlockController.isWakeAndUnlock(),
+ mStatusBarWindowViewController.onBiometricAuthModeChanged(
+ mBiometricUnlockController.isWakeAndUnlock(),
mBiometricUnlockController.isBiometricUnlock());
}
@@ -4027,7 +4092,7 @@
}
if (reason == DozeEvent.PULSE_REASON_DOCKING && mStatusBarWindow != null) {
- mStatusBarWindow.suppressWakeUpGesture(true);
+ mStatusBarWindowViewController.suppressWakeUpGesture(true);
}
boolean passiveAuthInterrupt = reason == DozeEvent.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
@@ -4051,7 +4116,7 @@
updateNotificationPanelTouchState();
mScrimController.setWakeLockScreenSensorActive(false);
if (mStatusBarWindow != null) {
- mStatusBarWindow.suppressWakeUpGesture(false);
+ mStatusBarWindowViewController.suppressWakeUpGesture(false);
}
setPulsing(false);
}
@@ -4062,7 +4127,7 @@
mKeyguardViewMediator.setPulsing(pulsing);
mNotificationPanel.setPulsing(pulsing);
mVisualStabilityManager.setPulsing(pulsing);
- mStatusBarWindow.setPulsing(pulsing);
+ mStatusBarWindowViewController.setPulsing(pulsing);
mIgnoreTouchWhilePulsing = false;
if (mKeyguardUpdateMonitor != null && passiveAuthInterrupt) {
mKeyguardUpdateMonitor.onAuthInterruptDetected(pulsing /* active */);
@@ -4093,7 +4158,7 @@
}
mIgnoreTouchWhilePulsing = ignore;
if (isDozing() && ignore) {
- mStatusBarWindow.cancelCurrentTouch();
+ mStatusBarWindowViewController.cancelCurrentTouch();
}
}
@@ -4227,12 +4292,11 @@
// all notifications
protected ViewGroup mStackScroller;
- protected NotificationGroupManager mGroupManager;
-
- protected NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
+ private final NotificationGroupManager mGroupManager;
+ private final NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
// handling reordering
- protected VisualStabilityManager mVisualStabilityManager;
+ private final VisualStabilityManager mVisualStabilityManager;
protected AccessibilityManager mAccessibilityManager;
@@ -4248,10 +4312,9 @@
protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
protected KeyguardManager mKeyguardManager;
- private DeviceProvisionedController mDeviceProvisionedController
- = Dependency.get(DeviceProvisionedController.class);
+ private final DeviceProvisionedController mDeviceProvisionedController;
- protected NavigationBarController mNavigationBarController;
+ private final NavigationBarController mNavigationBarController;
// UI-specific methods
@@ -4267,7 +4330,7 @@
protected NotificationShelf mNotificationShelf;
protected EmptyShadeView mEmptyShadeView;
- protected AssistManager mAssistManager;
+ private final AssistManager mAssistManager;
public boolean isDeviceInteractive() {
return mDeviceInteractive;
@@ -4326,7 +4389,7 @@
}
}
- protected NotificationListener mNotificationListener;
+ private final NotificationListener mNotificationListener;
public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
if (snoozeOption.getSnoozeCriterion() != null) {
@@ -4462,8 +4525,7 @@
executeActionDismissingKeyguard(() -> {
try {
intent.send(null, 0, null, null, null, null, getActivityOptions(
- mActivityLaunchAnimator.getLaunchAnimation(associatedView,
- mShadeController.isOccluded())));
+ mActivityLaunchAnimator.getLaunchAnimation(associatedView, isOccluded())));
} catch (PendingIntent.CanceledException e) {
// the stack trace isn't very helpful here.
// Just log the exception message.
@@ -4551,7 +4613,7 @@
*/
public void onBouncerPreHideAnimation() {
mNotificationPanel.onBouncerPreHideAnimation();
- mStatusBarWindow.onBouncerPreHideAnimation();
+ mStatusBarWindowViewController.onBouncerPreHideAnimation();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index df23f8ca..75b0cdc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -61,6 +61,8 @@
import java.io.PrintWriter;
import java.util.ArrayList;
+import androidx.annotation.VisibleForTesting;
+
/**
* Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back
* via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done,
@@ -160,6 +162,7 @@
private boolean mLastLockVisible;
private OnDismissAction mAfterKeyguardGoneAction;
+ private Runnable mKeyguardGoneCancelAction;
private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>();
// Dismiss action to be launched when we stop dozing or the keyguard is gone.
@@ -329,10 +332,20 @@
return false;
}
- private void hideBouncer(boolean destroyView) {
+ @VisibleForTesting
+ void hideBouncer(boolean destroyView) {
if (mBouncer == null) {
return;
}
+ if (mShowing) {
+ // If we were showing the bouncer and then aborting, we need to also clear out any
+ // potential actions unless we actually unlocked.
+ mAfterKeyguardGoneAction = null;
+ if (mKeyguardGoneCancelAction != null) {
+ mKeyguardGoneCancelAction.run();
+ mKeyguardGoneCancelAction = null;
+ }
+ }
mBouncer.hide(destroyView);
cancelPendingWakeupAction();
}
@@ -365,6 +378,7 @@
mBouncer.showWithDismissAction(r, cancelAction);
} else {
mAfterKeyguardGoneAction = r;
+ mKeyguardGoneCancelAction = cancelAction;
mBouncer.show(false /* resetSecuritySelection */);
}
}
@@ -672,6 +686,7 @@
mAfterKeyguardGoneAction.onDismiss();
mAfterKeyguardGoneAction = null;
}
+ mKeyguardGoneCancelAction = null;
for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) {
mAfterKeyguardGoneRunnables.get(i).run();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index a9e818d..d04c7bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -19,29 +19,18 @@
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
import android.annotation.LayoutRes;
-import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.hardware.display.AmbientDisplayConfiguration;
-import android.media.AudioManager;
-import android.media.session.MediaSessionLegacyHelper;
import android.net.Uri;
import android.os.Bundle;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.DisplayCutout;
-import android.view.GestureDetector;
-import android.view.InputDevice;
import android.view.InputQueue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -56,21 +45,9 @@
import android.view.WindowInsetsController;
import android.widget.FrameLayout;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.view.FloatingActionMode;
import com.android.internal.widget.FloatingToolbar;
-import com.android.systemui.Dependency;
-import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
-import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.DragDownHelper;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
-import com.android.systemui.statusbar.phone.ScrimController.ScrimVisibility;
-import com.android.systemui.tuner.TunerService;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
/**
* Combined status bar and notification panel view. Also holding backdrop and scrims.
@@ -79,87 +56,21 @@
public static final String TAG = "StatusBarWindowView";
public static final boolean DEBUG = StatusBar.DEBUG;
- private final GestureDetector mGestureDetector;
- private final StatusBarStateController mStatusBarStateController;
- private boolean mDoubleTapEnabled;
- private boolean mSingleTapEnabled;
- private DragDownHelper mDragDownHelper;
- private NotificationStackScrollLayout mStackScrollLayout;
- private NotificationPanelView mNotificationPanel;
- private View mBrightnessMirror;
- private LockIcon mLockIcon;
- private PhoneStatusBarView mStatusBarView;
-
private int mRightInset = 0;
private int mLeftInset = 0;
- private StatusBar mService;
- private final Paint mTransparentSrcPaint = new Paint();
- private FalsingManager mFalsingManager;
-
// Implements the floating action mode for TextView's Cut/Copy/Past menu. Normally provided by
// DecorView, but since this is a special window we have to roll our own.
private View mFloatingActionModeOriginatingView;
private ActionMode mFloatingActionMode;
private FloatingToolbar mFloatingToolbar;
private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;
- private boolean mTouchCancelled;
- private boolean mTouchActive;
- private boolean mExpandAnimationRunning;
- private boolean mExpandAnimationPending;
- private boolean mSuppressingWakeUpGesture;
- private final GestureDetector.SimpleOnGestureListener mGestureListener =
- new GestureDetector.SimpleOnGestureListener() {
- @Override
- public boolean onSingleTapConfirmed(MotionEvent e) {
- if (mSingleTapEnabled && !mSuppressingWakeUpGesture) {
- mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this,
- "SINGLE_TAP");
- return true;
- }
- return false;
- }
-
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- if (mDoubleTapEnabled || mSingleTapEnabled) {
- mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this,
- "DOUBLE_TAP");
- return true;
- }
- return false;
- }
- };
- private final TunerService.Tunable mTunable = (key, newValue) -> {
- AmbientDisplayConfiguration configuration = new AmbientDisplayConfiguration(mContext);
- switch (key) {
- case Settings.Secure.DOZE_DOUBLE_TAP_GESTURE:
- mDoubleTapEnabled = configuration.doubleTapGestureEnabled(UserHandle.USER_CURRENT);
- break;
- case Settings.Secure.DOZE_TAP_SCREEN_GESTURE:
- mSingleTapEnabled = configuration.tapGestureEnabled(UserHandle.USER_CURRENT);
- }
- };
-
- /**
- * If set to true, the current gesture started below the notch and we need to dispatch touch
- * events manually as it's outside of the regular view bounds.
- */
- private boolean mExpandingBelowNotch;
- private KeyguardBypassController mBypassController;
+ private InteractionEventHandler mInteractionEventHandler;
public StatusBarWindowView(Context context, AttributeSet attrs) {
super(context, attrs);
setMotionEventSplittingEnabled(false);
- mTransparentSrcPaint.setColor(0);
- mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
- mFalsingManager = Dependency.get(FalsingManager.class); // TODO: inject into a controller.
- mGestureDetector = new GestureDetector(context, mGestureListener);
- mStatusBarStateController = Dependency.get(StatusBarStateController.class);
- Dependency.get(TunerService.class).addTunable(mTunable,
- Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
- Settings.Secure.DOZE_TAP_SCREEN_GESTURE);
}
@Override
@@ -226,11 +137,6 @@
}
}
- @VisibleForTesting
- protected NotificationStackScrollLayout getStackScrollLayout() {
- return mStackScrollLayout;
- }
-
@Override
public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
@@ -242,61 +148,6 @@
}
@Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mStackScrollLayout = findViewById(R.id.notification_stack_scroller);
- mNotificationPanel = findViewById(R.id.notification_panel);
- mBrightnessMirror = findViewById(R.id.brightness_mirror);
- mLockIcon = findViewById(R.id.lock_icon);
- }
-
- @Override
- public void onViewAdded(View child) {
- super.onViewAdded(child);
- if (child.getId() == R.id.brightness_mirror) {
- mBrightnessMirror = child;
- }
- }
-
- /**
- * Propagate {@link StatusBar} pulsing state.
- */
- public void setPulsing(boolean pulsing) {
- if (mLockIcon != null) {
- mLockIcon.setPulsing(pulsing);
- }
- }
-
- /**
- * Called when the biometric authentication mode changes.
- * @param wakeAndUnlock If the type is {@link BiometricUnlockController#isWakeAndUnlock()}
- * @param isUnlock If the type is {@link BiometricUnlockController#isBiometricUnlock()} ()
- */
- public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
- if (mLockIcon != null) {
- mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock, isUnlock);
- }
- }
-
- public void setStatusBarView(PhoneStatusBarView statusBarView) {
- mStatusBarView = statusBarView;
- }
-
- public void setService(StatusBar service) {
- mService = service;
- NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
- ExpandHelper.Callback expandHelperCallback = stackScrollLayout.getExpandHelperCallback();
- DragDownHelper.DragDownCallback dragDownCallback = stackScrollLayout.getDragDownCallback();
- setDragDownHelper(new DragDownHelper(getContext(), this, expandHelperCallback,
- dragDownCallback, mFalsingManager));
- }
-
- @VisibleForTesting
- void setDragDownHelper(DragDownHelper dragDownHelper) {
- mDragDownHelper = dragDownHelper;
- }
-
- @Override
protected void onAttachedToWindow () {
super.onAttachedToWindow();
setWillNotDraw(!DEBUG);
@@ -304,152 +155,53 @@
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- if (mService.interceptMediaKey(event)) {
+ if (mInteractionEventHandler.interceptMediaKey(event)) {
return true;
}
+
if (super.dispatchKeyEvent(event)) {
return true;
}
- boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
- switch (event.getKeyCode()) {
- case KeyEvent.KEYCODE_BACK:
- if (!down) {
- mService.onBackPressed();
- }
- return true;
- case KeyEvent.KEYCODE_MENU:
- if (!down) {
- return mService.onMenuPressed();
- }
- case KeyEvent.KEYCODE_SPACE:
- if (!down) {
- return mService.onSpacePressed();
- }
- break;
- case KeyEvent.KEYCODE_VOLUME_DOWN:
- case KeyEvent.KEYCODE_VOLUME_UP:
- if (mService.isDozing()) {
- MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(
- event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
- return true;
- }
- break;
- }
- return false;
+
+ return mInteractionEventHandler.dispatchKeyEvent(event);
}
- public void setTouchActive(boolean touchActive) {
- mTouchActive = touchActive;
- }
-
- void suppressWakeUpGesture(boolean suppress) {
- mSuppressingWakeUpGesture = suppress;
+ protected void setInteractionEventHandler(InteractionEventHandler listener) {
+ mInteractionEventHandler = listener;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
- boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
- boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
- boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
+ Boolean result = mInteractionEventHandler.handleDispatchTouchEvent(ev);
- // Reset manual touch dispatch state here but make sure the UP/CANCEL event still gets
- // delivered.
- boolean expandingBelowNotch = mExpandingBelowNotch;
- if (isUp || isCancel) {
- mExpandingBelowNotch = false;
- }
-
- if (!isCancel && mService.shouldIgnoreTouch()) {
- return false;
- }
- if (isDown && mNotificationPanel.isFullyCollapsed()) {
- mNotificationPanel.startExpandLatencyTracking();
- }
- if (isDown) {
- setTouchActive(true);
- mTouchCancelled = false;
- } else if (ev.getActionMasked() == MotionEvent.ACTION_UP
- || ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {
- setTouchActive(false);
- }
- if (mTouchCancelled || mExpandAnimationRunning || mExpandAnimationPending) {
- return false;
- }
- mFalsingManager.onTouchEvent(ev, getWidth(), getHeight());
- mGestureDetector.onTouchEvent(ev);
- if (mBrightnessMirror != null && mBrightnessMirror.getVisibility() == VISIBLE) {
- // Disallow new pointers while the brightness mirror is visible. This is so that you
- // can't touch anything other than the brightness slider while the mirror is showing
- // and the rest of the panel is transparent.
- if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
- return false;
- }
- }
- if (isDown) {
- getStackScrollLayout().closeControlsIfOutsideTouch(ev);
- }
- if (mService.isDozing()) {
- mService.mDozeScrimController.extendPulse();
- }
-
- // In case we start outside of the view bounds (below the status bar), we need to dispatch
- // the touch manually as the view system can't accomodate for touches outside of the
- // regular view bounds.
- if (isDown && ev.getY() >= mBottom) {
- mExpandingBelowNotch = true;
- expandingBelowNotch = true;
- }
- if (expandingBelowNotch) {
- return mStatusBarView.dispatchTouchEvent(ev);
- }
-
- return super.dispatchTouchEvent(ev);
+ return result != null ? result : super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
- NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
- if (mService.isDozing() && !mService.isPulsing()) {
- // Capture all touch events in always-on.
- return true;
- }
- boolean intercept = false;
- if (mNotificationPanel.isFullyExpanded()
- && mDragDownHelper.isDragDownEnabled()
- && !mService.isBouncerShowing()
- && !mService.isDozing()) {
- intercept = mDragDownHelper.onInterceptTouchEvent(ev);
- }
+ boolean intercept = mInteractionEventHandler.shouldInterceptTouchEvent(ev);
if (!intercept) {
- super.onInterceptTouchEvent(ev);
+ intercept = super.onInterceptTouchEvent(ev);
}
if (intercept) {
- MotionEvent cancellation = MotionEvent.obtain(ev);
- cancellation.setAction(MotionEvent.ACTION_CANCEL);
- stackScrollLayout.onInterceptTouchEvent(cancellation);
- mNotificationPanel.onInterceptTouchEvent(cancellation);
- cancellation.recycle();
+ mInteractionEventHandler.didIntercept(ev);
}
+
return intercept;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
- boolean handled = false;
- if (mService.isDozing()) {
- handled = !mService.isPulsing();
- }
- if ((mDragDownHelper.isDragDownEnabled() && !handled) || mDragDownHelper.isDraggingDown()) {
- // we still want to finish our drag down gesture when locking the screen
- handled = mDragDownHelper.onTouchEvent(ev);
- }
+ boolean handled = mInteractionEventHandler.handleTouchEvent(ev);
+
if (!handled) {
handled = super.onTouchEvent(ev);
}
- final int action = ev.getAction();
- if (!handled && (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL)) {
- mService.setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
+
+ if (!handled) {
+ mInteractionEventHandler.didNotHandleTouchEvent(ev);
}
+
return handled;
}
@@ -465,77 +217,6 @@
}
}
- public void cancelExpandHelper() {
- NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
- if (stackScrollLayout != null) {
- stackScrollLayout.cancelExpandHelper();
- }
- }
-
- public void cancelCurrentTouch() {
- if (mTouchActive) {
- final long now = SystemClock.uptimeMillis();
- MotionEvent event = MotionEvent.obtain(now, now,
- MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
- event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
- dispatchTouchEvent(event);
- event.recycle();
- mTouchCancelled = true;
- }
- }
-
- public void setExpandAnimationRunning(boolean expandAnimationRunning) {
- mExpandAnimationRunning = expandAnimationRunning;
- }
-
- public void setExpandAnimationPending(boolean pending) {
- mExpandAnimationPending = pending;
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.print(" mExpandAnimationPending="); pw.println(mExpandAnimationPending);
- pw.print(" mExpandAnimationRunning="); pw.println(mExpandAnimationRunning);
- pw.print(" mTouchCancelled="); pw.println(mTouchCancelled);
- pw.print(" mTouchActive="); pw.println(mTouchActive);
- }
-
- /**
- * Called whenever the scrims become opaque, transparent or semi-transparent.
- */
- public void onScrimVisibilityChanged(@ScrimVisibility int scrimsVisible) {
- if (mLockIcon != null) {
- mLockIcon.onScrimVisibilityChanged(scrimsVisible);
- }
- }
-
- /**
- * When we're launching an affordance, like double pressing power to open camera.
- */
- public void onShowingLaunchAffordanceChanged(boolean showing) {
- if (mLockIcon != null) {
- mLockIcon.onShowingLaunchAffordanceChanged(showing);
- }
- }
-
- public void setBypassController(KeyguardBypassController bypassController) {
- mBypassController = bypassController;
- }
-
- public void setBouncerShowingScrimmed(boolean bouncerShowing) {
- if (mLockIcon != null) {
- mLockIcon.setBouncerShowingScrimmed(bouncerShowing);
- }
- }
-
- /**
- * When {@link KeyguardBouncer} starts to be dismissed and starts to play its animation.
- */
- public void onBouncerPreHideAnimation() {
- if (mLockIcon != null) {
- mLockIcon.onBouncerPreHideAnimation();
- }
- }
-
public class LayoutParams extends FrameLayout.LayoutParams {
public boolean ignoreRightInset;
@@ -657,6 +338,35 @@
}
}
+ interface InteractionEventHandler {
+ /**
+ * Returns a result for {@link ViewGroup#dispatchTouchEvent(MotionEvent)} or null to defer
+ * to the super method.
+ */
+ Boolean handleDispatchTouchEvent(MotionEvent ev);
+
+ /**
+ * Returns if the view should intercept the touch event.
+ *
+ * The touch event may still be interecepted if
+ * {@link ViewGroup#onInterceptTouchEvent(MotionEvent)} decides to do so.
+ */
+ boolean shouldInterceptTouchEvent(MotionEvent ev);
+
+ /**
+ * Called when the view decides to intercept the touch event.
+ */
+ void didIntercept(MotionEvent ev);
+
+ boolean handleTouchEvent(MotionEvent ev);
+
+ void didNotHandleTouchEvent(MotionEvent ev);
+
+ boolean interceptMediaKey(KeyEvent event);
+
+ boolean dispatchKeyEvent(KeyEvent event);
+ }
+
/**
* Minimal window to satisfy FloatingToolbar.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
new file mode 100644
index 0000000..f21085e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowViewController.java
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2019 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.systemui.statusbar.phone;
+
+import android.app.StatusBarManager;
+import android.hardware.display.AmbientDisplayConfiguration;
+import android.media.AudioManager;
+import android.media.session.MediaSessionLegacyHelper;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.view.GestureDetector;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewStub;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.ExpandHelper;
+import com.android.systemui.R;
+import com.android.systemui.doze.DozeLog;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.DragDownHelper;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.InjectionInflationController;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import javax.inject.Inject;
+
+/**
+ * Controller for {@link StatusBarWindowView}.
+ */
+public class StatusBarWindowViewController {
+ private final StatusBarWindowView mView;
+ private final FalsingManager mFalsingManager;
+ private final GestureDetector mGestureDetector;
+ private View mBrightnessMirror;
+ private boolean mTouchActive;
+ private boolean mTouchCancelled;
+ private boolean mExpandAnimationPending;
+ private boolean mExpandAnimationRunning;
+ private NotificationStackScrollLayout mStackScrollLayout;
+ private LockIcon mLockIcon;
+ private PhoneStatusBarView mStatusBarView;
+ private StatusBar mService;
+ private DragDownHelper mDragDownHelper;
+ private boolean mSuppressingWakeUpGesture;
+ private boolean mDoubleTapEnabled;
+ private boolean mSingleTapEnabled;
+ private boolean mExpandingBelowNotch;
+
+ private StatusBarWindowViewController(
+ StatusBarWindowView view,
+ InjectionInflationController injectionInflationController,
+ NotificationWakeUpCoordinator coordinator,
+ PulseExpansionHandler pulseExpansionHandler,
+ DynamicPrivacyController dynamicPrivacyController,
+ KeyguardBypassController bypassController,
+ FalsingManager falsingManager,
+ PluginManager pluginManager,
+ TunerService tunerService,
+ ShadeController shadeController,
+ NotificationLockscreenUserManager notificationLockscreenUserManager,
+ NotificationEntryManager notificationEntryManager,
+ DozeLog dozeLog) {
+ mView = view;
+ mFalsingManager = falsingManager;
+
+ // TODO: create controller for NotificationPanelView
+ NotificationPanelView notificationPanelView = new NotificationPanelView(
+ view.getContext(),
+ null,
+ injectionInflationController,
+ coordinator,
+ pulseExpansionHandler,
+ dynamicPrivacyController,
+ bypassController,
+ falsingManager,
+ pluginManager,
+ shadeController,
+ notificationLockscreenUserManager,
+ notificationEntryManager,
+ dozeLog);
+ ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ notificationPanelView.setVisibility(View.INVISIBLE);
+ notificationPanelView.setId(R.id.notification_panel);
+ LayoutInflater li = injectionInflationController.injectable(
+ LayoutInflater.from(mView.getContext()));
+
+ li.inflate(R.layout.status_bar_expanded, notificationPanelView);
+ notificationPanelView.onChildrenAttached();
+
+ ViewStub statusBarExpanded = view.findViewById(R.id.status_bar_expanded);
+ mView.addView(notificationPanelView, mView.indexOfChild(statusBarExpanded), lp);
+ mView.removeView(statusBarExpanded);
+
+ mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller);
+ mLockIcon = mView.findViewById(R.id.lock_icon);
+ mBrightnessMirror = mView.findViewById(R.id.brightness_mirror);
+
+ TunerService.Tunable tunable = (key, newValue) -> {
+ AmbientDisplayConfiguration configuration =
+ new AmbientDisplayConfiguration(mView.getContext());
+ switch (key) {
+ case Settings.Secure.DOZE_DOUBLE_TAP_GESTURE:
+ mDoubleTapEnabled = configuration.doubleTapGestureEnabled(
+ UserHandle.USER_CURRENT);
+ break;
+ case Settings.Secure.DOZE_TAP_SCREEN_GESTURE:
+ mSingleTapEnabled = configuration.tapGestureEnabled(UserHandle.USER_CURRENT);
+ }
+ };
+ tunerService.addTunable(tunable,
+ Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
+ Settings.Secure.DOZE_TAP_SCREEN_GESTURE);
+
+ GestureDetector.SimpleOnGestureListener gestureListener =
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent e) {
+ if (mSingleTapEnabled && !mSuppressingWakeUpGesture) {
+ mService.wakeUpIfDozing(
+ SystemClock.uptimeMillis(), mView, "SINGLE_TAP");
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ if (mDoubleTapEnabled || mSingleTapEnabled) {
+ mService.wakeUpIfDozing(
+ SystemClock.uptimeMillis(), mView, "DOUBLE_TAP");
+ return true;
+ }
+ return false;
+ }
+ };
+ mGestureDetector = new GestureDetector(mView.getContext(), gestureListener);
+
+ mView.setInteractionEventHandler(new StatusBarWindowView.InteractionEventHandler() {
+ @Override
+ public Boolean handleDispatchTouchEvent(MotionEvent ev) {
+ boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
+ boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
+ boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
+
+ if (isUp || isCancel) {
+ mExpandingBelowNotch = false;
+ }
+
+ // Reset manual touch dispatch state here but make sure the UP/CANCEL event still
+ // gets
+ // delivered.
+
+ if (!isCancel && mService.shouldIgnoreTouch()) {
+ return false;
+ }
+ if (isDown && notificationPanelView.isFullyCollapsed()) {
+ notificationPanelView.startExpandLatencyTracking();
+ }
+ if (isDown) {
+ setTouchActive(true);
+ mTouchCancelled = false;
+ } else if (ev.getActionMasked() == MotionEvent.ACTION_UP
+ || ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {
+ setTouchActive(false);
+ }
+ if (mTouchCancelled || mExpandAnimationRunning || mExpandAnimationPending) {
+ return false;
+ }
+ mFalsingManager.onTouchEvent(ev, mView.getWidth(), mView.getHeight());
+ mGestureDetector.onTouchEvent(ev);
+ if (mBrightnessMirror != null
+ && mBrightnessMirror.getVisibility() == View.VISIBLE) {
+ // Disallow new pointers while the brightness mirror is visible. This is so that
+ // you can't touch anything other than the brightness slider while the mirror is
+ // showing and the rest of the panel is transparent.
+ if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
+ return false;
+ }
+ }
+ if (isDown) {
+ getStackScrollLayout().closeControlsIfOutsideTouch(ev);
+ }
+ if (mService.isDozing()) {
+ mService.mDozeScrimController.extendPulse();
+ }
+ // In case we start outside of the view bounds (below the status bar), we need to
+ // dispatch
+ // the touch manually as the view system can't accommodate for touches outside of
+ // the
+ // regular view bounds.
+ if (isDown && ev.getY() >= mView.getBottom()) {
+ mExpandingBelowNotch = true;
+ }
+ if (mExpandingBelowNotch) {
+ return mStatusBarView.dispatchTouchEvent(ev);
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean shouldInterceptTouchEvent(MotionEvent ev) {
+ if (mService.isDozing() && !mService.isPulsing()) {
+ // Capture all touch events in always-on.
+ return true;
+ }
+ boolean intercept = false;
+ if (notificationPanelView.isFullyExpanded()
+ && mDragDownHelper.isDragDownEnabled()
+ && !mService.isBouncerShowing()
+ && !mService.isDozing()) {
+ intercept = mDragDownHelper.onInterceptTouchEvent(ev);
+ }
+
+ return intercept;
+
+ }
+
+ @Override
+ public void didIntercept(MotionEvent ev) {
+ NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
+ MotionEvent cancellation = MotionEvent.obtain(ev);
+ cancellation.setAction(MotionEvent.ACTION_CANCEL);
+ stackScrollLayout.onInterceptTouchEvent(cancellation);
+ notificationPanelView.onInterceptTouchEvent(cancellation);
+ cancellation.recycle();
+ }
+
+ @Override
+ public boolean handleTouchEvent(MotionEvent ev) {
+ boolean handled = false;
+ if (mService.isDozing()) {
+ handled = !mService.isPulsing();
+ }
+ if ((mDragDownHelper.isDragDownEnabled() && !handled)
+ || mDragDownHelper.isDraggingDown()) {
+ // we still want to finish our drag down gesture when locking the screen
+ handled = mDragDownHelper.onTouchEvent(ev);
+ }
+
+ return handled;
+ }
+
+ @Override
+ public void didNotHandleTouchEvent(MotionEvent ev) {
+ final int action = ev.getActionMasked();
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ mService.setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
+ }
+ }
+
+ @Override
+ public boolean interceptMediaKey(KeyEvent event) {
+ return mService.interceptMediaKey(event);
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
+ switch (event.getKeyCode()) {
+ case KeyEvent.KEYCODE_BACK:
+ if (!down) {
+ mService.onBackPressed();
+ }
+ return true;
+ case KeyEvent.KEYCODE_MENU:
+ if (!down) {
+ return mService.onMenuPressed();
+ }
+ break;
+ case KeyEvent.KEYCODE_SPACE:
+ if (!down) {
+ return mService.onSpacePressed();
+ }
+ break;
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ if (mService.isDozing()) {
+ MediaSessionLegacyHelper.getHelper(mView.getContext())
+ .sendVolumeKeyEvent(
+ event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
+ return true;
+ }
+ break;
+ }
+ return false;
+ }
+ });
+
+ mView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
+ @Override
+ public void onChildViewAdded(View parent, View child) {
+ if (child.getId() == R.id.brightness_mirror) {
+ mBrightnessMirror = child;
+ }
+ }
+
+ @Override
+ public void onChildViewRemoved(View parent, View child) {
+ }
+ });
+ }
+
+ public StatusBarWindowView getView() {
+ return mView;
+ }
+
+ public void setTouchActive(boolean touchActive) {
+ mTouchActive = touchActive;
+ }
+
+ public void cancelCurrentTouch() {
+ if (mTouchActive) {
+ final long now = SystemClock.uptimeMillis();
+ MotionEvent event = MotionEvent.obtain(now, now,
+ MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
+ event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ mView.dispatchTouchEvent(event);
+ event.recycle();
+ mTouchCancelled = true;
+ }
+ }
+
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.print(" mExpandAnimationPending=");
+ pw.println(mExpandAnimationPending);
+ pw.print(" mExpandAnimationRunning=");
+ pw.println(mExpandAnimationRunning);
+ pw.print(" mTouchCancelled=");
+ pw.println(mTouchCancelled);
+ pw.print(" mTouchActive=");
+ pw.println(mTouchActive);
+ }
+
+ public void setExpandAnimationPending(boolean pending) {
+ mExpandAnimationPending = pending;
+ }
+
+ public void setExpandAnimationRunning(boolean running) {
+ mExpandAnimationRunning = running;
+ }
+
+ public void cancelExpandHelper() {
+ NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
+ if (stackScrollLayout != null) {
+ stackScrollLayout.cancelExpandHelper();
+ }
+ }
+
+ @VisibleForTesting
+ protected NotificationStackScrollLayout getStackScrollLayout() {
+ return mStackScrollLayout;
+ }
+
+ /**
+ * Called whenever the scrims become opaque, transparent or semi-transparent.
+ */
+ public void onScrimVisibilityChanged(Integer scrimsVisible) {
+ if (mLockIcon != null) {
+ mLockIcon.onScrimVisibilityChanged(scrimsVisible);
+ }
+ }
+
+ /**
+ * Propagate {@link StatusBar} pulsing state.
+ */
+ public void setPulsing(boolean pulsing) {
+ if (mLockIcon != null) {
+ mLockIcon.setPulsing(pulsing);
+ }
+ }
+
+ /**
+ * Called when the biometric authentication mode changes.
+ *
+ * @param wakeAndUnlock If the type is {@link BiometricUnlockController#isWakeAndUnlock()}
+ * @param isUnlock If the type is {@link BiometricUnlockController#isBiometricUnlock()} ()
+ */
+ public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
+ if (mLockIcon != null) {
+ mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock, isUnlock);
+ }
+ }
+
+ public void setStatusBarView(PhoneStatusBarView statusBarView) {
+ mStatusBarView = statusBarView;
+ }
+
+ public void setService(StatusBar statusBar) {
+ mService = statusBar;
+ NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
+ ExpandHelper.Callback expandHelperCallback = stackScrollLayout.getExpandHelperCallback();
+ DragDownHelper.DragDownCallback dragDownCallback = stackScrollLayout.getDragDownCallback();
+ setDragDownHelper(
+ new DragDownHelper(
+ mView.getContext(), mView, expandHelperCallback,
+ dragDownCallback, mFalsingManager));
+ }
+
+ @VisibleForTesting
+ void setDragDownHelper(DragDownHelper dragDownHelper) {
+ mDragDownHelper = dragDownHelper;
+ }
+
+ public void suppressWakeUpGesture(boolean suppress) {
+ mSuppressingWakeUpGesture = suppress;
+ }
+
+ /**
+ * When we're launching an affordance, like double pressing power to open camera.
+ */
+ public void onShowingLaunchAffordanceChanged(Boolean showing) {
+ if (mLockIcon != null) {
+ mLockIcon.onShowingLaunchAffordanceChanged(showing);
+ }
+ }
+
+ public void setBouncerShowingScrimmed(boolean bouncerShowing) {
+ if (mLockIcon != null) {
+ mLockIcon.setBouncerShowingScrimmed(bouncerShowing);
+ }
+ }
+
+ /**
+ * When {@link KeyguardBouncer} starts to be dismissed and starts to play its animation.
+ */
+ public void onBouncerPreHideAnimation() {
+ if (mLockIcon != null) {
+ mLockIcon.onBouncerPreHideAnimation();
+ }
+ }
+
+ /**
+ * Builder for {@link StatusBarWindowViewController}.
+ */
+ public static class Builder {
+ private final InjectionInflationController mInjectionInflationController;
+ private final NotificationWakeUpCoordinator mCoordinator;
+ private final PulseExpansionHandler mPulseExpansionHandler;
+ private final DynamicPrivacyController mDynamicPrivacyController;
+ private final KeyguardBypassController mBypassController;
+ private final FalsingManager mFalsingManager;
+ private final PluginManager mPluginManager;
+ private final TunerService mTunerService;
+ private ShadeController mShadeController;
+ private final NotificationLockscreenUserManager mNotificationLockScreenUserManager;
+ private final NotificationEntryManager mNotificationEntryManager;
+ private final DozeLog mDozeLog;
+ private StatusBarWindowView mView;
+
+ @Inject
+ public Builder(
+ InjectionInflationController injectionInflationController,
+ NotificationWakeUpCoordinator coordinator,
+ PulseExpansionHandler pulseExpansionHandler,
+ DynamicPrivacyController dynamicPrivacyController,
+ KeyguardBypassController bypassController,
+ FalsingManager falsingManager,
+ PluginManager pluginManager,
+ TunerService tunerService,
+ NotificationLockscreenUserManager notificationLockscreenUserManager,
+ NotificationEntryManager notificationEntryManager,
+ DozeLog dozeLog) {
+ mInjectionInflationController = injectionInflationController;
+ mCoordinator = coordinator;
+ mPulseExpansionHandler = pulseExpansionHandler;
+ mDynamicPrivacyController = dynamicPrivacyController;
+ mBypassController = bypassController;
+ mFalsingManager = falsingManager;
+ mPluginManager = pluginManager;
+ mTunerService = tunerService;
+ mNotificationLockScreenUserManager = notificationLockscreenUserManager;
+ mNotificationEntryManager = notificationEntryManager;
+ mDozeLog = dozeLog;
+ }
+
+ /**
+ * Provide {@link StatusBarWindowView} to attach this controller to.
+ */
+ public Builder setStatusBarWindowView(StatusBarWindowView view) {
+ mView = view;
+ return this;
+ }
+
+ /**
+ * Provide {@link ShadeController} that this view needs.
+ */
+ public Builder setShadeController(ShadeController shadeController) {
+ mShadeController = shadeController;
+ return this;
+ }
+
+ /**
+ * Build a {@link StatusBarWindowView}.
+ */
+ public StatusBarWindowViewController build() {
+ return new StatusBarWindowViewController(
+ mView,
+ mInjectionInflationController,
+ mCoordinator,
+ mPulseExpansionHandler,
+ mDynamicPrivacyController,
+ mBypassController,
+ mFalsingManager,
+ mPluginManager,
+ mTunerService,
+ mShadeController,
+ mNotificationLockScreenUserManager,
+ mNotificationEntryManager,
+ mDozeLog);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
index a46f018..47b56e0 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.PermissionChecker;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.hardware.usb.IUsbManager;
@@ -84,14 +85,27 @@
final AlertController.AlertParams ap = mAlertParams;
ap.mTitle = appName;
if (mDevice == null) {
+ // Accessory Case
+
ap.mMessage = getString(R.string.usb_accessory_permission_prompt, appName,
mAccessory.getDescription());
mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
} else {
- ap.mMessage = getString(R.string.usb_device_permission_prompt, appName,
- mDevice.getProductName());
+ boolean hasRecordPermission =
+ PermissionChecker.checkPermissionForPreflight(
+ this, android.Manifest.permission.RECORD_AUDIO, -1, aInfo.uid,
+ mPackageName)
+ == android.content.pm.PackageManager.PERMISSION_GRANTED;
+ boolean isAudioCaptureDevice = mDevice.getHasAudioCapture();
+ boolean useRecordWarning = isAudioCaptureDevice && !hasRecordPermission;
+
+ int strID = useRecordWarning
+ ? R.string.usb_device_permission_prompt_warn
+ : R.string.usb_device_permission_prompt;
+ ap.mMessage = getString(strID, appName, mDevice.getProductName());
mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mDevice);
}
+
ap.mPositiveButtonText = getString(android.R.string.ok);
ap.mNegativeButtonText = getString(android.R.string.cancel);
ap.mPositiveButtonListener = this;
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
index fa7af0b..be5e0a0 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
@@ -36,6 +36,7 @@
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -53,7 +54,7 @@
private final Context context;
private Uri hprofUri;
- private long pss;
+ private long rss;
final StringBuilder body = new StringBuilder();
public DumpTruck(Context context) {
@@ -66,7 +67,7 @@
* @param pids
* @return this, for chaining
*/
- public DumpTruck captureHeaps(int[] pids) {
+ public DumpTruck captureHeaps(List<Long> pids) {
final GarbageMonitor gm = Dependency.get(GarbageMonitor.class);
final File dumpDir = new File(context.getCacheDir(), FILEPROVIDER_PATH);
@@ -79,8 +80,8 @@
final ArrayList<String> paths = new ArrayList<String>();
final int myPid = android.os.Process.myPid();
- final int[] pids_copy = Arrays.copyOf(pids, pids.length);
- for (int pid : pids_copy) {
+ for (Long pidL : pids) {
+ final int pid = pidL.intValue();
body.append(" pid ").append(pid);
if (gm != null) {
GarbageMonitor.ProcessMemInfo info = gm.getMemInfo(pid);
@@ -88,11 +89,9 @@
body.append(":")
.append(" up=")
.append(info.getUptime())
- .append(" pss=")
- .append(info.currentPss)
- .append(" uss=")
- .append(info.currentUss);
- pss = info.currentPss;
+ .append(" rss=")
+ .append(info.currentRss);
+ rss = info.currentRss;
}
}
if (pid == myPid) {
@@ -147,7 +146,7 @@
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_SUBJECT,
- String.format("SystemUI memory dump (pss=%dM)", pss / 1024));
+ String.format("SystemUI memory dump (rss=%dM)", rss / 1024));
shareIntent.putExtra(Intent.EXTRA_TEXT, body.toString());
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index e84d9a9..2d5ebc4 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -35,7 +35,6 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
-import android.os.Debug;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -49,6 +48,7 @@
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
+import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
@@ -56,6 +56,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
@@ -101,7 +102,6 @@
private final LongSparseArray<ProcessMemInfo> mData = new LongSparseArray<>();
private final ArrayList<Long> mPids = new ArrayList<>();
- private int[] mPidsArray = new int[1];
private long mHeapLimit;
@@ -163,8 +163,8 @@
return mData.get(pid);
}
- public int[] getTrackedProcesses() {
- return mPidsArray;
+ public List<Long> getTrackedProcesses() {
+ return mPids;
}
public void startTrackingProcess(long pid, String name, long start) {
@@ -172,43 +172,40 @@
if (mPids.contains(pid)) return;
mPids.add(pid);
- updatePidsArrayL();
+ logPids();
mData.put(pid, new ProcessMemInfo(pid, name, start));
}
}
- private void updatePidsArrayL() {
- final int N = mPids.size();
- mPidsArray = new int[N];
- StringBuffer sb = new StringBuffer("Now tracking processes: ");
- for (int i = 0; i < N; i++) {
- final int p = mPids.get(i).intValue();
- mPidsArray[i] = p;
- sb.append(p);
- sb.append(" ");
+ private void logPids() {
+ if (DEBUG) {
+ StringBuffer sb = new StringBuffer("Now tracking processes: ");
+ for (int i = 0; i < mPids.size(); i++) {
+ final int p = mPids.get(i).intValue();
+ sb.append(" ");
+ }
+ Log.v(TAG, sb.toString());
}
- if (DEBUG) Log.v(TAG, sb.toString());
}
private void update() {
synchronized (mPids) {
- Debug.MemoryInfo[] dinfos = mAm.getProcessMemoryInfo(mPidsArray);
- for (int i = 0; i < dinfos.length; i++) {
- Debug.MemoryInfo dinfo = dinfos[i];
- if (i > mPids.size()) {
- if (DEBUG) Log.e(TAG, "update: unknown process info received: " + dinfo);
+ for (int i = 0; i < mPids.size(); i++) {
+ final int pid = mPids.get(i).intValue();
+ // rssValues contains [VmRSS, RssFile, RssAnon, VmSwap].
+ long[] rssValues = Process.getRss(pid);
+ if (rssValues == null && rssValues.length == 0) {
+ if (DEBUG) Log.e(TAG, "update: Process.getRss() didn't provide any values.");
break;
}
- final long pid = mPids.get(i).intValue();
+ long rss = rssValues[0];
final ProcessMemInfo info = mData.get(pid);
- info.pss[info.head] = info.currentPss = dinfo.getTotalPss();
- info.uss[info.head] = info.currentUss = dinfo.getTotalPrivateDirty();
- info.head = (info.head + 1) % info.pss.length;
- if (info.currentPss > info.max) info.max = info.currentPss;
- if (info.currentUss > info.max) info.max = info.currentUss;
- if (info.currentPss == 0) {
- if (DEBUG) Log.v(TAG, "update: pid " + pid + " has pss=0, it probably died");
+ info.rss[info.head] = info.currentRss = rss;
+ info.head = (info.head + 1) % info.rss.length;
+ if (info.currentRss > info.max) info.max = info.currentRss;
+ if (info.currentRss == 0) {
+ if (DEBUG) Log.v(TAG, "update: pid " + pid + " has rss=0, it probably died");
mData.remove(pid);
}
}
@@ -216,7 +213,7 @@
final long pid = mPids.get(i).intValue();
if (mData.get(pid) == null) {
mPids.remove(i);
- updatePidsArrayL();
+ logPids();
}
}
}
@@ -269,7 +266,7 @@
private static class MemoryIconDrawable extends Drawable {
- long pss, limit;
+ long rss, limit;
final Drawable baseIcon;
final Paint paint = new Paint();
final float dp;
@@ -280,9 +277,9 @@
paint.setColor(QSTileImpl.getColorForState(context, STATE_ACTIVE));
}
- public void setPss(long pss) {
- if (pss != this.pss) {
- this.pss = pss;
+ public void setRss(long rss) {
+ if (rss != this.rss) {
+ this.rss = rss;
invalidateSelf();
}
}
@@ -298,8 +295,8 @@
public void draw(Canvas canvas) {
baseIcon.draw(canvas);
- if (limit > 0 && pss > 0) {
- float frac = Math.min(1f, (float) pss / limit);
+ if (limit > 0 && rss > 0) {
+ float frac = Math.min(1f, (float) rss / limit);
final Rect bounds = getBounds();
canvas.translate(bounds.left + 8 * dp, bounds.top + 5 * dp);
@@ -360,10 +357,10 @@
}
private static class MemoryGraphIcon extends QSTile.Icon {
- long pss, limit;
+ long rss, limit;
- public void setPss(long pss) {
- this.pss = pss;
+ public void setRss(long rss) {
+ this.rss = rss;
}
public void setHeapLimit(long limit) {
@@ -373,7 +370,7 @@
@Override
public Drawable getDrawable(Context context) {
final MemoryIconDrawable drawable = new MemoryIconDrawable(context);
- drawable.setPss(pss);
+ drawable.setRss(rss);
drawable.setLimit(limit);
return drawable;
}
@@ -386,13 +383,15 @@
public static final boolean ADD_TO_DEFAULT_ON_DEBUGGABLE_BUILDS = true;
private final GarbageMonitor gm;
+ private final ActivityStarter mActivityStarter;
private ProcessMemInfo pmi;
private boolean dumpInProgress;
@Inject
- public MemoryTile(QSHost host, GarbageMonitor monitor) {
+ public MemoryTile(QSHost host, GarbageMonitor monitor, ActivityStarter starter) {
super(host);
gm = monitor;
+ mActivityStarter = starter;
}
@Override
@@ -423,7 +422,7 @@
dumpInProgress = false;
refreshState();
getHost().collapsePanels();
- mContext.startActivity(shareIntent);
+ mActivityStarter.postStartActivityDismissingKeyguard(shareIntent, 0);
});
}
}.start();
@@ -461,14 +460,14 @@
? "Dumping..."
: mContext.getString(R.string.heap_dump_tile_name);
if (pmi != null) {
- icon.setPss(pmi.currentPss);
+ icon.setRss(pmi.currentRss);
state.secondaryLabel =
String.format(
- "pss: %s / %s",
- formatBytes(pmi.currentPss * 1024),
+ "rss: %s / %s",
+ formatBytes(pmi.currentRss * 1024),
formatBytes(gm.mHeapLimit * 1024));
} else {
- icon.setPss(0);
+ icon.setRss(0);
state.secondaryLabel = null;
}
state.icon = icon;
@@ -478,8 +477,8 @@
refreshState();
}
- public long getPss() {
- return pmi != null ? pmi.currentPss : 0;
+ public long getRss() {
+ return pmi != null ? pmi.currentRss : 0;
}
public long getHeapLimit() {
@@ -492,9 +491,8 @@
public long pid;
public String name;
public long startTime;
- public long currentPss, currentUss;
- public long[] pss = new long[HEAP_TRACK_HISTORY_LEN];
- public long[] uss = new long[HEAP_TRACK_HISTORY_LEN];
+ public long currentRss;
+ public long[] rss = new long[HEAP_TRACK_HISTORY_LEN];
public long max = 1;
public int head = 0;
@@ -516,17 +514,12 @@
pw.print(name.replace('"', '-'));
pw.print("\", \"start\": ");
pw.print(startTime);
- pw.print(", \"pss\": [");
- // write pss values starting from the oldest, which is pss[head], wrapping around to
- // pss[(head-1) % pss.length]
- for (int i = 0; i < pss.length; i++) {
+ pw.print(", \"rss\": [");
+ // write rss values starting from the oldest, which is rss[head], wrapping around to
+ // rss[(head-1) % rss.length]
+ for (int i = 0; i < rss.length; i++) {
if (i > 0) pw.print(",");
- pw.print(pss[(head + i) % pss.length]);
- }
- pw.print("], \"uss\": [");
- for (int i = 0; i < uss.length; i++) {
- if (i > 0) pw.print(",");
- pw.print(uss[(head + i) % uss.length]);
+ pw.print(rss[(head + i) % rss.length]);
}
pw.println("] }");
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
index 2e94c7c..38537fd 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
@@ -26,20 +26,24 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.Context;
import android.net.ConnectivityManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Process;
import android.provider.Settings;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
@@ -62,6 +66,7 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
import java.util.ArrayList;
import java.util.HashMap;
@@ -105,6 +110,14 @@
private CarrierTextController mCarrierTextController;
private TestableLooper mTestableLooper;
+ private Void checkMainThread(InvocationOnMock inv) {
+ Looper mainLooper = Dependency.get(Dependency.MAIN_HANDLER).getLooper();
+ if (!mainLooper.isCurrentThread()) {
+ fail("This call should be done from the main thread");
+ }
+ return null;
+ }
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -112,6 +125,7 @@
mContext.addMockSystemService(WifiManager.class, mWifiManager);
mContext.addMockSystemService(ConnectivityManager.class, mConnectivityManager);
+ when(mConnectivityManager.isNetworkSupported(anyInt())).thenReturn(true);
mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
mContext.addMockSystemService(SubscriptionManager.class, mSubscriptionManager);
mContext.getOrCreateTestableResources().addOverride(
@@ -121,19 +135,43 @@
mDependency.injectMockDependency(WakefulnessLifecycle.class);
mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
new Handler(mTestableLooper.getLooper()));
- mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
+ mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
+
+ doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
+ .registerCallback(any(KeyguardUpdateMonitorCallback.class));
+ doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
+ .removeCallback(any(KeyguardUpdateMonitorCallback.class));
mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("",
new CharSequence[]{}, false, new int[]{});
- when(mTelephonyManager.getPhoneCount()).thenReturn(3);
+ when(mTelephonyManager.getMaxPhoneCount()).thenReturn(3);
- mCarrierTextController = new TestCarrierTextController(mContext, SEPARATOR, true, true,
- mKeyguardUpdateMonitor);
- // This should not start listening on any of the real dependencies
+ mCarrierTextController = new CarrierTextController(mContext, SEPARATOR, true, true);
+ // This should not start listening on any of the real dependencies but will test that
+ // callbacks in mKeyguardUpdateMonitor are done in the mTestableLooper thread
mCarrierTextController.setListening(mCarrierTextCallback);
}
@Test
+ public void testKeyguardUpdateMonitorCalledInMainThread() throws Exception {
+ // This test will run on the main looper (which is not the same as the looper set as MAIN
+ // for CarrierTextCallback. This will fail if calls to mKeyguardUpdateMonitor are not done
+ // through the looper set in the set up
+ HandlerThread thread = new HandlerThread("testThread",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+ TestableLooper testableLooper = new TestableLooper(thread.getLooper());
+ Handler h = new Handler(testableLooper.getLooper());
+ h.post(() -> {
+ mCarrierTextController.setListening(null);
+ mCarrierTextController.setListening(mCarrierTextCallback);
+ });
+ testableLooper.processAllMessages();
+ mTestableLooper.processAllMessages();
+ thread.quitSafely();
+ }
+
+ @Test
public void testAirplaneMode() {
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
reset(mCarrierTextCallback);
@@ -466,20 +504,4 @@
assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
captor.getValue().carrierText);
}
-
- public static class TestCarrierTextController extends CarrierTextController {
- private KeyguardUpdateMonitor mKUM;
-
- public TestCarrierTextController(Context context, CharSequence separator,
- boolean showAirplaneMode, boolean showMissingSim, KeyguardUpdateMonitor kum) {
- super(context, separator, showAirplaneMode, showMissingSim);
- mKUM = kum;
- }
-
- @Override
- public void setListening(CarrierTextCallback callback) {
- super.setListening(callback);
- mKeyguardUpdateMonitor = mKUM;
- }
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index ad7bba1..57b0987 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -25,6 +25,7 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
@@ -481,6 +482,25 @@
assertThat(mKeyguardUpdateMonitor.isUserUnlocked(randomUser)).isFalse();
}
+ @Test
+ public void testTrustUsuallyManaged_whenTrustChanges() {
+ int user = KeyguardUpdateMonitor.getCurrentUser();
+ when(mTrustManager.isTrustUsuallyManaged(eq(user))).thenReturn(true);
+ mKeyguardUpdateMonitor.onTrustManagedChanged(false /* managed */, user);
+ assertThat(mKeyguardUpdateMonitor.isTrustUsuallyManaged(user)).isTrue();
+ }
+
+ @Test
+ public void testTrustUsuallyManaged_resetWhenUserIsRemoved() {
+ int user = KeyguardUpdateMonitor.getCurrentUser();
+ when(mTrustManager.isTrustUsuallyManaged(eq(user))).thenReturn(true);
+ mKeyguardUpdateMonitor.onTrustManagedChanged(false /* managed */, user);
+ assertThat(mKeyguardUpdateMonitor.isTrustUsuallyManaged(user)).isTrue();
+
+ mKeyguardUpdateMonitor.handleUserRemoved(user);
+ assertThat(mKeyguardUpdateMonitor.isTrustUsuallyManaged(user)).isFalse();
+ }
+
private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) {
int subscription = simInited
? 1/* mock subid=1 */ : SubscriptionManager.DUMMY_SUBSCRIPTION_ID_BASE;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
index a245d41..cf77850 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
@@ -24,6 +24,7 @@
import androidx.test.InstrumentationRegistry;
+import com.android.systemui.assist.AssistManager;
import com.android.systemui.utils.leaks.LeakCheckedTest;
import com.android.systemui.utils.leaks.LeakCheckedTest.SysuiLeakCheck;
@@ -64,6 +65,7 @@
when(inst.getTargetContext()).thenThrow(new RuntimeException(
"SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
+ mDependency.injectMockDependency(AssistManager.class);
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
index 7a09137..2c85424 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.verify;
import android.content.Context;
+import android.hardware.biometrics.Authenticator;
import android.hardware.biometrics.BiometricPrompt;
import android.os.Bundle;
import android.test.suitebuilder.annotation.SmallTest;
@@ -70,7 +71,7 @@
@Test
public void testOnAuthenticationSucceeded_noConfirmationRequired_sendsActionAuthenticated() {
- initDialog(mContext, mCallback, new MockInjector());
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
// The onAuthenticated runnable is posted when authentication succeeds.
mBiometricView.onAuthenticationSucceeded();
@@ -81,7 +82,7 @@
@Test
public void testOnAuthenticationSucceeded_confirmationRequired_updatesDialogContents() {
- initDialog(mContext, mCallback, new MockInjector());
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
mBiometricView.setRequireConfirmation(true);
mBiometricView.onAuthenticationSucceeded();
@@ -97,7 +98,7 @@
@Test
public void testPositiveButton_sendsActionAuthenticated() {
Button button = new Button(mContext);
- initDialog(mContext, mCallback, new MockInjector() {
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
@Override
public Button getPositiveButton() {
return button;
@@ -114,7 +115,7 @@
@Test
public void testNegativeButton_beforeAuthentication_sendsActionButtonNegative() {
Button button = new Button(mContext);
- initDialog(mContext, mCallback, new MockInjector() {
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
@Override
public Button getNegativeButton() {
return button;
@@ -131,7 +132,7 @@
@Test
public void testNegativeButton_whenPendingConfirmation_sendsActionUserCanceled() {
Button button = new Button(mContext);
- initDialog(mContext, mCallback, new MockInjector() {
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
@Override
public Button getNegativeButton() {
return button;
@@ -149,7 +150,7 @@
@Test
public void testTryAgainButton_sendsActionTryAgain() {
Button button = new Button(mContext);
- initDialog(mContext, mCallback, new MockInjector() {
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
@Override
public Button getTryAgainButton() {
return button;
@@ -165,7 +166,7 @@
@Test
public void testError_sendsActionError() {
- initDialog(mContext, mCallback, new MockInjector());
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
final String testError = "testError";
mBiometricView.onError(testError);
waitForIdleSync();
@@ -176,7 +177,7 @@
@Test
public void testBackgroundClicked_sendsActionUserCanceled() {
- initDialog(mContext, mCallback, new MockInjector());
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
View view = new View(mContext);
mBiometricView.setBackgroundView(view);
@@ -186,7 +187,7 @@
@Test
public void testBackgroundClicked_afterAuthenticated_neverSendsUserCanceled() {
- initDialog(mContext, mCallback, new MockInjector());
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
View view = new View(mContext);
mBiometricView.setBackgroundView(view);
@@ -197,8 +198,7 @@
@Test
public void testBackgroundClicked_whenSmallDialog_neverSendsUserCanceled() {
- initDialog(mContext, mCallback, new MockInjector());
- mBiometricView.setPanelController(mPanelController);
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
mBiometricView.updateSize(AuthDialog.SIZE_SMALL);
View view = new View(mContext);
@@ -213,7 +213,7 @@
Button tryAgainButton = new Button(mContext);
TextView indicatorView = new TextView(mContext);
- initDialog(mContext, mCallback, new MockInjector() {
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
@Override
public Button getTryAgainButton() {
return tryAgainButton;
@@ -249,16 +249,18 @@
// Create new dialog and restore the previous state into it
Button tryAgainButton2 = new Button(mContext);
TextView indicatorView2 = new TextView(mContext);
- initDialog(mContext, mCallback, state, new MockInjector() {
- @Override
- public Button getTryAgainButton() {
- return tryAgainButton2;
- }
- @Override
- public TextView getIndicatorView() {
- return indicatorView2;
- }
- });
+ initDialog(mContext, false /* allowDeviceCredential */, mCallback, state,
+ new MockInjector() {
+ @Override
+ public Button getTryAgainButton() {
+ return tryAgainButton2;
+ }
+
+ @Override
+ public TextView getIndicatorView() {
+ return indicatorView2;
+ }
+ });
mBiometricView.setRequireConfirmation(requireConfirmation);
waitForIdleSync();
@@ -271,26 +273,51 @@
// dialog size is known.
}
- private Bundle buildBiometricPromptBundle() {
+ @Test
+ public void testNegativeButton_whenDeviceCredentialAllowed() throws InterruptedException {
+ Button negativeButton = new Button(mContext);
+ initDialog(mContext, true /* allowDeviceCredential */, mCallback, new MockInjector() {
+ @Override
+ public Button getNegativeButton() {
+ return negativeButton;
+ }
+ });
+
+ negativeButton.performClick();
+ waitForIdleSync();
+
+ verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL);
+ }
+
+ private Bundle buildBiometricPromptBundle(boolean allowDeviceCredential) {
Bundle bundle = new Bundle();
bundle.putCharSequence(BiometricPrompt.KEY_TITLE, "Title");
- bundle.putCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT, "Negative");
+ int authenticators = Authenticator.TYPE_BIOMETRIC;
+ if (allowDeviceCredential) {
+ authenticators |= Authenticator.TYPE_CREDENTIAL;
+ } else {
+ bundle.putCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT, "Negative");
+ }
+ bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED, authenticators);
return bundle;
}
- private void initDialog(Context context, AuthBiometricView.Callback callback,
+ private void initDialog(Context context, boolean allowDeviceCredential,
+ AuthBiometricView.Callback callback,
Bundle savedState, MockInjector injector) {
mBiometricView = new TestableBiometricView(context, null, injector);
- mBiometricView.setBiometricPromptBundle(buildBiometricPromptBundle());
+ mBiometricView.setBiometricPromptBundle(buildBiometricPromptBundle(allowDeviceCredential));
mBiometricView.setCallback(callback);
mBiometricView.restoreState(savedState);
mBiometricView.onFinishInflateInternal();
mBiometricView.onAttachedToWindowInternal();
+
+ mBiometricView.setPanelController(mPanelController);
}
- private void initDialog(Context context, AuthBiometricView.Callback callback,
- MockInjector injector) {
- initDialog(context, callback, null /* savedState */, injector);
+ private void initDialog(Context context, boolean allowDeviceCredential,
+ AuthBiometricView.Callback callback, MockInjector injector) {
+ initDialog(context, allowDeviceCredential, callback, null /* savedState */, injector);
}
private class MockInjector extends AuthBiometricView.Injector {
@@ -338,6 +365,16 @@
public int getDelayAfterError() {
return 0; // Keep this at 0 for tests to invoke callback immediately.
}
+
+ @Override
+ public int getMediumToLargeAnimationDurationMs() {
+ return 0;
+ }
+
+ @Override
+ public int getAnimateCredentialStartDelayMs() {
+ return 0;
+ }
}
private class TestableBiometricView extends AuthBiometricView {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
index d4fc3f8..990f74a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
@@ -16,12 +16,30 @@
package com.android.systemui.biometrics;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.content.Context;
+import android.hardware.biometrics.Authenticator;
+import android.hardware.biometrics.BiometricAuthenticator;
+import android.hardware.biometrics.BiometricPrompt;
+import android.os.Bundle;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.ScrollView;
import com.android.systemui.SysuiTestCase;
@@ -43,22 +61,21 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
-
- AuthContainerView.Config config = new AuthContainerView.Config();
- config.mContext = mContext;
- config.mCallback = mCallback;
- mAuthContainer = new TestableAuthContainer(config);
}
@Test
public void testActionAuthenticated_sendsDismissedAuthenticated() {
+ initializeContainer(Authenticator.TYPE_BIOMETRIC);
+
mAuthContainer.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_AUTHENTICATED);
- verify(mCallback).onDismissed(eq(AuthDialogCallback.DISMISSED_AUTHENTICATED));
+ verify(mCallback).onDismissed(eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED));
}
@Test
public void testActionUserCanceled_sendsDismissedUserCanceled() {
+ initializeContainer(Authenticator.TYPE_BIOMETRIC);
+
mAuthContainer.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_USER_CANCELED);
verify(mCallback).onDismissed(eq(AuthDialogCallback.DISMISSED_USER_CANCELED));
@@ -66,6 +83,8 @@
@Test
public void testActionButtonNegative_sendsDismissedButtonNegative() {
+ initializeContainer(Authenticator.TYPE_BIOMETRIC);
+
mAuthContainer.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE);
verify(mCallback).onDismissed(eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE));
@@ -73,6 +92,8 @@
@Test
public void testActionTryAgain_sendsTryAgain() {
+ initializeContainer(Authenticator.TYPE_BIOMETRIC);
+
mAuthContainer.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN);
verify(mCallback).onTryAgainPressed();
@@ -80,14 +101,77 @@
@Test
public void testActionError_sendsDismissedError() {
+ initializeContainer(Authenticator.TYPE_BIOMETRIC);
+
mAuthContainer.mBiometricCallback.onAction(
AuthBiometricView.Callback.ACTION_ERROR);
verify(mCallback).onDismissed(AuthDialogCallback.DISMISSED_ERROR);
}
+ @Test
+ public void testActionUseDeviceCredential_sendsOnDeviceCredentialPressed() {
+ initializeContainer(
+ Authenticator.TYPE_BIOMETRIC | Authenticator.TYPE_CREDENTIAL);
+
+ mAuthContainer.mBiometricCallback.onAction(
+ AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL);
+ verify(mCallback).onDeviceCredentialPressed();
+
+ // Credential view is attached to the frame layout
+ waitForIdleSync();
+ assertNotNull(mAuthContainer.mCredentialView);
+ verify(mAuthContainer.mFrameLayout).addView(eq(mAuthContainer.mCredentialView));
+ }
+
+ @Test
+ public void testAnimateToCredentialUI_invokesStartTransitionToCredentialUI() {
+ initializeContainer(
+ Authenticator.TYPE_BIOMETRIC | Authenticator.TYPE_CREDENTIAL);
+
+ mAuthContainer.mBiometricView = mock(AuthBiometricView.class);
+ mAuthContainer.animateToCredentialUI();
+ verify(mAuthContainer.mBiometricView).startTransitionToCredentialUI();
+ }
+
+ @Test
+ public void testShowBiometricUI() {
+ initializeContainer(Authenticator.TYPE_BIOMETRIC);
+
+ assertNotEquals(null, mAuthContainer.mBiometricView);
+
+ mAuthContainer.onAttachedToWindowInternal();
+ verify(mAuthContainer.mBiometricScrollView).addView(mAuthContainer.mBiometricView);
+ // Credential view is not added
+ verify(mAuthContainer.mFrameLayout, never()).addView(any());
+ }
+
+ @Test
+ public void testShowCredentialUI_doesNotInflateBiometricUI() {
+ initializeContainer(Authenticator.TYPE_CREDENTIAL);
+
+ mAuthContainer.onAttachedToWindowInternal();
+
+ assertNull(null, mAuthContainer.mBiometricView);
+ assertNotNull(mAuthContainer.mCredentialView);
+ verify(mAuthContainer.mFrameLayout).addView(mAuthContainer.mCredentialView);
+ }
+
+ private void initializeContainer(int authenticators) {
+ AuthContainerView.Config config = new AuthContainerView.Config();
+ config.mContext = mContext;
+ config.mCallback = mCallback;
+ config.mModalityMask |= BiometricAuthenticator.TYPE_FINGERPRINT;
+
+ Bundle bundle = new Bundle();
+ bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED, authenticators);
+ config.mBiometricPromptBundle = bundle;
+
+ mAuthContainer = new TestableAuthContainer(config);
+ }
+
private class TestableAuthContainer extends AuthContainerView {
TestableAuthContainer(AuthContainerView.Config config) {
- super(config);
+ super(config, new MockInjector());
}
@Override
@@ -95,4 +179,32 @@
mConfig.mCallback.onDismissed(reason);
}
}
+
+ private final class MockInjector extends AuthContainerView.Injector {
+ @Override
+ public ScrollView getBiometricScrollView(FrameLayout parent) {
+ return mock(ScrollView.class);
+ }
+
+ @Override
+ public FrameLayout inflateContainerView(LayoutInflater factory, ViewGroup root) {
+ return mock(FrameLayout.class);
+ }
+
+ @Override
+ public AuthPanelController getPanelController(Context context, View view,
+ boolean isManagedProfile) {
+ return mock(AuthPanelController.class);
+ }
+
+ @Override
+ public ImageView getBackgroundView(FrameLayout parent) {
+ return mock(ImageView.class);
+ }
+
+ @Override
+ public View getPanelView(FrameLayout parent) {
+ return mock(View.class);
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index eb7be4f..dcdb5c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -22,8 +22,11 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -33,6 +36,8 @@
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
+import android.hardware.biometrics.Authenticator;
+import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
import android.os.Bundle;
@@ -69,7 +74,7 @@
@Mock
private AuthDialog mDialog2;
- private TestableBiometricDialogImpl mBiometricDialogImpl;
+ private TestableAuthController mAuthController;
@Before
@@ -90,78 +95,90 @@
when(mDialog1.getOpPackageName()).thenReturn("Dialog1");
when(mDialog2.getOpPackageName()).thenReturn("Dialog2");
- mBiometricDialogImpl = new TestableBiometricDialogImpl(new MockInjector());
- mBiometricDialogImpl.mContext = context;
- mBiometricDialogImpl.mComponents = mContext.getComponents();
+ when(mDialog1.isAllowDeviceCredentials()).thenReturn(false);
+ when(mDialog2.isAllowDeviceCredentials()).thenReturn(false);
- mBiometricDialogImpl.start();
+ mAuthController = new TestableAuthController(new MockInjector());
+ mAuthController.mContext = context;
+ mAuthController.mComponents = mContext.getComponents();
+
+ mAuthController.start();
}
// Callback tests
@Test
public void testSendsReasonUserCanceled_whenDismissedByUserCancel() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
- mBiometricDialogImpl.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED);
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ mAuthController.onDismissed(AuthDialogCallback.DISMISSED_USER_CANCELED);
verify(mReceiver).onDialogDismissed(BiometricPrompt.DISMISSED_REASON_USER_CANCEL);
}
@Test
public void testSendsReasonNegative_whenDismissedByButtonNegative() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
- mBiometricDialogImpl.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE);
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE);
verify(mReceiver).onDialogDismissed(BiometricPrompt.DISMISSED_REASON_NEGATIVE);
}
@Test
public void testSendsReasonConfirmed_whenDismissedByButtonPositive() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
- mBiometricDialogImpl.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_POSITIVE);
- verify(mReceiver).onDialogDismissed(BiometricPrompt.DISMISSED_REASON_CONFIRMED);
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BUTTON_POSITIVE);
+ verify(mReceiver).onDialogDismissed(BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED);
}
@Test
public void testSendsReasonConfirmNotRequired_whenDismissedByAuthenticated() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
- mBiometricDialogImpl.onDismissed(AuthDialogCallback.DISMISSED_AUTHENTICATED);
- verify(mReceiver).onDialogDismissed(BiometricPrompt.DISMISSED_REASON_CONFIRM_NOT_REQUIRED);
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED);
+ verify(mReceiver).onDialogDismissed(
+ BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED);
}
@Test
public void testSendsReasonError_whenDismissedByError() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
- mBiometricDialogImpl.onDismissed(AuthDialogCallback.DISMISSED_ERROR);
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ mAuthController.onDismissed(AuthDialogCallback.DISMISSED_ERROR);
verify(mReceiver).onDialogDismissed(BiometricPrompt.DISMISSED_REASON_ERROR);
}
@Test
- public void testSendsReasonDismissedBySystemServer_whenDismissedByServer() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
- mBiometricDialogImpl.onDismissed(AuthDialogCallback.DISMISSED_BY_SYSTEM_SERVER);
+ public void testSendsReasonServerRequested_whenDismissedByServer() throws Exception {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ mAuthController.onDismissed(AuthDialogCallback.DISMISSED_BY_SYSTEM_SERVER);
verify(mReceiver).onDialogDismissed(BiometricPrompt.DISMISSED_REASON_SERVER_REQUESTED);
}
+ @Test
+ public void testSendsReasonCredentialConfirmed_whenDeviceCredentialAuthenticated()
+ throws Exception {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ mAuthController.onDismissed(AuthDialogCallback.DISMISSED_CREDENTIAL_AUTHENTICATED);
+ verify(mReceiver).onDialogDismissed(BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED);
+ }
+
// Statusbar tests
@Test
public void testShowInvoked_whenSystemRequested()
throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
verify(mDialog1).show(any(), any());
}
@Test
- public void testOnAuthenticationSucceededInvoked_whenSystemRequested() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
- mBiometricDialogImpl.onBiometricAuthenticated(true, null /* failureReason */);
+ public void testOnAuthenticationSucceededInvoked_whenSystemRequested() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ mAuthController.onBiometricAuthenticated(true, null /* failureReason */);
verify(mDialog1).onAuthenticationSucceeded();
}
@Test
- public void testOnAuthenticationFailedInvoked_whenSystemRequested() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
+ public void testOnAuthenticationFailedInvoked_whenSystemRequested() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
final String failureReason = "failure reason";
- mBiometricDialogImpl.onBiometricAuthenticated(false, failureReason);
+ mAuthController.onBiometricAuthenticated(false, failureReason);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mDialog1).onAuthenticationFailed(captor.capture());
@@ -170,10 +187,10 @@
}
@Test
- public void testOnHelpInvoked_whenSystemRequested() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
+ public void testOnHelpInvoked_whenSystemRequested() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
final String helpMessage = "help";
- mBiometricDialogImpl.onBiometricHelp(helpMessage);
+ mAuthController.onBiometricHelp(helpMessage);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mDialog1).onHelp(captor.capture());
@@ -182,10 +199,11 @@
}
@Test
- public void testOnErrorInvoked_whenSystemRequested() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
+ public void testOnErrorInvoked_whenSystemRequested() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ final int error = 1;
final String errMessage = "error message";
- mBiometricDialogImpl.onBiometricError(errMessage);
+ mAuthController.onBiometricError(error, errMessage);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mDialog1).onError(captor.capture());
@@ -194,30 +212,82 @@
}
@Test
- public void testDismissWithoutCallbackInvoked_whenSystemRequested() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
- mBiometricDialogImpl.hideBiometricDialog();
+ public void testErrorLockout_whenCredentialAllowed_AnimatesToCredentialUI() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT;
+ final String errorString = "lockout";
+
+ when(mDialog1.isAllowDeviceCredentials()).thenReturn(true);
+
+ mAuthController.onBiometricError(error, errorString);
+ verify(mDialog1, never()).onError(anyString());
+ verify(mDialog1).animateToCredentialUI();
+ }
+
+ @Test
+ public void testErrorLockoutPermanent_whenCredentialAllowed_AnimatesToCredentialUI() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
+ final String errorString = "lockout_permanent";
+
+ when(mDialog1.isAllowDeviceCredentials()).thenReturn(true);
+
+ mAuthController.onBiometricError(error, errorString);
+ verify(mDialog1, never()).onError(anyString());
+ verify(mDialog1).animateToCredentialUI();
+ }
+
+ @Test
+ public void testErrorLockout_whenCredentialNotAllowed_sendsOnError() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT;
+ final String errorString = "lockout";
+
+ when(mDialog1.isAllowDeviceCredentials()).thenReturn(false);
+
+ mAuthController.onBiometricError(error, errorString);
+ verify(mDialog1).onError(eq(errorString));
+ verify(mDialog1, never()).animateToCredentialUI();
+ }
+
+ @Test
+ public void testErrorLockoutPermanent_whenCredentialNotAllowed_sendsOnError() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ final int error = BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
+ final String errorString = "lockout_permanent";
+
+ when(mDialog1.isAllowDeviceCredentials()).thenReturn(false);
+
+ mAuthController.onBiometricError(error, errorString);
+ verify(mDialog1).onError(eq(errorString));
+ verify(mDialog1, never()).animateToCredentialUI();
+ }
+
+ @Test
+ public void testDismissWithoutCallbackInvoked_whenSystemRequested() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ mAuthController.hideAuthenticationDialog();
verify(mDialog1).dismissFromSystemServer();
}
@Test
- public void testClientNotified_whenDismissedBySystemServer() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
- mBiometricDialogImpl.hideBiometricDialog();
+ public void testClientNotified_whenDismissedBySystemServer() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
+ mAuthController.hideAuthenticationDialog();
verify(mDialog1).dismissFromSystemServer();
- assertNotNull(mBiometricDialogImpl.mCurrentDialog);
- assertNotNull(mBiometricDialogImpl.mReceiver);
+ assertNotNull(mAuthController.mCurrentDialog);
+ assertNotNull(mAuthController.mReceiver);
}
// Corner case tests
@Test
- public void testShowNewDialog_beforeOldDialogDismissed_SkipsAnimations() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
+ public void testShowNewDialog_beforeOldDialogDismissed_SkipsAnimations() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
verify(mDialog1).show(any(), any());
- showDialog(BiometricPrompt.TYPE_FACE);
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
// First dialog should be dismissed without animation
verify(mDialog1).dismissWithoutCallback(eq(false) /* animate */);
@@ -227,11 +297,20 @@
}
@Test
- public void testConfigurationPersists_whenOnConfigurationChanged() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
+ public void testConfigurationPersists_whenOnConfigurationChanged() {
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
verify(mDialog1).show(any(), any());
- mBiometricDialogImpl.onConfigurationChanged(new Configuration());
+ // Return that the UI is in "showing" state
+ doAnswer(invocation -> {
+ Object[] args = invocation.getArguments();
+ Bundle savedState = (Bundle) args[0];
+ savedState.putInt(
+ AuthDialog.KEY_CONTAINER_STATE, AuthContainerView.STATE_SHOWING);
+ return null; // onSaveState returns void
+ }).when(mDialog1).onSaveState(any());
+
+ mAuthController.onConfigurationChanged(new Configuration());
ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
verify(mDialog1).onSaveState(captor.capture());
@@ -248,37 +327,63 @@
}
@Test
+ public void testConfigurationPersists_whenBiometricFallbackToCredential() {
+ showDialog(Authenticator.TYPE_CREDENTIAL | Authenticator.TYPE_BIOMETRIC,
+ BiometricPrompt.TYPE_FACE);
+ verify(mDialog1).show(any(), any());
+
+ // Pretend that the UI is now showing device credential UI.
+ doAnswer(invocation -> {
+ Object[] args = invocation.getArguments();
+ Bundle savedState = (Bundle) args[0];
+ savedState.putInt(
+ AuthDialog.KEY_CONTAINER_STATE, AuthContainerView.STATE_SHOWING);
+ savedState.putBoolean(AuthDialog.KEY_CREDENTIAL_SHOWING, true);
+ return null; // onSaveState returns void
+ }).when(mDialog1).onSaveState(any());
+
+ mAuthController.onConfigurationChanged(new Configuration());
+
+ // Check that the new dialog was initialized to the credential UI.
+ ArgumentCaptor<Bundle> captor = ArgumentCaptor.forClass(Bundle.class);
+ verify(mDialog2).show(any(), captor.capture());
+ assertEquals(Authenticator.TYPE_CREDENTIAL,
+ mAuthController.mLastBiometricPromptBundle
+ .getInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED));
+ }
+
+ @Test
public void testClientNotified_whenTaskStackChangesDuringAuthentication() throws Exception {
- showDialog(BiometricPrompt.TYPE_FACE);
+ showDialog(Authenticator.TYPE_BIOMETRIC, BiometricPrompt.TYPE_FACE);
List<ActivityManager.RunningTaskInfo> tasks = new ArrayList<>();
ActivityManager.RunningTaskInfo taskInfo = mock(ActivityManager.RunningTaskInfo.class);
taskInfo.topActivity = mock(ComponentName.class);
when(taskInfo.topActivity.getPackageName()).thenReturn("other_package");
tasks.add(taskInfo);
- when(mBiometricDialogImpl.mActivityTaskManager.getTasks(anyInt())).thenReturn(tasks);
+ when(mAuthController.mActivityTaskManager.getTasks(anyInt())).thenReturn(tasks);
- mBiometricDialogImpl.mTaskStackListener.onTaskStackChanged();
+ mAuthController.mTaskStackListener.onTaskStackChanged();
waitForIdleSync();
- assertNull(mBiometricDialogImpl.mCurrentDialog);
- assertNull(mBiometricDialogImpl.mReceiver);
+ assertNull(mAuthController.mCurrentDialog);
+ assertNull(mAuthController.mReceiver);
verify(mDialog1).dismissWithoutCallback(true /* animate */);
verify(mReceiver).onDialogDismissed(eq(BiometricPrompt.DISMISSED_REASON_USER_CANCEL));
}
// Helpers
- private void showDialog(int type) {
- mBiometricDialogImpl.showBiometricDialog(createTestDialogBundle(),
+ private void showDialog(int authenticators, int biometricModality) {
+ mAuthController.showAuthenticationDialog(createTestDialogBundle(authenticators),
mReceiver /* receiver */,
- type,
+ biometricModality,
true /* requireConfirmation */,
0 /* userId */,
"testPackage");
}
- private Bundle createTestDialogBundle() {
+ private Bundle createTestDialogBundle(int authenticators) {
Bundle bundle = new Bundle();
bundle.putCharSequence(BiometricPrompt.KEY_TITLE, "Title");
@@ -290,13 +395,16 @@
// by user settings, and should be tested in BiometricService.
bundle.putBoolean(BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true);
+ bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED, authenticators);
+
return bundle;
}
- private final class TestableBiometricDialogImpl extends AuthController {
+ private final class TestableAuthController extends AuthController {
private int mBuildCount = 0;
+ private Bundle mLastBiometricPromptBundle;
- public TestableBiometricDialogImpl(Injector injector) {
+ public TestableAuthController(Injector injector) {
super(injector);
}
@@ -304,6 +412,9 @@
protected AuthDialog buildDialog(Bundle biometricPromptBundle,
boolean requireConfirmation, int userId, int type, String opPackageName,
boolean skipIntro) {
+
+ mLastBiometricPromptBundle = biometricPromptBundle;
+
AuthDialog dialog;
if (mBuildCount == 0) {
dialog = mDialog1;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index b252a0d..1bd01e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -367,12 +367,13 @@
}
@Test
- public void testShowBiometricDialog() {
+ public void testShowAuthenticationDialog() {
Bundle bundle = new Bundle();
String packageName = "test";
- mCommandQueue.showBiometricDialog(bundle, null /* receiver */, 1, true, 3, packageName);
+ mCommandQueue.showAuthenticationDialog(bundle, null /* receiver */, 1, true, 3,
+ packageName);
waitForIdleSync();
- verify(mCallbacks).showBiometricDialog(eq(bundle), eq(null), eq(1), eq(true), eq(3),
+ verify(mCallbacks).showAuthenticationDialog(eq(bundle), eq(null), eq(1), eq(true), eq(3),
eq(packageName));
}
@@ -394,16 +395,17 @@
@Test
public void testOnBiometricError() {
+ final int errorCode = 1;
String errorMessage = "test_error_message";
- mCommandQueue.onBiometricError(errorMessage);
+ mCommandQueue.onBiometricError(errorCode, errorMessage);
waitForIdleSync();
- verify(mCallbacks).onBiometricError(eq(errorMessage));
+ verify(mCallbacks).onBiometricError(eq(errorCode), eq(errorMessage));
}
@Test
- public void testHideBiometricDialog() {
- mCommandQueue.hideBiometricDialog();
+ public void testHideAuthenticationDialog() {
+ mCommandQueue.hideAuthenticationDialog();
waitForIdleSync();
- verify(mCallbacks).hideBiometricDialog();
+ verify(mCallbacks).hideAuthenticationDialog();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java
index 7d2ccdc..618272c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java
@@ -28,6 +28,7 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -240,4 +241,10 @@
verify(mSecondaryNavBar).disableAnimationsDuringHide(eq(500L));
}
+
+ @Test
+ public void testGetAssistHandlerViewController_noCrash() {
+ reset(mNavigationBarController.mNavigationBars);
+ mNavigationBarController.getAssistHandlerViewController();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java
index 5558393..145a25c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimatorTest.java
@@ -17,11 +17,8 @@
package com.android.systemui.statusbar.notification;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyObject;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,23 +27,20 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
import android.view.RemoteAnimationAdapter;
import android.view.View;
-import android.widget.FrameLayout;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.StatusBarWindowView;
+import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.stubbing.Answer;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -55,6 +49,8 @@
private ActivityLaunchAnimator mLaunchAnimator;
private ActivityLaunchAnimator.Callback mCallback = mock(ActivityLaunchAnimator.Callback.class);
+ private StatusBarWindowViewController mStatusBarWindowViewController = mock(
+ StatusBarWindowViewController.class);
private StatusBarWindowView mStatusBarWindowView = mock(StatusBarWindowView.class);
private NotificationListContainer mNotificationContainer
= mock(NotificationListContainer.class);
@@ -62,10 +58,11 @@
@Before
public void setUp() throws Exception {
+ when(mStatusBarWindowViewController.getView()).thenReturn(mStatusBarWindowView);
when(mStatusBarWindowView.getResources()).thenReturn(mContext.getResources());
when(mCallback.areLaunchAnimationsEnabled()).thenReturn(true);
mLaunchAnimator = new ActivityLaunchAnimator(
- mStatusBarWindowView,
+ mStatusBarWindowViewController,
mCallback,
mock(NotificationPanelView.class),
mNotificationContainer);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 30e02e6..866ea51 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -41,7 +41,6 @@
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.os.Handler;
@@ -69,6 +68,7 @@
import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationRemoveInterceptor;
@@ -145,8 +145,8 @@
private class TestableNotificationEntryManager extends NotificationEntryManager {
private final CountDownLatch mCountDownLatch;
- TestableNotificationEntryManager(Context context) {
- super(context);
+ TestableNotificationEntryManager() {
+ super(new NotificationData(mock(NotificationSectionsFeatureManager.class)));
mCountDownLatch = new CountDownLatch(1);
}
@@ -225,6 +225,7 @@
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
mDependency.injectTestDependency(SmartReplyController.class, mSmartReplyController);
mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
+ mDependency.injectMockDependency(NotificationMediaManager.class);
mCountDownLatch = new CountDownLatch(1);
@@ -250,7 +251,7 @@
mEntry.expandedIcon = mock(StatusBarIconView.class);
- mEntryManager = new TestableNotificationEntryManager(mContext);
+ mEntryManager = new TestableNotificationEntryManager();
Dependency.get(InitController.class).executePostInitTasks();
mEntryManager.setUpWithPresenter(mPresenter, mListContainer, mHeadsUpManager);
mEntryManager.addNotificationEntryListener(mEntryListener);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
index 8d496a7..6d275419 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
@@ -46,6 +46,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
+import com.android.systemui.util.DeviceConfigProxyFake;
import org.junit.Before;
import org.junit.Test;
@@ -73,7 +74,9 @@
private DeviceProvisionedListener mProvisionedListener;
// TODO: Remove this once EntryManager no longer needs to be mocked
- private NotificationData mNotificationData = new NotificationData(mContext);
+ private NotificationData mNotificationData =
+ new NotificationData(new NotificationSectionsFeatureManager(
+ new DeviceConfigProxyFake(), mContext));
private int mNextNotifId = 0;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
new file mode 100644
index 0000000..b3d0d22
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 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.systemui.statusbar.notification
+
+import android.provider.DeviceConfig
+import android.provider.Settings
+import android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL
+import android.testing.AndroidTestingRunner
+
+import androidx.test.filters.SmallTest
+
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.DeviceConfigProxyFake
+
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class NotificationSectionsFeatureManagerTest : SysuiTestCase() {
+ var manager: NotificationSectionsFeatureManager? = null
+ val proxyFake = DeviceConfigProxyFake()
+
+ @Before
+ public fun setup() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 1)
+ manager = NotificationSectionsFeatureManager(proxyFake, mContext)
+ manager!!.clearCache()
+ }
+
+ @Test
+ public fun testPeopleFilteringOff_newInterruptionModelOn() {
+ proxyFake.setProperty(
+ DeviceConfig.NAMESPACE_SYSTEMUI, NOTIFICATIONS_USE_PEOPLE_FILTERING, "false", false)
+
+ assertFalse("People filtering should be disabled", manager!!.isFilteringEnabled())
+ assertTrue("Expecting 2 buckets when people filtering is disabled",
+ manager!!.getNumberOfBuckets() == 2)
+ }
+
+ @Test
+ public fun testPeopleFilteringOn_newInterruptionModelOn() {
+ proxyFake.setProperty(
+ DeviceConfig.NAMESPACE_SYSTEMUI, NOTIFICATIONS_USE_PEOPLE_FILTERING, "true", false)
+
+ assertTrue("People filtering should be enabled", manager!!.isFilteringEnabled())
+ assertTrue("Expecting 3 buckets when people filtering is enabled",
+ manager!!.getNumberOfBuckets() == 3)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
index 657ec61d..5fbacb1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
@@ -50,7 +50,6 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Person;
-import android.content.Context;
import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -78,6 +77,7 @@
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.SbnBuilder;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationData.KeyguardEnvironment;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -139,7 +139,8 @@
mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
- mNotificationData = new TestableNotificationData(mContext);
+ mNotificationData = new TestableNotificationData(
+ mock(NotificationSectionsFeatureManager.class));
mNotificationData.updateRanking(mock(NotificationListenerService.RankingMap.class));
mRow = new NotificationTestHelper(getContext()).createRow();
Dependency.get(InitController.class).executePostInitTasks();
@@ -631,8 +632,8 @@
}
public static class TestableNotificationData extends NotificationData {
- public TestableNotificationData(Context context) {
- super(context);
+ public TestableNotificationData(NotificationSectionsFeatureManager sectionsFeatureManager) {
+ super(sectionsFeatureManager);
}
public static final String OVERRIDE_RANK = "r";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
index addceb5..3f467ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
@@ -32,10 +32,12 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.util.DeviceConfigProxy;
import org.junit.Assert;
import org.junit.Before;
@@ -64,7 +66,9 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mRoundnessManager = new NotificationRoundnessManager(mBypassController, mContext);
+ mRoundnessManager = new NotificationRoundnessManager(
+ mBypassController,
+ new NotificationSectionsFeatureManager(new DeviceConfigProxy(), mContext));
com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
NotificationTestHelper testHelper = new NotificationTestHelper(getContext());
mFirst = testHelper.createRow();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 31054260..11ae0cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -55,7 +55,6 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -65,6 +64,7 @@
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -79,6 +79,7 @@
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarTest.TestableNotificationEntryManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.util.DeviceConfigProxyFake;
import org.junit.After;
import org.junit.Before;
@@ -144,11 +145,10 @@
mDependency.injectMockDependency(ShadeController.class);
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
- mEntryManager = new TestableNotificationEntryManager(mContext);
+ mEntryManager = new TestableNotificationEntryManager(mNotificationData);
mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
Dependency.get(InitController.class).executePostInitTasks();
- mEntryManager.setUpForTest(mock(NotificationPresenter.class), null, mHeadsUpManager,
- mNotificationData);
+ mEntryManager.setUpForTest(mock(NotificationPresenter.class), null, mHeadsUpManager);
NotificationShelf notificationShelf = mock(NotificationShelf.class);
@@ -166,7 +166,8 @@
mock(SysuiStatusBarStateController.class),
mHeadsUpManager,
mKeyguardBypassController,
- new FalsingManagerFake());
+ new FalsingManagerFake(),
+ new NotificationSectionsFeatureManager(new DeviceConfigProxyFake(), mContext));
mStackScroller = spy(mStackScrollerInternal);
mStackScroller.setShelf(notificationShelf);
mStackScroller.setStatusBar(mBar);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 3ba3e28..cb87d7d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -89,6 +89,8 @@
private KeyguardBypassController mKeyguardBypassController;
@Mock
private Handler mHandler;
+ @Mock
+ private KeyguardSecurityModel mKeyguardSecurityModel;
private KeyguardBouncer mBouncer;
@@ -97,6 +99,9 @@
com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
MockitoAnnotations.initMocks(this);
mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
+ mDependency.injectTestDependency(KeyguardSecurityModel.class, mKeyguardSecurityModel);
+ when(mKeyguardSecurityModel.getSecurityMode(anyInt()))
+ .thenReturn(KeyguardSecurityModel.SecurityMode.None);
DejankUtils.setImmediate(true);
final ViewGroup container = new FrameLayout(getContext());
when(mKeyguardHostView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
@@ -306,14 +311,6 @@
}
@Test
- public void testNeedsFullscreenBouncer_asksKeyguardView() {
- mBouncer.ensureView();
- mBouncer.needsFullscreenBouncer();
- verify(mKeyguardHostView).getSecurityMode();
- verify(mKeyguardHostView, never()).getCurrentSecurityMode();
- }
-
- @Test
public void testIsFullscreenBouncer_asksKeyguardView() {
mBouncer.ensureView();
mBouncer.isFullscreenBouncer();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index 0bff5aa..237f6ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -80,7 +80,7 @@
import org.mockito.MockitoAnnotations;
@RunWith(AndroidTestingRunner.class)
-@RunWithLooper()
+@RunWithLooper(setAsMainLooper = true)
@SmallTest
public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
private static final int EXTERNAL_DISPLAY_ID = 2;
@@ -217,7 +217,7 @@
// Set IME window status for default NavBar.
mCommandQueue.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
BACK_DISPOSITION_DEFAULT, true, false);
- Handler.getMain().runWithScissors(() -> { }, 500);
+ processAllMessages();
// Verify IME window state will be updated in default NavBar & external NavBar state reset.
assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN,
@@ -228,7 +228,7 @@
// Set IME window status for external NavBar.
mCommandQueue.setImeWindowStatus(EXTERNAL_DISPLAY_ID, null,
IME_VISIBLE, BACK_DISPOSITION_DEFAULT, true, false);
- Handler.getMain().runWithScissors(() -> { }, 500);
+ processAllMessages();
// Verify IME window state will be updated in external NavBar & default NavBar state reset.
assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index f1da4e8..98485b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -40,8 +40,8 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.doze.DozeLog;
import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.doze.DozeLog;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.plugins.PluginManager;
@@ -52,7 +52,10 @@
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -122,8 +125,6 @@
mDependency.injectTestDependency(StatusBarStateController.class,
mStatusBarStateController);
mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mUpdateMonitor);
- mDependency.injectMockDependency(ShadeController.class);
- mDependency.injectMockDependency(NotificationLockscreenUserManager.class);
mDependency.injectMockDependency(ConfigurationController.class);
mDependency.injectMockDependency(ZenModeController.class);
NotificationWakeUpCoordinator coordinator =
@@ -217,12 +218,22 @@
TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator,
PulseExpansionHandler expansionHandler,
KeyguardBypassController bypassController) {
- super(NotificationPanelViewTest.this.mContext, null,
+ super(
+ NotificationPanelViewTest.this.mContext,
+ null,
new InjectionInflationController(
SystemUIFactory.getInstance().getRootComponent()),
- coordinator, expansionHandler, mock(DynamicPrivacyController.class),
+ coordinator,
+ expansionHandler,
+ mock(DynamicPrivacyController.class),
bypassController,
- mFalsingManager, mock(PluginManager.class), mock(DozeLog.class));
+ mFalsingManager,
+ mock(PluginManager.class),
+ mock(ShadeController.class),
+ mock(NotificationLockscreenUserManager.class),
+ new NotificationEntryManager(new NotificationData(mock(
+ NotificationSectionsFeatureManager.class))),
+ mock(DozeLog.class));
mNotificationStackScroller = mNotificationStackScrollLayout;
mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 4140b0d..214e26a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -46,6 +46,7 @@
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.util.function.TriConsumer;
import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.DejankUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -95,6 +96,7 @@
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true);
+ DejankUtils.setImmediate(true);
mScrimController = new SynchronousScrimController(mScrimBehind, mScrimInFront,
mScrimForBubble,
(scrimState, scrimBehindAlpha, scrimInFrontColor) -> {
@@ -113,6 +115,7 @@
@After
public void tearDown() {
mScrimController.finishAnimationsImmediately();
+ DejankUtils.setImmediate(false);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index c3b25ce..aafcdd0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -227,6 +227,31 @@
verify(mStatusBar, never()).animateKeyguardUnoccluding();
}
+ @Test
+ public void testHiding_cancelsGoneRunnable() {
+ OnDismissAction action = mock(OnDismissAction.class);
+ Runnable cancelAction = mock(Runnable.class);
+ mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
+ true /* afterKeyguardGone */);
+
+ mStatusBarKeyguardViewManager.hideBouncer(true);
+ mStatusBarKeyguardViewManager.hide(0, 30);
+ verify(action, never()).onDismiss();
+ verify(cancelAction).run();
+ }
+
+ @Test
+ public void testHiding_doesntCancelWhenShowing() {
+ OnDismissAction action = mock(OnDismissAction.class);
+ Runnable cancelAction = mock(Runnable.class);
+ mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
+ true /* afterKeyguardGone */);
+
+ mStatusBarKeyguardViewManager.hide(0, 30);
+ verify(action).onDismiss();
+ verify(cancelAction, never()).run();
+ }
+
private class TestableStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager {
public TestableStatusBarKeyguardViewManager(Context context,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 7de7f9e..914717c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -59,12 +59,13 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.view.ViewGroup.LayoutParams;
import androidx.test.filters.SmallTest;
-import com.android.internal.logging.MetricsLogger;
+import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
@@ -73,19 +74,21 @@
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.InitController;
import com.android.systemui.R;
-import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.appops.AppOpsController;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.doze.DozeEvent;
import com.android.systemui.doze.DozeHost;
+import com.android.systemui.doze.DozeLog;
import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
-import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -96,16 +99,21 @@
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
+import com.android.systemui.statusbar.VibratorHelper;
+import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotifPipelineInitializer;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -114,9 +122,14 @@
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
import org.junit.Test;
@@ -135,6 +148,15 @@
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
public class StatusBarTest extends SysuiTestCase {
+
+ private StatusBar mStatusBar;
+ private FakeMetricsLogger mMetricsLogger;
+ private PowerManager mPowerManager;
+ private TestableNotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
+ private CommandQueue mCommandQueue;
+
+ @Mock private LightBarController mLightBarController;
+ @Mock private StatusBarIconController mStatusBarIconController;
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock private KeyguardStateController mKeyguardStateController;
@Mock private KeyguardIndicationController mKeyguardIndicationController;
@@ -148,11 +170,7 @@
@Mock private ArrayList<NotificationEntry> mNotificationList;
@Mock private BiometricUnlockController mBiometricUnlockController;
@Mock private NotificationData mNotificationData;
- @Mock
- private NotificationInterruptionStateProvider.HeadsUpSuppressor mHeadsUpSuppressor;
-
- // Mock dependencies:
- @Mock private NotificationViewHierarchyManager mViewHierarchyManager;
+ @Mock private NotificationInterruptionStateProvider.HeadsUpSuppressor mHeadsUpSuppressor;
@Mock private VisualStabilityManager mVisualStabilityManager;
@Mock private NotificationListener mNotificationListener;
@Mock private KeyguardViewMediator mKeyguardViewMediator;
@@ -163,51 +181,48 @@
@Mock private BatteryController mBatteryController;
@Mock private DeviceProvisionedController mDeviceProvisionedController;
@Mock private StatusBarNotificationPresenter mNotificationPresenter;
- @Mock
- private NotificationEntryListener mEntryListener;
- @Mock
- private NotificationFilter mNotificationFilter;
- @Mock
- private NotificationAlertingManager mNotificationAlertingManager;
- @Mock
- private NotificationLogger.ExpansionStateLogger mExpansionStateLogger;
- @Mock
- private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- @Mock
- private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
- @Mock
- private StatusBarWindowView mStatusBarWindowView;
- @Mock
- private BroadcastDispatcher mBroadcastDispatcher;
-
- private TestableStatusBar mStatusBar;
- private FakeMetricsLogger mMetricsLogger;
- private PowerManager mPowerManager;
- private TestableNotificationEntryManager mEntryManager;
- private TestableNotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
- private NotificationLogger mNotificationLogger;
- private CommandQueue mCommandQueue;
+ @Mock private NotificationEntryListener mEntryListener;
+ @Mock private NotificationFilter mNotificationFilter;
+ @Mock private NotificationAlertingManager mNotificationAlertingManager;
+ @Mock private NotificationLogger.ExpansionStateLogger mExpansionStateLogger;
+ @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ @Mock private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
+ @Mock private StatusBarWindowView mStatusBarWindowView;
+ @Mock private BroadcastDispatcher mBroadcastDispatcher;
+ @Mock private AssistManager mAssistManager;
+ @Mock private NotificationGutsManager mNotificationGutsManager;
+ @Mock private NotificationMediaManager mNotificationMediaManager;
+ @Mock private ForegroundServiceController mForegroundServiceController;
+ @Mock private AppOpsController mAppOpsController;
+ @Mock private NavigationBarController mNavigationBarController;
+ @Mock private BypassHeadsUpNotifier mBypassHeadsUpNotifier;
+ @Mock private SysuiColorExtractor mColorExtractor;
+ @Mock private ColorExtractor.GradientColors mGradientColors;
+ @Mock private DozeLog mDozeLog;
+ @Mock private PulseExpansionHandler mPulseExpansionHandler;
+ @Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
+ @Mock private KeyguardBypassController mKeyguardBypassController;
+ @Mock private InjectionInflationController mInjectionInflationController;
+ @Mock private DynamicPrivacyController mDynamicPrivacyController;
+ @Mock private NotifPipelineInitializer mNotifPipelineInitializer;
+ @Mock private ZenModeController mZenModeController;
+ @Mock private AutoHideController mAutoHideController;
+ @Mock private NotificationViewHierarchyManager mNotificationViewHierarchyManager;
+ @Mock private UserSwitcherController mUserSwitcherController;
+ @Mock private NetworkController mNetworkController;
+ @Mock private VibratorHelper mVibratorHelper;
+ @Mock private BubbleController mBubbleController;
+ @Mock private NotificationGroupManager mGroupManager;
+ @Mock private NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
+ @Mock private StatusBarWindowController mStatusBarWindowController;
+ @Mock private NotificationIconAreaController mNotificationIconAreaController;
+ @Mock private StatusBarWindowViewController.Builder mStatusBarWindowViewControllerBuilder;
+ @Mock private StatusBarWindowViewController mStatusBarWindowViewController;
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
- mDependency.injectMockDependency(AssistManager.class);
- mDependency.injectMockDependency(NotificationGutsManager.class);
- mDependency.injectMockDependency(NotificationMediaManager.class);
- mDependency.injectMockDependency(ForegroundServiceController.class);
- mDependency.injectTestDependency(NotificationViewHierarchyManager.class,
- mViewHierarchyManager);
- mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
- mDependency.injectTestDependency(NotificationListener.class, mNotificationListener);
- mDependency.injectTestDependency(AppOpsController.class, mock(AppOpsController.class));
- mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
- mDependency.injectTestDependency(DeviceProvisionedController.class,
- mDeviceProvisionedController);
- mDependency.injectMockDependency(BubbleController.class);
mDependency.injectTestDependency(NotificationFilter.class, mNotificationFilter);
- mDependency.injectTestDependency(NotificationAlertingManager.class,
- mNotificationAlertingManager);
- mDependency.injectTestDependency(BroadcastDispatcher.class, mBroadcastDispatcher);
IPowerManager powerManagerService = mock(IPowerManager.class);
mPowerManager = new PowerManager(mContext, powerManagerService,
@@ -217,21 +232,17 @@
new TestableNotificationInterruptionStateProvider(mContext, mPowerManager,
mDreamManager, mAmbientDisplayConfiguration, mNotificationFilter,
mStatusBarStateController, mBatteryController);
- mDependency.injectTestDependency(NotificationInterruptionStateProvider.class,
- mNotificationInterruptionStateProvider);
- mDependency.injectMockDependency(NavigationBarController.class);
mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
mMetricsLogger = new FakeMetricsLogger();
- mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
- mEntryManager = new TestableNotificationEntryManager(mContext);
- mNotificationLogger = new NotificationLogger(mNotificationListener,
- Dependency.get(UiOffloadThread.class), mEntryManager, mStatusBarStateController,
+ TestableNotificationEntryManager entryManager = new TestableNotificationEntryManager(
+ mNotificationData);
+ NotificationLogger notificationLogger = new NotificationLogger(mNotificationListener,
+ Dependency.get(UiOffloadThread.class), entryManager, mStatusBarStateController,
mExpansionStateLogger);
- mNotificationLogger.setVisibilityReporter(mock(Runnable.class));
- mDependency.injectTestDependency(NotificationLogger.class, mNotificationLogger);
+ notificationLogger.setVisibilityReporter(mock(Runnable.class));
mCommandQueue = mock(CommandQueue.class);
when(mCommandQueue.asBinder()).thenReturn(new Binder());
@@ -260,32 +271,99 @@
mHeadsUpManager, mHeadsUpSuppressor);
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
- mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager,
- mKeyguardIndicationController, mStackScroller,
- mPowerManager, mNotificationPanelView, mBarService, mNotificationListener,
- mNotificationLogger, mVisualStabilityManager, mViewHierarchyManager,
- mEntryManager, mScrimController, mBiometricUnlockController,
- mKeyguardViewMediator, mRemoteInputManager, mock(NotificationGroupManager.class),
- mock(NotificationGroupAlertTransferHelper.class), mock(FalsingManager.class),
- mock(StatusBarWindowController.class), mock(NotificationIconAreaController.class),
- mDozeScrimController, mock(NotificationShelf.class),
- mLockscreenUserManager, mCommandQueue, mNotificationPresenter,
- mock(BubbleController.class), mock(NavigationBarController.class),
- mock(AutoHideController.class), mKeyguardUpdateMonitor, mStatusBarWindowView,
- mBroadcastDispatcher);
+
+ WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
+ wakefulnessLifecycle.dispatchStartedWakingUp();
+ wakefulnessLifecycle.dispatchFinishedWakingUp();
+
+ when(mGradientColors.supportsDarkText()).thenReturn(true);
+ when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
+ ConfigurationController configurationController = new ConfigurationControllerImpl(mContext);
+
+ when(mStatusBarWindowViewControllerBuilder.build())
+ .thenReturn(mStatusBarWindowViewController);
+
+ mStatusBar = new StatusBar(
+ mLightBarController,
+ mAutoHideController,
+ mKeyguardUpdateMonitor,
+ mStatusBarIconController,
+ mDozeLog,
+ mInjectionInflationController,
+ mPulseExpansionHandler,
+ mNotificationWakeUpCoordinator,
+ mKeyguardBypassController,
+ mKeyguardStateController,
+ mHeadsUpManager,
+ mDynamicPrivacyController,
+ mBypassHeadsUpNotifier,
+ true,
+ mNotifPipelineInitializer,
+ new FalsingManagerFake(),
+ mBroadcastDispatcher,
+ new RemoteInputQuickSettingsDisabler(
+ mContext,
+ configurationController
+ ),
+ mNotificationGutsManager,
+ notificationLogger,
+ entryManager,
+ mNotificationInterruptionStateProvider,
+ mNotificationViewHierarchyManager,
+ mForegroundServiceController,
+ mAppOpsController,
+ mKeyguardViewMediator,
+ mZenModeController,
+ mNotificationAlertingManager,
+ new DisplayMetrics(),
+ mMetricsLogger,
+ Dependency.get(UiOffloadThread.class),
+ mNotificationMediaManager,
+ mLockscreenUserManager,
+ mRemoteInputManager,
+ mUserSwitcherController,
+ mNetworkController,
+ mBatteryController,
+ mColorExtractor,
+ new ScreenLifecycle(),
+ wakefulnessLifecycle,
+ mStatusBarStateController,
+ mVibratorHelper,
+ mBubbleController,
+ mGroupManager,
+ mGroupAlertTransferHelper,
+ mVisualStabilityManager,
+ mDeviceProvisionedController,
+ mNavigationBarController,
+ mAssistManager,
+ mNotificationListener,
+ configurationController,
+ mStatusBarWindowController,
+ mStatusBarWindowViewControllerBuilder);
+ // TODO: we should be able to call mStatusBar.start() and have all the below values
+ // initialized automatically.
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mContext.getComponents();
- SystemUIFactory.getInstance().getRootComponent()
- .getStatusBarInjector()
- .createStatusBar(mStatusBar);
- mStatusBar.mKeyguardStateController = mKeyguardStateController;
- mStatusBar.setHeadsUpManager(mHeadsUpManager);
+ mStatusBar.mStatusBarKeyguardViewManager = mStatusBarKeyguardViewManager;
+ mStatusBar.mStatusBarWindow = mStatusBarWindowView;
+ mStatusBar.mBiometricUnlockController = mBiometricUnlockController;
+ mStatusBar.mScrimController = mScrimController;
+ mStatusBar.mNotificationPanel = mNotificationPanelView;
+ mStatusBar.mCommandQueue = mCommandQueue;
+ mStatusBar.mDozeScrimController = mDozeScrimController;
+ mStatusBar.mNotificationIconAreaController = mNotificationIconAreaController;
+ mStatusBar.mPresenter = mNotificationPresenter;
+ mStatusBar.mKeyguardIndicationController = mKeyguardIndicationController;
+ mStatusBar.mPowerManager = mPowerManager;
+ mStatusBar.mBarService = mBarService;
+ mStatusBar.mStackScroller = mStackScroller;
+ mStatusBar.mStatusBarWindowViewController = mStatusBarWindowViewController;
mStatusBar.putComponent(StatusBar.class, mStatusBar);
Dependency.get(InitController.class).executePostInitTasks();
- mEntryManager.setUpForTest(mock(NotificationPresenter.class), mStackScroller,
- mHeadsUpManager, mNotificationData);
- mEntryManager.addNotificationEntryListener(mEntryListener);
- mNotificationLogger.setUpWithContainer(mStackScroller);
+ entryManager.setUpForTest(mock(NotificationPresenter.class), mStackScroller,
+ mHeadsUpManager);
+ entryManager.addNotificationEntryListener(mEntryListener);
+ notificationLogger.setUpWithContainer(mStackScroller);
}
@Test
@@ -608,8 +686,8 @@
@Test
@RunWithLooper(setAsMainLooper = true)
public void testUpdateKeyguardState_DoesNotCrash() {
- mStatusBar.mState = StatusBarState.KEYGUARD;
- when(mStatusBar.mLockscreenUserManager.getCurrentProfiles()).thenReturn(
+ mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
+ when(mLockscreenUserManager.getCurrentProfiles()).thenReturn(
new SparseArray<>());
mStatusBar.onStateChanged(StatusBarState.SHADE);
}
@@ -713,11 +791,11 @@
// Starting a pulse while docking should suppress wakeup gesture
mStatusBar.mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class),
DozeEvent.PULSE_REASON_DOCKING);
- verify(mStatusBarWindowView).suppressWakeUpGesture(eq(true));
+ verify(mStatusBarWindowViewController).suppressWakeUpGesture(eq(true));
// Ending a pulse should restore wakeup gesture
pulseCallback[0].onPulseFinished();
- verify(mStatusBarWindowView).suppressWakeUpGesture(eq(false));
+ verify(mStatusBarWindowViewController).suppressWakeUpGesture(eq(false));
}
@Test
@@ -740,8 +818,7 @@
verify(mStatusBarStateController).setState(eq(StatusBarState.KEYGUARD));
// If useFullscreenUserSwitcher is true, state is set to FULLSCREEN_USER_SWITCHER.
- mStatusBar.mUserSwitcherController = mock(UserSwitcherController.class);
- when(mStatusBar.mUserSwitcherController.useFullscreenUserSwitcher()).thenReturn(true);
+ when(mUserSwitcherController.useFullscreenUserSwitcher()).thenReturn(true);
mStatusBar.showKeyguardImpl();
verify(mStatusBarStateController).setState(eq(StatusBarState.FULLSCREEN_USER_SWITCHER));
}
@@ -793,116 +870,23 @@
any(UserHandle.class));
}
- static class TestableStatusBar extends StatusBar {
- public TestableStatusBar(StatusBarKeyguardViewManager man,
- KeyguardIndicationController key,
- NotificationStackScrollLayout stack,
- PowerManager pm, NotificationPanelView panelView,
- IStatusBarService barService, NotificationListener notificationListener,
- NotificationLogger notificationLogger,
- VisualStabilityManager visualStabilityManager,
- NotificationViewHierarchyManager viewHierarchyManager,
- TestableNotificationEntryManager entryManager, ScrimController scrimController,
- BiometricUnlockController biometricUnlockController,
- KeyguardViewMediator keyguardViewMediator,
- NotificationRemoteInputManager notificationRemoteInputManager,
- NotificationGroupManager notificationGroupManager,
- NotificationGroupAlertTransferHelper notificationGroupAlertTransferHelper,
- FalsingManager falsingManager,
- StatusBarWindowController statusBarWindowController,
- NotificationIconAreaController notificationIconAreaController,
- DozeScrimController dozeScrimController,
- NotificationShelf notificationShelf,
- NotificationLockscreenUserManager notificationLockscreenUserManager,
- CommandQueue commandQueue,
- StatusBarNotificationPresenter notificationPresenter,
- BubbleController bubbleController,
- NavigationBarController navBarController,
- AutoHideController autoHideController,
- KeyguardUpdateMonitor keyguardUpdateMonitor,
- StatusBarWindowView statusBarWindow,
- BroadcastDispatcher broadcastDispatcher) {
- mStatusBarKeyguardViewManager = man;
- mKeyguardIndicationController = key;
- mStackScroller = stack;
- mPowerManager = pm;
- mNotificationPanel = panelView;
- mBarService = barService;
- mNotificationListener = notificationListener;
- mNotificationLogger = notificationLogger;
- mWakefulnessLifecycle = createAwakeWakefulnessLifecycle();
- mVisualStabilityManager = visualStabilityManager;
- mViewHierarchyManager = viewHierarchyManager;
- mEntryManager = entryManager;
- mScrimController = scrimController;
- mBiometricUnlockController = biometricUnlockController;
- mKeyguardViewMediator = keyguardViewMediator;
- mRemoteInputManager = notificationRemoteInputManager;
- mGroupManager = notificationGroupManager;
- mGroupAlertTransferHelper = notificationGroupAlertTransferHelper;
- mFalsingManager = falsingManager;
- mStatusBarWindowController = statusBarWindowController;
- mNotificationIconAreaController = notificationIconAreaController;
- mDozeScrimController = dozeScrimController;
- mNotificationShelf = notificationShelf;
- mLockscreenUserManager = notificationLockscreenUserManager;
- mCommandQueue = commandQueue;
- mPresenter = notificationPresenter;
- mGestureWakeLock = mock(PowerManager.WakeLock.class);
- mBubbleController = bubbleController;
- mNavigationBarController = navBarController;
- mAutoHideController = autoHideController;
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
- mStatusBarWindow = statusBarWindow;
- mDozeServiceHost.mWakeLockScreenPerformsAuth = false;
- mBroadcastDispatcher = broadcastDispatcher;
- }
-
- private WakefulnessLifecycle createAwakeWakefulnessLifecycle() {
- WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
- wakefulnessLifecycle.dispatchStartedWakingUp();
- wakefulnessLifecycle.dispatchFinishedWakingUp();
- return wakefulnessLifecycle;
- }
-
- @Override
- protected void updateTheme() {
- // Do nothing for now, until we have more mocking and StatusBar is smaller.
- }
-
- public void setBarStateForTest(int state) {
- mState = state;
- }
-
- void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
- mHeadsUpManager = headsUpManager;
- }
-
- public void setUserSetupForTest(boolean userSetup) {
- mUserSetup = userSetup;
- }
-
- }
-
public static class TestableNotificationEntryManager extends NotificationEntryManager {
- public TestableNotificationEntryManager(Context context) {
- super(context);
+ public TestableNotificationEntryManager(NotificationData notificationData) {
+ super(notificationData);
}
public void setUpForTest(NotificationPresenter presenter,
NotificationListContainer listContainer,
- HeadsUpManagerPhone headsUpManager,
- NotificationData notificationData) {
+ HeadsUpManagerPhone headsUpManager) {
super.setUpWithPresenter(presenter, listContainer, headsUpManager);
- mNotificationData = notificationData;
}
}
public static class TestableNotificationInterruptionStateProvider extends
NotificationInterruptionStateProvider {
- public TestableNotificationInterruptionStateProvider(
+ TestableNotificationInterruptionStateProvider(
Context context,
PowerManager powerManager,
IDreamManager dreamManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
index 00d87c3..9f4dfb4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
@@ -16,55 +16,89 @@
package com.android.systemui.statusbar.phone;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.os.SystemClock;
+import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-import com.android.systemui.Dependency;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.doze.DozeLog;
+import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.DragDownHelper;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
-@RunWith(AndroidJUnit4.class)
-@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class StatusBarWindowViewTest extends SysuiTestCase {
private StatusBarWindowView mView;
- private StatusBar mStatusBar;
- private DragDownHelper mDragDownHelper;
- private NotificationStackScrollLayout mStackScrollLayout;
+ private StatusBarWindowViewController mController;
+
+ @Mock private NotificationWakeUpCoordinator mCoordinator;
+ @Mock private PulseExpansionHandler mPulseExpansionHandler;
+ @Mock private DynamicPrivacyController mDynamicPrivacyController;
+ @Mock private KeyguardBypassController mBypassController;
+ @Mock private PluginManager mPluginManager;
+ @Mock private TunerService mTunerService;
+ @Mock private DragDownHelper mDragDownHelper;
+ @Mock private ShadeController mShadeController;
+ @Mock private NotificationLockscreenUserManager mNotificationLockScreenUserManager;
+ @Mock private NotificationEntryManager mNotificationEntryManager;
+ @Mock private StatusBar mStatusBar;
+ @Mock private DozeLog mDozeLog;
@Before
public void setUp() {
- mDependency.injectMockDependency(StatusBarStateController.class);
- mView = spy(new StatusBarWindowView(getContext(), null));
- mStackScrollLayout = mock(NotificationStackScrollLayout.class);
- when(mView.getStackScrollLayout()).thenReturn(mStackScrollLayout);
- mStatusBar = mock(StatusBar.class);
- mView.setService(mStatusBar);
- mDragDownHelper = mock(DragDownHelper.class);
- mView.setDragDownHelper(mDragDownHelper);
+ MockitoAnnotations.initMocks(this);
+
+ mView = new StatusBarWindowView(getContext(), null);
+ mContext.putComponent(StatusBar.class, mStatusBar);
+ when(mStatusBar.isDozing()).thenReturn(false);
+ mDependency.injectTestDependency(ShadeController.class, mShadeController);
+
+ mController = new StatusBarWindowViewController.Builder(
+ new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent()),
+ mCoordinator,
+ mPulseExpansionHandler,
+ mDynamicPrivacyController,
+ mBypassController,
+ new FalsingManagerFake(),
+ mPluginManager,
+ mTunerService,
+ mNotificationLockScreenUserManager,
+ mNotificationEntryManager,
+ mDozeLog)
+ .setShadeController(mShadeController)
+ .setStatusBarWindowView(mView)
+ .build();
+ mController.setService(mStatusBar);
+ mController.setDragDownHelper(mDragDownHelper);
+
}
@Test
- public void testDragDownHelperCalledWhenDraggingDown() throws Exception {
- when(Dependency.get(StatusBarStateController.class).getState())
- .thenReturn(StatusBarState.SHADE);
+ public void testDragDownHelperCalledWhenDraggingDown() {
when(mDragDownHelper.isDraggingDown()).thenReturn(true);
long now = SystemClock.elapsedRealtime();
MotionEvent ev = MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, 0 /* x */, 0 /* y */,
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 4f021ad..514eb77 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -350,9 +350,9 @@
protected abstract boolean hasRightsToCurrentUserLocked();
+ @Nullable
@Override
- public List<AccessibilityWindowInfo> getWindows() {
- ensureWindowsAvailableTimed(Display.DEFAULT_DISPLAY);
+ public AccessibilityWindowInfo.WindowListSparseArray getWindows() {
synchronized (mLock) {
if (!hasRightsToCurrentUserLocked()) {
return null;
@@ -362,38 +362,39 @@
if (!permissionGranted) {
return null;
}
- List<AccessibilityWindowInfo> internalWindowList =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- if (internalWindowList == null) {
- return null;
- }
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
}
- List<AccessibilityWindowInfo> returnedWindowList = new ArrayList<>();
- final int windowCount = internalWindowList.size();
- for (int i = 0; i < windowCount; i++) {
- AccessibilityWindowInfo window = internalWindowList.get(i);
- AccessibilityWindowInfo windowClone =
- AccessibilityWindowInfo.obtain(window);
- windowClone.setConnectionId(mId);
- returnedWindowList.add(windowClone);
+ final AccessibilityWindowInfo.WindowListSparseArray allWindows =
+ new AccessibilityWindowInfo.WindowListSparseArray();
+ final ArrayList<Integer> displayList = mA11yWindowManager.getDisplayListLocked();
+ final int displayListCounts = displayList.size();
+ if (displayListCounts > 0) {
+ for (int i = 0; i < displayListCounts; i++) {
+ final int displayId = displayList.get(i);
+ ensureWindowsAvailableTimedLocked(displayId);
+
+ final List<AccessibilityWindowInfo> windowList = getWindowsByDisplayLocked(
+ displayId);
+ if (windowList != null) {
+ allWindows.put(displayId, windowList);
+ }
+ }
}
- return returnedWindowList;
+ return allWindows;
}
}
@Override
public AccessibilityWindowInfo getWindow(int windowId) {
- int displayId = Display.INVALID_DISPLAY;
synchronized (mLock) {
+ int displayId = Display.INVALID_DISPLAY;
if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) {
displayId = mA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked(
mSystemSupport.getCurrentUserIdLocked(), windowId);
}
- }
- ensureWindowsAvailableTimed(displayId);
- synchronized (mLock) {
+ ensureWindowsAvailableTimedLocked(displayId);
+
if (!hasRightsToCurrentUserLocked()) {
return null;
}
@@ -1316,35 +1317,33 @@
*
* @param displayId The logical display id.
*/
- private void ensureWindowsAvailableTimed(int displayId) {
- synchronized (mLock) {
- if (mA11yWindowManager.getWindowListLocked(displayId) != null) {
- return;
- }
- // If we have no registered callback, update the state we
- // we may have to register one but it didn't happen yet.
- if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) {
- // Invokes client change to make sure tracking window enabled.
- mSystemSupport.onClientChangeLocked(false);
- }
- // We have no windows but do not care about them, done.
- if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) {
- return;
- }
+ private void ensureWindowsAvailableTimedLocked(int displayId) {
+ if (mA11yWindowManager.getWindowListLocked(displayId) != null) {
+ return;
+ }
+ // If we have no registered callback, update the state we
+ // we may have to register one but it didn't happen yet.
+ if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) {
+ // Invokes client change to make sure tracking window enabled.
+ mSystemSupport.onClientChangeLocked(false);
+ }
+ // We have no windows but do not care about them, done.
+ if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) {
+ return;
+ }
- // Wait for the windows with a timeout.
- final long startMillis = SystemClock.uptimeMillis();
- while (mA11yWindowManager.getWindowListLocked(displayId) == null) {
- final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
- final long remainMillis = WAIT_WINDOWS_TIMEOUT_MILLIS - elapsedMillis;
- if (remainMillis <= 0) {
- return;
- }
- try {
- mLock.wait(remainMillis);
- } catch (InterruptedException ie) {
- /* ignore */
- }
+ // Wait for the windows with a timeout.
+ final long startMillis = SystemClock.uptimeMillis();
+ while (mA11yWindowManager.getWindowListLocked(displayId) == null) {
+ final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
+ final long remainMillis = WAIT_WINDOWS_TIMEOUT_MILLIS - elapsedMillis;
+ if (remainMillis <= 0) {
+ return;
+ }
+ try {
+ mLock.wait(remainMillis);
+ } catch (InterruptedException ie) {
+ /* ignore */
}
}
}
@@ -1442,6 +1441,24 @@
interrogatingPid, interrogatingTid);
}
+ private List<AccessibilityWindowInfo> getWindowsByDisplayLocked(int displayId) {
+ final List<AccessibilityWindowInfo> internalWindowList =
+ mA11yWindowManager.getWindowListLocked(displayId);
+ if (internalWindowList == null) {
+ return null;
+ }
+ final List<AccessibilityWindowInfo> returnedWindowList = new ArrayList<>();
+ final int windowCount = internalWindowList.size();
+ for (int i = 0; i < windowCount; i++) {
+ AccessibilityWindowInfo window = internalWindowList.get(i);
+ AccessibilityWindowInfo windowClone =
+ AccessibilityWindowInfo.obtain(window);
+ windowClone.setConnectionId(mId);
+ returnedWindowList.add(windowClone);
+ }
+ return returnedWindowList;
+ }
+
public ComponentName getComponentName() {
return mComponentName;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 1f11059..3b105ad 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -30,6 +30,7 @@
import android.accessibilityservice.AccessibilityGestureEvent;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.AccessibilityShortcutInfo;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -1208,6 +1209,18 @@
return false;
}
+ private boolean readInstalledAccessibilityShortcutLocked(UserState userState) {
+ final List<AccessibilityShortcutInfo> shortcutInfos = AccessibilityManager
+ .getInstance(mContext).getInstalledAccessibilityShortcutListAsUser(
+ mContext, mCurrentUserId);
+ if (!shortcutInfos.equals(userState.mInstalledShortcuts)) {
+ userState.mInstalledShortcuts.clear();
+ userState.mInstalledShortcuts.addAll(shortcutInfos);
+ return true;
+ }
+ return false;
+ }
+
private boolean readEnabledAccessibilityServicesLocked(UserState userState) {
mTempComponentNameSet.clear();
readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
@@ -1741,6 +1754,7 @@
private boolean readConfigurationForUserStateLocked(UserState userState) {
boolean somethingChanged = readInstalledAccessibilityServiceLocked(userState);
+ somethingChanged |= readInstalledAccessibilityShortcutLocked(userState);
somethingChanged |= readEnabledAccessibilityServicesLocked(userState);
somethingChanged |= readTouchExplorationGrantedAccessibilityServicesLocked(userState);
somethingChanged |= readTouchExplorationEnabledSettingLocked(userState);
@@ -2671,6 +2685,8 @@
public final List<AccessibilityServiceInfo> mInstalledServices =
new ArrayList<>();
+ public final List<AccessibilityShortcutInfo> mInstalledShortcuts = new ArrayList<>();
+
private final Set<ComponentName> mBindingServices = new HashSet<>();
public final Set<ComponentName> mEnabledServices = new HashSet<>();
@@ -3083,6 +3099,8 @@
|| mUserInteractiveUiTimeoutUri.equals(uri)) {
readUserRecommendedUiTimeoutSettingsLocked(userState);
}
+ // TODO(a11y shortcut): Monitor new setting keys, when user adds shortcut, and
+ // remove from the list of enabled targets anything that's been uninstalled.
}
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 0038a27..cb858ac 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -1472,11 +1472,27 @@
public int getDisplayIdByUserIdAndWindowIdLocked(int userId, int windowId) {
final IBinder windowToken = getWindowTokenForUserAndWindowIdLocked(userId, windowId);
final int displayId = mWindowManagerInternal.getDisplayIdForWindow(windowToken);
-
return displayId;
}
/**
+ * Returns the display list including all displays which are tracking windows.
+ *
+ * @return The display list.
+ */
+ public ArrayList<Integer> getDisplayListLocked() {
+ final ArrayList<Integer> displayList = new ArrayList<>();
+ final int count = mDisplayWindowsObservers.size();
+ for (int i = 0; i < count; i++) {
+ final DisplayWindowsObserver observer = mDisplayWindowsObservers.valueAt(i);
+ if (observer != null) {
+ displayList.add(observer.mDisplayId);
+ }
+ }
+ return displayList;
+ }
+
+ /**
* Gets current input focused window token from window manager, and returns its windowId.
*
* @param userId The userId
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/AccessibilityGestureDetector.java b/services/accessibility/java/com/android/server/accessibility/gestures/AccessibilityGestureDetector.java
index 7e8fb29..3dfe59e 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/AccessibilityGestureDetector.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/AccessibilityGestureDetector.java
@@ -408,9 +408,6 @@
cancelGesture();
}
- public boolean firstTapDetected() {
- return mFirstTapDetected;
- }
@Override
public void onLongPress(MotionEvent e) {
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java b/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java
index dc7a9aa..5ac3b69 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/EventDispatcher.java
@@ -72,10 +72,16 @@
*
* @param prototype The prototype from which to create the injected events.
* @param action The action of the event.
+ * @param rawEvent The original event prior to magnification or other transformations.
* @param pointerIdBits The bits of the pointers to send.
* @param policyFlags The policy flags associated with the event.
*/
- void sendMotionEvent(MotionEvent prototype, int action, int pointerIdBits, int policyFlags) {
+ void sendMotionEvent(
+ MotionEvent prototype,
+ int action,
+ MotionEvent rawEvent,
+ int pointerIdBits,
+ int policyFlags) {
prototype.setAction(action);
MotionEvent event = null;
@@ -105,11 +111,8 @@
// Make sure that the user will see the event.
policyFlags |= WindowManagerPolicy.FLAG_PASS_TO_USER;
- // TODO: For now pass null for the raw event since the touch
- // explorer is the last event transformation and it does
- // not care about the raw event.
if (mReceiver != null) {
- mReceiver.onMotionEvent(event, null, policyFlags);
+ mReceiver.onMotionEvent(event, rawEvent, policyFlags);
} else {
Slog.e(LOG_TAG, "Error sending event: no receiver specified.");
}
@@ -280,7 +283,12 @@
if (!isInjectedPointerDown(pointerId)) {
pointerIdBits |= (1 << pointerId);
final int action = computeInjectionAction(MotionEvent.ACTION_DOWN, i);
- sendMotionEvent(prototype, action, pointerIdBits, policyFlags);
+ sendMotionEvent(
+ prototype,
+ action,
+ mState.getLastReceivedEvent(),
+ pointerIdBits,
+ policyFlags);
}
}
}
@@ -303,7 +311,8 @@
}
pointerIdBits |= (1 << pointerId);
final int action = computeInjectionAction(MotionEvent.ACTION_UP, i);
- sendMotionEvent(prototype, action, pointerIdBits, policyFlags);
+ sendMotionEvent(
+ prototype, action, mState.getLastReceivedEvent(), pointerIdBits, policyFlags);
}
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index f4ac821..b62e260 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -183,9 +183,9 @@
private void clear() {
// If we have not received an event then we are in initial
// state. Therefore, there is not need to clean anything.
- MotionEvent event = mReceivedPointerTracker.getLastReceivedEvent();
+ MotionEvent event = mState.getLastReceivedEvent();
if (event != null) {
- clear(mReceivedPointerTracker.getLastReceivedEvent(), WindowManagerPolicy.FLAG_TRUSTED);
+ clear(event, WindowManagerPolicy.FLAG_TRUSTED);
}
}
@@ -229,7 +229,7 @@
Slog.d(LOG_TAG, mState.toString());
}
- mReceivedPointerTracker.onMotionEvent(rawEvent);
+ mState.onReceivedMotionEvent(rawEvent);
if (mGestureDetector.onMotionEvent(event, rawEvent, policyFlags)) {
// Event was handled by the gesture detector.
@@ -250,9 +250,9 @@
} else if (mState.isTouchExploring()) {
handleMotionEventStateTouchExploring(event, rawEvent, policyFlags);
} else if (mState.isDragging()) {
- handleMotionEventStateDragging(event, policyFlags);
+ handleMotionEventStateDragging(event, rawEvent, policyFlags);
} else if (mState.isDelegating()) {
- handleMotionEventStateDelegating(event, policyFlags);
+ handleMotionEventStateDelegating(event, rawEvent, policyFlags);
} else if (mState.isGestureDetecting()) {
// Already handled.
} else {
@@ -292,7 +292,7 @@
}
// Pointers should not be zero when running this command.
- if (mReceivedPointerTracker.getLastReceivedEvent().getPointerCount() == 0) {
+ if (mState.getLastReceivedEvent().getPointerCount() == 0) {
return;
}
// Try to use the standard accessibility API to long click
@@ -368,11 +368,15 @@
// We have just decided that the user is touch,
// exploring so start sending events.
- mSendHoverEnterAndMoveDelayed.addEvent(event);
+ mSendHoverEnterAndMoveDelayed.addEvent(event, mState.getLastReceivedEvent());
mSendHoverEnterAndMoveDelayed.forceSendAndRemove();
mSendHoverExitDelayed.cancel();
mDispatcher.sendMotionEvent(
- event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags);
+ event,
+ MotionEvent.ACTION_HOVER_MOVE,
+ mState.getLastReceivedEvent(),
+ pointerIdBits,
+ policyFlags);
return true;
}
}
@@ -387,7 +391,7 @@
switch (event.getActionMasked()) {
// The only way to leave the clear state is for a pointer to go down.
case MotionEvent.ACTION_DOWN:
- handleActionDown(event, policyFlags);
+ handleActionDown(event, rawEvent, policyFlags);
break;
default:
// Some other nonsensical event.
@@ -399,7 +403,7 @@
* Handles ACTION_DOWN while in the clear or touch interacting states. This event represents the
* first finger touching the screen.
*/
- private void handleActionDown(MotionEvent event, int policyFlags) {
+ private void handleActionDown(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
mAms.onTouchInteractionStart();
// If we still have not notified the user for the last
@@ -407,24 +411,12 @@
// we resent the delayed callback and wait again.
mSendHoverEnterAndMoveDelayed.cancel();
mSendHoverExitDelayed.cancel();
-
// If a touch exploration gesture is in progress send events for its end.
if (mState.isTouchExploring()) {
sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
}
- // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double
- // tap.
- if (!mGestureDetector.firstTapDetected() && mState.isClear()) {
- mSendTouchExplorationEndDelayed.forceSendAndRemove();
- mSendTouchInteractionEndDelayed.forceSendAndRemove();
- mDispatcher.sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
- } else {
- // Let gesture to handle to avoid duplicated TYPE_TOUCH_INTERACTION_END event.
- mSendTouchInteractionEndDelayed.cancel();
- }
-
- if (!mGestureDetector.firstTapDetected() && !mState.isTouchExploring()) {
+ if (mState.isClear()) {
if (!mSendHoverEnterAndMoveDelayed.isPending()) {
// Queue a delayed transition to STATE_TOUCH_EXPLORING.
// If we do not detect that this is a gesture, delegation or drag the transition
@@ -432,11 +424,17 @@
// The idea is to avoid getting stuck in STATE_TOUCH_INTERACTING
final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
final int pointerIdBits = (1 << pointerId);
- mSendHoverEnterAndMoveDelayed.post(event, pointerIdBits, policyFlags);
+ mSendHoverEnterAndMoveDelayed.post(event, rawEvent, pointerIdBits, policyFlags);
} else {
// Cache the event until we discern exploration from gesturing.
- mSendHoverEnterAndMoveDelayed.addEvent(event);
+ mSendHoverEnterAndMoveDelayed.addEvent(event, rawEvent);
}
+ mSendTouchExplorationEndDelayed.forceSendAndRemove();
+ mSendTouchInteractionEndDelayed.forceSendAndRemove();
+ mDispatcher.sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
+ } else {
+ // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double tap.
+ mSendTouchInteractionEndDelayed.cancel();
}
}
@@ -453,7 +451,7 @@
case MotionEvent.ACTION_DOWN:
// Continue the previous interaction.
mSendTouchInteractionEndDelayed.cancel();
- handleActionDown(event, policyFlags);
+ handleActionDown(event, rawEvent, policyFlags);
break;
case MotionEvent.ACTION_POINTER_DOWN:
handleActionPointerDown();
@@ -462,7 +460,7 @@
handleActionMoveStateTouchInteracting(event, rawEvent, policyFlags);
break;
case MotionEvent.ACTION_UP:
- handleActionUp(event, policyFlags);
+ handleActionUp(event, rawEvent, policyFlags);
break;
}
}
@@ -487,7 +485,7 @@
handleActionMoveStateTouchExploring(event, rawEvent, policyFlags);
break;
case MotionEvent.ACTION_UP:
- handleActionUp(event, policyFlags);
+ handleActionUp(event, rawEvent, policyFlags);
break;
default:
break;
@@ -520,7 +518,7 @@
// figure out what the user is doing.
if (mSendHoverEnterAndMoveDelayed.isPending()) {
// Cache the event until we discern exploration from gesturing.
- mSendHoverEnterAndMoveDelayed.addEvent(event);
+ mSendHoverEnterAndMoveDelayed.addEvent(event, rawEvent);
}
break;
case 2:
@@ -538,7 +536,7 @@
mDraggingPointerId = pointerId;
event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags());
mDispatcher.sendMotionEvent(
- event, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags);
+ event, MotionEvent.ACTION_DOWN, rawEvent, pointerIdBits, policyFlags);
} else {
// Two pointers moving arbitrary are delegated to the view hierarchy.
mState.startDelegating();
@@ -558,13 +556,13 @@
* Handles ACTION_UP while in the touch interacting state. This event represents all fingers
* being lifted from the screen.
*/
- private void handleActionUp(MotionEvent event, int policyFlags) {
+ private void handleActionUp(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
mAms.onTouchInteractionEnd();
final int pointerId = event.getPointerId(event.getActionIndex());
final int pointerIdBits = (1 << pointerId);
if (mSendHoverEnterAndMoveDelayed.isPending()) {
// If we have not delivered the enter schedule an exit.
- mSendHoverExitDelayed.post(event, pointerIdBits, policyFlags);
+ mSendHoverExitDelayed.post(event, rawEvent, pointerIdBits, policyFlags);
} else {
// The user is touch exploring so we send events for end.
sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
@@ -588,7 +586,7 @@
// Touch exploration.
sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags);
mDispatcher.sendMotionEvent(
- event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags);
+ event, MotionEvent.ACTION_HOVER_MOVE, rawEvent, pointerIdBits, policyFlags);
break;
case 2:
if (mSendHoverEnterAndMoveDelayed.isPending()) {
@@ -638,7 +636,8 @@
* @param event The event to be handled.
* @param policyFlags The policy flags associated with the event.
*/
- private void handleMotionEventStateDragging(MotionEvent event, int policyFlags) {
+ private void handleMotionEventStateDragging(
+ MotionEvent event, MotionEvent rawEvent, int policyFlags) {
int pointerIdBits = 0;
// Clear the dragging pointer id if it's no longer valid.
if (event.findPointerIndex(mDraggingPointerId) == -1) {
@@ -662,7 +661,7 @@
mState.startDelegating();
if (mDraggingPointerId != INVALID_POINTER_ID) {
mDispatcher.sendMotionEvent(
- event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags);
+ event, MotionEvent.ACTION_UP, rawEvent, pointerIdBits, policyFlags);
}
mDispatcher.sendDownForAllNotInjectedPointers(event, policyFlags);
} break;
@@ -681,6 +680,7 @@
mDispatcher.sendMotionEvent(
event,
MotionEvent.ACTION_MOVE,
+ rawEvent,
pointerIdBits,
policyFlags);
} else {
@@ -690,7 +690,11 @@
// Remove move history before send injected non-move events
event = MotionEvent.obtainNoHistory(event);
// Send an event to the end of the drag gesture.
- mDispatcher.sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits,
+ mDispatcher.sendMotionEvent(
+ event,
+ MotionEvent.ACTION_UP,
+ rawEvent,
+ pointerIdBits,
policyFlags);
// Deliver all pointers to the view hierarchy.
mDispatcher.sendDownForAllNotInjectedPointers(event, policyFlags);
@@ -700,7 +704,11 @@
mState.startDelegating();
event = MotionEvent.obtainNoHistory(event);
// Send an event to the end of the drag gesture.
- mDispatcher.sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits,
+ mDispatcher.sendMotionEvent(
+ event,
+ MotionEvent.ACTION_UP,
+ rawEvent,
+ pointerIdBits,
policyFlags);
// Deliver all pointers to the view hierarchy.
mDispatcher.sendDownForAllNotInjectedPointers(event, policyFlags);
@@ -713,7 +721,7 @@
mDraggingPointerId = INVALID_POINTER_ID;
// Send an event to the end of the drag gesture.
mDispatcher.sendMotionEvent(
- event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags);
+ event, MotionEvent.ACTION_UP, rawEvent, pointerIdBits, policyFlags);
}
} break;
case MotionEvent.ACTION_UP: {
@@ -726,7 +734,7 @@
mDraggingPointerId = INVALID_POINTER_ID;
// Send an event to the end of the drag gesture.
mDispatcher.sendMotionEvent(
- event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags);
+ event, MotionEvent.ACTION_UP, rawEvent, pointerIdBits, policyFlags);
}
} break;
}
@@ -738,7 +746,8 @@
* @param event The event to be handled.
* @param policyFlags The policy flags associated with the event.
*/
- private void handleMotionEventStateDelegating(MotionEvent event, int policyFlags) {
+ private void handleMotionEventStateDelegating(
+ MotionEvent event, MotionEvent rawEvent, int policyFlags) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
Slog.e(LOG_TAG, "Delegating state can only be reached if "
@@ -749,7 +758,7 @@
case MotionEvent.ACTION_UP: {
// Deliver the event.
mDispatcher.sendMotionEvent(
- event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags);
+ event, event.getAction(), rawEvent, ALL_POINTER_ID_BITS, policyFlags);
// Announce the end of a the touch interaction.
mAms.onTouchInteractionEnd();
@@ -759,7 +768,7 @@
default: {
// Deliver the event.
mDispatcher.sendMotionEvent(
- event, event.getAction(), ALL_POINTER_ID_BITS, policyFlags);
+ event, event.getAction(), rawEvent, ALL_POINTER_ID_BITS, policyFlags);
}
}
}
@@ -792,7 +801,11 @@
mSendTouchExplorationEndDelayed.post();
}
mDispatcher.sendMotionEvent(
- event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags);
+ event,
+ MotionEvent.ACTION_HOVER_EXIT,
+ mState.getLastReceivedEvent(),
+ pointerIdBits,
+ policyFlags);
}
}
@@ -807,7 +820,11 @@
if (event != null && event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) {
final int pointerIdBits = event.getPointerIdBits();
mDispatcher.sendMotionEvent(
- event, MotionEvent.ACTION_HOVER_ENTER, pointerIdBits, policyFlags);
+ event,
+ MotionEvent.ACTION_HOVER_ENTER,
+ mState.getLastReceivedEvent(),
+ pointerIdBits,
+ policyFlags);
}
}
@@ -891,20 +908,23 @@
private final String LOG_TAG_SEND_HOVER_DELAYED = "SendHoverEnterAndMoveDelayed";
private final List<MotionEvent> mEvents = new ArrayList<MotionEvent>();
+ private final List<MotionEvent> mRawEvents = new ArrayList<MotionEvent>();
private int mPointerIdBits;
private int mPolicyFlags;
- public void post(MotionEvent event, int pointerIdBits, int policyFlags) {
+ public void post(
+ MotionEvent event, MotionEvent rawEvent, int pointerIdBits, int policyFlags) {
cancel();
- addEvent(event);
+ addEvent(event, rawEvent);
mPointerIdBits = pointerIdBits;
mPolicyFlags = policyFlags;
mHandler.postDelayed(this, mDetermineUserIntentTimeout);
}
- public void addEvent(MotionEvent event) {
+ public void addEvent(MotionEvent event, MotionEvent rawEvent) {
mEvents.add(MotionEvent.obtain(event));
+ mRawEvents.add(MotionEvent.obtain(rawEvent));
}
public void cancel() {
@@ -925,6 +945,10 @@
for (int i = eventCount - 1; i >= 0; i--) {
mEvents.remove(i).recycle();
}
+ final int rawEventcount = mRawEvents.size();
+ for (int i = rawEventcount - 1; i >= 0; i--) {
+ mRawEvents.remove(i).recycle();
+ }
}
public void forceSendAndRemove() {
@@ -939,10 +963,10 @@
mDispatcher.sendAccessibilityEvent(
AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START);
- if (!mEvents.isEmpty()) {
+ if (!mEvents.isEmpty() && !mRawEvents.isEmpty()) {
// Deliver a down event.
mDispatcher.sendMotionEvent(mEvents.get(0), MotionEvent.ACTION_HOVER_ENTER,
- mPointerIdBits, mPolicyFlags);
+ mRawEvents.get(0), mPointerIdBits, mPolicyFlags);
if (DEBUG) {
Slog.d(LOG_TAG_SEND_HOVER_DELAYED,
"Injecting motion event: ACTION_HOVER_ENTER");
@@ -952,7 +976,7 @@
final int eventCount = mEvents.size();
for (int i = 1; i < eventCount; i++) {
mDispatcher.sendMotionEvent(mEvents.get(i), MotionEvent.ACTION_HOVER_MOVE,
- mPointerIdBits, mPolicyFlags);
+ mRawEvents.get(i), mPointerIdBits, mPolicyFlags);
if (DEBUG) {
Slog.d(LOG_TAG_SEND_HOVER_DELAYED,
"Injecting motion event: ACTION_HOVER_MOVE");
@@ -970,12 +994,15 @@
private final String LOG_TAG_SEND_HOVER_DELAYED = "SendHoverExitDelayed";
private MotionEvent mPrototype;
+ private MotionEvent mRawEvent;
private int mPointerIdBits;
private int mPolicyFlags;
- public void post(MotionEvent prototype, int pointerIdBits, int policyFlags) {
+ public void post(
+ MotionEvent prototype, MotionEvent rawEvent, int pointerIdBits, int policyFlags) {
cancel();
mPrototype = MotionEvent.obtain(prototype);
+ mRawEvent = MotionEvent.obtain(rawEvent);
mPointerIdBits = pointerIdBits;
mPolicyFlags = policyFlags;
mHandler.postDelayed(this, mDetermineUserIntentTimeout);
@@ -993,8 +1020,14 @@
}
private void clear() {
- mPrototype.recycle();
+ if (mPrototype != null) {
+ mPrototype.recycle();
+ }
+ if (mRawEvent != null) {
+ mRawEvent.recycle();
+ }
mPrototype = null;
+ mRawEvent = null;
mPointerIdBits = -1;
mPolicyFlags = 0;
}
@@ -1011,8 +1044,12 @@
Slog.d(LOG_TAG_SEND_HOVER_DELAYED, "Injecting motion event:"
+ " ACTION_HOVER_EXIT");
}
- mDispatcher.sendMotionEvent(mPrototype, MotionEvent.ACTION_HOVER_EXIT,
- mPointerIdBits, mPolicyFlags);
+ mDispatcher.sendMotionEvent(
+ mPrototype,
+ MotionEvent.ACTION_HOVER_EXIT,
+ mRawEvent,
+ mPointerIdBits,
+ mPolicyFlags);
if (!mSendTouchExplorationEndDelayed.isPending()) {
mSendTouchExplorationEndDelayed.cancel();
mSendTouchExplorationEndDelayed.post();
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
index 49938fa..f463260 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
@@ -71,6 +71,7 @@
// Helper class to track received pointers.
// Todo: collapse or hide this class so multiple classes don't modify it.
private final ReceivedPointerTracker mReceivedPointerTracker;
+ private MotionEvent mLastReceivedEvent;
public TouchState() {
mReceivedPointerTracker = new ReceivedPointerTracker();
@@ -80,6 +81,10 @@
public void clear() {
setState(STATE_CLEAR);
// Reset the pointer trackers.
+ if (mLastReceivedEvent != null) {
+ mLastReceivedEvent.recycle();
+ mLastReceivedEvent = null;
+ }
mReceivedPointerTracker.clear();
}
@@ -89,6 +94,10 @@
* @param rawEvent The raw touch event.
*/
public void onReceivedMotionEvent(MotionEvent rawEvent) {
+ if (mLastReceivedEvent != null) {
+ mLastReceivedEvent.recycle();
+ }
+ mLastReceivedEvent = MotionEvent.obtain(rawEvent);
mReceivedPointerTracker.onMotionEvent(rawEvent);
}
@@ -216,6 +225,11 @@
return mReceivedPointerTracker;
}
+ /** @return The last received event. */
+ public MotionEvent getLastReceivedEvent() {
+ return mLastReceivedEvent;
+ }
+
/** This class tracks where and when a pointer went down. It does not track its movement. */
class ReceivedPointerTracker {
private static final String LOG_TAG_RECEIVED_POINTER_TRACKER = "ReceivedPointerTracker";
@@ -232,8 +246,6 @@
// or if it goes up the next one that most recently went down.
private int mPrimaryPointerId;
- // Keep track of the last up pointer data.
- private MotionEvent mLastReceivedEvent;
ReceivedPointerTracker() {
clear();
@@ -254,11 +266,6 @@
* @param event The event to process.
*/
public void onMotionEvent(MotionEvent event) {
- if (mLastReceivedEvent != null) {
- mLastReceivedEvent.recycle();
- }
- mLastReceivedEvent = MotionEvent.obtain(event);
-
final int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
@@ -279,11 +286,6 @@
}
}
- /** @return The last received event. */
- public MotionEvent getLastReceivedEvent() {
- return mLastReceivedEvent;
- }
-
/** @return The number of received pointers that are down. */
public int getReceivedPointerDownCount() {
return Integer.bitCount(mReceivedPointersDown);
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 80bc1af..4e80977 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -48,10 +48,12 @@
":services.core.protolog.json",
],
cmd: "cp $(location :generate-protolog.json) $(out) && " +
- "{ diff $(out) $(location :services.core.protolog.json) >/dev/null 2>&1 || " +
- "{ echo -e '##### ProtoLog viewer config is stale. ### \nRun: \n " +
- "cp $(location :generate-protolog.json) " +
- "$(location :services.core.protolog.json)\n' >&2 && false; } }",
+ "{ ! (diff $(out) $(location :services.core.protolog.json) | grep -q '^<') || " +
+ "{ echo -e '\\n\\n################################################################\\n#\\n" +
+ "# ERROR: ProtoLog viewer config is stale. To update it, run:\\n#\\n" +
+ "# cp $(location :generate-protolog.json) " +
+ "$(location :services.core.protolog.json)\\n#\\n" +
+ "################################################################\\n\\n' >&2 && false; } }",
out: ["services.core.protolog.json"],
}
@@ -106,7 +108,7 @@
"android.hardware.biometrics.fingerprint-V2.1-java",
"android.hardware.oemlock-V1.0-java",
"android.hardware.tetheroffload.control-V1.0-java",
- "android.hardware.vibrator-V1.0-java",
+ "android.hardware.vibrator-V1.4-java",
"android.hardware.configstore-V1.0-java",
"android.hardware.contexthub-V1.0-java",
"android.hidl.manager-V1.2-java",
diff --git a/services/core/java/com/android/server/AnimationThread.java b/services/core/java/com/android/server/AnimationThread.java
index c607b1e..fad743e 100644
--- a/services/core/java/com/android/server/AnimationThread.java
+++ b/services/core/java/com/android/server/AnimationThread.java
@@ -64,7 +64,7 @@
*/
@VisibleForTesting
public static void dispose() {
- synchronized (DisplayThread.class) {
+ synchronized (AnimationThread.class) {
if (sInstance == null) {
return;
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 18a8148..9acafae 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -495,7 +495,7 @@
* arg1 = One of the NETWORK_TESTED_RESULT_* constants.
* arg2 = NetID.
*/
- public static final int EVENT_NETWORK_TESTED = 41;
+ private static final int EVENT_NETWORK_TESTED = 41;
/**
* Event for NetworkMonitor/NetworkAgentInfo to inform ConnectivityService that the private DNS
@@ -503,7 +503,7 @@
* obj = PrivateDnsConfig
* arg2 = netid
*/
- public static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42;
+ private static final int EVENT_PRIVATE_DNS_CONFIG_RESOLVED = 42;
/**
* Request ConnectivityService display provisioning notification.
@@ -511,12 +511,12 @@
* arg2 = NetID.
* obj = Intent to be launched when notification selected by user, null if !arg1.
*/
- public static final int EVENT_PROVISIONING_NOTIFICATION = 43;
+ private static final int EVENT_PROVISIONING_NOTIFICATION = 43;
/**
* This event can handle dismissing notification by given network id.
*/
- public static final int EVENT_TIMEOUT_NOTIFICATION = 44;
+ private static final int EVENT_TIMEOUT_NOTIFICATION = 44;
/**
* Used to specify whether a network should be used even if connectivity is partial.
@@ -531,13 +531,13 @@
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown.
*/
- public static final int PROVISIONING_NOTIFICATION_SHOW = 1;
+ private static final int PROVISIONING_NOTIFICATION_SHOW = 1;
/**
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be hidden.
*/
- public static final int PROVISIONING_NOTIFICATION_HIDE = 0;
+ private static final int PROVISIONING_NOTIFICATION_HIDE = 0;
private static String eventName(int what) {
return sMagicDecoderRing.get(what, Integer.toString(what));
@@ -1938,7 +1938,7 @@
}
}
- return mPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules,
+ return NetworkPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules,
isNetworkMetered, isBackgroundRestricted);
}
@@ -2204,7 +2204,7 @@
final String iface = networkAgent.linkProperties.getInterfaceName();
final int timeout;
- int type = ConnectivityManager.TYPE_NONE;
+ final int type;
if (networkAgent.networkCapabilities.hasTransport(
NetworkCapabilities.TRANSPORT_CELLULAR)) {
@@ -2219,11 +2219,10 @@
15);
type = ConnectivityManager.TYPE_WIFI;
} else {
- // do not track any other networks
- timeout = 0;
+ return; // do not track any other networks
}
- if (timeout > 0 && iface != null && type != ConnectivityManager.TYPE_NONE) {
+ if (timeout > 0 && iface != null) {
try {
mNMS.addIdleTimer(iface, timeout, type);
} catch (Exception e) {
@@ -2299,7 +2298,6 @@
@VisibleForTesting
protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208";
- private static final String DEFAULT_TCP_RWND_KEY = "net.tcp.default_init_rwnd";
private void updateTcpBufferSizes(String tcpBufferSizes) {
String[] values = null;
@@ -2375,7 +2373,8 @@
}
@Override
- protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer,
+ @Nullable String[] args) {
PriorityDump.dump(mPriorityDumper, fd, writer, args);
}
@@ -2837,7 +2836,7 @@
private NetworkMonitorCallbacks(NetworkAgentInfo nai) {
mNetId = nai.network.netId;
- mNai = new AutodestructReference(nai);
+ mNai = new AutodestructReference<>(nai);
}
@Override
@@ -4292,7 +4291,7 @@
public void onChange(boolean selfChange, Uri uri) {
final Integer what = mUriEventMap.get(uri);
if (what != null) {
- mHandler.obtainMessage(what.intValue()).sendToTarget();
+ mHandler.obtainMessage(what).sendToTarget();
} else {
loge("No matching event to send for URI=" + uri);
}
@@ -4729,12 +4728,10 @@
private static final String ATTR_MNC = "mnc";
private String getProvisioningUrlBaseFromFile() {
- FileReader fileReader = null;
- XmlPullParser parser = null;
+ XmlPullParser parser;
Configuration config = mContext.getResources().getConfiguration();
- try {
- fileReader = new FileReader(mProvisioningUrlFile);
+ try (FileReader fileReader = new FileReader(mProvisioningUrlFile)) {
parser = Xml.newPullParser();
parser.setInput(fileReader);
XmlUtils.beginDocument(parser, TAG_PROVISIONING_URLS);
@@ -4769,12 +4766,6 @@
loge("Xml parser exception reading Carrier Provisioning Urls file: " + e);
} catch (IOException e) {
loge("I/O exception reading Carrier Provisioning Urls file: " + e);
- } finally {
- if (fileReader != null) {
- try {
- fileReader.close();
- } catch (IOException e) {}
- }
}
return null;
}
@@ -5104,8 +5095,8 @@
}
}
- // This checks that the passed capabilities either do not request a specific SSID/SignalStrength
- // , or the calling app has permission to do so.
+ // This checks that the passed capabilities either do not request a
+ // specific SSID/SignalStrength, or the calling app has permission to do so.
private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc,
int callerPid, int callerUid) {
if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) {
@@ -5238,7 +5229,7 @@
final int uid = Binder.getCallingUid();
Integer uidReqs = mBandwidthRequests.get(uid);
if (uidReqs == null) {
- uidReqs = new Integer(0);
+ uidReqs = 0;
}
mBandwidthRequests.put(uid, ++uidReqs);
}
@@ -5572,7 +5563,7 @@
}
private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp,
- LinkProperties oldLp) {
+ @NonNull LinkProperties oldLp) {
int netId = networkAgent.network.netId;
// The NetworkAgentInfo does not know whether clatd is running on its network or not, or
@@ -5687,7 +5678,7 @@
*/
private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
// Compare the route diff to determine which routes should be added and removed.
- CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>(
+ CompareResult<RouteInfo> routeDiff = new CompareResult<>(
oldLp != null ? oldLp.getAllRoutes() : null,
newLp != null ? newLp.getAllRoutes() : null);
@@ -5706,7 +5697,7 @@
}
}
for (RouteInfo route : routeDiff.added) {
- if (route.hasGateway() == false) continue;
+ if (!route.hasGateway()) continue;
if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
try {
mNMS.addRoute(netId, route);
@@ -5935,8 +5926,8 @@
* 3. the VPN is fully-routed
* 4. the VPN interface is non-null
*
- * @See INetd#firewallAddUidInterfaceRules
- * @See INetd#firewallRemoveUidInterfaceRules
+ * @see INetd#firewallAddUidInterfaceRules
+ * @see INetd#firewallRemoveUidInterfaceRules
*/
private boolean requiresVpnIsolation(@NonNull NetworkAgentInfo nai, NetworkCapabilities nc,
LinkProperties lp) {
@@ -7051,9 +7042,9 @@
}
@Override
- public void onShellCommand(FileDescriptor in, FileDescriptor out,
- FileDescriptor err, String[] args, ShellCallback callback,
- ResultReceiver resultReceiver) {
+ public void onShellCommand(@NonNull FileDescriptor in, @NonNull FileDescriptor out,
+ FileDescriptor err, @NonNull String[] args, ShellCallback callback,
+ @NonNull ResultReceiver resultReceiver) {
(new ShellCmd()).exec(this, in, out, err, args, callback, resultReceiver);
}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 2fcb7fa..35a06a9 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -2499,13 +2499,6 @@
mContext.enforceCallingPermission(android.Manifest.permission.ACCESS_FINE_LOCATION,
"Access Fine Location permission not granted to inject Location");
- if (location == null) {
- if (D) {
- Log.d(TAG, "injectLocation(): called with null location");
- }
- return false;
- }
-
synchronized (mLock) {
LocationProvider provider = getLocationProviderLocked(location.getProvider());
if (provider == null || !provider.isUseableLocked()) {
@@ -2708,9 +2701,6 @@
@Override
public ProviderProperties getProviderProperties(String providerName) {
synchronized (mLock) {
- checkResolutionLevelIsSufficientForProviderUseLocked(getCallerAllowedResolutionLevel(),
- providerName);
-
LocationProvider provider = getLocationProviderLocked(providerName);
if (provider == null) {
return null;
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index fa1653d..793e342 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -88,7 +88,7 @@
}
};
- if (mWipeExternalStorage || mWipeEsims) {
+ if (mWipeExternalStorage) {
// thr will be started at the end of this task.
new WipeDataTask(context, thr).execute();
} else {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 67686e0..3916f0d 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -208,6 +208,12 @@
*/
private static final String ISOLATED_STORAGE_ENABLED = "isolated_storage_enabled";
+ /**
+ * If {@code 1}, enables FuseDaemon to intercept file system ops. If {@code -1},
+ * disables FuseDaemon. If {@code 0}, uses the default value from the build system.
+ */
+ private static final String FUSE_ENABLED = "fuse_enabled";
+
public static class Lifecycle extends SystemService {
private StorageManagerService mStorageManagerService;
@@ -817,8 +823,10 @@
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
mContext.getMainExecutor(), (properties) -> {
refreshIsolatedStorageSettings();
+ refreshFuseSettings();
});
refreshIsolatedStorageSettings();
+ refreshFuseSettings();
}
/**
@@ -882,6 +890,18 @@
SystemProperties.set(StorageManager.PROP_ISOLATED_STORAGE, Boolean.toString(res));
}
+ private void refreshFuseSettings() {
+ int isFuseEnabled = DeviceConfig.getInt(DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
+ FUSE_ENABLED, 0);
+ if (isFuseEnabled == 1) {
+ SystemProperties.set(StorageManager.PROP_FUSE, "true");
+ } else if (isFuseEnabled == -1) {
+ SystemProperties.set(StorageManager.PROP_FUSE, "false");
+ }
+ // else, keep the build config.
+ // This can be overridden be direct adjustment of persist.sys.prop
+ }
+
/**
* MediaProvider has a ton of code that makes assumptions about storage
* paths never changing, so we outright kill them to pick up new state.
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index ecbbef1..0f8a3b5 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -33,6 +33,9 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.telephony.Annotation.DataFailureCause;
+import android.telephony.Annotation.RadioPowerState;
+import android.telephony.Annotation.SrvccState;
import android.telephony.CallAttributes;
import android.telephony.CallQuality;
import android.telephony.CellInfo;
@@ -245,7 +248,7 @@
private int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- @TelephonyManager.RadioPowerState
+ @RadioPowerState
private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE;
private final LocalLog mLocalLog = new LocalLog(100);
@@ -271,8 +274,8 @@
PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE;
static final int READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK =
- PhoneStateListener.LISTEN_OUTGOING_CALL_EMERGENCY_NUMBER
- | PhoneStateListener.LISTEN_OUTGOING_SMS_EMERGENCY_NUMBER;
+ PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL
+ | PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS;
private static final int MSG_USER_SWITCHED = 1;
private static final int MSG_UPDATE_DEFAULT_SUB = 2;
@@ -382,7 +385,7 @@
mContext = context;
mBatteryStats = BatteryStatsService.getService();
- int numPhones = TelephonyManager.getDefault().getPhoneCount();
+ int numPhones = TelephonyManager.getDefault().getMaxPhoneCount();
if (DBG) log("TelephonyRegistry: ctor numPhones=" + numPhones);
mNumPhones = numPhones;
mCallState = new int[numPhones];
@@ -1718,7 +1721,7 @@
}
public void notifyPreciseDataConnectionFailed(int phoneId, int subId, String apnType,
- String apn, @DataFailCause.FailCause int failCause) {
+ String apn, @DataFailureCause int failCause) {
if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) {
return;
}
@@ -1748,7 +1751,7 @@
}
@Override
- public void notifySrvccStateChanged(int subId, @TelephonyManager.SrvccState int state) {
+ public void notifySrvccStateChanged(int subId, @SrvccState int state) {
if (!checkNotifyPermission("notifySrvccStateChanged()")) {
return;
}
@@ -1855,8 +1858,7 @@
}
}
- public void notifyRadioPowerStateChanged(int phoneId, int subId,
- @TelephonyManager.RadioPowerState int state) {
+ public void notifyRadioPowerStateChanged(int phoneId, int subId, @RadioPowerState int state) {
if (!checkNotifyPermission("notifyRadioPowerStateChanged()")) {
return;
}
@@ -1930,7 +1932,7 @@
mOutgoingCallEmergencyNumber[phoneId] = emergencyNumber;
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_OUTGOING_CALL_EMERGENCY_NUMBER)
+ PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL)
&& idMatch(r.subId, subId, phoneId)) {
try {
r.callback.onOutgoingEmergencyCall(emergencyNumber);
@@ -1955,7 +1957,7 @@
mOutgoingSmsEmergencyNumber[phoneId] = emergencyNumber;
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_OUTGOING_SMS_EMERGENCY_NUMBER)
+ PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS)
&& idMatch(r.subId, subId, phoneId)) {
try {
r.callback.onOutgoingEmergencySms(emergencyNumber);
@@ -2227,7 +2229,7 @@
private void broadcastPreciseDataConnectionStateChanged(int state, int networkType,
String apnType, String apn, LinkProperties linkProperties,
- @DataFailCause.FailCause int failCause) {
+ @DataFailureCause int failCause) {
Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
intent.putExtra(PhoneConstants.STATE_KEY, state);
intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType);
diff --git a/services/core/java/com/android/server/UiThread.java b/services/core/java/com/android/server/UiThread.java
index b2fa684..34fc9ab 100644
--- a/services/core/java/com/android/server/UiThread.java
+++ b/services/core/java/com/android/server/UiThread.java
@@ -21,6 +21,8 @@
import android.os.Process;
import android.os.Trace;
+import com.android.internal.annotations.VisibleForTesting;
+
/**
* Shared singleton thread for showing UI. This is a foreground thread, and in
* additional should not have operations that can take more than a few ms scheduled
@@ -68,4 +70,20 @@
return sHandler;
}
}
+
+ /**
+ * Disposes current ui thread if it's initialized. Should only be used in tests to set up a
+ * new environment.
+ */
+ @VisibleForTesting
+ public static void dispose() {
+ synchronized (UiThread.class) {
+ if (sInstance == null) {
+ return;
+ }
+
+ getHandler().runWithScissors(sInstance::quit, 0 /* timeout */);
+ sInstance = null;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 9936d73..d622fb4 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -29,6 +29,7 @@
import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.hardware.vibrator.V1_0.EffectStrength;
+import android.hardware.vibrator.V1_4.Capabilities;
import android.icu.text.DateFormat;
import android.media.AudioAttributes;
import android.media.AudioManager;
@@ -108,6 +109,9 @@
// If a vibration is playing for longer than 5s, it's probably not haptic feedback.
private static final long MAX_HAPTIC_FEEDBACK_DURATION = 5000;
+ // If HAL supports callbacks set the timeout to ASYNC_TIMEOUT_MULTIPLIER * duration.
+ private static final long ASYNC_TIMEOUT_MULTIPLIER = 2;
+
// A mapping from the intensity adjustment to the scaling to apply, where the intensity
// adjustment is defined as the delta between the default intensity level and the user selected
@@ -123,6 +127,7 @@
private final boolean mAllowPriorityVibrationsInLowPowerMode;
private final boolean mSupportsAmplitudeControl;
private final boolean mSupportsExternalControl;
+ private final long mCapabilities;
private final int mDefaultVibrationAmplitude;
private final SparseArray<VibrationEffect> mFallbackEffects;
private final SparseArray<Integer> mProcStatesCache = new SparseArray();
@@ -163,9 +168,10 @@
static native void vibratorOff();
static native boolean vibratorSupportsAmplitudeControl();
static native void vibratorSetAmplitude(int amplitude);
- static native long vibratorPerformEffect(long effect, long strength);
+ static native long vibratorPerformEffect(long effect, long strength, Vibration vibration);
static native boolean vibratorSupportsExternalControl();
static native void vibratorSetExternalControl(boolean enabled);
+ static native long vibratorGetCapabilities();
private final IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
@@ -226,6 +232,14 @@
}
}
+ private void onComplete() {
+ synchronized (mLock) {
+ if (this == mCurrentVibration) {
+ doCancelVibrateLocked();
+ }
+ }
+ }
+
public boolean hasTimeoutLongerThan(long millis) {
final long duration = effect.getDuration();
return duration >= 0 && duration > millis;
@@ -347,6 +361,7 @@
mSupportsAmplitudeControl = vibratorSupportsAmplitudeControl();
mSupportsExternalControl = vibratorSupportsExternalControl();
+ mCapabilities = vibratorGetCapabilities();
mContext = context;
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
@@ -1135,10 +1150,14 @@
}
// Input devices don't support prebaked effect, so skip trying it with them.
if (!usingInputDeviceVibrators) {
- long timeout = vibratorPerformEffect(prebaked.getId(),
- prebaked.getEffectStrength());
+ long duration = vibratorPerformEffect(prebaked.getId(),
+ prebaked.getEffectStrength(), vib);
+ long timeout = duration;
+ if ((mCapabilities & Capabilities.PERFORM_COMPLETION_CALLBACK) != 0) {
+ timeout *= ASYNC_TIMEOUT_MULTIPLIER;
+ }
if (timeout > 0) {
- noteVibratorOnLocked(vib.uid, timeout);
+ noteVibratorOnLocked(vib.uid, duration);
return timeout;
}
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 08f75e6..9209a21 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -192,34 +192,38 @@
@Override
public void stopForegroundServicesForUidPackage(final int uid, final String packageName) {
synchronized (mAm) {
- final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid));
- final int N = smap.mServicesByInstanceName.size();
- final ArrayList<ServiceRecord> toStop = new ArrayList<>(N);
- for (int i = 0; i < N; i++) {
- final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i);
- if (uid == r.serviceInfo.applicationInfo.uid
- || packageName.equals(r.serviceInfo.packageName)) {
- if (r.isForeground) {
- toStop.add(r);
- }
- }
- }
+ stopAllForegroundServicesLocked(uid, packageName);
+ }
+ }
+ }
- // Now stop them all
- final int numToStop = toStop.size();
- if (numToStop > 0 && DEBUG_FOREGROUND_SERVICE) {
- Slog.i(TAG, "Package " + packageName + "/" + uid
- + " entering FAS with foreground services");
- }
- for (int i = 0; i < numToStop; i++) {
- final ServiceRecord r = toStop.get(i);
- if (DEBUG_FOREGROUND_SERVICE) {
- Slog.i(TAG, " Stopping fg for service " + r);
- }
- setServiceForegroundInnerLocked(r, 0, null, 0, 0);
+ void stopAllForegroundServicesLocked(final int uid, final String packageName) {
+ final ServiceMap smap = getServiceMapLocked(UserHandle.getUserId(uid));
+ final int N = smap.mServicesByInstanceName.size();
+ final ArrayList<ServiceRecord> toStop = new ArrayList<>(N);
+ for (int i = 0; i < N; i++) {
+ final ServiceRecord r = smap.mServicesByInstanceName.valueAt(i);
+ if (uid == r.serviceInfo.applicationInfo.uid
+ || packageName.equals(r.serviceInfo.packageName)) {
+ if (r.isForeground) {
+ toStop.add(r);
}
}
}
+
+ // Now stop them all
+ final int numToStop = toStop.size();
+ if (numToStop > 0 && DEBUG_FOREGROUND_SERVICE) {
+ Slog.i(TAG, "Package " + packageName + "/" + uid
+ + " in FAS with foreground services");
+ }
+ for (int i = 0; i < numToStop; i++) {
+ final ServiceRecord r = toStop.get(i);
+ if (DEBUG_FOREGROUND_SERVICE) {
+ Slog.i(TAG, " Stopping fg for service " + r);
+ }
+ setServiceForegroundInnerLocked(r, 0, null, 0, 0);
+ }
}
/**
@@ -1019,12 +1023,23 @@
}
}
if (!aa.mAppOnTop) {
- if (active == null) {
- active = new ArrayList<>();
+ // Transitioning a fg-service host app out of top: if it's bg restricted,
+ // it loses the fg service state now.
+ if (!appRestrictedAnyInBackground(aa.mUid, aa.mPackageName)) {
+ if (active == null) {
+ active = new ArrayList<>();
+ }
+ if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Adding active: pkg="
+ + aa.mPackageName + ", uid=" + aa.mUid);
+ active.add(aa);
+ } else {
+ if (DEBUG_FOREGROUND_SERVICE) {
+ Slog.d(TAG, "bg-restricted app "
+ + aa.mPackageName + "/" + aa.mUid
+ + " exiting top; demoting fg services ");
+ }
+ stopAllForegroundServicesLocked(aa.mUid, aa.mPackageName);
}
- if (DEBUG_FOREGROUND_SERVICE) Slog.d(TAG, "Adding active: pkg="
- + aa.mPackageName + ", uid=" + aa.mUid);
- active.add(aa);
}
}
smap.removeMessages(ServiceMap.MSG_UPDATE_FOREGROUND_APPS);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b520900..7cbd1fc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2405,7 +2405,8 @@
final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */);
mProcessList.init(this, activeUids);
mLowMemDetector = null;
- mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids, handlerThread);
+ mOomAdjuster = hasHandlerThread
+ ? new OomAdjuster(this, mProcessList, activeUids, handlerThread) : null;
mIntentFirewall = hasHandlerThread
? new IntentFirewall(new IntentFirewallInterface(), mHandler) : null;
@@ -7440,6 +7441,7 @@
dst.setProcess(r);
dst.notifyAll();
}
+ dst.mRestartCount = 0;
updateOomAdjLocked(r, true, OomAdjuster.OOM_ADJ_REASON_GET_PROVIDER);
maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
src.info.authority);
@@ -9734,6 +9736,10 @@
sb.append("Foreground: ")
.append(process.isInterestingToUserLocked() ? "Yes" : "No")
.append("\n");
+ if (process.startTime > 0) {
+ long runtimeMillis = SystemClock.elapsedRealtime() - process.startTime;
+ sb.append("Process-Runtime: ").append(runtimeMillis).append("\n");
+ }
}
if (activityShortComponentName != null) {
sb.append("Activity: ").append(activityShortComponentName).append("\n");
@@ -13883,9 +13889,20 @@
return false;
}
+ /**
+ * Remove the dying provider from known provider map and launching provider map.
+ * @param proc The dying process recoder
+ * @param cpr The provider to be removed.
+ * @param always If true, remove the provider from launching map always, no more restart attempt
+ * @return true if the given provider is in launching
+ */
private final boolean removeDyingProviderLocked(ProcessRecord proc,
ContentProviderRecord cpr, boolean always) {
- final boolean inLaunching = mLaunchingProviders.contains(cpr);
+ boolean inLaunching = mLaunchingProviders.contains(cpr);
+ if (inLaunching && !always && ++cpr.mRestartCount > ContentProviderRecord.MAX_RETRY_COUNT) {
+ // It's being launched but we've reached maximum attempts, force the removal
+ always = true;
+ }
if (!inLaunching || always) {
synchronized (cpr) {
@@ -13937,6 +13954,8 @@
if (inLaunching && always) {
mLaunchingProviders.remove(cpr);
+ cpr.mRestartCount = 0;
+ inLaunching = false;
}
return inLaunching;
}
@@ -14152,6 +14171,10 @@
for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
ContentProviderRecord cpr = mLaunchingProviders.get(i);
if (cpr.launchingApp == app) {
+ if (++cpr.mRestartCount > ContentProviderRecord.MAX_RETRY_COUNT) {
+ // It's being launched but we've reached maximum attempts, mark it as bad
+ alwaysBad = true;
+ }
if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
restart = true;
} else {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 058afd3..8be2438 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2859,7 +2859,21 @@
return 0;
}
- private int runCompat(PrintWriter pw) {
+ private void killPackage(String packageName, PrintWriter pw) throws RemoteException {
+ int uid = mPm.getPackageUid(packageName, 0, mUserId);
+ if (uid < 0) {
+ // uid is negative if the package wasn't found.
+ pw.println("Didn't find package " + packageName + " on device.");
+ } else {
+ pw.println("Killing package " + packageName + " (UID " + uid + ").");
+ final long origId = Binder.clearCallingIdentity();
+ mInterface.killUid(UserHandle.getAppId(uid),
+ UserHandle.USER_ALL, "killPackage");
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ private int runCompat(PrintWriter pw) throws RemoteException {
final CompatConfig config = CompatConfig.get();
String toggleValue = getNextArgRequired();
long changeId;
@@ -2873,13 +2887,14 @@
pw.println("Unknown or invalid change: '" + changeIdString + "'.");
}
String packageName = getNextArgRequired();
- switch(toggleValue) {
+ switch (toggleValue) {
case "enable":
if (!config.addOverride(changeId, packageName, true)) {
pw.println("Warning! Change " + changeId + " is not known yet. Enabling it"
+ " could have no effect.");
}
pw.println("Enabled change " + changeId + " for " + packageName + ".");
+ killPackage(packageName, pw);
return 0;
case "disable":
if (!config.addOverride(changeId, packageName, false)) {
@@ -2887,11 +2902,13 @@
+ " could have no effect.");
}
pw.println("Disabled change " + changeId + " for " + packageName + ".");
+ killPackage(packageName, pw);
return 0;
case "reset":
if (config.removeOverride(changeId, packageName)) {
pw.println("Reset change " + changeId + " for " + packageName
+ " to default value.");
+ killPackage(packageName, pw);
} else {
pw.println("No override exists for changeId " + changeId + ".");
}
@@ -3210,6 +3227,7 @@
pw.println(" Write all pending state to storage.");
pw.println(" compat enable|disable|reset <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>");
pw.println(" Toggles a change either by id or by name for <PACKAGE_NAME>.");
+ pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect).");
pw.println();
Intent.printIntentArgsHelp(pw, "");
}
diff --git a/services/core/java/com/android/server/am/ContentProviderRecord.java b/services/core/java/com/android/server/am/ContentProviderRecord.java
index 46dfc7c..d8d8ccc 100644
--- a/services/core/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/core/java/com/android/server/am/ContentProviderRecord.java
@@ -38,6 +38,9 @@
import java.util.ArrayList;
final class ContentProviderRecord implements ComponentName.WithComponentName {
+ // Maximum attempts to bring up the content provider before giving up.
+ static final int MAX_RETRY_COUNT = 3;
+
final ActivityManagerService service;
public final ProviderInfo info;
final int uid;
@@ -54,6 +57,7 @@
ArrayMap<IBinder, ExternalProcessHandle> externalProcessTokenToHandle;
// Count for external process for which we have no handles.
int externalProcessNoHandleCount;
+ int mRestartCount; // number of times we tried before bringing up it successfully.
ProcessRecord proc; // if non-null, hosting process.
ProcessRecord launchingApp; // if non-null, waiting for this app to be launched.
String stringName;
diff --git a/services/core/java/com/android/server/am/TEST_MAPPING b/services/core/java/com/android/server/am/TEST_MAPPING
index 21d4925..bc4707f 100644
--- a/services/core/java/com/android/server/am/TEST_MAPPING
+++ b/services/core/java/com/android/server/am/TEST_MAPPING
@@ -33,7 +33,6 @@
},
{
"name": "FrameworksMockingServicesTests",
- "file_patterns": ["AppCompactor\\.java"],
"options": [
{
"include-filter": "com.android.server.am."
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 5c8e530..17541911 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -133,12 +133,12 @@
static final int CONTINUE_USER_SWITCH_MSG = 20;
static final int USER_SWITCH_TIMEOUT_MSG = 30;
static final int START_PROFILES_MSG = 40;
- static final int SYSTEM_USER_START_MSG = 50;
- static final int SYSTEM_USER_CURRENT_MSG = 60;
+ static final int USER_START_MSG = 50;
+ static final int USER_CURRENT_MSG = 60;
static final int FOREGROUND_PROFILE_CHANGED_MSG = 70;
static final int REPORT_USER_SWITCH_COMPLETE_MSG = 80;
static final int USER_SWITCH_CALLBACKS_TIMEOUT_MSG = 90;
- static final int SYSTEM_USER_UNLOCK_MSG = 100;
+ static final int USER_UNLOCK_MSG = 100;
static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 110;
static final int START_USER_SWITCH_FG_MSG = 120;
@@ -368,16 +368,18 @@
}
}
- mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
- userId, 0));
- Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
- intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
- new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
- AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
- Binder.getCallingUid(), Binder.getCallingPid(), userId);
+ if (!mInjector.getUserManager().isPreCreated(userId)) {
+ mHandler.sendMessage(mHandler.obtainMessage(REPORT_LOCKED_BOOT_COMPLETE_MSG,
+ userId, 0));
+ Intent intent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED, null);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ mInjector.broadcastIntent(intent, null, resultTo, 0, null, null,
+ new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
+ AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
+ Binder.getCallingUid(), Binder.getCallingPid(), userId);
+ }
}
// We need to delay unlocking managed profiles until the parent user
@@ -438,8 +440,7 @@
// Dispatch unlocked to system services; when fully dispatched,
// that calls through to the next "unlocked" phase
- mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
- .sendToTarget();
+ mHandler.obtainMessage(USER_UNLOCK_MSG, userId, 0, uss).sendToTarget();
});
return true;
}
@@ -555,6 +556,17 @@
}
}
+ if (userInfo.preCreated) {
+ Slog.i(TAG, "Stopping pre-created user " + userInfo.toFullString());
+ // Pre-created user was started right after creation so services could properly
+ // intialize it; it should be stopped right away as it's not really a "real" user.
+ // TODO(b/140750212): in the long-term, we should add a onCreateUser() callback
+ // on SystemService instead.
+ stopUser(userInfo.id, /* force= */ true, /* stopUserCallback= */ null,
+ /* keyEvictedCallback= */ null);
+ return;
+ }
+
// Spin up app widgets prior to boot-complete, so they can be ready promptly
mInjector.startUserWidgets(userId);
@@ -799,7 +811,8 @@
mInjector.systemServiceManagerCleanupUser(userId);
mInjector.stackSupervisorRemoveUser(userId);
// Remove the user if it is ephemeral.
- if (getUserInfo(userId).isEphemeral()) {
+ UserInfo userInfo = getUserInfo(userId);
+ if (userInfo.isEphemeral() && !userInfo.preCreated) {
mInjector.getUserManager().removeUserEvenWhenDisallowed(userId);
}
@@ -1069,6 +1082,11 @@
return false;
}
+ if (foreground && userInfo.preCreated) {
+ Slog.w(TAG, "Cannot start pre-created user #" + userId + " as foreground");
+ return false;
+ }
+
if (foreground && mUserSwitchUiEnabled) {
t.traceBegin("startFreezingScreen");
mInjector.getWindowManager().startFreezingScreen(
@@ -1166,7 +1184,7 @@
updateStartedUserArrayLU();
}
needStart = true;
- t.traceBegin("updateStateStopping");
+ t.traceEnd();
}
if (uss.state == UserState.STATE_BOOTING) {
@@ -1178,15 +1196,13 @@
// Booting up a new user, need to tell system services about it.
// Note that this is on the same handler as scheduling of broadcasts,
// which is important because it needs to go first.
- mHandler.sendMessage(
- mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
+ mHandler.sendMessage(mHandler.obtainMessage(USER_START_MSG, userId, 0));
t.traceEnd();
}
t.traceBegin("sendMessages");
if (foreground) {
- mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
- oldUserId));
+ mHandler.sendMessage(mHandler.obtainMessage(USER_CURRENT_MSG, userId, oldUserId));
mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
@@ -1195,6 +1211,10 @@
oldUserId, userId, uss), USER_SWITCH_TIMEOUT_MS);
}
+ if (userInfo.preCreated) {
+ needStart = false;
+ }
+
if (needStart) {
// Send USER_STARTED broadcast
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
@@ -2168,14 +2188,14 @@
case START_PROFILES_MSG:
startProfiles();
break;
- case SYSTEM_USER_START_MSG:
+ case USER_START_MSG:
mInjector.batteryStatsServiceNoteEvent(
BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
Integer.toString(msg.arg1), msg.arg1);
mInjector.getSystemServiceManager().startUser(TimingsTraceAndSlog.newAsyncLog(),
msg.arg1);
break;
- case SYSTEM_USER_UNLOCK_MSG:
+ case USER_UNLOCK_MSG:
final int userId = msg.arg1;
mInjector.getSystemServiceManager().unlockUser(userId);
// Loads recents on a worker thread that allows disk I/O
@@ -2184,7 +2204,7 @@
});
finishUserUnlocked((UserState) msg.obj);
break;
- case SYSTEM_USER_CURRENT_MSG:
+ case USER_CURRENT_MSG:
mInjector.batteryStatsServiceNoteEvent(
BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
Integer.toString(msg.arg2), msg.arg2);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index ccbe08f..a6ac17d 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -59,6 +59,7 @@
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPlaybackClient;
import android.hardware.hdmi.HdmiTvClient;
+import android.hardware.input.InputManager;
import android.hardware.usb.UsbManager;
import android.media.AudioAttributes;
import android.media.AudioFocusInfo;
@@ -545,6 +546,10 @@
private String mEnabledSurroundFormats;
private boolean mSurroundModeChanged;
+ private boolean mMicMuteFromSwitch;
+ private boolean mMicMuteFromApi;
+ private boolean mMicMuteFromRestrictions;
+
@GuardedBy("mSettingsLock")
private int mAssistantUid;
@@ -882,6 +887,8 @@
mRoleObserver.register();
onIndicateSystemReady();
+
+ setMicMuteFromSwitchInput();
}
RoleObserver mRoleObserver;
@@ -1021,6 +1028,8 @@
sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
SENDMSG_QUEUE, 1, 0, null, 0);
+
+ setMicMuteFromSwitchInput();
}
private void onDispatchAudioServerStateChange(boolean state) {
@@ -1557,12 +1566,13 @@
AudioSystem.setMasterMute(masterMute);
broadcastMasterMuteStatus(masterMute);
- boolean microphoneMute = mUserManagerInternal.getUserRestriction(
+ mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction(
currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
if (DEBUG_VOL) {
- Log.d(TAG, String.format("Mic mute %s, user=%d", microphoneMute, currentUser));
+ Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions,
+ currentUser));
}
- AudioSystem.muteMicrophone(microphoneMute);
+ setMicrophoneMuteNoCallerCheck(currentUser);
}
private int rescaleIndex(int index, int srcStream, int dstStream) {
@@ -2837,20 +2847,45 @@
!= PackageManager.PERMISSION_GRANTED) {
return;
}
- setMicrophoneMuteNoCallerCheck(on, userId);
+ mMicMuteFromApi = on;
+ setMicrophoneMuteNoCallerCheck(userId);
}
- private void setMicrophoneMuteNoCallerCheck(boolean on, int userId) {
+ /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */
+ public void setMicrophoneMuteFromSwitch(boolean on) {
+ int userId = Binder.getCallingUid();
+ if (userId != android.os.Process.SYSTEM_UID) {
+ Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!");
+ return;
+ }
+ mMicMuteFromSwitch = on;
+ setMicrophoneMuteNoCallerCheck(userId);
+ }
+
+ private void setMicMuteFromSwitchInput() {
+ InputManager im = mContext.getSystemService(InputManager.class);
+ final int isMicMuted = im.isMicMuted();
+ if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) {
+ setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF);
+ }
+ }
+
+ public boolean isMicrophoneMuted() {
+ return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi;
+ }
+
+ private void setMicrophoneMuteNoCallerCheck(int userId) {
+ final boolean muted = isMicrophoneMuted();
if (DEBUG_VOL) {
- Log.d(TAG, String.format("Mic mute %s, user=%d", on, userId));
+ Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId));
}
// only mute for the current user
- if (getCurrentUserId() == userId) {
+ if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) {
final boolean currentMute = AudioSystem.isMicrophoneMuted();
final long identity = Binder.clearCallingIdentity();
- AudioSystem.muteMicrophone(on);
+ AudioSystem.muteMicrophone(muted);
Binder.restoreCallingIdentity(identity);
- if (on != currentMute) {
+ if (muted != currentMute) {
mContext.sendBroadcastAsUser(
new Intent(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED)
.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL);
@@ -5390,7 +5425,8 @@
final boolean isRestricted =
newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
if (wasRestricted != isRestricted) {
- setMicrophoneMuteNoCallerCheck(isRestricted, userId);
+ mMicMuteFromRestrictions = isRestricted;
+ setMicrophoneMuteNoCallerCheck(userId);
}
}
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 7302b98..4f1db3c 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -25,21 +25,18 @@
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE;
import android.app.ActivityManager;
-import android.app.AppOpsManager;
import android.app.IActivityManager;
-import android.app.KeyguardManager;
import android.app.UserSwitchObserver;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
+import android.hardware.biometrics.Authenticator;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.biometrics.BiometricsProtoEnums;
-import android.hardware.biometrics.IBiometricConfirmDeviceCredentialCallback;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceReceiver;
@@ -96,11 +93,8 @@
private static final int MSG_ON_READY_FOR_AUTHENTICATION = 8;
private static final int MSG_AUTHENTICATE = 9;
private static final int MSG_CANCEL_AUTHENTICATION = 10;
- private static final int MSG_ON_CONFIRM_DEVICE_CREDENTIAL_SUCCESS = 11;
- private static final int MSG_ON_CONFIRM_DEVICE_CREDENTIAL_ERROR = 12;
- private static final int MSG_REGISTER_CANCELLATION_CALLBACK = 13;
- private static final int MSG_ON_AUTHENTICATION_TIMED_OUT = 14;
-
+ private static final int MSG_ON_AUTHENTICATION_TIMED_OUT = 11;
+ private static final int MSG_ON_DEVICE_CREDENTIAL_PRESSED = 12;
private static final int[] FEATURE_ID = {
TYPE_FINGERPRINT,
TYPE_IRIS,
@@ -133,19 +127,19 @@
*/
static final int STATE_AUTH_PENDING_CONFIRM = 5;
/**
- * Biometric authentication was canceled, but the device is now showing ConfirmDeviceCredential
- */
- static final int STATE_BIOMETRIC_AUTH_CANCELED_SHOWING_CDC = 6;
- /**
* Biometric authenticated, waiting for SysUI to finish animation
*/
- static final int STATE_AUTHENTICATED_PENDING_SYSUI = 7;
+ static final int STATE_AUTHENTICATED_PENDING_SYSUI = 6;
/**
* Biometric error, waiting for SysUI to finish animation
*/
- static final int STATE_ERROR_PENDING_SYSUI = 8;
+ static final int STATE_ERROR_PENDING_SYSUI = 7;
+ /**
+ * Device credential in AuthController is showing
+ */
+ static final int STATE_SHOWING_DEVICE_CREDENTIAL = 8;
- final class AuthSession implements IBinder.DeathRecipient {
+ final class AuthSession {
// Map of Authenticator/Cookie pairs. We expect to receive the cookies back from
// <Biometric>Services before we can start authenticating. Pairs that have been returned
// are moved to mModalitiesMatched.
@@ -185,14 +179,10 @@
// Timestamp when hardware authentication occurred
private long mAuthenticatedTimeMs;
- // TODO(b/123378871): Remove when moved.
- private IBiometricConfirmDeviceCredentialCallback mConfirmDeviceCredentialCallback;
-
AuthSession(HashMap<Integer, Integer> modalities, IBinder token, long sessionId,
int userId, IBiometricServiceReceiver receiver, String opPackageName,
Bundle bundle, int callingUid, int callingPid, int callingUserId,
- int modality, boolean requireConfirmation,
- IBiometricConfirmDeviceCredentialCallback callback) {
+ int modality, boolean requireConfirmation) {
mModalitiesWaiting = modalities;
mToken = token;
mSessionId = sessionId;
@@ -205,25 +195,12 @@
mCallingUserId = callingUserId;
mModality = modality;
mRequireConfirmation = requireConfirmation;
- mConfirmDeviceCredentialCallback = callback;
-
- if (isFromConfirmDeviceCredential()) {
- try {
- token.linkToDeath(this, 0 /* flags */);
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to link to death", e);
- }
- }
}
boolean isCrypto() {
return mSessionId != 0;
}
- boolean isFromConfirmDeviceCredential() {
- return mBundle.getBoolean(BiometricPrompt.KEY_FROM_CONFIRM_DEVICE_CREDENTIAL, false);
- }
-
boolean containsCookie(int cookie) {
if (mModalitiesWaiting != null && mModalitiesWaiting.containsValue(cookie)) {
return true;
@@ -234,35 +211,19 @@
return false;
}
- // TODO(b/123378871): Remove when moved.
- @Override
- public void binderDied() {
- mHandler.post(() -> {
- Slog.e(TAG, "Binder died, killing ConfirmDeviceCredential");
- if (mConfirmDeviceCredentialCallback == null) {
- Slog.e(TAG, "Callback is null");
- return;
- }
-
- try {
- mConfirmDeviceCredentialCallback.cancel();
- mConfirmDeviceCredentialCallback = null;
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to send cancel", e);
- }
- });
+ boolean isAllowDeviceCredential() {
+ return Utils.isDeviceCredentialAllowed(mBundle);
}
}
private final Injector mInjector;
@VisibleForTesting
final IBiometricService.Stub mImpl;
- private final AppOpsManager mAppOps;
private final boolean mHasFeatureFingerprint;
private final boolean mHasFeatureIris;
private final boolean mHasFeatureFace;
@VisibleForTesting
- SettingObserver mSettingObserver;
+ final SettingObserver mSettingObserver;
private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks;
private final Random mRandom = new Random();
@@ -277,7 +238,7 @@
// Get and cache the available authenticator (manager) classes. Used since aidl doesn't support
// polymorphism :/
- final ArrayList<Authenticator> mAuthenticators = new ArrayList<>();
+ final ArrayList<AuthenticatorWrapper> mAuthenticators = new ArrayList<>();
// The current authentication session, null if idle/done. We need to track both the current
// and pending sessions since errors may be sent to either.
@@ -286,14 +247,6 @@
@VisibleForTesting
AuthSession mPendingAuthSession;
- // TODO(b/123378871): Remove when moved.
- // When BiometricPrompt#setAllowDeviceCredentials is set to true, we need to store the
- // client (app) receiver. BiometricService internally launches CDCA which invokes
- // BiometricService to start authentication (normal path). When auth is success/rejected,
- // CDCA will use an aidl method to poke BiometricService - the result will then be forwarded
- // to this receiver.
- private IBiometricServiceReceiver mConfirmDeviceCredentialReceiver;
-
@VisibleForTesting
final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
@@ -363,8 +316,7 @@
(Bundle) args.arg5 /* bundle */,
args.argi2 /* callingUid */,
args.argi3 /* callingPid */,
- args.argi4 /* callingUserId */,
- (IBiometricConfirmDeviceCredentialCallback) args.arg6 /* callback */);
+ args.argi4 /* callingUserId */);
args.recycle();
break;
}
@@ -378,31 +330,16 @@
break;
}
- case MSG_ON_CONFIRM_DEVICE_CREDENTIAL_SUCCESS: {
- handleOnConfirmDeviceCredentialSuccess();
- break;
- }
-
- case MSG_ON_CONFIRM_DEVICE_CREDENTIAL_ERROR: {
- SomeArgs args = (SomeArgs) msg.obj;
- handleOnConfirmDeviceCredentialError(
- args.argi1 /* error */,
- (String) args.arg1 /* errorMsg */);
- args.recycle();
- break;
- }
-
- case MSG_REGISTER_CANCELLATION_CALLBACK: {
- handleRegisterCancellationCallback(
- (IBiometricConfirmDeviceCredentialCallback) msg.obj /* callback */);
- break;
- }
-
case MSG_ON_AUTHENTICATION_TIMED_OUT: {
handleAuthenticationTimedOut((String) msg.obj /* errorMessage */);
break;
}
+ case MSG_ON_DEVICE_CREDENTIAL_PRESSED: {
+ handleOnDeviceCredentialPressed();
+ break;
+ }
+
default:
Slog.e(TAG, "Unknown message: " + msg);
break;
@@ -410,11 +347,11 @@
}
};
- private final class Authenticator {
- int mType;
- BiometricAuthenticator mAuthenticator;
+ private final class AuthenticatorWrapper {
+ final int mType;
+ final BiometricAuthenticator mAuthenticator;
- Authenticator(int type, BiometricAuthenticator authenticator) {
+ AuthenticatorWrapper(int type, BiometricAuthenticator authenticator) {
mType = type;
mAuthenticator = authenticator;
}
@@ -445,9 +382,9 @@
private final ContentResolver mContentResolver;
private final List<BiometricService.EnabledOnKeyguardCallback> mCallbacks;
- private Map<Integer, Boolean> mFaceEnabledOnKeyguard = new HashMap<>();
- private Map<Integer, Boolean> mFaceEnabledForApps = new HashMap<>();
- private Map<Integer, Boolean> mFaceAlwaysRequireConfirmation = new HashMap<>();
+ private final Map<Integer, Boolean> mFaceEnabledOnKeyguard = new HashMap<>();
+ private final Map<Integer, Boolean> mFaceEnabledForApps = new HashMap<>();
+ private final Map<Integer, Boolean> mFaceAlwaysRequireConfirmation = new HashMap<>();
/**
* Creates a content observer.
@@ -622,6 +559,11 @@
public void onTryAgainPressed() {
mHandler.sendEmptyMessage(MSG_ON_TRY_AGAIN_PRESSED);
}
+
+ @Override
+ public void onDeviceCredentialPressed() {
+ mHandler.sendEmptyMessage(MSG_ON_DEVICE_CREDENTIAL_PRESSED);
+ }
};
@@ -644,18 +586,12 @@
@Override // Binder call
public void authenticate(IBinder token, long sessionId, int userId,
- IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle,
- IBiometricConfirmDeviceCredentialCallback callback)
+ IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle)
throws RemoteException {
final int callingUid = Binder.getCallingUid();
final int callingPid = Binder.getCallingPid();
final int callingUserId = UserHandle.getCallingUserId();
- // TODO(b/123378871): Remove when moved.
- if (callback != null) {
- checkInternalPermission();
- }
-
// In the BiometricServiceBase, check do the AppOps and foreground check.
if (userId == callingUserId) {
// Check the USE_BIOMETRIC permission here.
@@ -672,12 +608,12 @@
return;
}
- final boolean isFromConfirmDeviceCredential =
- bundle.getBoolean(BiometricPrompt.KEY_FROM_CONFIRM_DEVICE_CREDENTIAL, false);
- if (isFromConfirmDeviceCredential) {
+ if (bundle.get(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED) != null) {
checkInternalPermission();
}
+ Utils.combineAuthenticatorBundles(bundle);
+
// Check the usage of this in system server. Need to remove this check if it becomes
// a public API.
final boolean useDefaultTitle =
@@ -691,39 +627,6 @@
}
}
- // Launch CDC instead if necessary. CDC will return results through an AIDL call, since
- // we can't get activity results. Store the receiver somewhere so we can forward the
- // result back to the client.
- // TODO(b/123378871): Remove when moved.
- if (bundle.getBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL)) {
- mHandler.post(() -> {
- final KeyguardManager kgm = getContext().getSystemService(
- KeyguardManager.class);
- if (!kgm.isDeviceSecure()) {
- try {
- receiver.onError(
- BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL,
- getContext().getString(
- R.string.biometric_error_device_not_secured));
- } catch (RemoteException e) {
- Slog.e(TAG, "Remote exception", e);
- }
- return;
- }
- mConfirmDeviceCredentialReceiver = receiver;
- // Use this so we don't need to duplicate logic..
- final Intent intent = kgm.createConfirmDeviceCredentialIntent(null /* title */,
- null /* description */, userId);
- // Then give it the bundle to do magic behavior..
- intent.putExtra(KeyguardManager.EXTRA_BIOMETRIC_PROMPT_BUNDLE, bundle);
- // Create a new task with this activity located at the root.
- intent.setFlags(
- Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
- getContext().startActivityAsUser(intent, UserHandle.CURRENT);
- });
- return;
- }
-
SomeArgs args = SomeArgs.obtain();
args.arg1 = token;
args.arg2 = sessionId;
@@ -734,41 +637,11 @@
args.argi2 = callingUid;
args.argi3 = callingPid;
args.argi4 = callingUserId;
- args.arg6 = callback;
mHandler.obtainMessage(MSG_AUTHENTICATE, args).sendToTarget();
}
@Override // Binder call
- public void onConfirmDeviceCredentialSuccess() {
- checkInternalPermission();
-
- mHandler.sendEmptyMessage(MSG_ON_CONFIRM_DEVICE_CREDENTIAL_SUCCESS);
- }
-
- @Override // Binder call
- public void onConfirmDeviceCredentialError(int error, String message) {
- checkInternalPermission();
-
- SomeArgs args = SomeArgs.obtain();
- args.argi1 = error;
- args.arg1 = message;
- mHandler.obtainMessage(MSG_ON_CONFIRM_DEVICE_CREDENTIAL_ERROR, args).sendToTarget();
- }
-
- @Override // Binder call
- public void registerCancellationCallback(
- IBiometricConfirmDeviceCredentialCallback callback) {
- // TODO(b/123378871): Remove when moved.
- // This callback replaces the one stored in the current session. If the session is null
- // we can ignore this, since it means ConfirmDeviceCredential was launched by something
- // else (not BiometricPrompt)
- checkInternalPermission();
-
- mHandler.obtainMessage(MSG_REGISTER_CANCELLATION_CALLBACK, callback).sendToTarget();
- }
-
- @Override // Binder call
public void cancelAuthentication(IBinder token, String opPackageName)
throws RemoteException {
checkPermission();
@@ -864,14 +737,6 @@
}
}
- private void checkAppOp(String opPackageName, int callingUid) {
- if (mAppOps.noteOp(AppOpsManager.OP_USE_BIOMETRIC, callingUid,
- opPackageName) != AppOpsManager.MODE_ALLOWED) {
- Slog.w(TAG, "Rejecting " + opPackageName + "; permission denied");
- throw new SecurityException("Permission denied");
- }
- }
-
private void checkInternalPermission() {
getContext().enforceCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL,
"Must have USE_BIOMETRIC_INTERNAL permission");
@@ -942,7 +807,6 @@
mInjector = injector;
mImpl = new BiometricServiceWrapper();
- mAppOps = context.getSystemService(AppOpsManager.class);
mEnabledOnKeyguardCallbacks = new ArrayList<>();
mSettingObserver = mInjector.getSettingObserver(context, mHandler,
mEnabledOnKeyguardCallbacks);
@@ -983,8 +847,8 @@
// Cache the authenticators
for (int featureId : FEATURE_ID) {
if (hasFeature(featureId)) {
- Authenticator authenticator =
- new Authenticator(featureId, getAuthenticator(featureId));
+ AuthenticatorWrapper authenticator =
+ new AuthenticatorWrapper(featureId, getAuthenticator(featureId));
mAuthenticators.add(authenticator);
}
}
@@ -1022,7 +886,7 @@
int modality = TYPE_NONE;
int firstHwAvailable = TYPE_NONE;
- for (Authenticator authenticatorWrapper : mAuthenticators) {
+ for (AuthenticatorWrapper authenticatorWrapper : mAuthenticators) {
modality = authenticatorWrapper.getType();
BiometricAuthenticator authenticator = authenticatorWrapper.getAuthenticator();
if (authenticator.isHardwareDetected()) {
@@ -1119,7 +983,7 @@
}
private void logDialogDismissed(int reason) {
- if (reason == BiometricPrompt.DISMISSED_REASON_CONFIRMED) {
+ if (reason == BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED) {
// Explicit auth, authentication confirmed.
// Latency in this case is authenticated -> confirmed. <Biometric>Service
// should have the first half (first acquired -> authenticated).
@@ -1265,49 +1129,6 @@
}
}
- private void handleOnConfirmDeviceCredentialSuccess() {
- if (mConfirmDeviceCredentialReceiver == null) {
- Slog.w(TAG, "handleOnConfirmDeviceCredentialSuccess null!");
- return;
- }
- try {
- mConfirmDeviceCredentialReceiver.onAuthenticationSucceeded();
- if (mCurrentAuthSession != null) {
- mCurrentAuthSession = null;
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException", e);
- }
- mConfirmDeviceCredentialReceiver = null;
- }
-
- private void handleOnConfirmDeviceCredentialError(int error, String message) {
- if (mConfirmDeviceCredentialReceiver == null) {
- Slog.w(TAG, "handleOnConfirmDeviceCredentialError null! Error: "
- + error + " " + message);
- return;
- }
- try {
- mConfirmDeviceCredentialReceiver.onError(error, message);
- if (mCurrentAuthSession != null) {
- mCurrentAuthSession = null;
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException", e);
- }
- mConfirmDeviceCredentialReceiver = null;
- }
-
- private void handleRegisterCancellationCallback(
- IBiometricConfirmDeviceCredentialCallback callback) {
- if (mCurrentAuthSession == null) {
- Slog.d(TAG, "Current auth session null");
- return;
- }
- Slog.d(TAG, "Updating cancel callback");
- mCurrentAuthSession.mConfirmDeviceCredentialCallback = callback;
- }
-
private void handleOnError(int cookie, int error, String message) {
Slog.d(TAG, "handleOnError: " + error + " cookie: " + cookie);
// Errors can either be from the current auth session or the pending auth session.
@@ -1318,34 +1139,34 @@
// of their intended receivers.
try {
if (mCurrentAuthSession != null && mCurrentAuthSession.containsCookie(cookie)) {
-
mCurrentAuthSession.mErrorEscrow = error;
mCurrentAuthSession.mErrorStringEscrow = message;
- if (mCurrentAuthSession.isFromConfirmDeviceCredential()) {
- // If we were invoked by ConfirmDeviceCredential, do not delete the current
- // auth session since we still need to respond to cancel signal while
- if (DEBUG) Slog.d(TAG, "From CDC, transition to CANCELED_SHOWING_CDC state");
-
- // Send the error to ConfirmDeviceCredential so that it goes to Pin/Pattern/Pass
- // screen
- mCurrentAuthSession.mClientReceiver.onError(error, message);
- mCurrentAuthSession.mState = STATE_BIOMETRIC_AUTH_CANCELED_SHOWING_CDC;
- mStatusBarService.hideBiometricDialog();
- } else if (mCurrentAuthSession.mState == STATE_AUTH_STARTED) {
- mCurrentAuthSession.mState = STATE_ERROR_PENDING_SYSUI;
- if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) {
- mStatusBarService.hideBiometricDialog();
+ if (mCurrentAuthSession.mState == STATE_AUTH_STARTED) {
+ final boolean errorLockout = error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT
+ || error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
+ if (mCurrentAuthSession.isAllowDeviceCredential() && errorLockout) {
+ // SystemUI handles transition from biometric to device credential.
+ mCurrentAuthSession.mState = STATE_SHOWING_DEVICE_CREDENTIAL;
+ mStatusBarService.onBiometricError(error, message);
} else {
- mStatusBarService.onBiometricError(message);
+ mCurrentAuthSession.mState = STATE_ERROR_PENDING_SYSUI;
+ if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) {
+ mStatusBarService.hideAuthenticationDialog();
+ } else {
+ mStatusBarService.onBiometricError(error, message);
+ }
}
} else if (mCurrentAuthSession.mState == STATE_AUTH_PAUSED) {
// In the "try again" state, we should forward canceled errors to
// the client and and clean up. The only error we should get here is
// ERROR_CANCELED due to another client kicking us out.
mCurrentAuthSession.mClientReceiver.onError(error, message);
- mStatusBarService.hideBiometricDialog();
+ mStatusBarService.hideAuthenticationDialog();
mCurrentAuthSession = null;
+ } else if (mCurrentAuthSession.mState == STATE_SHOWING_DEVICE_CREDENTIAL) {
+ Slog.d(TAG, "Biometric canceled, ignoring from state: "
+ + mCurrentAuthSession.mState);
} else {
Slog.e(TAG, "Impossible session error state: "
+ mCurrentAuthSession.mState);
@@ -1353,12 +1174,38 @@
} else if (mPendingAuthSession != null
&& mPendingAuthSession.containsCookie(cookie)) {
if (mPendingAuthSession.mState == STATE_AUTH_CALLED) {
- mPendingAuthSession.mClientReceiver.onError(error, message);
- mPendingAuthSession = null;
+ // If any error is received while preparing the auth session (lockout, etc),
+ // and if device credential is allowed, just show the credential UI.
+ if (mPendingAuthSession.isAllowDeviceCredential()) {
+ int authenticators = mPendingAuthSession.mBundle
+ .getInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED, 0);
+ // Disallow biometric and notify SystemUI to show the authentication prompt.
+ authenticators &= ~Authenticator.TYPE_BIOMETRIC;
+ mPendingAuthSession.mBundle.putInt(
+ BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED,
+ authenticators);
+
+ mCurrentAuthSession = mPendingAuthSession;
+ mCurrentAuthSession.mState = STATE_SHOWING_DEVICE_CREDENTIAL;
+ mPendingAuthSession = null;
+
+ mStatusBarService.showAuthenticationDialog(
+ mCurrentAuthSession.mBundle,
+ mInternalReceiver,
+ 0 /* biometricModality */,
+ false /* requireConfirmation */,
+ mCurrentAuthSession.mUserId,
+ mCurrentAuthSession.mOpPackageName);
+ } else {
+ mPendingAuthSession.mClientReceiver.onError(error, message);
+ mPendingAuthSession = null;
+ }
} else {
Slog.e(TAG, "Impossible pending session error state: "
+ mPendingAuthSession.mState);
}
+ } else {
+ Slog.e(TAG, "Unknown cookie: " + cookie);
}
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
@@ -1396,9 +1243,12 @@
try {
switch (reason) {
- case BiometricPrompt.DISMISSED_REASON_CONFIRMED:
- case BiometricPrompt.DISMISSED_REASON_CONFIRM_NOT_REQUIRED:
- mKeyStore.addAuthToken(mCurrentAuthSession.mTokenEscrow);
+ case BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED:
+ case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED:
+ case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED:
+ if (mCurrentAuthSession.mTokenEscrow != null) {
+ mKeyStore.addAuthToken(mCurrentAuthSession.mTokenEscrow);
+ }
mCurrentAuthSession.mClientReceiver.onAuthenticationSucceeded();
break;
@@ -1450,12 +1300,37 @@
mCurrentAuthSession.mCallingUid,
mCurrentAuthSession.mCallingPid,
mCurrentAuthSession.mCallingUserId,
- mCurrentAuthSession.mModality,
- mCurrentAuthSession.mConfirmDeviceCredentialCallback);
+ mCurrentAuthSession.mModality);
}
+ private void handleOnDeviceCredentialPressed() {
+ Slog.d(TAG, "onDeviceCredentialPressed");
+ if (mCurrentAuthSession == null) {
+ Slog.e(TAG, "Auth session null");
+ return;
+ }
+
+ // Cancel authentication. Skip the token/package check since we are cancelling
+ // from system server. The interface is permission protected so this is fine.
+ cancelInternal(null /* token */, null /* package */, false /* fromClient */);
+
+ mCurrentAuthSession.mState = STATE_SHOWING_DEVICE_CREDENTIAL;
+ }
+
+ /**
+ * Invoked when each service has notified that its client is ready to be started. When
+ * all biometrics are ready, this invokes the SystemUI dialog through StatusBar.
+ */
private void handleOnReadyForAuthentication(int cookie, boolean requireConfirmation,
int userId) {
+ if (mPendingAuthSession == null) {
+ // Only should happen if a biometric was locked out when authenticate() was invoked.
+ // In that case, if device credentials are allowed, the UI is already showing. If not
+ // allowed, the error has already been returned to the caller.
+ Slog.w(TAG, "Pending auth session null");
+ return;
+ }
+
Iterator it = mPendingAuthSession.mModalitiesWaiting.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, Integer> pair = (Map.Entry) it.next();
@@ -1497,7 +1372,7 @@
}
if (!continuing) {
- mStatusBarService.showBiometricDialog(mCurrentAuthSession.mBundle,
+ mStatusBarService.showAuthenticationDialog(mCurrentAuthSession.mBundle,
mInternalReceiver, modality, requireConfirmation, userId,
mCurrentAuthSession.mOpPackageName);
}
@@ -1509,16 +1384,21 @@
private void handleAuthenticate(IBinder token, long sessionId, int userId,
IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle,
- int callingUid, int callingPid, int callingUserId,
- IBiometricConfirmDeviceCredentialCallback callback) {
+ int callingUid, int callingPid, int callingUserId) {
mHandler.post(() -> {
final Pair<Integer, Integer> result = checkAndGetBiometricModality(userId);
final int modality = result.first;
final int error = result.second;
- // Check for errors, notify callback, and return
- if (error != BiometricConstants.BIOMETRIC_SUCCESS) {
+ final boolean credentialAllowed = Utils.isDeviceCredentialAllowed(bundle);
+
+ if (error != BiometricConstants.BIOMETRIC_SUCCESS && credentialAllowed) {
+ // If there's a problem but device credential is allowed, only show credential UI.
+ bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED,
+ Authenticator.TYPE_CREDENTIAL);
+ } else if (error != BiometricConstants.BIOMETRIC_SUCCESS) {
+ // Check for errors, notify callback, and return
try {
final String hardwareUnavailable =
getContext().getString(R.string.biometric_error_hw_unavailable);
@@ -1546,7 +1426,7 @@
// Start preparing for authentication. Authentication starts when
// all modalities requested have invoked onReadyForAuthentication.
authenticateInternal(token, sessionId, userId, receiver, opPackageName, bundle,
- callingUid, callingPid, callingUserId, modality, callback);
+ callingUid, callingPid, callingUserId, modality);
});
}
@@ -1561,8 +1441,7 @@
*/
private void authenticateInternal(IBinder token, long sessionId, int userId,
IBiometricServiceReceiver receiver, String opPackageName, Bundle bundle,
- int callingUid, int callingPid, int callingUserId, int modality,
- IBiometricConfirmDeviceCredentialCallback callback) {
+ int callingUid, int callingPid, int callingUserId, int modality) {
try {
boolean requireConfirmation = bundle.getBoolean(
BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true /* default */);
@@ -1576,27 +1455,49 @@
// with the cookie. Once all cookies are received, we can show the prompt
// and let the services start authenticating. The cookie should be non-zero.
final int cookie = mRandom.nextInt(Integer.MAX_VALUE - 1) + 1;
+ final int authenticators = bundle.getInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED);
Slog.d(TAG, "Creating auth session. Modality: " + modality
- + ", cookie: " + cookie);
- final HashMap<Integer, Integer> authenticators = new HashMap<>();
- authenticators.put(modality, cookie);
- mPendingAuthSession = new AuthSession(authenticators, token, sessionId, userId,
+ + ", cookie: " + cookie
+ + ", authenticators: " + authenticators);
+ final HashMap<Integer, Integer> modalities = new HashMap<>();
+
+ // If it's only device credential, we don't need to wait - LockSettingsService is
+ // always ready to check credential (SystemUI invokes that path).
+ if ((authenticators & ~Authenticator.TYPE_CREDENTIAL) != 0) {
+ modalities.put(modality, cookie);
+ }
+ mPendingAuthSession = new AuthSession(modalities, token, sessionId, userId,
receiver, opPackageName, bundle, callingUid, callingPid, callingUserId,
- modality, requireConfirmation, callback);
- mPendingAuthSession.mState = STATE_AUTH_CALLED;
- // No polymorphism :(
- if ((modality & TYPE_FINGERPRINT) != 0) {
- mFingerprintService.prepareForAuthentication(token, sessionId, userId,
- mInternalReceiver, opPackageName, cookie,
- callingUid, callingPid, callingUserId);
- }
- if ((modality & TYPE_IRIS) != 0) {
- Slog.w(TAG, "Iris unsupported");
- }
- if ((modality & TYPE_FACE) != 0) {
- mFaceService.prepareForAuthentication(requireConfirmation,
- token, sessionId, userId, mInternalReceiver, opPackageName,
- cookie, callingUid, callingPid, callingUserId);
+ modality, requireConfirmation);
+
+ if (authenticators == Authenticator.TYPE_CREDENTIAL) {
+ mPendingAuthSession.mState = STATE_SHOWING_DEVICE_CREDENTIAL;
+ mCurrentAuthSession = mPendingAuthSession;
+ mPendingAuthSession = null;
+
+ mStatusBarService.showAuthenticationDialog(
+ mCurrentAuthSession.mBundle,
+ mInternalReceiver,
+ 0 /* biometricModality */,
+ false /* requireConfirmation */,
+ mCurrentAuthSession.mUserId,
+ mCurrentAuthSession.mOpPackageName);
+ } else {
+ mPendingAuthSession.mState = STATE_AUTH_CALLED;
+ // No polymorphism :(
+ if ((modality & TYPE_FINGERPRINT) != 0) {
+ mFingerprintService.prepareForAuthentication(token, sessionId, userId,
+ mInternalReceiver, opPackageName, cookie,
+ callingUid, callingPid, callingUserId);
+ }
+ if ((modality & TYPE_IRIS) != 0) {
+ Slog.w(TAG, "Iris unsupported");
+ }
+ if ((modality & TYPE_FACE) != 0) {
+ mFaceService.prepareForAuthentication(requireConfirmation,
+ token, sessionId, userId, mInternalReceiver, opPackageName,
+ cookie, callingUid, callingPid, callingUserId);
+ }
}
} catch (RemoteException e) {
Slog.e(TAG, "Unable to start authentication", e);
@@ -1609,20 +1510,7 @@
return;
}
- if (mCurrentAuthSession != null
- && mCurrentAuthSession.mState == STATE_BIOMETRIC_AUTH_CANCELED_SHOWING_CDC) {
- if (DEBUG) Slog.d(TAG, "Cancel received while ConfirmDeviceCredential showing");
- try {
- mCurrentAuthSession.mConfirmDeviceCredentialCallback.cancel();
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to cancel ConfirmDeviceCredential", e);
- }
-
- // TODO(b/123378871): Remove when moved. Piggy back on this for now to clean up.
- handleOnConfirmDeviceCredentialError(BiometricConstants.BIOMETRIC_ERROR_CANCELED,
- getContext().getString(R.string.biometric_error_canceled));
- } else if (mCurrentAuthSession != null
- && mCurrentAuthSession.mState != STATE_AUTH_STARTED) {
+ if (mCurrentAuthSession != null && mCurrentAuthSession.mState != STATE_AUTH_STARTED) {
// We need to check the current authenticators state. If we're pending confirm
// or idle, we need to dismiss the dialog and send an ERROR_CANCELED to the client,
// since we won't be getting an onError from the driver.
@@ -1635,24 +1523,12 @@
);
mCurrentAuthSession = null;
- mStatusBarService.hideBiometricDialog();
+ mStatusBarService.hideAuthenticationDialog();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
}
} else {
- boolean fromCDC = false;
- if (mCurrentAuthSession != null) {
- fromCDC = mCurrentAuthSession.mBundle.getBoolean(
- BiometricPrompt.KEY_FROM_CONFIRM_DEVICE_CREDENTIAL, false);
- }
-
- if (fromCDC) {
- if (DEBUG) Slog.d(TAG, "Cancelling from CDC");
- cancelInternal(token, opPackageName, false /* fromClient */);
- } else {
- cancelInternal(token, opPackageName, true /* fromClient */);
- }
-
+ cancelInternal(token, opPackageName, true /* fromClient */);
}
}
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index 4fa29ac..ed5f9de 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -17,10 +17,15 @@
package com.android.server.biometrics;
import android.content.Context;
+import android.hardware.biometrics.Authenticator;
+import android.hardware.biometrics.BiometricPrompt;
import android.os.Build;
+import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;
+import com.android.internal.annotations.VisibleForTesting;
+
public class Utils {
public static boolean isDebugEnabled(Context context, int targetUserId) {
if (targetUserId == UserHandle.USER_NULL) {
@@ -38,4 +43,43 @@
}
return true;
}
+
+ /**
+ * Combine {@link BiometricPrompt#KEY_ALLOW_DEVICE_CREDENTIAL} with
+ * {@link BiometricPrompt#KEY_AUTHENTICATORS_ALLOWED}, as the former is not flexible
+ * enough.
+ */
+ public static void combineAuthenticatorBundles(Bundle bundle) {
+ boolean biometricEnabled = true; // enabled by default
+ boolean credentialEnabled = bundle.getBoolean(
+ BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL, false);
+ if (bundle.get(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED) != null) {
+ final int authenticatorFlags =
+ bundle.getInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED);
+ biometricEnabled = (authenticatorFlags & Authenticator.TYPE_BIOMETRIC) != 0;
+ // Using both KEY_ALLOW_DEVICE_CREDENTIAL and KEY_AUTHENTICATORS_ALLOWED together
+ // is not supported. Default to overwriting.
+ credentialEnabled = (authenticatorFlags & Authenticator.TYPE_CREDENTIAL) != 0;
+ }
+
+ bundle.remove(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL);
+
+ int authenticators = 0;
+ if (biometricEnabled) {
+ authenticators |= Authenticator.TYPE_BIOMETRIC;
+ }
+ if (credentialEnabled) {
+ authenticators |= Authenticator.TYPE_CREDENTIAL;
+ }
+ bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED, authenticators);
+ }
+
+ /**
+ * @param bundle should be first processed by {@link #combineAuthenticatorBundles(Bundle)}
+ * @return true if device credential allowed.
+ */
+ public static boolean isDeviceCredentialAllowed(Bundle bundle) {
+ final int authenticators = bundle.getInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED);
+ return (authenticators & Authenticator.TYPE_CREDENTIAL) != 0;
+ }
}
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 8e09d0e..852b26d 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -47,7 +47,8 @@
@Override
public void reportChange(long changeId, ApplicationInfo appInfo) {
- reportChange(changeId, appInfo, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
+ reportChange(changeId, appInfo.uid,
+ StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
}
@Override
@@ -60,13 +61,18 @@
}
@Override
+ public void reportChangeByUid(long changeId, int uid) {
+ reportChange(changeId, uid, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
+ }
+
+ @Override
public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) {
- reportChange(changeId, appInfo,
+ reportChange(changeId, appInfo.uid,
StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED);
return true;
}
- reportChange(changeId, appInfo,
+ reportChange(changeId, appInfo.uid,
StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED);
return false;
}
@@ -81,6 +87,19 @@
}
@Override
+ public boolean isChangeEnabledByUid(long changeId, int uid) {
+ String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
+ if (packages == null || packages.length == 0) {
+ return true;
+ }
+ boolean enabled = true;
+ for (String packageName : packages) {
+ enabled = enabled && isChangeEnabledByPackageName(changeId, packageName);
+ }
+ return enabled;
+ }
+
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
CompatConfig.get().dumpConfig(pw);
@@ -95,8 +114,7 @@
return null;
}
- private void reportChange(long changeId, ApplicationInfo appInfo, int state) {
- int uid = appInfo.uid;
+ private void reportChange(long changeId, int uid, int state) {
mChangeReporter.reportChange(uid, changeId, state);
}
}
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 66bd27c..aea6d8d 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -16,6 +16,7 @@
package com.android.server.connectivity;
+import android.annotation.NonNull;
import android.net.ConnectivityManager;
import android.net.IDnsResolver;
import android.net.INetd;
@@ -325,13 +326,13 @@
* This is necessary because the LinkProperties in mNetwork come from the transport layer, which
* has no idea that 464xlat is running on top of it.
*/
- public void fixupLinkProperties(LinkProperties oldLp, LinkProperties lp) {
+ public void fixupLinkProperties(@NonNull LinkProperties oldLp, @NonNull LinkProperties lp) {
lp.setNat64Prefix(mNat64Prefix);
if (!isRunning()) {
return;
}
- if (lp == null || lp.getAllInterfaceNames().contains(mIface)) {
+ if (lp.getAllInterfaceNames().contains(mIface)) {
return;
}
@@ -434,7 +435,7 @@
@Override
public void interfaceRemoved(String iface) {
- mNetwork.handler().post(() -> { handleInterfaceRemoved(iface); });
+ mNetwork.handler().post(() -> handleInterfaceRemoved(iface));
}
@Override
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 7b3eae1..6b70e5f 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -199,13 +199,22 @@
*/
private @NonNull List<String> mLockdownWhitelist = Collections.emptyList();
- /**
- * List of UIDs for which networking should be blocked until VPN is ready, during brief periods
- * when VPN is not running. For example, during system startup or after a crash.
+ /**
+ * A memory of what UIDs this class told netd to block for the lockdown feature.
+ *
+ * Netd maintains ranges of UIDs for which network should be restricted to using only the VPN
+ * for the lockdown feature. This class manages these UIDs and sends this information to netd.
+ * To avoid sending the same commands multiple times (which would be wasteful) and to be able
+ * to revoke lists (when the rules should change), it's simplest to keep this cache of what
+ * netd knows, so it can be diffed and sent most efficiently.
+ *
+ * The contents of this list must only be changed when updating the UIDs lists with netd,
+ * since it needs to keep in sync with the picture netd has of them.
+ *
* @see mLockdown
*/
@GuardedBy("this")
- private Set<UidRange> mBlockedUsers = new ArraySet<>();
+ private final Set<UidRange> mBlockedUidsAsToldToNetd = new ArraySet<>();
// Handle of the user initiating VPN.
private final int mUserHandle;
@@ -254,7 +263,7 @@
}
/**
- * Update current state, dispaching event to listeners.
+ * Update current state, dispatching event to listeners.
*/
@VisibleForTesting
protected void updateState(DetailedState detailedState, String reason) {
@@ -1325,7 +1334,7 @@
* {@link Vpn} goes through a VPN connection or is blocked until one is
* available, {@code false} to lift the requirement.
*
- * @see #mBlockedUsers
+ * @see #mBlockedUidsAsToldToNetd
*/
@GuardedBy("this")
private void setVpnForcedLocked(boolean enforce) {
@@ -1336,37 +1345,47 @@
exemptedPackages = new ArrayList<>(mLockdownWhitelist);
exemptedPackages.add(mPackage);
}
- final Set<UidRange> removedRanges = new ArraySet<>(mBlockedUsers);
+ final Set<UidRange> rangesToTellNetdToRemove = new ArraySet<>(mBlockedUidsAsToldToNetd);
- Set<UidRange> addedRanges = Collections.emptySet();
+ final Set<UidRange> rangesToTellNetdToAdd;
if (enforce) {
- addedRanges = createUserAndRestrictedProfilesRanges(mUserHandle,
- /* allowedApplications */ null,
- /* disallowedApplications */ exemptedPackages);
+ final Set<UidRange> rangesThatShouldBeBlocked =
+ createUserAndRestrictedProfilesRanges(mUserHandle,
+ /* allowedApplications */ null,
+ /* disallowedApplications */ exemptedPackages);
// The UID range of the first user (0-99999) would block the IPSec traffic, which comes
// directly from the kernel and is marked as uid=0. So we adjust the range to allow
// it through (b/69873852).
- for (UidRange range : addedRanges) {
+ for (UidRange range : rangesThatShouldBeBlocked) {
if (range.start == 0) {
- addedRanges.remove(range);
+ rangesThatShouldBeBlocked.remove(range);
if (range.stop != 0) {
- addedRanges.add(new UidRange(1, range.stop));
+ rangesThatShouldBeBlocked.add(new UidRange(1, range.stop));
}
}
}
- removedRanges.removeAll(addedRanges);
- addedRanges.removeAll(mBlockedUsers);
+ rangesToTellNetdToRemove.removeAll(rangesThatShouldBeBlocked);
+ rangesToTellNetdToAdd = rangesThatShouldBeBlocked;
+ // The ranges to tell netd to add are the ones that should be blocked minus the
+ // ones it already knows to block. Note that this will change the contents of
+ // rangesThatShouldBeBlocked, but the list of ranges that should be blocked is
+ // not used after this so it's fine to destroy it.
+ rangesToTellNetdToAdd.removeAll(mBlockedUidsAsToldToNetd);
+ } else {
+ rangesToTellNetdToAdd = Collections.emptySet();
}
- setAllowOnlyVpnForUids(false, removedRanges);
- setAllowOnlyVpnForUids(true, addedRanges);
+ // If mBlockedUidsAsToldToNetd used to be empty, this will always be a no-op.
+ setAllowOnlyVpnForUids(false, rangesToTellNetdToRemove);
+ // If nothing should be blocked now, this will now be a no-op.
+ setAllowOnlyVpnForUids(true, rangesToTellNetdToAdd);
}
/**
- * Either add or remove a list of {@link UidRange}s to the list of UIDs that are only allowed
- * to make connections through sockets that have had {@code protect()} called on them.
+ * Tell netd to add or remove a list of {@link UidRange}s to the list of UIDs that are only
+ * allowed to make connections through sockets that have had {@code protect()} called on them.
*
* @param enforce {@code true} to add to the blacklist, {@code false} to remove.
* @param ranges {@link Collection} of {@link UidRange}s to add (if {@param enforce} is
@@ -1388,9 +1407,9 @@
return false;
}
if (enforce) {
- mBlockedUsers.addAll(ranges);
+ mBlockedUidsAsToldToNetd.addAll(ranges);
} else {
- mBlockedUsers.removeAll(ranges);
+ mBlockedUidsAsToldToNetd.removeAll(ranges);
}
return true;
}
@@ -1557,17 +1576,18 @@
/**
* @param uid The target uid.
*
- * @return {@code true} if {@code uid} is included in one of the mBlockedUsers ranges and the
- * VPN is not connected, or if the VPN is connected but does not apply to the {@code uid}.
+ * @return {@code true} if {@code uid} is included in one of the mBlockedUidsAsToldToNetd
+ * ranges and the VPN is not connected, or if the VPN is connected but does not apply to
+ * the {@code uid}.
*
* @apiNote This method don't check VPN lockdown status.
- * @see #mBlockedUsers
+ * @see #mBlockedUidsAsToldToNetd
*/
public synchronized boolean isBlockingUid(int uid) {
if (mNetworkInfo.isConnected()) {
return !appliesToUid(uid);
} else {
- return UidRange.containsUid(mBlockedUsers, uid);
+ return UidRange.containsUid(mBlockedUidsAsToldToNetd, uid);
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 4f4baab..61d4d4b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -850,36 +850,25 @@
mAddress, Constants.ADDR_BROADCAST, systemAudioStatusOn));
if (systemAudioStatusOn) {
+ // If TV sends out SAM Request with a path of a non-CEC device, which should not show
+ // up in the CEC device list and not under the current AVR device, the AVR would switch
+ // to ARC.
int sourcePhysicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
- if (sourcePhysicalAddress != getActiveSource().physicalAddress) {
- // If the Active Source recorded by the current device is not synced up with TV,
- // update the Active Source internally.
- if (sourcePhysicalAddress == mService.getPhysicalAddress()) {
- // If the active path is the current device itself, update with local info
- if (mService.playback() != null) {
- setActiveSource(mService.playback().mAddress, sourcePhysicalAddress);
- } else {
- setActiveSource(mAddress, sourcePhysicalAddress);
- }
- } else {
- // If it's not the current device, look for the device info from the list
- for (HdmiDeviceInfo info : HdmiUtils.sparseArrayToList(mDeviceInfos)) {
- if (info.getPhysicalAddress() == sourcePhysicalAddress) {
- setActiveSource(info.getLogicalAddress(), info.getPhysicalAddress());
- break;
- }
- }
- }
- // If the Active path from TV's System Audio Mode request does not belong to any
- // device in the local device list, record the new Active physicalAddress with an
- // unregistered logical address first. Then query the Active Source again.
- if (sourcePhysicalAddress != getActiveSource().physicalAddress) {
- setActiveSource(Constants.ADDR_UNREGISTERED, sourcePhysicalAddress);
- mService.sendCecCommand(
- HdmiCecMessageBuilder.buildRequestActiveSource(mAddress));
+ if (HdmiUtils.getLocalPortFromPhysicalAddress(
+ sourcePhysicalAddress, getDeviceInfo().getPhysicalAddress())
+ != HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE) {
+ return true;
+ }
+ boolean isDeviceInCecDeviceList = false;
+ for (HdmiDeviceInfo info : HdmiUtils.sparseArrayToList(mDeviceInfos)) {
+ if (info.getPhysicalAddress() == sourcePhysicalAddress) {
+ isDeviceInCecDeviceList = true;
+ break;
}
}
- switchInputOnReceivingNewActivePath(sourcePhysicalAddress);
+ if (!isDeviceInCecDeviceList) {
+ switchInputOnReceivingNewActivePath(sourcePhysicalAddress);
+ }
}
return true;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index c3354e1..1794df3 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -311,6 +311,11 @@
private IHdmiControlCallback mDisplayStatusCallback = null;
@Nullable
+ // Save callback when the device is still under logcial address allocation
+ // Invoke once new local device is ready.
+ private IHdmiControlCallback mOtpCallbackPendingAddressAllocation = null;
+
+ @Nullable
private HdmiCecController mCecController;
// HDMI port information. Stored in the unmodifiable list to keep the static information
@@ -785,17 +790,21 @@
// Address allocation completed for all devices. Notify each device.
if (allocatingDevices.size() == ++finished[0]) {
mAddressAllocated = true;
- // Reinvoke the saved display status callback once the local device is ready.
- if (mDisplayStatusCallback != null) {
- queryDisplayStatus(mDisplayStatusCallback);
- mDisplayStatusCallback = null;
- }
if (initiatedBy != INITIATED_BY_HOTPLUG) {
// In case of the hotplug we don't call onInitializeCecComplete()
// since we reallocate the logical address only.
onInitializeCecComplete(initiatedBy);
}
notifyAddressAllocated(allocatedDevices, initiatedBy);
+ // Reinvoke the saved display status callback once the local device is ready.
+ if (mDisplayStatusCallback != null) {
+ queryDisplayStatus(mDisplayStatusCallback);
+ mDisplayStatusCallback = null;
+ }
+ if (mOtpCallbackPendingAddressAllocation != null) {
+ oneTouchPlay(mOtpCallbackPendingAddressAllocation);
+ mOtpCallbackPendingAddressAllocation = null;
+ }
mCecMessageBuffer.processMessages();
}
}
@@ -2246,8 +2255,16 @@
}
@ServiceThreadOnly
- private void oneTouchPlay(final IHdmiControlCallback callback) {
+ @VisibleForTesting
+ protected void oneTouchPlay(final IHdmiControlCallback callback) {
assertRunOnServiceThread();
+ if (!mAddressAllocated) {
+ mOtpCallbackPendingAddressAllocation = callback;
+ Slog.d(TAG, "Local device is under address allocation. "
+ + "Save OTP callback for later process.");
+ return;
+ }
+
HdmiCecLocalDeviceSource source = playback();
if (source == null) {
source = audioSystem();
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index c8fc5fc..4962af1 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -77,7 +77,6 @@
sendCommand(HdmiCecMessageBuilder.buildTextViewOn(getSourceAddress(), mTargetAddress));
broadcastActiveSource();
queryDevicePowerStatus();
- mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
addTimer(mState, HdmiConfig.TIMEOUT_MS);
return true;
}
@@ -99,6 +98,7 @@
}
private void queryDevicePowerStatus() {
+ mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(),
mTargetAddress));
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 8fbad4c..7e6e668 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -47,6 +47,7 @@
import android.hardware.input.InputManagerInternal;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.TouchCalibration;
+import android.media.AudioManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -296,6 +297,9 @@
/** Switch code: Camera lens cover. When set the lens is covered. */
public static final int SW_CAMERA_LENS_COVER = 0x09;
+ /** Switch code: Microphone. When set it is off. */
+ public static final int SW_MUTE_DEVICE = 0x0e;
+
public static final int SW_LID_BIT = 1 << SW_LID;
public static final int SW_TABLET_MODE_BIT = 1 << SW_TABLET_MODE;
public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE;
@@ -306,6 +310,7 @@
public static final int SW_JACK_BITS =
SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT | SW_LINEOUT_INSERT_BIT;
public static final int SW_CAMERA_LENS_COVER_BIT = 1 << SW_CAMERA_LENS_COVER;
+ public static final int SW_MUTE_DEVICE_BIT = 1 << SW_MUTE_DEVICE;
/** Whether to use the dev/input/event or uevent subsystem for the audio jack. */
final boolean mUseDevInputEventForAudioJack;
@@ -972,6 +977,11 @@
}
@Override // Binder call
+ public int isMicMuted() {
+ return getSwitchState(-1, InputDevice.SOURCE_ANY, SW_MUTE_DEVICE);
+ }
+
+ @Override // Binder call
public void registerTabletModeChangedListener(ITabletModeChangedListener listener) {
if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE,
"registerTabletModeChangedListener()")) {
@@ -1804,6 +1814,12 @@
mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED,
args).sendToTarget();
}
+
+ if ((switchMask & SW_MUTE_DEVICE_BIT) != 0) {
+ final boolean micMute = ((switchValues & SW_MUTE_DEVICE_BIT) != 0);
+ AudioManager audioManager = mContext.getSystemService(AudioManager.class);
+ audioManager.setMicrophoneMuteFromSwitch(micMute);
+ }
}
// Native callback.
diff --git a/services/core/java/com/android/server/integrity/TEST_MAPPING b/services/core/java/com/android/server/integrity/TEST_MAPPING
new file mode 100644
index 0000000..b45b4ea
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/TEST_MAPPING
@@ -0,0 +1,18 @@
+{
+ "presubmit": [
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.integrity."
+ },
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java b/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java
new file mode 100644
index 0000000..fc44306
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 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.server.integrity.engine;
+
+import com.android.server.integrity.model.Rule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The engine used to evaluate rules against app installs.
+ *
+ * <p>Every app install is evaluated against rules (pushed by the verifier) by the evaluation engine
+ * to allow/block that install.
+ */
+public final class RuleEvaluationEngine {
+ private static final String TAG = "RuleEvaluation";
+
+ // The engine for loading rules, retrieving metadata for app installs, and evaluating app
+ // installs against rules.
+ private static RuleEvaluationEngine sRuleEvaluationEngine;
+
+ // The subset of rules loaded to be used to evaluate an app install request.
+ // TODO: Load rules relevant to app installs.
+ private List<Rule> mRules;
+
+ private RuleEvaluationEngine() {
+ // Initialize rules with the empty rule set.
+ mRules = new ArrayList<>();
+ }
+
+ /**
+ * Provide a singleton instance of the rule evaluation engine.
+ */
+ public static synchronized RuleEvaluationEngine getRuleEvaluationEngine() {
+ if (sRuleEvaluationEngine == null) {
+ return new RuleEvaluationEngine();
+ }
+ return sRuleEvaluationEngine;
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/engine/RuleLoader.java b/services/core/java/com/android/server/integrity/engine/RuleLoader.java
new file mode 100644
index 0000000..af24d7a
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/engine/RuleLoader.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 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.server.integrity.engine;
+
+import com.android.server.integrity.model.Rule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A helper class for loading rules to the rule evaluation engine.
+ *
+ * <p>Expose fine-grained APIs for loading rules to be passed to the rule evaluation engine.
+ *
+ * <p>It supports:
+ * <ul>
+ * <li>Loading rules based on some keys, such as PACKAGE_NAME and APP_CERT.</li>
+ * </ul>
+ *
+ * <p>It does NOT support:
+ * <ul>
+ * <li>Loading the list of all rules.</li>
+ * <li>Merging rules resulting from different APIs.</li>
+ * </ul>
+ */
+final class RuleLoader {
+
+ List<Rule> loadRulesByPackageName(String packageName) {
+ // TODO: Add logic based on rule storage.
+ return new ArrayList<>();
+ }
+
+ List<Rule> loadRulesByAppCertificate(String appCertificate) {
+ // TODO: Add logic based on rule storage.
+ return new ArrayList<>();
+ }
+
+ List<Rule> loadRulesByInstallerName(String installerName) {
+ // TODO: Add logic based on rule storage.
+ return new ArrayList<>();
+ }
+
+ List<Rule> loadRulesByInstallerCertificate(String installerCertificate) {
+ // TODO: Add logic based on rule storage.
+ return new ArrayList<>();
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/model/AppInstallMetadata.java b/services/core/java/com/android/server/integrity/model/AppInstallMetadata.java
new file mode 100644
index 0000000..660bd2e
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/AppInstallMetadata.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2019 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.server.integrity.model;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
+
+/**
+ * The app install metadata.
+ *
+ * <p>The integrity component retrieves metadata for app installs from package manager, passing it
+ * to the rule evaluation engine to evaluate the metadata against the rules.
+ *
+ * <p>Instances of this class are immutable.
+ */
+public final class AppInstallMetadata {
+ private final String mPackageName;
+ // Raw string encoding for the SHA-256 hash of the certificate of the app.
+ private final String mAppCertificate;
+ private final String mInstallerName;
+ // Raw string encoding for the SHA-256 hash of the certificate of the installer.
+ private final String mInstallerCertificate;
+ private final int mVersionCode;
+ private final boolean mIsPreInstalled;
+
+ private AppInstallMetadata(Builder builder) {
+ this.mPackageName = builder.mPackageName;
+ this.mAppCertificate = builder.mAppCertificate;
+ this.mInstallerName = builder.mInstallerName;
+ this.mInstallerCertificate = builder.mInstallerCertificate;
+ this.mVersionCode = builder.mVersionCode;
+ this.mIsPreInstalled = builder.mIsPreInstalled;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public String getAppCertificate() {
+ return mAppCertificate;
+ }
+
+ @Nullable
+ public String getInstallerName() {
+ return mInstallerName;
+ }
+
+ @Nullable
+ public String getInstallerCertificate() {
+ return mInstallerCertificate;
+ }
+
+ /**
+ * @see AppInstallMetadata.Builder#setVersionCode(int)
+ */
+ public int getVersionCode() {
+ return mVersionCode;
+ }
+
+ /**
+ * @see AppInstallMetadata.Builder#setIsPreInstalled(boolean)
+ */
+ public boolean isPreInstalled() {
+ return mIsPreInstalled;
+ }
+
+ /**
+ * Builder class for constructing {@link AppInstallMetadata} objects.
+ */
+ public static final class Builder {
+ private String mPackageName;
+ private String mAppCertificate;
+ private String mInstallerName;
+ private String mInstallerCertificate;
+ private int mVersionCode;
+ private boolean mIsPreInstalled;
+
+ /**
+ * Set package name of the app to be installed.
+ *
+ * @see AppInstallMetadata#getPackageName()
+ */
+ public Builder setPackageName(String packageName) {
+ this.mPackageName = checkNotNull(packageName);
+ return this;
+ }
+
+ /**
+ * Set certificate of the app to be installed.
+ *
+ * <p>It is represented as the raw string encoding for the SHA-256 hash of the certificate
+ * of the app.
+ *
+ * @see AppInstallMetadata#getAppCertificate()
+ */
+ public Builder setAppCertificate(String appCertificate) {
+ this.mAppCertificate = checkNotNull(appCertificate);
+ return this;
+ }
+
+ /**
+ * Set name of the installer installing the app.
+ *
+ * @see AppInstallMetadata#getInstallerName()
+ */
+ public Builder setInstallerName(String installerName) {
+ this.mInstallerName = checkNotNull(installerName);
+ return this;
+ }
+
+ /**
+ * Set certificate of the installer installing the app.
+ *
+ * <p>It is represented as the raw string encoding for the SHA-256 hash of the certificate
+ * of the installer.
+ *
+ * @see AppInstallMetadata#getInstallerCertificate()
+ */
+ public Builder setInstallerCertificate(String installerCertificate) {
+ this.mInstallerCertificate = checkNotNull(installerCertificate);
+ return this;
+ }
+
+ /**
+ * Set version code of the app to be installed.
+ *
+ * @see AppInstallMetadata#getVersionCode()
+ */
+ public Builder setVersionCode(int versionCode) {
+ this.mVersionCode = versionCode;
+ return this;
+ }
+
+ /**
+ * Set whether the app is pre-installed on the device or not.
+ *
+ * @see AppInstallMetadata#isPreInstalled()
+ */
+ public Builder setIsPreInstalled(boolean isPreInstalled) {
+ this.mIsPreInstalled = isPreInstalled;
+ return this;
+ }
+
+ /**
+ * Build {@link AppInstallMetadata}.
+ */
+ public AppInstallMetadata build() {
+ checkArgument(mPackageName != null);
+ checkArgument(mAppCertificate != null);
+ return new AppInstallMetadata(this);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/model/AtomicFormula.java b/services/core/java/com/android/server/integrity/model/AtomicFormula.java
new file mode 100644
index 0000000..a9cc62a4da
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/AtomicFormula.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2019 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.server.integrity.model;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
+
+/**
+ * Represents a simple formula consisting of an app install metadata field and a value.
+ *
+ * <p>Instances of this class are immutable.
+ */
+public final class AtomicFormula extends Formula {
+
+ enum Key {
+ PACKAGE_NAME,
+ APP_CERTIFICATE,
+ INSTALLER_NAME,
+ INSTALLER_CERTIFICATE,
+ VERSION_CODE,
+ PRE_INSTALLED
+ }
+
+ enum Operator {
+ EQ,
+ LT,
+ LE,
+ GT,
+ GE
+ }
+
+ private final Key mKey;
+ private final Operator mOperator;
+
+ // The value of a key can take either 1 of 3 forms: String, Integer, or Boolean.
+ // It cannot have multiple values.
+ @Nullable
+ private final String mStringValue;
+ @Nullable
+ private final Integer mIntValue;
+ @Nullable
+ private final Boolean mBoolValue;
+
+ public AtomicFormula(Key key, Operator operator, String stringValue) {
+ validateOperator(key, operator);
+ checkArgument(
+ key == Key.PACKAGE_NAME || key == Key.APP_CERTIFICATE || key == Key.INSTALLER_NAME
+ || key == Key.INSTALLER_CERTIFICATE,
+ String.format("Key %s cannot have string value", key));
+ this.mKey = checkNotNull(key);
+ this.mOperator = checkNotNull(operator);
+ this.mStringValue = checkNotNull(stringValue);
+ this.mIntValue = null;
+ this.mBoolValue = null;
+ }
+
+ public AtomicFormula(Key key, Operator operator, Integer intValue) {
+ validateOperator(key, operator);
+ checkArgument(key == Key.VERSION_CODE,
+ String.format("Key %s cannot have integer value", key));
+ this.mKey = checkNotNull(key);
+ this.mOperator = checkNotNull(operator);
+ this.mStringValue = null;
+ this.mIntValue = checkNotNull(intValue);
+ this.mBoolValue = null;
+ }
+
+ public AtomicFormula(Key key, Operator operator, Boolean boolValue) {
+ validateOperator(key, operator);
+ checkArgument(key == Key.PRE_INSTALLED,
+ String.format("Key %s cannot have boolean value", key));
+ this.mKey = checkNotNull(key);
+ this.mOperator = checkNotNull(operator);
+ this.mStringValue = null;
+ this.mIntValue = null;
+ this.mBoolValue = checkNotNull(boolValue);
+ }
+
+ public Key getKey() {
+ return mKey;
+ }
+
+ public Operator getOperator() {
+ return mOperator;
+ }
+
+ public String getStringValue() {
+ return mStringValue;
+ }
+
+ public Integer getIntValue() {
+ return mIntValue;
+ }
+
+ public Boolean getBoolValue() {
+ return mBoolValue;
+ }
+
+ private void validateOperator(Key key, Operator operator) {
+ boolean validOperator;
+ switch (key) {
+ case PACKAGE_NAME:
+ case APP_CERTIFICATE:
+ case INSTALLER_NAME:
+ case INSTALLER_CERTIFICATE:
+ case PRE_INSTALLED:
+ validOperator = (operator == Operator.EQ);
+ break;
+ case VERSION_CODE:
+ validOperator = true;
+ break;
+ default:
+ validOperator = false;
+ }
+ if (!validOperator) {
+ throw new IllegalArgumentException(
+ String.format("Invalid operator %s used for key %s", operator, key));
+ }
+ }
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/services/core/java/com/android/server/integrity/model/Formula.java
similarity index 68%
copy from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
copy to services/core/java/com/android/server/integrity/model/Formula.java
index 8b35852..4cfa2c7 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/services/core/java/com/android/server/integrity/model/Formula.java
@@ -14,13 +14,11 @@
* limitations under the License.
*/
-package android.hardware.biometrics;
+package com.android.server.integrity.model;
/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
- * @hide
+ * Represents a rule logic/content.
*/
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+abstract class Formula {
+
+}
diff --git a/services/core/java/com/android/server/integrity/model/OpenFormula.java b/services/core/java/com/android/server/integrity/model/OpenFormula.java
new file mode 100644
index 0000000..218cdc9
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/OpenFormula.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 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.server.integrity.model;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
+
+/**
+ * Represents a complex formula consisting of other simple and complex formulas.
+ *
+ * <p>Instances of this class are immutable.
+ */
+public final class OpenFormula extends Formula {
+
+ enum Connector {
+ AND,
+ OR,
+ NOT
+ }
+
+ private final Connector mConnector;
+ private final Formula mMainFormula;
+ private final Formula mAuxiliaryFormula;
+
+ public OpenFormula(Connector connector, Formula mainFormula,
+ @Nullable Formula auxiliaryFormula) {
+ validateAuxiliaryFormula(connector, auxiliaryFormula);
+ this.mConnector = checkNotNull(connector);
+ this.mMainFormula = checkNotNull(mainFormula);
+ // TODO: Add validators on auxiliary formula
+ this.mAuxiliaryFormula = auxiliaryFormula;
+ }
+
+ public Connector getConnector() {
+ return mConnector;
+ }
+
+ public Formula getMainFormula() {
+ return mMainFormula;
+ }
+
+ public Formula getAuxiliaryFormula() {
+ return mAuxiliaryFormula;
+ }
+
+ private void validateAuxiliaryFormula(Connector connector, Formula auxiliaryFormula) {
+ boolean validAuxiliaryFormula;
+ switch (connector) {
+ case AND:
+ case OR:
+ validAuxiliaryFormula = (auxiliaryFormula != null);
+ break;
+ case NOT:
+ validAuxiliaryFormula = (auxiliaryFormula == null);
+ break;
+ default:
+ validAuxiliaryFormula = false;
+ }
+ if (!validAuxiliaryFormula) {
+ throw new IllegalArgumentException(
+ String.format("Invalid formulas used for connector %s", connector));
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/model/Rule.java b/services/core/java/com/android/server/integrity/model/Rule.java
new file mode 100644
index 0000000..4fd40c1
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/Rule.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 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.server.integrity.model;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+/**
+ * Represent rules to be used in the rule evaluation engine to match against app installs.
+ *
+ * <p>Instances of this class are immutable.
+ */
+public final class Rule {
+
+ enum Effect {
+ DENY
+ }
+
+ // Holds an empty rule instance.
+ public static final Rule EMPTY = new Rule();
+
+ private final Formula mFormula;
+ private final Effect mEffect;
+
+ private Rule() {
+ this.mFormula = null;
+ this.mEffect = null;
+ }
+
+ public Rule(Formula formula, Effect effect) {
+ this.mFormula = checkNotNull(formula);
+ this.mEffect = checkNotNull(effect);
+ }
+
+ /**
+ * Indicates whether the rule is empty or not.
+ *
+ * @return {@code true} if the rule is empty, and {@code false} otherwise.
+ */
+ public boolean isEmpty() {
+ return mFormula == null && mEffect == null;
+ }
+
+ public Formula getFormula() {
+ return mFormula;
+ }
+
+ public Effect getEffect() {
+ return mEffect;
+ }
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 378d9eb..bad484f 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -61,7 +61,10 @@
import android.database.sqlite.SQLiteDatabase;
import android.hardware.authsecret.V1_0.IAuthSecret;
import android.hardware.biometrics.BiometricManager;
+import android.hardware.face.Face;
import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.Fingerprint;
+import android.hardware.fingerprint.FingerprintManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -117,6 +120,7 @@
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.server.LocalServices;
+import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
import com.android.server.locksettings.LockSettingsStorage.PersistentData;
@@ -387,8 +391,15 @@
return mContext;
}
- public Handler getHandler() {
- return new Handler();
+ public ServiceThread getServiceThread() {
+ ServiceThread handlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
+ true /*allowIo*/);
+ handlerThread.start();
+ return handlerThread;
+ }
+
+ public Handler getHandler(ServiceThread handlerThread) {
+ return new Handler(handlerThread.getLooper());
}
public LockSettingsStorage getStorage() {
@@ -483,6 +494,23 @@
public boolean isGsiRunning() {
return SystemProperties.getInt(GSI_RUNNING_PROP, 0) > 0;
}
+
+ public FingerprintManager getFingerprintManager() {
+ if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+ return (FingerprintManager) mContext.getSystemService(Context.FINGERPRINT_SERVICE);
+ } else {
+ return null;
+ }
+ }
+
+ public FaceManager getFaceManager() {
+ if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
+ return (FaceManager) mContext.getSystemService(Context.FACE_SERVICE);
+ } else {
+ return null;
+ }
+ }
+
}
public LockSettingsService(Context context) {
@@ -495,7 +523,7 @@
mContext = injector.getContext();
mKeyStore = injector.getKeyStore();
mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager(mKeyStore);
- mHandler = injector.getHandler();
+ mHandler = injector.getHandler(injector.getServiceThread());
mStrongAuth = injector.getStrongAuth();
mActivityManager = injector.getActivityManager();
@@ -2713,6 +2741,7 @@
fixateNewestUserKeyAuth(userId);
unlockKeystore(auth.deriveKeyStorePassword(), userId);
setKeystorePassword(null, userId);
+ removeBiometricsForUser(userId);
}
setSyntheticPasswordHandleLocked(newHandle, userId);
synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
@@ -2728,6 +2757,85 @@
return newHandle;
}
+ private void removeBiometricsForUser(int userId) {
+ removeAllFingerprintForUser(userId);
+ removeAllFaceForUser(userId);
+ }
+
+ private void removeAllFingerprintForUser(final int userId) {
+ FingerprintManager mFingerprintManager = mInjector.getFingerprintManager();
+ if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
+ if (mFingerprintManager.hasEnrolledFingerprints(userId)) {
+ mFingerprintManager.setActiveUser(userId);
+ CountDownLatch latch = new CountDownLatch(1);
+ // For the purposes of M and N, groupId is the same as userId.
+ Fingerprint finger = new Fingerprint(null, userId, 0, 0);
+ mFingerprintManager.remove(finger, userId,
+ fingerprintManagerRemovalCallback(latch));
+ try {
+ latch.await(10000, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Slog.e(TAG, "Latch interrupted when removing fingerprint", e);
+ }
+ }
+ }
+ }
+
+ private void removeAllFaceForUser(final int userId) {
+ FaceManager mFaceManager = mInjector.getFaceManager();
+ if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
+ if (mFaceManager.hasEnrolledTemplates(userId)) {
+ mFaceManager.setActiveUser(userId);
+ CountDownLatch latch = new CountDownLatch(1);
+ Face face = new Face(null, 0, 0);
+ mFaceManager.remove(face, userId, faceManagerRemovalCallback(latch));
+ try {
+ latch.await(10000, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Slog.e(TAG, "Latch interrupted when removing face", e);
+ }
+ }
+ }
+ }
+
+ private FingerprintManager.RemovalCallback fingerprintManagerRemovalCallback(
+ CountDownLatch latch) {
+ return new FingerprintManager.RemovalCallback() {
+ @Override
+ public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence err) {
+ Slog.e(TAG, String.format(
+ "Can't remove fingerprint %d in group %d. Reason: %s",
+ fp.getBiometricId(), fp.getGroupId(), err));
+ latch.countDown();
+ }
+
+ @Override
+ public void onRemovalSucceeded(Fingerprint fp, int remaining) {
+ if (remaining == 0) {
+ latch.countDown();
+ }
+ }
+ };
+ }
+
+ private FaceManager.RemovalCallback faceManagerRemovalCallback(CountDownLatch latch) {
+ return new FaceManager.RemovalCallback() {
+ @Override
+ public void onRemovalError(Face face, int errMsgId, CharSequence err) {
+ Slog.e(TAG, String.format("Can't remove face %d. Reason: %s",
+ face.getBiometricId(), err));
+ latch.countDown();
+ }
+
+ @Override
+ public void onRemovalSucceeded(Face face, int remaining) {
+ if (remaining == 0) {
+ latch.countDown();
+ }
+ }
+ };
+ }
+
@GuardedBy("mSpManager")
private boolean spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType,
byte[] savedCredential, int requestedQuality, int userId,
diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING
index c1cba5f..56f5cc0 100644
--- a/services/core/java/com/android/server/locksettings/TEST_MAPPING
+++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit": [
+ "presubmit-devicepolicy": [
{
"name": "CtsDevicePolicyManagerTestCases",
"options": [
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 043c834..668f2be 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -26,6 +26,7 @@
import android.content.pm.PackageManager;
import android.media.IMediaRouter2Client;
import android.media.IMediaRouter2Manager;
+import android.media.IMediaRouterClient;
import android.media.MediaRoute2Info;
import android.media.MediaRoute2ProviderInfo;
import android.os.Binder;
@@ -86,7 +87,7 @@
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- registerClientLocked(client, uid, pid, packageName, userId, trusted);
+ registerClient2Locked(client, uid, pid, packageName, userId, trusted);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -99,7 +100,7 @@
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- unregisterClientLocked(client, false);
+ unregisterClient2Locked(client, false);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -155,14 +156,30 @@
}
}
- public void setControlCategories(@NonNull IMediaRouter2Client client,
+ //TODO: What would happen if a media app used MediaRouter and MediaRouter2 simultaneously?
+ public void setControlCategories(@NonNull IMediaRouterClient client,
+ @Nullable List<String> categories) {
+ Objects.requireNonNull(client, "client must not be null");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
+ setControlCategoriesLocked(clientRecord, categories);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ public void setControlCategories2(@NonNull IMediaRouter2Client client,
@Nullable List<String> categories) {
Objects.requireNonNull(client, "client must not be null");
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- setControlCategoriesLocked(client, categories);
+ ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
+ setControlCategoriesLocked(clientRecord, categories);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -174,7 +191,7 @@
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- selectRoute2Locked(client, route);
+ selectRoute2Locked(mAllClientRecords.get(client.asBinder()), route);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -193,6 +210,36 @@
}
}
+ public void registerClient(@NonNull IMediaRouterClient client, @NonNull String packageName) {
+ Objects.requireNonNull(client, "client must not be null");
+
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
+ final int userId = UserHandle.getUserId(uid);
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ registerClient1Locked(client, packageName, userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ public void unregisterClient(@NonNull IMediaRouterClient client) {
+ Objects.requireNonNull(client, "client must not be null");
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ unregisterClient1Locked(client);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
//TODO: Review this is handling multi-user properly.
void switchUser() {
synchronized (mLock) {
@@ -217,9 +264,9 @@
}
}
- void clientDied(ClientRecord clientRecord) {
+ void clientDied(Client2Record clientRecord) {
synchronized (mLock) {
- unregisterClientLocked(clientRecord.mClient, true);
+ unregisterClient2Locked(clientRecord.mClient, true);
}
}
@@ -229,18 +276,18 @@
}
}
- private void registerClientLocked(IMediaRouter2Client client,
+ private void registerClient2Locked(IMediaRouter2Client client,
int uid, int pid, String packageName, int userId, boolean trusted) {
final IBinder binder = client.asBinder();
- ClientRecord clientRecord = mAllClientRecords.get(binder);
- if (clientRecord == null) {
+ if (mAllClientRecords.get(binder) == null) {
boolean newUser = false;
UserRecord userRecord = mUserRecords.get(userId);
if (userRecord == null) {
userRecord = new UserRecord(userId);
newUser = true;
}
- clientRecord = new ClientRecord(userRecord, client, uid, pid, packageName, trusted);
+ Client2Record clientRecord = new Client2Record(userRecord, client, uid, pid,
+ packageName, trusted);
try {
binder.linkToDeath(clientRecord, 0);
} catch (RemoteException ex) {
@@ -261,8 +308,8 @@
}
}
- private void unregisterClientLocked(IMediaRouter2Client client, boolean died) {
- ClientRecord clientRecord = mAllClientRecords.remove(client.asBinder());
+ private void unregisterClient2Locked(IMediaRouter2Client client, boolean died) {
+ Client2Record clientRecord = (Client2Record) mAllClientRecords.remove(client.asBinder());
if (clientRecord != null) {
UserRecord userRecord = clientRecord.mUserRecord;
userRecord.mClientRecords.remove(clientRecord);
@@ -272,8 +319,7 @@
}
}
- private void selectRoute2Locked(IMediaRouter2Client client, MediaRoute2Info route) {
- ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
+ private void selectRoute2Locked(ClientRecord clientRecord, MediaRoute2Info route) {
if (clientRecord != null) {
MediaRoute2Info oldRoute = clientRecord.mSelectedRoute;
clientRecord.mSelectedRoute = route;
@@ -294,10 +340,7 @@
}
}
- private void setControlCategoriesLocked(IMediaRouter2Client client, List<String> categories) {
- final IBinder binder = client.asBinder();
- ClientRecord clientRecord = mAllClientRecords.get(binder);
-
+ private void setControlCategoriesLocked(ClientRecord clientRecord, List<String> categories) {
if (clientRecord != null) {
clientRecord.mControlCategories = categories;
@@ -349,9 +392,7 @@
obtainMessage(UserHandler::notifyProviderInfosUpdatedToManager,
userRecord.mHandler, manager));
- final int count = userRecord.mClientRecords.size();
- for (int i = 0; i < count; i++) {
- ClientRecord clientRecord = userRecord.mClientRecords.get(i);
+ for (ClientRecord clientRecord : userRecord.mClientRecords) {
clientRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::updateClientUsage,
clientRecord.mUserRecord.mHandler, clientRecord));
@@ -378,7 +419,7 @@
Slog.w(TAG, "Ignoring route selection for unknown client.");
}
if (clientRecord != null && managerRecord.mTrusted) {
- selectRoute2Locked(clientRecord.mClient, route);
+ selectRoute2Locked(clientRecord, route);
}
}
}
@@ -409,6 +450,37 @@
}
}
+ private void registerClient1Locked(IMediaRouterClient client, String packageName,
+ int userId) {
+ final IBinder binder = client.asBinder();
+ if (mAllClientRecords.get(binder) == null) {
+ boolean newUser = false;
+ UserRecord userRecord = mUserRecords.get(userId);
+ if (userRecord == null) {
+ userRecord = new UserRecord(userId);
+ newUser = true;
+ }
+ ClientRecord clientRecord = new Client1Record(userRecord, client, packageName);
+
+ if (newUser) {
+ mUserRecords.put(userId, userRecord);
+ initializeUserLocked(userRecord);
+ }
+
+ userRecord.mClientRecords.add(clientRecord);
+ mAllClientRecords.put(binder, clientRecord);
+ }
+ }
+
+ private void unregisterClient1Locked(IMediaRouterClient client) {
+ ClientRecord clientRecord = mAllClientRecords.remove(client.asBinder());
+ if (clientRecord != null) {
+ UserRecord userRecord = clientRecord.mUserRecord;
+ userRecord.mClientRecords.remove(clientRecord);
+ disposeUserIfNeededLocked(userRecord);
+ }
+ }
+
final class UserRecord {
public final int mUserId;
final ArrayList<ClientRecord> mClientRecords = new ArrayList<>();
@@ -430,25 +502,43 @@
}
}
- final class ClientRecord implements IBinder.DeathRecipient {
+ class ClientRecord {
public final UserRecord mUserRecord;
- public final IMediaRouter2Client mClient;
- public final int mUid;
- public final int mPid;
public final String mPackageName;
- public final boolean mTrusted;
public List<String> mControlCategories;
public MediaRoute2Info mSelectedRoute;
- ClientRecord(UserRecord userRecord, IMediaRouter2Client client,
- int uid, int pid, String packageName, boolean trusted) {
+ ClientRecord(UserRecord userRecord, String packageName) {
mUserRecord = userRecord;
+ mPackageName = packageName;
+ mControlCategories = Collections.emptyList();
+ }
+ }
+
+ final class Client1Record extends ClientRecord {
+ public final IMediaRouterClient mClient;
+
+ Client1Record(UserRecord userRecord, IMediaRouterClient client,
+ String packageName) {
+ super(userRecord, packageName);
+ mClient = client;
+ }
+ }
+
+ final class Client2Record extends ClientRecord
+ implements IBinder.DeathRecipient {
+ public final IMediaRouter2Client mClient;
+ public final int mUid;
+ public final int mPid;
+ public final boolean mTrusted;
+
+ Client2Record(UserRecord userRecord, IMediaRouter2Client client,
+ int uid, int pid, String packageName, boolean trusted) {
+ super(userRecord, packageName);
mClient = client;
mUid = uid;
mPid = pid;
- mPackageName = packageName;
mTrusted = trusted;
- mControlCategories = Collections.emptyList();
}
public void dispose() {
@@ -622,7 +712,9 @@
managers.add(managerRecord.mManager);
}
for (ClientRecord clientRecord : mUserRecord.mClientRecords) {
- clients.add(clientRecord.mClient);
+ if (clientRecord instanceof Client2Record) {
+ clients.add(((Client2Record) clientRecord).mClient);
+ }
}
}
for (IMediaRouter2Manager manager : managers) {
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 2670cd8..796a25d 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -249,6 +249,7 @@
synchronized (mLock) {
registerClientLocked(client, uid, pid, packageName, resolvedUserId, trusted);
}
+ mService2.registerClient(client, packageName);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -289,6 +290,7 @@
synchronized (mLock) {
unregisterClientLocked(client, false);
}
+ mService2.unregisterClient(client);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -395,6 +397,12 @@
// Binder call
@Override
+ public void setControlCategories(IMediaRouterClient client, List<String> controlCategories) {
+ mService2.setControlCategories(client, controlCategories);
+ }
+
+ // Binder call
+ @Override
public void requestUpdateVolume(IMediaRouterClient client, String routeId, int direction) {
if (client == null) {
throw new IllegalArgumentException("client must not be null");
@@ -487,8 +495,8 @@
// Binder call
@Override
- public void setControlCategories(IMediaRouter2Client client, List<String> categories) {
- mService2.setControlCategories(client, categories);
+ public void setControlCategories2(IMediaRouter2Client client, List<String> categories) {
+ mService2.setControlCategories2(client, categories);
}
void restoreBluetoothA2dp() {
@@ -561,6 +569,7 @@
synchronized (mLock) {
unregisterClientLocked(clientRecord.mClient, true);
}
+ mService2.unregisterClient(clientRecord.mClient);
}
private void registerClientLocked(IMediaRouterClient client,
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 48b0fd6..8560ae6 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -185,7 +185,7 @@
}
protected void addDefaultComponentOrPackage(String packageOrComponent) {
- if (packageOrComponent != null) {
+ if (!TextUtils.isEmpty(packageOrComponent)) {
synchronized (mDefaultsLock) {
ComponentName cn = ComponentName.unflattenFromString(packageOrComponent);
if (cn == null) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
old mode 100644
new mode 100755
index d480cb6e..5039566
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -94,7 +94,6 @@
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
-import static com.android.server.notification.PreferencesHelper.DEFAULT_ALLOW_BUBBLE;
import static com.android.server.utils.PriorityDump.PRIORITY_ARG;
import static com.android.server.utils.PriorityDump.PRIORITY_ARG_CRITICAL;
import static com.android.server.utils.PriorityDump.PRIORITY_ARG_NORMAL;
@@ -523,7 +522,6 @@
}
-
void loadDefaultApprovedServices(int userId) {
String defaultListenerAccess = getContext().getResources().getString(
com.android.internal.R.string.config_defaultListenerAccessPackages);
@@ -531,6 +529,9 @@
String[] listeners =
defaultListenerAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR);
for (int i = 0; i < listeners.length; i++) {
+ if (TextUtils.isEmpty(listeners[i])) {
+ continue;
+ }
ArraySet<ComponentName> approvedListeners =
mListeners.queryPackageForServices(listeners[i],
MATCH_DIRECT_BOOT_AWARE
@@ -547,6 +548,9 @@
if (defaultDndAccess != null) {
String[] dnds = defaultDndAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR);
for (int i = 0; i < dnds.length; i++) {
+ if (TextUtils.isEmpty(dnds[i])) {
+ continue;
+ }
mConditionProviders.addDefaultComponentOrPackage(dnds[i]);
}
}
@@ -565,12 +569,14 @@
.split(ManagedServices.ENABLED_SERVICES_SEPARATOR)));
for (int i = 0; i < assistants.size(); i++) {
String cnString = assistants.valueAt(i);
+ if (TextUtils.isEmpty(cnString)) {
+ continue;
+ }
mAssistants.addDefaultComponentOrPackage(cnString);
}
}
protected void allowDefaultApprovedServices(int userId) {
-
ArraySet<ComponentName> defaultListeners = mListeners.getDefaultComponents();
for (int i = 0; i < defaultListeners.size(); i++) {
ComponentName cn = defaultListeners.valueAt(i);
@@ -1331,16 +1337,15 @@
uidList = new int[] {intent.getIntExtra(Intent.EXTRA_UID, -1)};
}
if (pkgList != null && (pkgList.length > 0)) {
- for (String pkgName : pkgList) {
- if (cancelNotifications) {
+ if (cancelNotifications) {
+ for (String pkgName : pkgList) {
cancelAllNotificationsInt(MY_UID, MY_PID, pkgName, null, 0, 0,
!queryRestart, changeUserId, reason, null);
- } else if (hideNotifications) {
- hideNotificationsForPackages(pkgList);
- } else if (unhideNotifications) {
- unhideNotificationsForPackages(pkgList);
}
-
+ } else if (hideNotifications) {
+ hideNotificationsForPackages(pkgList);
+ } else if (unhideNotifications) {
+ unhideNotificationsForPackages(pkgList);
}
}
@@ -1429,10 +1434,8 @@
private final class SettingsObserver extends ContentObserver {
private final Uri NOTIFICATION_BADGING_URI
= Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BADGING);
- private final Uri NOTIFICATION_BUBBLES_URI_GLOBAL
+ private final Uri NOTIFICATION_BUBBLES_URI
= Settings.Global.getUriFor(Settings.Global.NOTIFICATION_BUBBLES);
- private final Uri NOTIFICATION_BUBBLES_URI_SECURE
- = Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BUBBLES);
private final Uri NOTIFICATION_LIGHT_PULSE_URI
= Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
private final Uri NOTIFICATION_RATE_LIMIT_URI
@@ -1450,9 +1453,7 @@
false, this, UserHandle.USER_ALL);
resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI,
false, this, UserHandle.USER_ALL);
- resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI_GLOBAL,
- false, this, UserHandle.USER_ALL);
- resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI_SECURE,
+ resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI,
false, this, UserHandle.USER_ALL);
update(null);
}
@@ -1479,41 +1480,9 @@
if (uri == null || NOTIFICATION_BADGING_URI.equals(uri)) {
mPreferencesHelper.updateBadgingEnabled();
}
- // In QPR we moved the setting to Global rather than Secure so that the setting
- // applied to work profiles. Unfortunately we need to maintain both to pass CTS without
- // a change to CTS outside of a normal letter release.
- if (uri == null || NOTIFICATION_BUBBLES_URI_GLOBAL.equals(uri)) {
- syncBubbleSettings(resolver, NOTIFICATION_BUBBLES_URI_GLOBAL);
+ if (uri == null || NOTIFICATION_BUBBLES_URI.equals(uri)) {
mPreferencesHelper.updateBubblesEnabled();
}
- if (NOTIFICATION_BUBBLES_URI_SECURE.equals(uri)) {
- syncBubbleSettings(resolver, NOTIFICATION_BUBBLES_URI_SECURE);
- }
- }
-
- private void syncBubbleSettings(ContentResolver resolver, Uri settingToFollow) {
- boolean followSecureSetting = settingToFollow.equals(NOTIFICATION_BUBBLES_URI_SECURE);
-
- int secureSettingValue = Settings.Secure.getInt(resolver,
- Settings.Secure.NOTIFICATION_BUBBLES, DEFAULT_ALLOW_BUBBLE ? 1 : 0);
- int globalSettingValue = Settings.Global.getInt(resolver,
- Settings.Global.NOTIFICATION_BUBBLES, DEFAULT_ALLOW_BUBBLE ? 1 : 0);
-
- if (globalSettingValue == secureSettingValue) {
- return;
- }
-
- if (followSecureSetting) {
- // Global => secure
- Settings.Global.putInt(resolver,
- Settings.Global.NOTIFICATION_BUBBLES,
- secureSettingValue);
- } else {
- // Secure => Global
- Settings.Secure.putInt(resolver,
- Settings.Secure.NOTIFICATION_BADGING,
- globalSettingValue);
- }
}
}
@@ -5045,12 +5014,13 @@
final int contentViewSize = contentView.estimateMemoryUsage();
if (contentViewSize > mWarnRemoteViewsSizeBytes
&& contentViewSize < mStripRemoteViewsSizeBytes) {
- Slog.w(TAG, "RemoteViews too large on tag: " + tag + " id: " + id
+ Slog.w(TAG, "RemoteViews too large on pkg: " + pkg + " tag: " + tag + " id: " + id
+ " this might be stripped in a future release");
}
if (contentViewSize >= mStripRemoteViewsSizeBytes) {
mUsageStats.registerImageRemoved(pkg);
- Slog.w(TAG, "Removed too large RemoteViews on tag: " + tag + " id: " + id);
+ Slog.w(TAG,
+ "Removed too large RemoteViews on pkg: " + pkg + " tag: " + tag + " id: " + id);
return true;
}
return false;
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 83bea9d..9e7b4648 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -738,6 +738,25 @@
}
@Override
+ public void invalidateCachesForOverlay(@Nullable String packageName, int userId)
+ throws RemoteException {
+ if (packageName == null) {
+ return;
+ }
+
+ enforceChangeOverlayPackagesPermission("invalidateCachesForOverlay");
+ userId = handleIncomingUser(userId, "invalidateCachesForOverlay");
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ mImpl.removeIdmapForOverlay(packageName, userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
public void onShellCommand(@NonNull final FileDescriptor in,
@NonNull final FileDescriptor out, @NonNull final FileDescriptor err,
@NonNull final String[] args, @NonNull final ShellCallback callback,
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 934511b..019c952 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -651,6 +651,11 @@
return mDefaultOverlays;
}
+ void removeIdmapForOverlay(String packageName, int userId) {
+ final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
+ removeIdmapIfPossible(oi);
+ }
+
List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName,
final int userId) {
final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName,
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 8b24224..a7d4237 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -259,6 +259,10 @@
// Don't hold mSessions lock when calling restoreSession, since it might trigger an APK
// atomic install which needs to query sessions, which requires lock on mSessions.
for (PackageInstallerSession session : stagedSessionsToRestore) {
+ if (mPm.isDeviceUpgrading()) {
+ session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
+ "Build fingerprint has changed");
+ }
mStagingManager.restoreSession(session);
}
// Broadcasts are not sent while we restore sessions on boot, since no processes would be
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 5bf484b..b85009b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -13212,9 +13212,11 @@
* @return verification timeout in milliseconds
*/
private long getVerificationTimeout() {
- return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
- android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
- DEFAULT_VERIFICATION_TIMEOUT);
+ long timeout = Global.getLong(mContext.getContentResolver(),
+ Global.PACKAGE_VERIFIER_TIMEOUT, DEFAULT_VERIFICATION_TIMEOUT);
+ // The setting can be used to increase the timeout but not decrease it, since that is
+ // equivalent to disabling the verifier.
+ return Math.max(timeout, DEFAULT_VERIFICATION_TIMEOUT);
}
/**
@@ -19980,7 +19982,11 @@
}
}
synchronized (mLock) {
- scheduleWritePackageRestrictionsLocked(userId);
+ if ((flags & PackageManager.SYNCHRONOUS) != 0) {
+ flushPackageRestrictionsAsUserInternalLocked(userId);
+ } else {
+ scheduleWritePackageRestrictionsLocked(userId);
+ }
updateSequenceNumberLP(pkgSetting, new int[] { userId });
final long callingId = Binder.clearCallingIdentity();
try {
@@ -20041,11 +20047,16 @@
mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
false /* checkShell */, "flushPackageRestrictions");
synchronized (mLock) {
- mSettings.writePackageRestrictionsLPr(userId);
- mDirtyUsers.remove(userId);
- if (mDirtyUsers.isEmpty()) {
- mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
- }
+ flushPackageRestrictionsAsUserInternalLocked(userId);
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void flushPackageRestrictionsAsUserInternalLocked(int userId) {
+ mSettings.writePackageRestrictionsLPr(userId);
+ mDirtyUsers.remove(userId);
+ if (mDirtyUsers.isEmpty()) {
+ mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
}
}
@@ -20255,7 +20266,7 @@
mInjector.getPermissionPolicyInternal();
permissionPolicyInternal.setOnInitializedCallback(userId -> {
// The SDK updated case is already handled when we run during the ctor.
- synchronized (mPackages) {
+ synchronized (mLock) {
mPermissionManager.updateAllPermissions(
StorageManager.UUID_PRIVATE_INTERNAL, false);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 944aefb..1c1c947 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -751,7 +751,7 @@
(!listThirdParty || !isSystem) &&
(!listApexOnly || isApex)) {
pw.print("package:");
- if (showSourceDir && !isApex) {
+ if (showSourceDir) {
pw.print(info.applicationInfo.sourceDir);
pw.print("=");
}
@@ -2415,6 +2415,7 @@
int userId = -1;
int flags = 0;
String opt;
+ boolean preCreateOnly = false;
while ((opt = getNextOption()) != null) {
if ("--profileOf".equals(opt)) {
userId = UserHandle.parseUserArg(getNextArgRequired());
@@ -2428,6 +2429,8 @@
flags |= UserInfo.FLAG_GUEST;
} else if ("--demo".equals(opt)) {
flags |= UserInfo.FLAG_DEMO;
+ } else if ("--pre-create-only".equals(opt)) {
+ preCreateOnly = true;
} else {
getErrPrintWriter().println("Error: unknown option " + opt);
return 1;
@@ -2451,7 +2454,7 @@
accm.addSharedAccountsFromParentUser(parentUserId, userId,
(Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
} else if (userId < 0) {
- info = um.createUser(name, flags);
+ info = preCreateOnly ? um.preCreateUser(flags) : um.createUser(name, flags);
} else {
info = um.createProfileForUser(name, flags, userId, null);
}
@@ -3364,8 +3367,11 @@
pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]");
pw.println(" Trim cache files to reach the given free space.");
pw.println("");
+ pw.println(" list users");
+ pw.println(" Lists the current users.");
+ pw.println("");
pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
- pw.println(" [--guest] USER_NAME");
+ pw.println(" [--guest] [--pre-create-only] USER_NAME");
pw.println(" Create a new user with the given USER_NAME, printing the new user identifier");
pw.println(" of the user.");
pw.println("");
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index dace598..95baa01 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -41,6 +41,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ShortcutServiceInternal;
import android.content.pm.UserInfo;
+import android.content.pm.UserInfo.UserInfoFlag;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.os.Binder;
@@ -158,6 +159,7 @@
private static final String ATTR_SERIAL_NO = "serialNumber";
private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
private static final String ATTR_PARTIAL = "partial";
+ private static final String ATTR_PRE_CREATED = "preCreated";
private static final String ATTR_GUEST_TO_REMOVE = "guestToRemove";
private static final String ATTR_USER_VERSION = "version";
private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId";
@@ -207,7 +209,8 @@
| UserInfo.FLAG_DEMO;
@VisibleForTesting
- static final int MIN_USER_ID = 10;
+ static final int MIN_USER_ID = UserHandle.MIN_SECONDARY_USER_ID;
+
// We need to keep process uid within Integer.MAX_VALUE.
@VisibleForTesting
static final int MAX_USER_ID = Integer.MAX_VALUE / UserHandle.PER_USER_RANGE;
@@ -597,7 +600,8 @@
final int userSize = mUsers.size();
for (int i = 0; i < userSize; i++) {
UserInfo ui = mUsers.valueAt(i).info;
- if ((ui.partial || ui.guestToRemove || ui.isEphemeral()) && i != 0) {
+ if ((ui.partial || ui.guestToRemove || (ui.isEphemeral() && !ui.preCreated))
+ && i != 0) {
partials.add(ui);
addRemovingUserIdLocked(ui.id);
ui.partial = true;
@@ -660,20 +664,25 @@
return null;
}
- @Override
public @NonNull List<UserInfo> getUsers(boolean excludeDying) {
+ return getUsers(/*excludePartial= */ true, excludeDying, /* excludePreCreated= */ true);
+ }
+
+ @Override
+ public @NonNull List<UserInfo> getUsers(boolean excludePartial, boolean excludeDying,
+ boolean excludePreCreated) {
checkManageOrCreateUsersPermission("query users");
synchronized (mUsersLock) {
ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
final int userSize = mUsers.size();
for (int i = 0; i < userSize; i++) {
UserInfo ui = mUsers.valueAt(i).info;
- if (ui.partial) {
+ if ((excludePartial && ui.partial)
+ || (excludeDying && mRemovingUserIds.get(ui.id))
+ || (excludePreCreated && ui.preCreated)) {
continue;
}
- if (!excludeDying || !mRemovingUserIds.get(ui.id)) {
- users.add(userWithName(ui));
- }
+ users.add(userWithName(ui));
}
return users;
}
@@ -1196,7 +1205,7 @@
private void checkManageOrInteractPermIfCallerInOtherProfileGroup(@UserIdInt int userId,
String name) {
- int callingUserId = UserHandle.getCallingUserId();
+ final int callingUserId = UserHandle.getCallingUserId();
if (callingUserId == userId || isSameProfileGroupNoChecks(callingUserId, userId) ||
hasManageUsersPermission()) {
return;
@@ -1210,7 +1219,7 @@
@Override
public boolean isDemoUser(@UserIdInt int userId) {
- int callingUserId = UserHandle.getCallingUserId();
+ final int callingUserId = UserHandle.getCallingUserId();
if (callingUserId != userId && !hasManageUsersPermission()) {
throw new SecurityException("You need MANAGE_USERS permission to query if u=" + userId
+ " is a demo user");
@@ -1222,6 +1231,19 @@
}
@Override
+ public boolean isPreCreated(@UserIdInt int userId) {
+ final int callingUserId = UserHandle.getCallingUserId();
+ if (callingUserId != userId && !hasManageUsersPermission()) {
+ throw new SecurityException("You need MANAGE_USERS permission to query if u=" + userId
+ + " is pre-created");
+ }
+ synchronized (mUsersLock) {
+ UserInfo userInfo = getUserInfoLU(userId);
+ return userInfo != null && userInfo.preCreated;
+ }
+ }
+
+ @Override
public boolean isRestricted() {
synchronized (mUsersLock) {
return getUserInfoLU(UserHandle.getCallingUserId()).isRestricted();
@@ -1871,7 +1893,7 @@
// Skip over users being removed
for (int i = 0; i < totalUserCount; i++) {
UserInfo user = mUsers.valueAt(i).info;
- if (!mRemovingUserIds.get(user.id) && !user.isGuest()) {
+ if (!mRemovingUserIds.get(user.id) && !user.isGuest() && !user.preCreated) {
aliveUserCount++;
}
}
@@ -2362,6 +2384,9 @@
if (userInfo.partial) {
serializer.attribute(null, ATTR_PARTIAL, "true");
}
+ if (userInfo.preCreated) {
+ serializer.attribute(null, ATTR_PRE_CREATED, "true");
+ }
if (userInfo.guestToRemove) {
serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true");
}
@@ -2518,6 +2543,7 @@
int profileBadge = 0;
int restrictedProfileParentId = UserInfo.NO_PROFILE_GROUP_ID;
boolean partial = false;
+ boolean preCreated = false;
boolean guestToRemove = false;
boolean persistSeedData = false;
String seedAccountName = null;
@@ -2562,6 +2588,10 @@
if ("true".equals(valueString)) {
partial = true;
}
+ valueString = parser.getAttributeValue(null, ATTR_PRE_CREATED);
+ if ("true".equals(valueString)) {
+ preCreated = true;
+ }
valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE);
if ("true".equals(valueString)) {
guestToRemove = true;
@@ -2615,6 +2645,7 @@
userInfo.lastLoggedInTime = lastLoggedInTime;
userInfo.lastLoggedInFingerprint = lastLoggedInFingerprint;
userInfo.partial = partial;
+ userInfo.preCreated = preCreated;
userInfo.guestToRemove = guestToRemove;
userInfo.profileGroupId = profileGroupId;
userInfo.profileBadge = profileBadge;
@@ -2686,7 +2717,8 @@
public UserInfo createProfileForUserEvenWhenDisallowed(String name, int flags,
@UserIdInt int userId, String[] disallowedPackages) {
checkManageOrCreateUsersPermission(flags);
- return createUserInternalUnchecked(name, flags, userId, disallowedPackages);
+ return createUserInternalUnchecked(name, flags, userId, /* preCreate= */ false,
+ disallowedPackages);
}
@Override
@@ -2701,12 +2733,27 @@
return createUserInternal(name, flags, UserHandle.USER_NULL);
}
- private UserInfo createUserInternal(String name, int flags, int parentId) {
+ @Override
+ public UserInfo preCreateUser(int flags) {
+ checkManageOrCreateUsersPermission(flags);
+
+ Preconditions.checkArgument(!UserInfo.isManagedProfile(flags),
+ "cannot pre-create managed profiles");
+
+ Slog.i(LOG_TAG, "Pre-creating user with flags " + UserInfo.flagsToString(flags));
+
+ return createUserInternalUnchecked(/* name= */ null, flags,
+ /* parentId= */ UserHandle.USER_NULL, /* preCreate= */ true,
+ /* disallowedPackages= */ null);
+ }
+
+ private UserInfo createUserInternal(@Nullable String name, @UserInfoFlag int flags,
+ @UserIdInt int parentId) {
return createUserInternal(name, flags, parentId, null);
}
- private UserInfo createUserInternal(String name, int flags, int parentId,
- String[] disallowedPackages) {
+ private UserInfo createUserInternal(@Nullable String name, @UserInfoFlag int flags,
+ @UserIdInt int parentId, @Nullable String[] disallowedPackages) {
String restriction = ((flags & UserInfo.FLAG_MANAGED_PROFILE) != 0)
? UserManager.DISALLOW_ADD_MANAGED_PROFILE
: UserManager.DISALLOW_ADD_USER;
@@ -2714,21 +2761,56 @@
Log.w(LOG_TAG, "Cannot add user. " + restriction + " is enabled.");
return null;
}
- return createUserInternalUnchecked(name, flags, parentId, disallowedPackages);
+ return createUserInternalUnchecked(name, flags, parentId, /* preCreate= */ false,
+ disallowedPackages);
}
- private UserInfo createUserInternalUnchecked(@Nullable String name, int flags,
- int parentId, @Nullable String[] disallowedPackages) {
- TimingsTraceAndSlog t = new TimingsTraceAndSlog();
- t.traceBegin("createUser");
- UserInfo userInfo =
- createUserInternalUncheckedNoTracing(name, flags, parentId, disallowedPackages, t);
- t.traceEnd();
- return userInfo;
+ private UserInfo createUserInternalUnchecked(@Nullable String name, @UserInfoFlag int flags,
+ @UserIdInt int parentId, boolean preCreate,
+ @Nullable String[] disallowedPackages) {
+ final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
+ t.traceBegin("createUser-" + flags);
+ try {
+ return createUserInternalUncheckedNoTracing(name, flags, parentId, preCreate,
+ disallowedPackages, t);
+ } finally {
+ t.traceEnd();
+ }
}
- private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name, int flags,
- int parentId, @Nullable String[] disallowedPackages, @NonNull TimingsTraceAndSlog t) {
+ private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name,
+ @UserInfoFlag int flags, @UserIdInt int parentId, boolean preCreate,
+ @Nullable String[] disallowedPackages, @NonNull TimingsTraceAndSlog t) {
+
+ // First try to use a pre-created user (if available).
+ // NOTE: currently we don't support pre-created managed profiles
+ if (!preCreate && (parentId < 0 && !UserInfo.isManagedProfile(flags))) {
+ final UserData preCreatedUserData;
+ synchronized (mUsersLock) {
+ preCreatedUserData = getPreCreatedUserLU(flags);
+ }
+ if (preCreatedUserData != null) {
+ final UserInfo preCreatedUser = preCreatedUserData.info;
+ Log.i(LOG_TAG, "Reusing pre-created user " + preCreatedUser.id + " for flags + "
+ + UserInfo.flagsToString(flags));
+ if (DBG) {
+ Log.d(LOG_TAG, "pre-created user flags: "
+ + UserInfo.flagsToString(preCreatedUser.flags)
+ + " new-user flags: " + UserInfo.flagsToString(flags));
+ }
+ preCreatedUser.name = name;
+ preCreatedUser.preCreated = false;
+ preCreatedUser.creationTime = getCreationTime();
+
+ dispatchUserAddedIntent(preCreatedUser);
+
+ writeUserLP(preCreatedUserData);
+ writeUserListLP();
+
+ return preCreatedUser;
+ }
+ }
+
DeviceStorageMonitorInternal dsm = LocalServices
.getService(DeviceStorageMonitorInternal.class);
if (dsm.isMemoryLow()) {
@@ -2736,8 +2818,8 @@
return null;
}
- final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;
- final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
+ final boolean isGuest = UserInfo.isGuest(flags);
+ final boolean isManagedProfile = UserInfo.isManagedProfile(flags);
final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;
final boolean isDemo = (flags & UserInfo.FLAG_DEMO) != 0;
final long ident = Binder.clearCallingIdentity();
@@ -2758,8 +2840,8 @@
return null;
}
if (!isGuest && !isManagedProfile && !isDemo && isUserLimitReached()) {
- // If we're not adding a guest/demo user or a managed profile and the limit has
- // been reached, cannot add a user.
+ // If we're not adding a guest/demo user or a managed profile,
+ // and the limit has been reached, cannot add a user.
Log.e(LOG_TAG, "Cannot add user. Maximum user limit is reached.");
return null;
}
@@ -2794,8 +2876,7 @@
userId = getNextAvailableId();
Environment.getUserSystemDirectory(userId).mkdirs();
- boolean ephemeralGuests = Resources.getSystem()
- .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
+ boolean ephemeralGuests = areGuestUsersEphemeral();
synchronized (mUsersLock) {
// Add ephemeral flag to guests/users if required. Also inherit it from parent.
@@ -2806,9 +2887,9 @@
userInfo = new UserInfo(userId, name, null, flags);
userInfo.serialNumber = mNextSerialNumber++;
- long now = System.currentTimeMillis();
- userInfo.creationTime = (now > EPOCH_PLUS_30_YEARS) ? now : 0;
+ userInfo.creationTime = getCreationTime();
userInfo.partial = true;
+ userInfo.preCreated = preCreate;
userInfo.lastLoggedInFingerprint = Build.FINGERPRINT;
if (isManagedProfile && parentId != UserHandle.USER_NULL) {
userInfo.profileBadge = getFreeProfileBadgeLU(parentId);
@@ -2869,17 +2950,40 @@
t.traceBegin("PM.onNewUserCreated");
mPm.onNewUserCreated(userId);
- t.traceEnd();
- Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
- addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
- android.Manifest.permission.MANAGE_USERS);
- MetricsLogger.count(mContext, isGuest ? TRON_GUEST_CREATED
- : (isDemo ? TRON_DEMO_CREATED : TRON_USER_CREATED), 1);
+ if (preCreate) {
+ // Must start user (which will be stopped right away, through
+ // UserController.finishUserUnlockedCompleted) so services can properly
+ // intialize it.
+ // TODO(b/140750212): in the long-term, we should add a onCreateUser() callback
+ // on SystemService instead.
+ Slog.i(LOG_TAG, "starting pre-created user " + userInfo.toFullString());
+ final IActivityManager am = ActivityManager.getService();
+ try {
+ am.startUserInBackground(userId);
+ } catch (RemoteException e) {
+ Slog.w(LOG_TAG, "could not start pre-created user " + userId, e);
+ }
+ } else {
+ dispatchUserAddedIntent(userInfo);
+ }
+
} finally {
Binder.restoreCallingIdentity(ident);
}
+
+ // TODO(b/140750212): it's possible to reach "max users overflow" when the user is created
+ // "from scratch" (i.e., not from a pre-created user) and reaches the maximum number of
+ // users without counting the pre-created one. Then when the pre-created is converted, the
+ // "effective" number of max users is exceeds. Example:
+ // Max: 3 Current: 2 full (u0 and u10) + 1 pre-created (u11)
+ // Step 1: create(/* flags doesn't match u11 */): u12 is created, "effective max" is now 3
+ // (u0, u10, u12) but "real" max is 4 (u0, u10, u11, u12)
+ // Step 2: create(/* flags match u11 */): u11 is converted, now "effective max" is also 4
+ // (u0, u10, u11, u12)
+ // One way to avoid this issue is by removing a pre-created user from the pool when the
+ // "real" max exceeds the max here.
+
return userInfo;
}
@@ -2888,6 +2992,62 @@
return mSystemPackageInstaller.installWhitelistedSystemPackages(isFirstBoot, isUpgrade);
}
+ private long getCreationTime() {
+ final long now = System.currentTimeMillis();
+ return (now > EPOCH_PLUS_30_YEARS) ? now : 0;
+ }
+
+ private void dispatchUserAddedIntent(@NonNull UserInfo userInfo) {
+ Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
+ addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id);
+ mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
+ android.Manifest.permission.MANAGE_USERS);
+ MetricsLogger.count(mContext, userInfo.isGuest() ? TRON_GUEST_CREATED
+ : (userInfo.isDemo() ? TRON_DEMO_CREATED : TRON_USER_CREATED), 1);
+ }
+
+ private boolean areGuestUsersEphemeral() {
+ return Resources.getSystem()
+ .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
+ }
+
+ /**
+ * Gets a pre-created user for the given flag.
+ *
+ * <p>Should be used only during user creation, so the pre-created user can be used (instead of
+ * creating and initializing a new user from scratch).
+ */
+ // TODO(b/140750212): add unit test
+ @GuardedBy("mUsersLock")
+ private @Nullable UserData getPreCreatedUserLU(@UserInfoFlag int flags) {
+ if (DBG) {
+ Slog.d(LOG_TAG, "getPreCreatedUser(): initialFlags= " + UserInfo.flagsToString(flags));
+ }
+ flags |= UserInfo.FLAG_FULL;
+ if (UserInfo.isGuest(flags) && areGuestUsersEphemeral()) {
+ flags |= UserInfo.FLAG_EPHEMERAL;
+ }
+ if (DBG) {
+ Slog.d(LOG_TAG, "getPreCreatedUser(): targetFlags= " + UserInfo.flagsToString(flags));
+ }
+ final int userSize = mUsers.size();
+ for (int i = 0; i < userSize; i++) {
+ final UserData user = mUsers.valueAt(i);
+ if (DBG) Slog.d(LOG_TAG, i + ":" + user.info.toFullString());
+ if (user.info.preCreated
+ && (user.info.flags & ~UserInfo.FLAG_INITIALIZED) == flags) {
+ if (!user.info.isInitialized()) {
+ Slog.w(LOG_TAG, "found pre-created user for flags "
+ + "" + UserInfo.flagsToString(flags)
+ + ", but it's not initialized yet: " + user.info.toFullString());
+ continue;
+ }
+ return user;
+ }
+ }
+ return null;
+ }
+
@VisibleForTesting
UserData putUserInfo(UserInfo userInfo) {
final UserData userData = new UserData();
@@ -3728,7 +3888,7 @@
try {
switch(cmd) {
case "list":
- return runList(pw);
+ return runList(pw, shell);
default:
return shell.handleDefaultCommands(cmd);
}
@@ -3738,17 +3898,58 @@
return -1;
}
- private int runList(PrintWriter pw) throws RemoteException {
+ private int runList(PrintWriter pw, Shell shell) throws RemoteException {
+ boolean all = false;
+ boolean verbose = false;
+ String opt;
+ while ((opt = shell.getNextOption()) != null) {
+ switch (opt) {
+ case "-v":
+ verbose = true;
+ break;
+ case "--all":
+ all = true;
+ break;
+ default:
+ pw.println("Invalid option: " + opt);
+ return -1;
+ }
+ }
final IActivityManager am = ActivityManager.getService();
- final List<UserInfo> users = getUsers(false);
+ final List<UserInfo> users = getUsers(/* excludePartial= */ !all,
+ /* excludingDying=*/ false, /* excludePreCreated= */ !all);
if (users == null) {
pw.println("Error: couldn't get users");
return 1;
} else {
- pw.println("Users:");
- for (int i = 0; i < users.size(); i++) {
- String running = am.isUserRunning(users.get(i).id, 0) ? " running" : "";
- pw.println("\t" + users.get(i).toString() + running);
+ final int size = users.size();
+ int currentUser = UserHandle.USER_NULL;
+ if (verbose) {
+ pw.printf("%d users:\n\n", size);
+ currentUser = am.getCurrentUser().id;
+ } else {
+ // NOTE: the standard "list users" command is used by integration tests and
+ // hence should not be changed. If you need to add more info, use the
+ // verbose option.
+ pw.println("Users:");
+ }
+ for (int i = 0; i < size; i++) {
+ final UserInfo user = users.get(i);
+ final boolean running = am.isUserRunning(user.id, 0);
+ final boolean current = user.id == currentUser;
+ if (verbose) {
+ pw.printf("%d: id=%d, name=%s, flags=%s%s%s%s%s\n", i, user.id, user.name,
+ UserInfo.flagsToString(user.flags),
+ running ? " (running)" : "",
+ user.partial ? " (partial)" : "",
+ user.preCreated ? " (pre-created)" : "",
+ current ? " (current)" : "");
+ } else {
+ // NOTE: the standard "list users" command is used by integration tests and
+ // hence should not be changed. If you need to add more info, use the
+ // verbose option.
+ pw.printf("\t%s%s\n", user, running ? " running" : "");
+ }
}
return 0;
}
@@ -3785,6 +3986,9 @@
if (userInfo.partial) {
pw.print(" <partial>");
}
+ if (userInfo.preCreated) {
+ pw.print(" <pre-created>");
+ }
pw.println();
pw.print(" Flags: "); pw.print(userInfo.flags); pw.print(" (");
pw.print(UserInfo.flagsToString(userInfo.flags)); pw.println(")");
@@ -3867,10 +4071,10 @@
// Dump some capabilities
pw.println();
- pw.println(" Max users: " + UserManager.getMaxSupportedUsers());
+ pw.print(" Max users: " + UserManager.getMaxSupportedUsers());
+ pw.println(" (limit reached: " + isUserLimitReached() + ")");
pw.println(" Supports switchable users: " + UserManager.supportsMultipleUsers());
- pw.println(" All guests ephemeral: " + Resources.getSystem().getBoolean(
- com.android.internal.R.bool.config_guestUserEphemeral));
+ pw.println(" All guests ephemeral: " + areGuestUsersEphemeral());
pw.println(" Is split-system user: " + UserManager.isSplitSystemUser());
pw.println(" Is headless-system mode: " + UserManager.isHeadlessSystemUserMode());
pw.println(" User version: " + mUserVersion);
@@ -4076,7 +4280,7 @@
public UserInfo createUserEvenWhenDisallowed(String name, int flags,
String[] disallowedPackages) {
UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL,
- disallowedPackages);
+ /* preCreated= */ false, disallowedPackages);
// Keep this in sync with UserManager.createUser
if (user != null && !user.isAdmin() && !user.isDemo()) {
setUserRestriction(UserManager.DISALLOW_SMS, true, user.id);
@@ -4270,7 +4474,7 @@
pw.println(" help");
pw.println(" Print this help text.");
pw.println("");
- pw.println(" list");
+ pw.println(" list [-v] [-all]");
pw.println(" Prints all users on the system.");
}
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 0e2e1b7..4213168 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -793,68 +793,62 @@
final CheckPermissionDelegate checkPermissionDelegate;
synchronized (mLock) {
+ if (mCheckPermissionDelegate == null) {
+ return checkPermissionImpl(permName, pkgName, userId);
+ }
checkPermissionDelegate = mCheckPermissionDelegate;
}
- if (checkPermissionDelegate == null) {
- return checkPermissionImpl(permName, pkgName, userId);
- }
return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
- this::checkPermissionImpl);
+ PermissionManagerService.this::checkPermissionImpl);
}
- private int checkPermissionImpl(@NonNull String permissionName, @NonNull String packageName,
- @UserIdInt int userId) {
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+ private int checkPermissionImpl(String permName, String pkgName, int userId) {
+ final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
if (pkg == null) {
return PackageManager.PERMISSION_DENIED;
}
- return checkPermissionInternal(pkg, true, permissionName, true, userId)
- ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED;
+ return checkPermissionInternal(pkg, true, permName, userId);
}
- private boolean checkPermissionInternal(@NonNull Package pkg, boolean isPackageExplicit,
- @NonNull String permissionName, boolean useRequestedPermissionsForLegacyApps,
- @UserIdInt int userId) {
+ private int checkPermissionInternal(@NonNull Package pkg, boolean isPackageExplicit,
+ @NonNull String permissionName, @UserIdInt int userId) {
final int callingUid = getCallingUid();
if (isPackageExplicit || pkg.mSharedUserId == null) {
if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
- return false;
+ return PackageManager.PERMISSION_DENIED;
}
} else {
if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
- return false;
+ return PackageManager.PERMISSION_DENIED;
}
}
final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null) {
- return false;
+ return PackageManager.PERMISSION_DENIED;
}
final PermissionsState permissionsState = ps.getPermissionsState();
- if (checkSinglePermissionInternal(uid, permissionsState, permissionName,
- useRequestedPermissionsForLegacyApps)) {
- return true;
+ if (checkSinglePermissionInternal(uid, permissionsState, permissionName)) {
+ return PackageManager.PERMISSION_GRANTED;
}
final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
- if (fullerPermissionName != null && checkSinglePermissionInternal(uid, permissionsState,
- fullerPermissionName, useRequestedPermissionsForLegacyApps)) {
- return true;
+ if (fullerPermissionName != null
+ && checkSinglePermissionInternal(uid, permissionsState, fullerPermissionName)) {
+ return PackageManager.PERMISSION_GRANTED;
}
- return false;
+ return PackageManager.PERMISSION_DENIED;
}
private boolean checkSinglePermissionInternal(int uid,
- @NonNull PermissionsState permissionsState, @NonNull String permissionName,
- boolean useRequestedPermissionsForLegacyApps) {
+ @NonNull PermissionsState permissionsState, @NonNull String permissionName) {
boolean hasPermission = permissionsState.hasPermission(permissionName,
UserHandle.getUserId(uid));
- if (!hasPermission && useRequestedPermissionsForLegacyApps
- && mSettings.isPermissionRuntime(permissionName)) {
+ if (!hasPermission && mSettings.isPermissionRuntime(permissionName)) {
final String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
final int packageNamesSize = packageNames != null ? packageNames.length : 0;
for (int i = 0; i < packageNamesSize; i++) {
@@ -897,13 +891,12 @@
checkPermissionDelegate = mCheckPermissionDelegate;
}
return checkPermissionDelegate.checkUidPermission(permName, uid,
- this::checkUidPermissionImpl);
+ PermissionManagerService.this::checkUidPermissionImpl);
}
- private int checkUidPermissionImpl(@NonNull String permissionName, int uid) {
+ private int checkUidPermissionImpl(String permName, int uid) {
final PackageParser.Package pkg = mPackageManagerInt.getPackage(uid);
- return checkUidPermissionInternal(uid, pkg, permissionName, true)
- ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED;
+ return checkUidPermissionInternal(pkg, uid, permName);
}
/**
@@ -913,25 +906,24 @@
*
* @see SystemConfig#getSystemPermissions()
*/
- private boolean checkUidPermissionInternal(int uid, @Nullable Package pkg,
- @NonNull String permissionName, boolean useRequestedPermissionsForLegacyApps) {
+ private int checkUidPermissionInternal(@Nullable Package pkg, int uid,
+ @NonNull String permissionName) {
if (pkg != null) {
final int userId = UserHandle.getUserId(uid);
- return checkPermissionInternal(pkg, false, permissionName,
- useRequestedPermissionsForLegacyApps, userId);
+ return checkPermissionInternal(pkg, false, permissionName, userId);
}
if (checkSingleUidPermissionInternal(uid, permissionName)) {
- return true;
+ return PackageManager.PERMISSION_GRANTED;
}
final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
if (fullerPermissionName != null
&& checkSingleUidPermissionInternal(uid, fullerPermissionName)) {
- return true;
+ return PackageManager.PERMISSION_GRANTED;
}
- return false;
+ return PackageManager.PERMISSION_DENIED;
}
private boolean checkSingleUidPermissionInternal(int uid, @NonNull String permissionName) {
@@ -941,17 +933,6 @@
}
}
- private int computeRuntimePermissionAppOpMode(int uid, @NonNull String permissionName) {
- boolean granted = isUidPermissionGranted(uid, permissionName);
- // TODO: Foreground permissions.
- return granted ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
- }
-
- private boolean isUidPermissionGranted(int uid, @NonNull String permissionName) {
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(uid);
- return checkUidPermissionInternal(uid, pkg, permissionName, false);
- }
-
@Override
public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
mContext.enforceCallingOrSelfPermission(
@@ -1577,7 +1558,6 @@
}
};
- final AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
for (int i = 0; i < permissionCount; i++) {
final String permName = pkg.requestedPermissions.get(i);
final BasePermission bp;
@@ -1643,16 +1623,9 @@
// If this permission was granted by default, make sure it is.
if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
+ // PermissionPolicyService will handle the app op for runtime permissions later.
grantRuntimePermissionInternal(permName, packageName, false,
Process.SYSTEM_UID, userId, delayingPermCallback);
- // Allow app op later as we are holding mPackages
- // PermissionPolicyService will handle the app op for foreground/background
- // permissions.
- String appOp = AppOpsManager.permissionToOp(permName);
- if (appOp != null) {
- mHandler.post(() -> appOpsManager.setUidMode(appOp, uid,
- AppOpsManager.MODE_ALLOWED));
- }
// If permission review is enabled the permissions for a legacy apps
// are represented as constantly granted runtime ones, so don't revoke.
} else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
@@ -4477,12 +4450,6 @@
StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
}
}
-
- @Override
- public int computeRuntimePermissionAppOpMode(int uid, @NonNull String permissionName) {
- return PermissionManagerService.this.computeRuntimePermissionAppOpMode(uid,
- permissionName);
- }
}
private static final class OnPermissionChangeListeners extends Handler {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 8f22f92..04ec5ba 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -445,13 +445,4 @@
/** Called when a new user has been created. */
public abstract void onNewUserCreated(@UserIdInt int userId);
-
- /**
- * Compute an app op mode based on its runtime permission state.
- *
- * @param uid the uid for the app op
- * @param permissionName the permission name for the app op
- * @return the computed mode
- */
- public abstract int computeRuntimePermissionAppOpMode(int uid, @NonNull String permissionName);
}
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index f3826e9e..77c16e3 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -424,16 +424,6 @@
*/
private final @NonNull ArrayList<OpToChange> mOpsToForeground = new ArrayList<>();
- /**
- * All ops that need to be flipped to foreground if allow.
- *
- * Currently, only used by the foreground/background permissions logic.
- *
- * @see #syncPackages
- */
- private final @NonNull ArrayList<OpToChange> mOpsToForegroundIfAllow =
- new ArrayList<>();
-
PermissionToOpSynchroniser(@NonNull Context context) {
mContext = context;
mPackageManager = context.getPackageManager();
@@ -443,7 +433,7 @@
/**
* Set app ops that were added in {@link #addPackage}.
*
- * <p>This processes ops previously added by {@link #addOpIfRestricted}
+ * <p>This processes ops previously added by {@link #addAppOps(PackageInfo, String)}
*/
private void syncPackages() {
// Remember which ops were already set. This makes sure that we always set the most
@@ -459,19 +449,6 @@
alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
}
- final int foregroundIfAllowedCount = mOpsToForegroundIfAllow.size();
- for (int i = 0; i < foregroundIfAllowedCount; i++) {
- final OpToChange op = mOpsToForegroundIfAllow.get(i);
- if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
- continue;
- }
-
- boolean wasSet = setUidModeForegroundIfAllow(op.code, op.uid, op.packageName);
- if (wasSet) {
- alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
- }
- }
-
final int foregroundCount = mOpsToForeground.size();
for (int i = 0; i < foregroundCount; i++) {
final OpToChange op = mOpsToForeground.get(i);
@@ -509,143 +486,139 @@
}
/**
- * Add op that belong to a restricted permission for later processing in
- * {@link #syncPackages()}.
- *
- * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
- *
- * @param permissionInfo The permission that is currently looked at
- * @param pkg The package looked at
+ * Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
*/
- private void addOpIfRestricted(@NonNull PermissionInfo permissionInfo,
- @NonNull PackageInfo pkg) {
- final String permission = permissionInfo.name;
- final int opCode = getSwitchOp(permission);
- final int uid = pkg.applicationInfo.uid;
-
- if (!permissionInfo.isRestricted()) {
+ private void addAppOps(@NonNull PackageInfo packageInfo, @NonNull String permissionName) {
+ PermissionInfo permissionInfo = getPermissionInfo(permissionName);
+ if (permissionInfo == null) {
return;
}
-
- if (opCode != OP_NONE) {
- int permissionFlags = mPackageManager.getPermissionFlags(permission,
- pkg.packageName, mContext.getUser());
- boolean isReviewRequired = (permissionFlags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0;
- if (!isReviewRequired) {
- boolean isRevokedCompat =
- (permissionFlags & FLAG_PERMISSION_REVOKED_COMPAT) != 0;
- if (permissionInfo.isHardRestricted()) {
- boolean shouldApplyRestriction =
- (permissionFlags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
- if (isRevokedCompat || shouldApplyRestriction) {
- mOpsToIgnore.add(new OpToChange(uid, pkg.packageName, opCode));
- } else {
- mOpsToAllow.add(new OpToChange(uid, pkg.packageName, opCode));
- }
- } else if (permissionInfo.isSoftRestricted()) {
- SoftRestrictedPermissionPolicy policy =
- SoftRestrictedPermissionPolicy.forPermission(mContext,
- pkg.applicationInfo, mContext.getUser(), permission);
- if (!isRevokedCompat && policy.mayGrantPermission()) {
- mOpsToAllow.add(new OpToChange(uid, pkg.packageName, opCode));
- } else {
- mOpsToIgnore.add(new OpToChange(uid, pkg.packageName, opCode));
- }
- }
- }
- }
-
- if (permissionInfo.isSoftRestricted()) {
- SoftRestrictedPermissionPolicy policy =
- SoftRestrictedPermissionPolicy.forPermission(mContext, pkg.applicationInfo,
- mContext.getUser(), permission);
- int extraOpCode = policy.getExtraAppOpCode();
- if (extraOpCode != OP_NONE) {
- if (policy.mayAllowExtraAppOp()) {
- mOpsToAllow.add(new OpToChange(uid, pkg.packageName, extraOpCode));
- } else {
- if (policy.mayDenyExtraAppOpIfGranted()) {
- mOpsToIgnore.add(new OpToChange(uid, pkg.packageName, extraOpCode));
- } else {
- mOpsToIgnoreIfNotAllowed.add(new OpToChange(uid, pkg.packageName,
- extraOpCode));
- }
- }
- }
- }
+ addPermissionAppOp(packageInfo, permissionInfo);
+ addExtraAppOp(packageInfo, permissionInfo);
}
- private boolean isBgPermRestricted(@NonNull String pkg, @NonNull String perm, int uid) {
- try {
- final PermissionInfo bgPermInfo = mPackageManager.getPermissionInfo(perm, 0);
-
- if (bgPermInfo.isSoftRestricted()) {
- Slog.wtf(LOG_TAG, "Support for soft restricted background permissions not "
- + "implemented");
- }
-
- return bgPermInfo.isHardRestricted() && (mPackageManager.getPermissionFlags(
- perm, pkg, UserHandle.getUserHandleForUid(uid))
- & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
- } catch (NameNotFoundException e) {
- Slog.w(LOG_TAG, "Cannot read permission state of " + perm, e);
- return false;
- }
- }
-
- /**
- * Add op that belong to a foreground permission for later processing in
- * {@link #syncPackages()}.
- *
- * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
- *
- * @param permissionInfo The permission that is currently looked at
- * @param pkg The package looked at
- */
- private void addOpIfFgPermissions(@NonNull PermissionInfo permissionInfo,
- @NonNull PackageInfo pkg) {
- final String bgPermissionName = permissionInfo.backgroundPermission;
-
- if (bgPermissionName == null) {
+ private void addPermissionAppOp(@NonNull PackageInfo packageInfo,
+ @NonNull PermissionInfo permissionInfo) {
+ if (!permissionInfo.isRuntime()) {
return;
}
- final String permission = permissionInfo.name;
- final int opCode = getSwitchOp(permission);
- final String pkgName = pkg.packageName;
- final int uid = pkg.applicationInfo.uid;
-
- // App does not support runtime permissions. Hence the state is encoded in the app-op.
- // To not override unrecoverable state don't change app-op unless bg perm is reviewed.
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
- // If the review is required for this permission, the grant state does not
- // really matter. To have a stable state, don't change the app-op if review is still
- // pending.
- int flags = mPackageManager.getPermissionFlags(bgPermissionName,
- pkg.packageName, UserHandle.getUserHandleForUid(uid));
-
- if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0
- && isBgPermRestricted(pkgName, bgPermissionName, uid)) {
- mOpsToForegroundIfAllow.add(new OpToChange(uid, pkgName, opCode));
- }
-
+ String permissionName = permissionInfo.name;
+ String packageName = packageInfo.packageName;
+ int permissionFlags = mPackageManager.getPermissionFlags(permissionName,
+ packageName, mContext.getUser());
+ boolean isReviewRequired = (permissionFlags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0;
+ if (isReviewRequired) {
return;
}
- if (mPackageManager.checkPermission(permission, pkgName)
- == PackageManager.PERMISSION_GRANTED) {
- final boolean isBgHardRestricted = isBgPermRestricted(pkgName, bgPermissionName,
- uid);
- final boolean isBgPermGranted = mPackageManager.checkPermission(bgPermissionName,
- pkgName) == PackageManager.PERMISSION_GRANTED;
+ // TODO: COARSE_LOCATION and FINE_LOCATION shares the same app op. We are solving this
+ // with switch op but once we start syncing single permission this won't work.
+ int appOpCode = getSwitchOp(permissionName);
+ if (appOpCode == OP_NONE) {
+ // Note that background permissions don't have an associated app op.
+ return;
+ }
- if (!isBgHardRestricted && isBgPermGranted) {
- mOpsToAllow.add(new OpToChange(uid, pkgName, opCode));
+ int appOpMode;
+ boolean shouldGrantAppOp = shouldGrantAppOp(packageInfo, permissionInfo);
+ if (shouldGrantAppOp) {
+ if (permissionInfo.backgroundPermission != null) {
+ PermissionInfo backgroundPermissionInfo = getPermissionInfo(
+ permissionInfo.backgroundPermission);
+ boolean shouldGrantBackgroundAppOp = backgroundPermissionInfo != null
+ && shouldGrantAppOp(packageInfo, backgroundPermissionInfo);
+ appOpMode = shouldGrantBackgroundAppOp ? MODE_ALLOWED : MODE_FOREGROUND;
} else {
- mOpsToForeground.add(new OpToChange(uid, pkgName, opCode));
+ appOpMode = MODE_ALLOWED;
}
} else {
- mOpsToIgnore.add(new OpToChange(uid, pkgName, opCode));
+ appOpMode = MODE_IGNORED;
+ }
+
+ int uid = packageInfo.applicationInfo.uid;
+ OpToChange opToChange = new OpToChange(uid, packageName, appOpCode);
+ switch (appOpMode) {
+ case MODE_ALLOWED:
+ mOpsToAllow.add(opToChange);
+ break;
+ case MODE_FOREGROUND:
+ mOpsToForeground.add(opToChange);
+ break;
+ case MODE_IGNORED:
+ mOpsToIgnore.add(opToChange);
+ break;
+ }
+ }
+
+ @Nullable
+ private PermissionInfo getPermissionInfo(@NonNull String permissionName) {
+ try {
+ return mPackageManager.getPermissionInfo(permissionName, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ return null;
+ }
+ }
+
+ private boolean shouldGrantAppOp(@NonNull PackageInfo packageInfo,
+ @NonNull PermissionInfo permissionInfo) {
+ String permissionName = permissionInfo.name;
+ String packageName = packageInfo.packageName;
+ boolean isGranted = mPackageManager.checkPermission(permissionName, packageName)
+ == PackageManager.PERMISSION_GRANTED;
+ if (!isGranted) {
+ return false;
+ }
+
+ int permissionFlags = mPackageManager.getPermissionFlags(permissionName, packageName,
+ mContext.getUser());
+ boolean isRevokedCompat = (permissionFlags & FLAG_PERMISSION_REVOKED_COMPAT)
+ == FLAG_PERMISSION_REVOKED_COMPAT;
+ if (isRevokedCompat) {
+ return false;
+ }
+
+ if (permissionInfo.isHardRestricted()) {
+ boolean shouldApplyRestriction =
+ (permissionFlags & FLAG_PERMISSION_APPLY_RESTRICTION)
+ == FLAG_PERMISSION_APPLY_RESTRICTION;
+ return !shouldApplyRestriction;
+ } else if (permissionInfo.isSoftRestricted()) {
+ SoftRestrictedPermissionPolicy policy =
+ SoftRestrictedPermissionPolicy.forPermission(mContext,
+ packageInfo.applicationInfo, mContext.getUser(), permissionName);
+ return policy.mayGrantPermission();
+ } else {
+ return true;
+ }
+ }
+
+ private void addExtraAppOp(@NonNull PackageInfo packageInfo,
+ @NonNull PermissionInfo permissionInfo) {
+ if (!permissionInfo.isSoftRestricted()) {
+ return;
+ }
+
+ String permissionName = permissionInfo.name;
+ SoftRestrictedPermissionPolicy policy =
+ SoftRestrictedPermissionPolicy.forPermission(mContext,
+ packageInfo.applicationInfo, mContext.getUser(), permissionName);
+ int extraOpCode = policy.getExtraAppOpCode();
+ if (extraOpCode == OP_NONE) {
+ return;
+ }
+
+ int uid = packageInfo.applicationInfo.uid;
+ String packageName = packageInfo.packageName;
+ OpToChange extraOpToChange = new OpToChange(uid, packageName, extraOpCode);
+ if (policy.mayAllowExtraAppOp()) {
+ mOpsToAllow.add(extraOpToChange);
+ } else {
+ if (policy.mayDenyExtraAppOpIfGranted()) {
+ mOpsToIgnore.add(extraOpToChange);
+ } else {
+ mOpsToIgnoreIfNotAllowed.add(extraOpToChange);
+ }
}
}
@@ -671,20 +644,7 @@
}
for (String permission : pkg.requestedPermissions) {
- final int opCode = getSwitchOp(permission);
- if (opCode == OP_NONE) {
- continue;
- }
-
- final PermissionInfo permissionInfo;
- try {
- permissionInfo = mPackageManager.getPermissionInfo(permission, 0);
- } catch (PackageManager.NameNotFoundException e) {
- continue;
- }
-
- addOpIfRestricted(permissionInfo, pkg);
- addOpIfFgPermissions(permissionInfo, pkg);
+ addAppOps(pkg, permission);
}
}
@@ -692,17 +652,6 @@
setUidMode(opCode, uid, MODE_ALLOWED, packageName);
}
- private boolean setUidModeForegroundIfAllow(int opCode, int uid,
- @NonNull String packageName) {
- final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager.opToPublicName(
- opCode), uid, packageName);
- if (currentMode == MODE_ALLOWED) {
- mAppOpsManager.setUidMode(opCode, uid, MODE_FOREGROUND);
- return true;
- }
- return false;
- }
-
private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) {
setUidMode(opCode, uid, MODE_FOREGROUND, packageName);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 88b1793..237a771 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -23,6 +23,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.Context.CONTEXT_RESTRICTED;
import static android.content.Context.WINDOW_SERVICE;
+import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
import static android.content.pm.PackageManager.FEATURE_HDMI_CEC;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
@@ -385,6 +386,7 @@
BurnInProtectionHelper mBurnInProtectionHelper;
private DisplayFoldController mDisplayFoldController;
AppOpsManager mAppOpsManager;
+ private boolean mHasFeatureAuto;
private boolean mHasFeatureWatch;
private boolean mHasFeatureLeanback;
private boolean mHasFeatureHdmiCec;
@@ -1753,6 +1755,7 @@
mDisplayManager = mContext.getSystemService(DisplayManager.class);
mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH);
mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK);
+ mHasFeatureAuto = mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE);
mHasFeatureHdmiCec = mContext.getPackageManager().hasSystemFeature(FEATURE_HDMI_CEC);
mAccessibilityShortcutController =
new AccessibilityShortcutController(mContext, new Handler(), mCurrentUserId);
@@ -5222,7 +5225,7 @@
awakenDreams();
}
- if (!isUserSetupComplete()) {
+ if (!mHasFeatureAuto && !isUserSetupComplete()) {
Slog.i(TAG, "Not going home because user setup is in progress.");
return;
}
diff --git a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
index 712012d..017c684 100644
--- a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
+++ b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java
@@ -21,6 +21,7 @@
import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
@@ -34,9 +35,9 @@
import com.android.server.LocalServices;
import com.android.server.role.RoleManagerService;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
/**
* Logic to retrieve the various legacy(pre-Q) equivalents of role holders.
@@ -125,9 +126,21 @@
}
case RoleManager.ROLE_HOME: {
PackageManager packageManager = mContext.getPackageManager();
- List<ResolveInfo> resolveInfos = new ArrayList<>();
- ComponentName componentName = packageManager.getHomeActivities(resolveInfos);
- String packageName = componentName != null ? componentName.getPackageName() : null;
+ String packageName;
+ if (packageManager.isDeviceUpgrading()) {
+ ResolveInfo resolveInfo = packageManager.resolveActivityAsUser(
+ new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME),
+ PackageManager.MATCH_DEFAULT_ONLY
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId);
+ packageName = resolveInfo != null && resolveInfo.activityInfo != null
+ ? resolveInfo.activityInfo.packageName : null;
+ if (packageName != null && isSettingsApplication(packageName, userId)) {
+ packageName = null;
+ }
+ } else {
+ packageName = null;
+ }
return CollectionUtils.singletonOrEmpty(packageName);
}
case RoleManager.ROLE_EMERGENCY: {
@@ -142,4 +155,16 @@
}
}
}
+
+ private boolean isSettingsApplication(@NonNull String packageName, @UserIdInt int userId) {
+ PackageManager packageManager = mContext.getPackageManager();
+ ResolveInfo resolveInfo = packageManager.resolveActivityAsUser(new Intent(
+ Settings.ACTION_SETTINGS), PackageManager.MATCH_DEFAULT_ONLY
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId);
+ if (resolveInfo == null || resolveInfo.activityInfo == null) {
+ return false;
+ }
+ return Objects.equals(packageName, resolveInfo.activityInfo.packageName);
+ }
}
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index bf8c042..aac0f90 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -51,7 +51,6 @@
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.service.sms.FinancialSmsService;
-import android.telephony.IFinancialSmsCallback;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -269,6 +268,7 @@
maybeMigrateRole(RoleManager.ROLE_DIALER, userId);
maybeMigrateRole(RoleManager.ROLE_SMS, userId);
maybeMigrateRole(RoleManager.ROLE_EMERGENCY, userId);
+ maybeMigrateRole(RoleManager.ROLE_HOME, userId);
// Some package state has changed, so grant default roles again.
Slog.i(LOG_TAG, "Granting default roles...");
@@ -701,40 +701,6 @@
dumpOutputStream.flush();
}
- /**
- * Get filtered SMS messages for financial app.
- */
- @Override
- public void getSmsMessagesForFinancialApp(
- String callingPkg, Bundle params, IFinancialSmsCallback callback) {
- int mode = PermissionChecker.checkCallingOrSelfPermission(
- getContext(),
- AppOpsManager.OPSTR_SMS_FINANCIAL_TRANSACTIONS);
-
- if (mode == PermissionChecker.PERMISSION_GRANTED) {
- FinancialSmsManager financialSmsManager = new FinancialSmsManager(getContext());
- financialSmsManager.getSmsMessages(new RemoteCallback((result) -> {
- CursorWindow messages = null;
- if (result == null) {
- Slog.w(LOG_TAG, "result is null.");
- } else {
- messages = result.getParcelable(FinancialSmsService.EXTRA_SMS_MSGS);
- }
- try {
- callback.onGetSmsMessagesForFinancialApp(messages);
- } catch (RemoteException e) {
- // do nothing
- }
- }), params);
- } else {
- try {
- callback.onGetSmsMessagesForFinancialApp(null);
- } catch (RemoteException e) {
- // do nothing
- }
- }
- }
-
private int getUidForPackage(String packageName) {
long ident = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 9c19aec..83891f6 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -370,7 +370,7 @@
private void checkAndMitigateNativeCrashes() {
mNumberOfNativeCrashPollsRemaining--;
// Check if native watchdog reported a crash
- if ("1".equals(SystemProperties.get("ro.init.updatable_crashing"))) {
+ if ("1".equals(SystemProperties.get("sys.init.updatable_crashing"))) {
execute(getModuleMetadataPackage());
// we stop polling after an attempt to execute rollback, regardless of whether the
// attempt succeeds or not
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index eadd09c..425da37 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -28,6 +28,7 @@
import android.util.SparseLongArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import libcore.io.IoUtils;
@@ -288,19 +289,25 @@
JSONObject dataJson = new JSONObject(
IoUtils.readFileAsString(rollbackJsonFile.getAbsolutePath()));
- return new Rollback(
- rollbackInfoFromJson(dataJson.getJSONObject("info")),
- backupDir,
- Instant.parse(dataJson.getString("timestamp")),
- dataJson.getInt("stagedSessionId"),
- rollbackStateFromString(dataJson.getString("state")),
- dataJson.getInt("apkSessionId"),
- dataJson.getBoolean("restoreUserDataInProgress"));
+ return rollbackFromJson(dataJson, backupDir);
} catch (JSONException | DateTimeParseException | ParseException e) {
throw new IOException(e);
}
}
+ @VisibleForTesting
+ static Rollback rollbackFromJson(JSONObject dataJson, File backupDir)
+ throws JSONException, ParseException {
+ return new Rollback(
+ rollbackInfoFromJson(dataJson.getJSONObject("info")),
+ backupDir,
+ Instant.parse(dataJson.getString("timestamp")),
+ dataJson.getInt("stagedSessionId"),
+ rollbackStateFromString(dataJson.getString("state")),
+ dataJson.getInt("apkSessionId"),
+ dataJson.getBoolean("restoreUserDataInProgress"));
+ }
+
private static JSONObject toJson(VersionedPackage pkg) throws JSONException {
JSONObject json = new JSONObject();
json.put("packageName", pkg.getPackageName());
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 5fd2ab8..3b2f324 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -180,8 +180,13 @@
verifyCaller(pkg);
enforceAccess(pkg, uri);
uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
- if (getPinnedSlice(uri).unpin(pkg, token)) {
- removePinnedSlice(uri);
+ try {
+ PinnedSliceState slice = getPinnedSlice(uri);
+ if (slice != null && slice.unpin(pkg, token)) {
+ removePinnedSlice(uri);
+ }
+ } catch (IllegalStateException exception) {
+ Slog.w(TAG, exception.getMessage());
}
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 8897eca..3439d38 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -609,13 +609,13 @@
}
@Override
- public void showBiometricDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver,
- int type, boolean requireConfirmation, int userId, String opPackageName) {
+ public void showAuthenticationDialog(Bundle bundle, IBiometricServiceReceiverInternal receiver,
+ int biometricModality, boolean requireConfirmation, int userId, String opPackageName) {
enforceBiometricDialog();
if (mBar != null) {
try {
- mBar.showBiometricDialog(bundle, receiver, type, requireConfirmation, userId,
- opPackageName);
+ mBar.showAuthenticationDialog(bundle, receiver, biometricModality,
+ requireConfirmation, userId, opPackageName);
} catch (RemoteException ex) {
}
}
@@ -644,22 +644,22 @@
}
@Override
- public void onBiometricError(String error) {
+ public void onBiometricError(int errorCode, String error) {
enforceBiometricDialog();
if (mBar != null) {
try {
- mBar.onBiometricError(error);
+ mBar.onBiometricError(errorCode, error);
} catch (RemoteException ex) {
}
}
}
@Override
- public void hideBiometricDialog() {
+ public void hideAuthenticationDialog() {
enforceBiometricDialog();
if (mBar != null) {
try {
- mBar.hideBiometricDialog();
+ mBar.hideAuthenticationDialog();
} catch (RemoteException ex) {
}
}
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 4c93564..5493afd 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -365,10 +365,16 @@
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, fout)) return;
IndentingPrintWriter pw = new IndentingPrintWriter(fout, " ");
- TextClassificationManager tcm = mContext.getSystemService(TextClassificationManager.class);
- tcm.dump(pw);
- pw.printPair("context", mContext); pw.println();
+ // Create a TCM instance with the system server identity. TCM creates a ContentObserver
+ // to listen for settings changes. It does not pass the checkContentProviderAccess check
+ // if we are using the shell identity, because AMS does not track of processes spawn from
+ // shell.
+ Binder.withCleanCallingIdentity(
+ () -> mContext.getSystemService(TextClassificationManager.class).dump(pw));
+
+ pw.printPair("context", mContext);
+ pw.println();
synchronized (mLock) {
int size = mUserStates.size();
pw.print("Number user states: "); pw.println(size);
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index e488cc9..9d9a37c 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -50,9 +50,9 @@
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.RootActivityContainer.FindTaskResult;
import static com.android.server.wm.RootActivityContainer.TAG_STATES;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
@@ -76,6 +76,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.am.EventLogTags;
+import com.android.server.protolog.common.ProtoLog;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -84,8 +85,7 @@
* Exactly one of these classes per Display in the system. Capable of holding zero or more
* attached {@link ActivityStack}s.
*/
-class ActivityDisplay extends ConfigurationContainer<ActivityStack>
- implements WindowContainerListener {
+class ActivityDisplay extends ConfigurationContainer<ActivityStack> {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityDisplay" : TAG_ATM;
private static final String TAG_STACK = TAG + POSTFIX_STACK;
@@ -201,11 +201,6 @@
}
}
- @Override
- public void onInitializeOverrideConfiguration(Configuration config) {
- getRequestedOverrideConfiguration().updateFrom(config);
- }
-
void addChild(ActivityStack stack, int position) {
if (position == POSITION_BOTTOM) {
position = 0;
@@ -291,9 +286,7 @@
}
// Since positionChildAt() is called during the creation process of pinned stacks,
- // ActivityStack#getStack() can be null. In this special case,
- // since DisplayContest#positionStackAt() is called in TaskStack#onConfigurationChanged(),
- // we don't have to call WindowContainerController#positionChildAt() here.
+ // ActivityStack#getStack() can be null.
if (stack.getTaskStack() != null && mDisplayContent != null) {
mDisplayContent.positionStackAt(insertPosition,
stack.getTaskStack(), includingParents);
@@ -1202,8 +1195,8 @@
// Stacks could be reparented from the removed display to other display. While
// reparenting the last stack of the removed display, the remove display is ready to be
// released (no more ActivityStack). But, we cannot release it at that moment or the
- // related WindowContainer and WindowContainerController will also be removed. So, we
- // set display as removed after reparenting stack finished.
+ // related WindowContainer will also be removed. So, we set display as removed after
+ // reparenting stack finished.
final ActivityDisplay toDisplay = mRootActivityContainer.getDefaultDisplay();
mRootActivityContainer.mStackSupervisor.beginDeferResume();
try {
@@ -1304,8 +1297,8 @@
final AppWindowToken newFocus;
final IBinder token = r.appToken;
if (token == null) {
- if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Clearing focused app, displayId="
- + mDisplayId);
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Clearing focused app, displayId=%d",
+ mDisplayId);
newFocus = null;
} else {
newFocus = mService.mWindowManager.mRoot.getAppWindowToken(token);
@@ -1313,8 +1306,9 @@
Slog.w(TAG_WM, "Attempted to set focus to non-existing app token: " + token
+ ", displayId=" + mDisplayId);
}
- if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Set focused app to: " + newFocus
- + " moveFocusNow=" + moveFocusNow + " displayId=" + mDisplayId);
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
+ "Set focused app to: %s moveFocusNow=%b displayId=%d", newFocus,
+ moveFocusNow, mDisplayId);
}
final boolean changed = mDisplayContent.setFocusedApp(newFocus);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c54ccd4..e54daf2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -54,20 +54,14 @@
import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
-import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
-import static android.content.pm.ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED;
import static android.content.pm.ActivityInfo.FLAG_MULTIPROCESS;
import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
-import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
-import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
-import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
-import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
@@ -86,7 +80,6 @@
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
-import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static android.os.Build.VERSION_CODES.O;
import static android.os.Process.SYSTEM_UID;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -96,6 +89,7 @@
import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
+import static com.android.server.am.ActivityRecordProto.APP_WINDOW_TOKEN;
import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
@@ -154,12 +148,12 @@
import static com.android.server.wm.IdentifierProto.HASH_CODE;
import static com.android.server.wm.IdentifierProto.TITLE;
import static com.android.server.wm.IdentifierProto.USER_ID;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.ActivityTaskManagerService.getInputDispatchingTimeoutLocked;
import static com.android.server.wm.TaskPersister.DEBUG;
import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
@@ -212,7 +206,6 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.service.voice.IVoiceInteractionSession;
import android.util.ArraySet;
@@ -226,19 +219,16 @@
import android.view.DisplayCutout;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.IApplicationToken;
-import android.view.RemoteAnimationDefinition;
import android.view.WindowManager.LayoutParams;
-import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.ReferrerIntent;
import com.android.internal.util.XmlUtils;
-import com.android.server.AttributeCache;
-import com.android.server.AttributeCache.Entry;
import com.android.server.am.AppTimeTracker;
import com.android.server.am.EventLogTags;
import com.android.server.am.PendingIntentRecord;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.uri.UriPermissionOwner;
import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
import com.android.server.wm.ActivityStack.ActivityState;
@@ -262,7 +252,7 @@
/**
* An entry in the history stack, representing an activity.
*/
-final class ActivityRecord extends ConfigurationContainer {
+final class ActivityRecord extends AppWindowToken {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_ATM;
private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
private static final String TAG_APP = TAG + POSTFIX_APP;
@@ -291,29 +281,17 @@
// How many activities have to be scheduled to stop to force a stop pass.
private static final int MAX_STOPPING_TO_FORCE = 3;
- final ActivityTaskManagerService mAtmService; // owner
- final IApplicationToken.Stub appToken; // window manager token
- // TODO: Remove after unification
- AppWindowToken mAppWindowToken;
-
+ // TODO: Move to AppWindowToken?
final ActivityInfo info; // activity info provided by developer in AndroidManifest
final int launchedFromPid; // always the pid who started the activity.
final int launchedFromUid; // always the uid who started the activity.
final String launchedFromPackage; // always the package who started the activity.
- final int mUserId; // Which user is this running for?
final Intent intent; // the original intent that generated us
- final ComponentName mActivityComponent; // the intent component, or target of an alias.
final String shortComponentName; // the short component name of the intent
final String resolvedType; // as per original caller;
- final String packageName; // the package implementing intent's component
final String processName; // process where this component wants to run
final String taskAffinity; // as per ActivityInfo.taskAffinity
final boolean stateNotNeeded; // As per ActivityInfo.flags
- boolean fullscreen; // The activity is opaque and fills the entire space of this task.
- // TODO: See if it possible to combine this with the fullscreen field.
- final boolean hasWallpaper; // Has a wallpaper window as a background.
- @VisibleForTesting
- boolean noDisplay; // activity is not displayed?
@VisibleForTesting
int mHandoverLaunchDisplayId = INVALID_DISPLAY; // Handover launch display id to next activity.
private final boolean componentSpecified; // did caller specify an explicit component?
@@ -324,7 +302,6 @@
private int icon; // resource identifier of activity's icon.
private int logo; // resource identifier of activity's logo.
private int theme; // resource identifier of activity's theme.
- private int realTheme; // actual theme resource we will use, never 0.
private int windowFlags; // custom window flags for preview window.
private TaskRecord task; // the task this is in.
private long createTime = System.currentTimeMillis();
@@ -374,6 +351,7 @@
boolean visible; // does this activity's window need to be shown?
boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
// might hide this activity?
+ // TODO: figureout how to consolidate with the same variable in AppWindowToken.
private boolean mDeferHidingClient; // If true we told WM to defer reporting to the client
// process that it is hidden.
boolean sleeping; // have we told the activity to sleep?
@@ -393,8 +371,6 @@
long lastLaunchTime; // time of last launch of this activity
ComponentName requestedVrComponent; // the requested component for handling VR mode.
- String stringName; // for caching of toString().
-
private boolean inHistory; // are we in the history stack?
final ActivityStackSupervisor mStackSupervisor;
final RootActivityContainer mRootActivityContainer;
@@ -411,8 +387,6 @@
int mRelaunchReason = RELAUNCH_REASON_NONE;
TaskDescription taskDescription; // the recents information for this activity
- boolean mLaunchTaskBehind; // this activity is actively being launched with
- // ActivityOptions.setLaunchTaskBehind, will be cleared once launch is completed.
// These configurations are collected from application's resources based on size-sensitive
// qualifiers. For example, layout-w800dp will be added to mHorizontalSizeConfigurations as 800
@@ -430,17 +404,6 @@
boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session
IVoiceInteractionSession voiceSession; // Voice interaction session for this activity
- // A hint to override the window specified rotation animation, or -1
- // to use the window specified value. We use this so that
- // we can select the right animation in the cases of starting
- // windows, where the app hasn't had time to set a value
- // on the window.
- int mRotationAnimationHint = -1;
-
- private boolean mShowWhenLocked;
- private boolean mInheritShownWhenLocked;
- private boolean mTurnScreenOn;
-
/**
* Current sequencing integer of the configuration, for skipping old activity configurations.
*/
@@ -603,7 +566,7 @@
pw.print(" idle="); pw.print(idle);
pw.print(" mStartingWindowState=");
pw.println(startingWindowStateToString(mStartingWindowState));
- pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
+ pw.print(prefix); pw.print("occludesParent="); pw.print(occludesParent());
pw.print(" noDisplay="); pw.print(noDisplay);
pw.print(" immersive="); pw.print(immersive);
pw.print(" launchMode="); pw.println(launchMode);
@@ -855,22 +818,7 @@
}
}
- @Override
- protected int getChildCount() {
- // {@link ActivityRecord} is a leaf node and has no children.
- return 0;
- }
-
- @Override
- protected ConfigurationContainer getChildAt(int index) {
- return null;
- }
-
- @Override
- protected ConfigurationContainer getParent() {
- return getTaskRecord();
- }
-
+ // TODO: Remove once TaskRecord and Task are unified.
TaskRecord getTaskRecord() {
return task;
}
@@ -914,31 +862,63 @@
this.task = task;
- if (!reparenting) {
+ // This is attaching the activity to the task which we only want to do once.
+ // TODO: Need to re-work after unifying the task level since it will already have a parent
+ // then. Just need to restructure the re-parent case not to do this. NOTE that the
+ // reparenting flag passed in can't be used directly for this as it isn't set in
+ // ActivityRecord#reparent() case that ends up calling this method.
+ if (task != null && getParent() == null) {
+ inHistory = true;
+ final Task container = task.getTask();
+ if (container != null) {
+ onAttachToTask(task.voiceSession != null, container.getDisplayContent(),
+ getInputDispatchingTimeoutLocked(this) * 1000000L);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "setTask: %s at top.", this);
+ container.addChild(this, Integer.MAX_VALUE /* add on top */);
+ }
+
+ // TODO(b/36505427): Maybe this call should be moved inside
+ // updateOverrideConfiguration()
+ task.updateOverrideConfigurationFromLaunchBounds();
+ // Make sure override configuration is up-to-date before using to create window
+ // controller.
+ updateOverrideConfiguration();
+
+ task.addActivityToTop(this);
+
+ // When an activity is started directly into a split-screen fullscreen stack, we need to
+ // update the initial multi-window modes so that the callbacks are scheduled correctly
+ // when the user leaves that mode.
+ mLastReportedMultiWindowMode = inMultiWindowMode();
+ mLastReportedPictureInPictureMode = inPinnedWindowingMode();
+ } else if (!reparenting) {
onParentChanged();
}
}
/**
- * Notifies AWT that this app is waiting to pause in order to determine if it will enter PIP.
- * This information helps AWT know that the app is in the process of pausing before it gets the
- * signal on the WM side.
+ * Sets the Task on this activity for the purposes of re-use during launch where we will
+ * re-use another activity instead of this one for the launch.
*/
- void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
- if (mAppWindowToken == null) {
- return;
- }
-
- mAppWindowToken.setWillCloseOrEnterPip(willCloseOrEnterPip);
+ void setTaskForReuse(TaskRecord task) {
+ this.task = task;
}
static class Token extends IApplicationToken.Stub {
- private final WeakReference<ActivityRecord> weakActivity;
+ private WeakReference<ActivityRecord> weakActivity;
private final String name;
+ private final String tokenString;
- Token(ActivityRecord activity, Intent intent) {
- weakActivity = new WeakReference<>(activity);
+ Token(Intent intent) {
name = intent.getComponent().flattenToShortString();
+ tokenString = "Token{" + Integer.toHexString(System.identityHashCode(this)) + "}";
+ }
+
+ private void attach(ActivityRecord activity) {
+ if (weakActivity != null) {
+ throw new IllegalStateException("Already attached..." + this);
+ }
+ weakActivity = new WeakReference<>(activity);
}
private static @Nullable ActivityRecord tokenToActivityRecordLocked(Token token) {
@@ -958,7 +938,9 @@
sb.append("Token{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(' ');
- sb.append(weakActivity.get());
+ if (weakActivity != null) {
+ sb.append(weakActivity.get());
+ }
sb.append('}');
return sb.toString();
}
@@ -1005,14 +987,15 @@
ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified,
boolean _rootVoiceInteraction, ActivityStackSupervisor supervisor,
ActivityOptions options, ActivityRecord sourceRecord) {
- mAtmService = _service;
+ super(_service.mWindowManager, _service, new Token(_intent), aInfo, options, _intent,
+ null /* displayContent */);
+ appToken.attach(this);
+
mRootActivityContainer = _service.mRootActivityContainer;
- appToken = new Token(this, _intent);
info = aInfo;
launchedFromPid = _launchedFromPid;
launchedFromUid = _launchedFromUid;
launchedFromPackage = _launchedFromPackage;
- mUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
intent = _intent;
shortComponentName = _intent.getComponent().flattenToShortString();
resolvedType = _resolvedType;
@@ -1037,17 +1020,6 @@
hasBeenLaunched = false;
mStackSupervisor = supervisor;
- // If the class name in the intent doesn't match that of the target, this is
- // probably an alias. We have to create a new ComponentName object to keep track
- // of the real activity name, so that FLAG_ACTIVITY_CLEAR_TOP is handled properly.
- if (aInfo.targetActivity == null
- || (aInfo.targetActivity.equals(_intent.getComponent().getClassName())
- && (aInfo.launchMode == LAUNCH_MULTIPLE
- || aInfo.launchMode == LAUNCH_SINGLE_TOP))) {
- mActivityComponent = _intent.getComponent();
- } else {
- mActivityComponent = new ComponentName(aInfo.packageName, aInfo.targetActivity);
- }
taskAffinity = aInfo.taskAffinity;
stateNotNeeded = (aInfo.flags & FLAG_STATE_NOT_NEEDED) != 0;
nonLocalizedLabel = aInfo.nonLocalizedLabel;
@@ -1060,11 +1032,6 @@
icon = aInfo.getIconResource();
logo = aInfo.getLogoResource();
theme = aInfo.getThemeResource();
- realTheme = theme;
- if (realTheme == 0) {
- realTheme = aInfo.applicationInfo.targetSdkVersion < HONEYCOMB
- ? android.R.style.Theme : android.R.style.Theme_Holo;
- }
if ((aInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
@@ -1080,21 +1047,8 @@
intent.addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
}
- packageName = aInfo.applicationInfo.packageName;
launchMode = aInfo.launchMode;
- Entry ent = AttributeCache.instance().get(packageName,
- realTheme, com.android.internal.R.styleable.Window, mUserId);
-
- if (ent != null) {
- fullscreen = !ActivityInfo.isTranslucentOrFloating(ent.array);
- hasWallpaper = ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
- noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
- } else {
- hasWallpaper = false;
- noDisplay = false;
- }
-
setActivityType(_componentSpecified, _launchedFromUid, _intent, options, sourceRecord);
immersive = (aInfo.flags & FLAG_IMMERSIVE) != 0;
@@ -1102,11 +1056,6 @@
requestedVrComponent = (aInfo.requestedVrComponent == null) ?
null : ComponentName.unflattenFromString(aInfo.requestedVrComponent);
- mShowWhenLocked = (aInfo.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
- mInheritShownWhenLocked = (aInfo.privateFlags & FLAG_INHERIT_SHOW_WHEN_LOCKED) != 0;
- mTurnScreenOn = (aInfo.flags & FLAG_TURN_SCREEN_ON) != 0;
-
- mRotationAnimationHint = aInfo.rotationAnimation;
lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
if (info.applicationInfo.isPrivilegedApp()
&& (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
@@ -1116,13 +1065,6 @@
if (options != null) {
pendingOptions = options;
- mLaunchTaskBehind = options.getLaunchTaskBehind();
-
- final int rotationAnimation = pendingOptions.getRotationAnimationHint();
- // Only override manifest supplied option if set.
- if (rotationAnimation >= 0) {
- mRotationAnimationHint = rotationAnimation;
- }
final PendingIntent usageReport = pendingOptions.getUsageTimeReport();
if (usageReport != null) {
appTimeTracker = new AppTimeTracker(usageReport);
@@ -1152,97 +1094,28 @@
return hasProcess() && app.hasThread();
}
- void createAppWindowToken() {
- if (mAppWindowToken != null) {
- throw new IllegalArgumentException("App Window Token=" + mAppWindowToken
- + " already created for r=" + this);
- }
-
- inHistory = true;
-
- // TODO(b/36505427): Maybe this call should be moved inside updateOverrideConfiguration()
- task.updateOverrideConfigurationFromLaunchBounds();
- // Make sure override configuration is up-to-date before using to create window controller.
- updateOverrideConfiguration();
-
- // TODO: remove after unification
- mAppWindowToken = mAtmService.mWindowManager.mRoot.getAppWindowToken(appToken.asBinder());
- if (mAppWindowToken != null) {
- // TODO: Should this throw an exception instead?
- Slog.w(TAG, "Attempted to add existing app token: " + appToken);
- } else {
- final Task container = task.getTask();
- if (container == null) {
- throw new IllegalArgumentException("createAppWindowToken: invalid task =" + task);
- }
- mAppWindowToken = createAppWindow(mAtmService.mWindowManager, appToken,
- task.voiceSession != null, container.getDisplayContent(),
- ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this)
- * 1000000L, fullscreen,
- (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0,
- info.applicationInfo.targetSdkVersion,
- info.screenOrientation, mRotationAnimationHint,
- mLaunchTaskBehind, isAlwaysFocusable());
- if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) {
- Slog.v(TAG, "addAppToken: "
- + mAppWindowToken + " task=" + container + " at "
- + Integer.MAX_VALUE);
- }
- container.addChild(mAppWindowToken, Integer.MAX_VALUE /* add on top */);
- }
-
- task.addActivityToTop(this);
-
- // When an activity is started directly into a split-screen fullscreen stack, we need to
- // update the initial multi-window modes so that the callbacks are scheduled correctly when
- // the user leaves that mode.
- mLastReportedMultiWindowMode = inMultiWindowMode();
- mLastReportedPictureInPictureMode = inPinnedWindowingMode();
- }
-
boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG, "setAppStartingWindow: token=" + appToken
- + " pkg=" + pkg + " transferFrom=" + transferFrom + " newTask=" + newTask
- + " taskSwitch=" + taskSwitch + " processRunning=" + processRunning
- + " allowTaskSnapshot=" + allowTaskSnapshot);
- }
- if (mAppWindowToken == null) {
- Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + appToken);
- return false;
- }
- if (mAppWindowToken.getTask() == null) {
- // Can be removed after unification of Task and TaskRecord.
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "setAppStartingWindow: token=%s"
+ + " pkg=%s transferFrom=%s newTask=%b taskSwitch=%b processRunning=%b"
+ + " allowTaskSnapshot=%b", appToken, pkg, transferFrom, newTask, taskSwitch,
+ processRunning, allowTaskSnapshot);
+ if (getParent() == null) {
Slog.w(TAG_WM, "Attempted to start a window to an app token not having attached to any"
+ " task: " + appToken);
return false;
}
- return mAppWindowToken.addStartingWindow(pkg, theme, compatInfo, nonLocalizedLabel,
+ return super.addStartingWindow(pkg, theme, compatInfo, nonLocalizedLabel,
labelRes, icon, logo, windowFlags, transferFrom, newTask, taskSwitch,
processRunning, allowTaskSnapshot, activityCreated, fromRecents);
}
- // TODO: Remove after unification
- @VisibleForTesting
- AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
- boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
- boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
- int rotationAnimationHint, boolean launchTaskBehind,
- boolean alwaysFocusable) {
- return new AppWindowToken(service, token, mActivityComponent, voiceInteraction, dc,
- inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
- rotationAnimationHint, launchTaskBehind, alwaysFocusable,
- this);
- }
-
void removeWindowContainer() {
- if (mAtmService.mWindowManager.mRoot == null) return;
+ if (mWmService.mRoot == null) return;
- final DisplayContent dc = mAtmService.mWindowManager.mRoot.getDisplayContent(
- getDisplayId());
+ final DisplayContent dc = mWmService.mRoot.getDisplayContent(getDisplayId());
if (dc == null) {
Slog.w(TAG, "removeWindowContainer: Attempted to remove token: "
+ appToken + " from non-existing displayId=" + getDisplayId());
@@ -1258,7 +1131,7 @@
* should ensure that the {@param newTask} is not already the parent of this activity.
*/
void reparent(TaskRecord newTask, int position, String reason) {
- if (mAppWindowToken == null) {
+ if (getParent() == null) {
Slog.w(TAG, "reparent: Attempted to reparent non-existing app token: " + appToken);
return;
}
@@ -1277,7 +1150,7 @@
+ " r=" + this + " (" + prevTask.getStackId() + ")");
}
- mAppWindowToken.reparent(newTask.getTask(), position);
+ reparent(newTask.getTask(), position);
// Reparenting prevents informing the parent stack of activity removal in the case that
// the new stack has the same parent. we must manually signal here if this is not the case.
@@ -1368,6 +1241,7 @@
/**
* @return Stack value from current task, null if there is no task.
*/
+ // TODO: Remove once ActivityStack and TaskStack are unified.
<T extends ActivityStack> T getActivityStack() {
return task != null ? (T) task.getStack() : null;
}
@@ -1382,14 +1256,13 @@
}
boolean setOccludesParent(boolean occludesParent) {
- final boolean changed = mAppWindowToken.setOccludesParent(occludesParent);
+ final boolean changed = super.setOccludesParent(occludesParent);
if (changed) {
if (!occludesParent) {
getActivityStack().convertActivityToTranslucent(this);
}
// Keep track of the number of fullscreen activities in this task.
task.numFullscreen += occludesParent ? +1 : -1;
- fullscreen = occludesParent;
}
// Always ensure visibility if this activity doesn't occlude parent, so the
// {@link #returningOptions} of the activity under this one can be applied in
@@ -1558,10 +1431,6 @@
OP_PICTURE_IN_PICTURE, info.applicationInfo.uid, packageName) == MODE_ALLOWED;
}
- boolean isAlwaysFocusable() {
- return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
- }
-
/** Move activity with its stack to front and make the stack focused. */
boolean moveFocusableActivityToTop(String reason) {
if (!isFocusable()) {
@@ -2202,9 +2071,7 @@
stack.removeTimeoutsForActivity(this);
// Clean-up activities are no longer relaunching (e.g. app process died). Notify window
// manager so it can update its bookkeeping.
- if (mAppWindowToken != null) {
- mAppWindowToken.clearRelaunching();
- }
+ clearRelaunching();
}
/**
@@ -2370,7 +2237,7 @@
*/
void applyOptionsLocked(ActivityOptions pendingOptions, Intent intent) {
final int animationType = pendingOptions.getAnimationType();
- final DisplayContent displayContent = mAppWindowToken.getDisplayContent();
+ final DisplayContent displayContent = getDisplayContent();
switch (animationType) {
case ANIM_CUSTOM:
displayContent.mAppTransition.overridePendingAppTransition(
@@ -2504,11 +2371,8 @@
if (!keysPaused) {
keysPaused = true;
- // TODO: remove the check after unification with AppWindowToken. The DC check is not
- // needed after no mock mAppWindowToken in tests.
- if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
- mAppWindowToken.getDisplayContent().getInputMonitor().pauseDispatchingLw(
- mAppWindowToken);
+ if (getDisplayContent() != null) {
+ getDisplayContent().getInputMonitor().pauseDispatchingLw(this);
}
}
}
@@ -2517,11 +2381,8 @@
if (keysPaused) {
keysPaused = false;
- // TODO: remove the check after unification with AppWindowToken. The DC check is not
- // needed after no mock mAppWindowToken in tests.
- if (mAppWindowToken != null && mAppWindowToken.getDisplayContent() != null) {
- mAppWindowToken.getDisplayContent().getInputMonitor().resumeDispatchingLw(
- mAppWindowToken);
+ if (getDisplayContent() != null) {
+ getDisplayContent().getInputMonitor().resumeDispatchingLw(this);
}
}
}
@@ -2543,12 +2404,12 @@
}
void setVisibility(boolean visible) {
- if (mAppWindowToken == null) {
+ if (getParent() == null) {
Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: "
+ appToken);
return;
}
- mAppWindowToken.setVisibility(visible, mDeferHidingClient);
+ setVisibility(visible, mDeferHidingClient);
mAtmService.addWindowLayoutReasons(
ActivityTaskManagerService.LAYOUT_REASON_VISIBILITY_CHANGED);
mStackSupervisor.getActivityMetricsLogger().notifyVisibilityChanged(this);
@@ -2584,12 +2445,12 @@
// an indication that the Surface will eventually be destroyed.
// This however isn't necessarily true if we are going to sleep.
if (state == STOPPING && !isSleeping()) {
- if (mAppWindowToken == null) {
+ if (getParent() == null) {
Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
+ appToken);
return;
}
- mAppWindowToken.detachChildren();
+ detachChildren();
}
if (state == RESUMED) {
@@ -2648,23 +2509,20 @@
}
void notifyAppResumed(boolean wasStopped) {
- if (mAppWindowToken == null) {
+ if (getParent() == null) {
Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: "
+ appToken);
return;
}
- mAppWindowToken.notifyAppResumed(wasStopped);
+ super.notifyAppResumed(wasStopped);
}
void notifyUnknownVisibilityLaunched() {
// No display activities never add a window, so there is no point in waiting them for
// relayout.
- if (!noDisplay) {
- if (mAppWindowToken != null) {
- mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
- .notifyLaunched(mAppWindowToken);
- }
+ if (!noDisplay && getDisplayContent() != null) {
+ getDisplayContent().mUnknownAppVisibilityController.notifyLaunched(this);
}
}
@@ -2964,10 +2822,7 @@
display.handleActivitySizeCompatModeIfNeeded(r);
}
- if (r.mAppWindowToken != null) {
- r.mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
- .notifyAppResumedFinished(r.mAppWindowToken);
- }
+ r.getDisplayContent().mUnknownAppVisibilityController.notifyAppResumedFinished(r);
}
/**
@@ -3115,9 +2970,7 @@
setState(STOPPED, "activityStoppedLocked");
}
- if (mAppWindowToken != null) {
- mAppWindowToken.notifyAppStopped();
- }
+ notifyAppStopped();
if (finishing) {
clearOptionsLocked();
@@ -3194,9 +3047,11 @@
stack.removeLaunchTickMessages();
}
- // IApplicationToken
+ boolean mayFreezeScreenLocked() {
+ return mayFreezeScreenLocked(app);
+ }
- public boolean mayFreezeScreenLocked(WindowProcessController app) {
+ private boolean mayFreezeScreenLocked(WindowProcessController app) {
// Only freeze the screen if this activity is currently attached to
// an application, and that application is not blocked or unresponding.
// In any other case, we can't count on getting the screen unfrozen,
@@ -3204,9 +3059,13 @@
return hasProcess() && !app.isCrashing() && !app.isNotResponding();
}
- public void startFreezingScreenLocked(WindowProcessController app, int configChanges) {
+ void startFreezingScreenLocked(int configChanges) {
+ startFreezingScreenLocked(app, configChanges);
+ }
+
+ void startFreezingScreenLocked(WindowProcessController app, int configChanges) {
if (mayFreezeScreenLocked(app)) {
- if (mAppWindowToken == null) {
+ if (getParent() == null) {
Slog.w(TAG_WM,
"Attempted to freeze screen with non-existing app token: " + appToken);
return;
@@ -3214,31 +3073,29 @@
// Window configuration changes only effect windows, so don't require a screen freeze.
int freezableConfigChanges = configChanges & ~(CONFIG_WINDOW_CONFIGURATION);
- if (freezableConfigChanges == 0 && mAppWindowToken.okToDisplay()) {
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + appToken);
+ if (freezableConfigChanges == 0 && okToDisplay()) {
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "Skipping set freeze of %s", appToken);
return;
}
- mAppWindowToken.startFreezingScreen();
+ startFreezingScreen();
}
}
- public void stopFreezingScreenLocked(boolean force) {
+ void stopFreezingScreenLocked(boolean force) {
if (force || frozenBeforeDestroy) {
frozenBeforeDestroy = false;
- if (mAppWindowToken == null) {
+ if (getParent() == null) {
return;
}
- if (DEBUG_ORIENTATION) {
- Slog.v(TAG_WM, "Clear freezing of " + appToken + ": hidden="
- + mAppWindowToken.isHidden() + " freezing="
- + mAppWindowToken.isFreezingScreen());
- }
- mAppWindowToken.stopFreezingScreen(true, force);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Clear freezing of %s: hidden=%b freezing=%b", appToken,
+ isHidden(), isFreezingScreen());
+ stopFreezingScreen(true, force);
}
}
- public void reportFullyDrawnLocked(boolean restoredFromBundle) {
+ void reportFullyDrawnLocked(boolean restoredFromBundle) {
final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
.getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
if (info != null) {
@@ -3247,74 +3104,42 @@
}
}
- /**
- * Called when the starting window for this container is drawn.
- */
- public void onStartingWindowDrawn(long timestamp) {
- synchronized (mAtmService.mGlobalLock) {
- mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
- getWindowingMode(), timestamp);
- }
- }
-
/** Called when the windows associated app window container are drawn. */
- public void onWindowsDrawn(boolean drawn, long timestamp) {
- synchronized (mAtmService.mGlobalLock) {
- mDrawn = drawn;
- if (!drawn) {
- return;
- }
- final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
- .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
- final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
- final @LaunchState int launchState = info != null ? info.getLaunchState() : -1;
- mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
- windowsDrawnDelayMs, launchState);
- mStackSupervisor.stopWaitingForActivityVisible(this);
- finishLaunchTickingLocked();
- if (task != null) {
- task.hasBeenVisible = true;
- }
+ void onWindowsDrawn(boolean drawn, long timestamp) {
+ mDrawn = drawn;
+ if (!drawn) {
+ return;
+ }
+ final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
+ .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
+ final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
+ final @LaunchState int launchState = info != null ? info.getLaunchState() : -1;
+ mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
+ windowsDrawnDelayMs, launchState);
+ mStackSupervisor.stopWaitingForActivityVisible(this);
+ finishLaunchTickingLocked();
+ if (task != null) {
+ task.hasBeenVisible = true;
}
}
/** Called when the windows associated app window container are visible. */
- public void onWindowsVisible() {
- synchronized (mAtmService.mGlobalLock) {
- mStackSupervisor.stopWaitingForActivityVisible(this);
- if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
- if (!nowVisible) {
- nowVisible = true;
- lastVisibleTime = SystemClock.uptimeMillis();
- mAtmService.scheduleAppGcsLocked();
- }
+ void onWindowsVisible() {
+ super.onWindowsVisible();
+ mStackSupervisor.stopWaitingForActivityVisible(this);
+ if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsVisibleLocked(): " + this);
+ if (!nowVisible) {
+ nowVisible = true;
+ lastVisibleTime = SystemClock.uptimeMillis();
+ mAtmService.scheduleAppGcsLocked();
}
}
/** Called when the windows associated app window container are no longer visible. */
- public void onWindowsGone() {
- synchronized (mAtmService.mGlobalLock) {
- if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
- nowVisible = false;
- }
- }
-
- void onAnimationFinished() {
- if (mRootActivityContainer.allResumedActivitiesIdle()
- || mStackSupervisor.isStoppingNoHistoryActivity()) {
- // If all activities are already idle or there is an activity that must be
- // stopped immediately after visible, then we now need to make sure we perform
- // the full stop of this activity. This is because we won't do that while they are still
- // waiting for the animation to finish.
- if (mStackSupervisor.mStoppingActivities.contains(this)) {
- mStackSupervisor.scheduleIdleLocked();
- }
- } else {
- // Instead of doing the full stop routine here, let's just hide any activities
- // we now can, and let them stop when the normal idle happens.
- mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
- false /* remove */, true /* processPausingActivities */);
- }
+ void onWindowsGone() {
+ super.onWindowsGone();
+ if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "windowsGone(): " + this);
+ nowVisible = false;
}
/**
@@ -3500,9 +3325,6 @@
void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
boolean fromRecents) {
- if (mAppWindowToken == null) {
- return;
- }
if (mTaskOverlay) {
// We don't show starting window for overlay activities.
return;
@@ -3530,26 +3352,20 @@
if (mStartingWindowState == STARTING_WINDOW_SHOWN && behindFullscreenActivity) {
if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
mStartingWindowState = STARTING_WINDOW_REMOVED;
- mAppWindowToken.removeStartingWindow();
+ removeStartingWindow();
}
}
void setRequestedOrientation(int requestedOrientation) {
- setOrientation(requestedOrientation, mayFreezeScreenLocked(app));
+ setOrientation(requestedOrientation, mayFreezeScreenLocked());
mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
task.taskId, requestedOrientation);
}
private void setOrientation(int requestedOrientation, boolean freezeScreenIfNeeded) {
- if (mAppWindowToken == null) {
- Slog.w(TAG_WM,
- "Attempted to set orientation of non-existing app token: " + appToken);
- return;
- }
-
final IBinder binder =
(freezeScreenIfNeeded && appToken != null) ? appToken.asBinder() : null;
- mAppWindowToken.setOrientation(requestedOrientation, binder, this);
+ setOrientation(requestedOrientation, binder, this);
// Push the new configuration to the requested app in case where it's not pushed, e.g. when
// the request is handled at task level with letterbox.
@@ -3559,23 +3375,6 @@
}
}
- int getOrientation() {
- if (mAppWindowToken == null) {
- return info.screenOrientation;
- }
-
- return mAppWindowToken.getOrientationIgnoreVisibility();
- }
-
- void setDisablePreviewScreenshots(boolean disable) {
- if (mAppWindowToken == null) {
- Slog.w(TAG_WM, "Attempted to set disable screenshots of non-existing app"
- + " token: " + appToken);
- return;
- }
- mAppWindowToken.setDisablePreviewScreenshots(disable);
- }
-
/**
* Set the last reported global configuration to the client. Should be called whenever a new
* global configuration is sent to the client for this activity.
@@ -3598,33 +3397,6 @@
}
/**
- * Get the configuration orientation by the requested screen orientation
- * ({@link ActivityInfo.ScreenOrientation}) of this activity.
- *
- * @return orientation in ({@link Configuration#ORIENTATION_LANDSCAPE},
- * {@link Configuration#ORIENTATION_PORTRAIT},
- * {@link Configuration#ORIENTATION_UNDEFINED}).
- */
- int getRequestedConfigurationOrientation() {
- final int screenOrientation = getOrientation();
- if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
- // NOSENSOR means the display's "natural" orientation, so return that.
- final ActivityDisplay display = getDisplay();
- if (display != null && display.mDisplayContent != null) {
- return display.mDisplayContent.getNaturalOrientation();
- }
- } else if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
- // LOCKED means the activity's orientation remains unchanged, so return existing value.
- return getConfiguration().orientation;
- } else if (isFixedOrientationLandscape(screenOrientation)) {
- return ORIENTATION_LANDSCAPE;
- } else if (isFixedOrientationPortrait(screenOrientation)) {
- return ORIENTATION_PORTRAIT;
- }
- return ORIENTATION_UNDEFINED;
- }
-
- /**
* @return {@code true} if this activity is in size compatibility mode that uses the different
* density or bounds from its parent.
*/
@@ -3705,6 +3477,8 @@
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
private void updateOverrideConfiguration() {
final Configuration overrideConfig = mTmpConfig;
+ overrideConfig.setTo(getRequestedOverrideConfiguration());
+
if (shouldUseSizeCompatMode()) {
if (mCompatDisplayInsets != null) {
// The override configuration is set only once in size compatibility mode.
@@ -3723,7 +3497,6 @@
// are relative to bounds and density, they will be calculated in
// {@link TaskRecord#computeConfigResourceOverrides} and the result will also be
// relatively fixed.
- overrideConfig.unset();
overrideConfig.colorMode = parentConfig.colorMode;
overrideConfig.densityDpi = parentConfig.densityDpi;
overrideConfig.screenLayout = parentConfig.screenLayout
@@ -3750,7 +3523,6 @@
return;
}
- overrideConfig.unset();
overrideConfig.windowConfiguration.setBounds(mTmpBounds);
}
@@ -3877,22 +3649,6 @@
onMergedOverrideConfigurationChanged();
}
- // TODO(b/80414790): Remove code below after unification.
- // Same as above it doesn't notify configuration listeners, and consequently AppWindowToken
- // can't get updated seq number. However WindowState's merged override configuration needs
- // to have this seq number because that's also used for activity config pushes during layout
- // traversal. Therefore explicitly update them here.
- if (mAppWindowToken == null) {
- return;
- }
- final Configuration appWindowTokenRequestedOverrideConfig =
- mAppWindowToken.getRequestedOverrideConfiguration();
- if (appWindowTokenRequestedOverrideConfig.seq != getResolvedOverrideConfiguration().seq) {
- appWindowTokenRequestedOverrideConfig.seq =
- getResolvedOverrideConfiguration().seq;
- mAppWindowToken.onMergedOverrideConfigurationChanged();
- }
-
final ActivityDisplay display = getDisplay();
if (display == null) {
return;
@@ -3920,7 +3676,7 @@
/** Returns true if the configuration is compatible with this activity. */
boolean isConfigurationCompatible(Configuration config) {
- final int orientation = getOrientation();
+ final int orientation = getRequestedOrientation();
if (isFixedOrientationPortrait(orientation)
&& config.orientation != ORIENTATION_PORTRAIT) {
return false;
@@ -4153,7 +3909,7 @@
if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
// Aha, the activity isn't handling the change, so DIE DIE DIE.
configChangeFlags |= changes;
- startFreezingScreenLocked(app, globalChanges);
+ startFreezingScreenLocked(globalChanges);
forceNewConfig = false;
preserveWindow &= isResizeOnlyChange(changes);
final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged());
@@ -4311,16 +4067,14 @@
: AM_RELAUNCH_ACTIVITY, mUserId, System.identityHashCode(this),
task.taskId, shortComponentName);
- startFreezingScreenLocked(app, 0);
+ startFreezingScreenLocked(0);
try {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
"Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + this
+ " callers=" + Debug.getCallers(6));
forceNewConfig = false;
- if (mAppWindowToken != null) {
- mAppWindowToken.startRelaunching();
- }
+ startRelaunching();
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
pendingNewIntents, configChangeFlags,
new MergedConfiguration(mAtmService.getGlobalConfiguration(),
@@ -4409,8 +4163,8 @@
return;
}
- if (mAppWindowToken != null) {
- mAppWindowToken.startFreezingScreen();
+ if (getParent() != null) {
+ startFreezingScreen();
}
// The process will be killed until the activity reports stopped with saved state (see
// {@link ActivityTaskManagerService.activityStopped}).
@@ -4578,67 +4332,24 @@
return info.applicationInfo.uid;
}
- void setShowWhenLocked(boolean showWhenLocked) {
- mShowWhenLocked = showWhenLocked;
- mRootActivityContainer.ensureActivitiesVisible(null, 0 /* configChanges */,
- false /* preserveWindows */);
- }
-
- void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
- mInheritShownWhenLocked = inheritShowWhenLocked;
- mRootActivityContainer.ensureActivitiesVisible(null, 0, false);
- }
-
- /**
- * @return true if the activity windowing mode is not
- * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and a) activity
- * contains windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the
- * activity has set {@link #mShowWhenLocked}, or b) if the activity has set
- * {@link #mInheritShownWhenLocked} and the activity behind this satisfies the
- * conditions a) above.
- * Multi-windowing mode will be exited if true is returned.
- */
- boolean canShowWhenLocked() {
- if (!inPinnedWindowingMode() && (mShowWhenLocked
- || (mAppWindowToken != null && mAppWindowToken.containsShowWhenLockedWindow()))) {
- return true;
- } else if (mInheritShownWhenLocked) {
- ActivityRecord r = getActivityBelow();
- return r != null && !r.inPinnedWindowingMode() && (r.mShowWhenLocked
- || (r.mAppWindowToken != null
- && r.mAppWindowToken.containsShowWhenLockedWindow()));
- } else {
- return false;
- }
- }
-
- /**
- * @return an {@link ActivityRecord} of the activity below this activity, or {@code null} if no
- * such activity exists.
- */
- @Nullable
- private ActivityRecord getActivityBelow() {
- final int pos = task.mActivities.indexOf(this);
- if (pos == -1) {
- throw new IllegalStateException("Activity not found in its task");
- }
- return pos == 0 ? null : task.getChildAt(pos - 1);
- }
-
- void setTurnScreenOn(boolean turnScreenOn) {
- mTurnScreenOn = turnScreenOn;
+ @Override
+ int getPid() {
+ return app != null ? app.getPid() : 0;
}
/**
* Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
- * {@link #mTurnScreenOn} is set and checks whether the ActivityRecord should be visible
- * depending on Keyguard state
+ * {@link AppWindowToken#getTurnScreenOnFlag} is set and checks whether the ActivityRecord
+ * should be visible depending on Keyguard state
*
* @return true if the screen can be turned on, false otherwise.
*/
boolean canTurnScreenOn() {
+ if (!getTurnScreenOnFlag()) {
+ return false;
+ }
final ActivityStack stack = getActivityStack();
- return mTurnScreenOn && stack != null &&
+ return stack != null &&
stack.checkKeyguardVisibility(this, true /* shouldBeVisible */, true /* isTop */);
}
@@ -4652,10 +4363,6 @@
return app == null || app.updateTopResumingActivityInProcessIfNeeded(this);
}
- boolean getTurnScreenOnFlag() {
- return mTurnScreenOn;
- }
-
boolean isTopRunningActivity() {
return mRootActivityContainer.topRunningActivity() == this;
}
@@ -4690,20 +4397,11 @@
return task.getChildAt(0) == this;
}
- void registerRemoteAnimations(RemoteAnimationDefinition definition) {
- if (mAppWindowToken == null) {
- Slog.w(TAG_WM, "Attempted to register remote animations with non-existing app"
- + " token: " + appToken);
- return;
- }
- mAppWindowToken.registerRemoteAnimations(definition);
- }
-
@Override
public String toString() {
if (stringName != null) {
return stringName + " t" + (task == null ? INVALID_TASK_ID : task.taskId) +
- (finishing ? " f}" : "}");
+ (finishing ? " f}" : "") + (mIsExiting ? " mIsExiting=" : "") + "}";
}
StringBuilder sb = new StringBuilder(128);
sb.append("ActivityRecord{");
@@ -4713,15 +4411,7 @@
sb.append(' ');
sb.append(intent.getComponent().flattenToShortString());
stringName = sb.toString();
- return toString();
- }
-
- void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
- proto.write(HASH_CODE, System.identityHashCode(this));
- proto.write(USER_ID, mUserId);
- proto.write(TITLE, intent.getComponent().flattenToShortString());
- proto.end(token);
+ return stringName;
}
/**
@@ -4729,7 +4419,7 @@
* {@code ActivityRecordProto} is the outer-most proto data.
*/
void writeToProto(ProtoOutputStream proto) {
- super.writeToProto(proto, CONFIGURATION_CONTAINER, WindowTraceLogLevel.ALL);
+ super.writeToProto(proto, APP_WINDOW_TOKEN, WindowTraceLogLevel.ALL);
writeIdentifierToProto(proto, IDENTIFIER);
proto.write(STATE, mState.toString());
proto.write(VISIBLE, visible);
@@ -4737,7 +4427,7 @@
if (hasProcess()) {
proto.write(PROC_ID, app.getPid());
}
- proto.write(TRANSLUCENT, !fullscreen);
+ proto.write(TRANSLUCENT, !occludesParent());
}
public void writeToProto(ProtoOutputStream proto, long fieldId) {
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 2ab3e01..24f58f1 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -1896,7 +1896,7 @@
continue;
}
- if (r.fullscreen || r.hasWallpaper) {
+ if (r.occludesParent() || r.hasWallpaper) {
// Stack isn't translucent if it has at least one fullscreen activity
// that is visible.
return false;
@@ -2106,7 +2106,11 @@
boolean aboveTop = top != null;
final boolean stackShouldBeVisible = shouldBeVisible(starting);
boolean behindFullscreenActivity = !stackShouldBeVisible;
- final boolean resumeTopActivity = isFocusable() && isInStackLocked(starting) == null;
+ // We should not resume activities that being launched behind because these
+ // activities are actually behind other fullscreen activities, but still required
+ // to be visible (such as performing Recents animation).
+ final boolean resumeTopActivity = isFocusable() && isInStackLocked(starting) == null
+ && top != null && !top.mLaunchTaskBehind;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
final ArrayList<ActivityRecord> activities = task.mActivities;
@@ -2255,8 +2259,7 @@
.isKeyguardOrAodShowing(displayId);
final boolean keyguardLocked = mStackSupervisor.getKeyguardController().isKeyguardLocked();
final boolean showWhenLocked = r.canShowWhenLocked();
- final boolean dismissKeyguard = r.mAppWindowToken != null
- && r.mAppWindowToken.containsDismissKeyguardWindow();
+ final boolean dismissKeyguard = r.containsDismissKeyguardWindow();
if (shouldBeVisible) {
if (dismissKeyguard && mTopDismissingKeyguardActivity == null) {
mTopDismissingKeyguardActivity = r;
@@ -2325,18 +2328,14 @@
// get it started and resume if no other stack in this stack is resumed.
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
if (r != starting) {
- r.startFreezingScreenLocked(r.app, configChanges);
+ r.startFreezingScreenLocked(configChanges);
}
if (!r.visible || r.mLaunchTaskBehind) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
r.setVisible(true);
}
if (r != starting) {
- // We should not resume activities that being launched behind because these
- // activities are actually behind other fullscreen activities, but still required
- // to be visible (such as performing Recents animation).
- mStackSupervisor.startSpecificActivityLocked(r, andResume && !r.mLaunchTaskBehind,
- true /* checkConfig */);
+ mStackSupervisor.startSpecificActivityLocked(r, andResume, true /* checkConfig */);
return true;
}
}
@@ -2345,7 +2344,7 @@
private boolean updateBehindFullscreen(boolean stackInvisible, boolean behindFullscreenActivity,
ActivityRecord r) {
- if (r.fullscreen) {
+ if (r.occludesParent()) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r
+ " stackInvisible=" + stackInvisible
+ " behindFullscreenActivity=" + behindFullscreenActivity);
@@ -2431,12 +2430,12 @@
if (r == topActivity) {
aboveTop = false;
}
- behindFullscreenActivity |= r.fullscreen;
+ behindFullscreenActivity |= r.occludesParent();
continue;
}
r.removeOrphanedStartingWindow(behindFullscreenActivity);
- behindFullscreenActivity |= r.fullscreen;
+ behindFullscreenActivity |= r.occludesParent();
}
}
}
@@ -2566,8 +2565,7 @@
final boolean canShowWhenLocked = !mTopActivityOccludesKeyguard
&& next.canShowWhenLocked();
final boolean mayDismissKeyguard = mTopDismissingKeyguardActivity != next
- && next.mAppWindowToken != null
- && next.mAppWindowToken.containsDismissKeyguardWindow();
+ && next.containsDismissKeyguardWindow();
if (canShowWhenLocked || mayDismissKeyguard) {
ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
@@ -2776,7 +2774,7 @@
final boolean lastActivityTranslucent = lastFocusedStack != null
&& (lastFocusedStack.inMultiWindowMode()
|| (lastFocusedStack.mLastPausedActivity != null
- && !lastFocusedStack.mLastPausedActivity.fullscreen));
+ && !lastFocusedStack.mLastPausedActivity.occludesParent()));
// This activity is now becoming visible.
if (!next.visible || next.stopped || lastActivityTranslucent) {
@@ -3055,7 +3053,7 @@
if (!startIt) {
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
+ task, new RuntimeException("here").fillInStackTrace());
- r.createAppWindowToken();
+ r.setTask(rTask);
ActivityOptions.abort(options);
return;
}
@@ -3082,12 +3080,7 @@
// Slot the activity into the history stack and proceed
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
new RuntimeException("here").fillInStackTrace());
- // TODO: Need to investigate if it is okay for the controller to already be created by the
- // time we get to this point. I think it is, but need to double check.
- // Use test in b/34179495 to trace the call path.
- if (r.mAppWindowToken == null) {
- r.createAppWindowToken();
- }
+ r.setTask(task);
// The transition animation and starting window are not needed if {@code allowMoveToFront}
// is false, because the activity won't be visible.
@@ -3944,7 +3937,7 @@
if (r.finishing) {
continue;
}
- if (r.fullscreen) {
+ if (r.occludesParent()) {
lastIsOpaque = true;
}
if (owner != null && r.app != owner) {
@@ -4335,7 +4328,7 @@
final ActivityRecord r = activities.get(activityIndex);
updatedConfig |= r.ensureActivityConfiguration(0 /* globalChanges */,
preserveWindow);
- if (r.fullscreen) {
+ if (r.occludesParent()) {
behindFullscreen = true;
break;
}
@@ -4438,7 +4431,7 @@
if (r.appToken == token) {
return true;
}
- if (r.fullscreen && !r.finishing) {
+ if (r.occludesParent() && !r.finishing) {
return false;
}
}
@@ -4718,8 +4711,7 @@
if (a.info.packageName.equals(packageName)) {
a.forceNewConfig = true;
if (starting != null && a == starting && a.visible) {
- a.startFreezingScreenLocked(starting.app,
- CONFIG_SCREEN_LAYOUT);
+ a.startFreezingScreenLocked(CONFIG_SCREEN_LAYOUT);
}
}
}
@@ -4950,7 +4942,7 @@
if (top != null && !top.isConfigurationCompatible(parentConfig)) {
// The final orientation of this activity will change after moving to full screen.
// Start freezing screen here to prevent showing a temporary full screen window.
- top.startFreezingScreenLocked(top.app, CONFIG_SCREEN_LAYOUT);
+ top.startFreezingScreenLocked(CONFIG_SCREEN_LAYOUT);
mService.moveTasksToFullscreenStack(mStackId, true /* onTop */);
return;
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index d151f86..3dff51d 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1901,7 +1901,7 @@
"Added restored task=" + task + " to stack=" + stack);
final ArrayList<ActivityRecord> activities = task.mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
- activities.get(activityNdx).createAppWindowToken();
+ activities.get(activityNdx).setTask(task);
}
return true;
}
@@ -2123,6 +2123,7 @@
return false;
}
+ // TODO: Change method name to reflect what it actually does.
final ArrayList<ActivityRecord> processStoppingActivitiesLocked(ActivityRecord idleActivity,
boolean remove, boolean processPausingActivities) {
ArrayList<ActivityRecord> stops = null;
@@ -2131,7 +2132,7 @@
for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord s = mStoppingActivities.get(activityNdx);
- final boolean animating = s.mAppWindowToken.isSelfAnimating();
+ final boolean animating = s.isSelfAnimating();
if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
+ " animating=" + animating + " finishing=" + s.finishing);
@@ -2482,9 +2483,7 @@
void activityRelaunchedLocked(IBinder token) {
final ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r != null) {
- if (r.mAppWindowToken != null) {
- r.mAppWindowToken.finishRelaunching();
- }
+ r.finishRelaunching();
if (r.getActivityStack().shouldSleepOrShutDownActivities()) {
r.setSleeping(true, true);
}
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 919141c..6ee64f3 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -386,6 +386,8 @@
throw new IllegalArgumentException("File descriptors passed in Intent");
}
+ // Get the flag earlier because the intent may be modified in resolveActivity below.
+ final boolean componentSpecified = intent.getComponent() != null;
// Don't modify the client's object!
intent = new Intent(intent);
@@ -409,7 +411,6 @@
.setCaller(caller)
.setResolvedType(resolvedTypes[i])
.setActivityInfo(aInfo)
- .setResultTo(resultTo)
.setRequestCode(-1)
.setCallingPid(callingPid)
.setCallingUid(callingUid)
@@ -417,7 +418,7 @@
.setRealCallingPid(realCallingPid)
.setRealCallingUid(realCallingUid)
.setActivityOptions(checkedOptions)
- .setComponentSpecified(intent.getComponent() != null)
+ .setComponentSpecified(componentSpecified)
// Top activity decides on animation being run, so we allow only for the
// top one as otherwise an activity below might consume it.
@@ -430,7 +431,8 @@
// Lock the loop to ensure the activities launched in a sequence.
synchronized (mService.mGlobalLock) {
for (int i = 0; i < starters.length; i++) {
- final int startResult = starters[i].setOutActivity(outActivity).execute();
+ final int startResult = starters[i].setResultTo(resultTo)
+ .setOutActivity(outActivity).execute();
if (startResult < START_SUCCESS) {
// Abort by error result and recycle unused starters.
for (int j = i + 1; j < starters.length; j++) {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 54bb5f7..38e5e3e 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1684,14 +1684,16 @@
== (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
&& mLaunchMode == LAUNCH_MULTIPLE;
- // If mStartActivity does not have a task associated with it, associate it with the
- // reused activity's task. Do not do so if we're clearing top and resetting for a
- // standard launchMode activity.
- if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
- mStartActivity.setTask(targetTask);
- }
-
+ boolean clearTaskForReuse = false;
if (reusedActivity != null) {
+ // If mStartActivity does not have a task associated with it, associate it with the
+ // reused activity's task. Do not do so if we're clearing top and resetting for a
+ // standard launchMode activity.
+ if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
+ mStartActivity.setTaskForReuse(reusedActivity.getTaskRecord());
+ clearTaskForReuse = true;
+ }
+
if (targetTask.intent == null) {
// This task was started because of movement of the activity based on
// affinity...
@@ -1739,6 +1741,13 @@
complyActivityFlags(targetTask, reusedActivity);
+ if (clearTaskForReuse) {
+ // Clear task for re-use so later code to methods
+ // {@link #setTaskFromReuseOrCreateNewTask}, {@link #setTaskFromSourceRecord}, or
+ // {@link #setTaskFromInTask} can parent it to the task.
+ mStartActivity.setTaskForReuse(null);
+ }
+
if (mAddingToTask) {
return START_SUCCESS;
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 468a13d..299ab8a 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -807,7 +807,7 @@
mUiHandler = new UiHandler();
mIntentFirewall = intentFirewall;
final File systemDir = SystemServiceManager.ensureSystemDir();
- mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
+ mAppWarnings = createAppWarnings(mUiContext, mH, mUiHandler, systemDir);
mCompatModePackages = new CompatModePackages(this, systemDir, mH);
mPendingIntentController = intentController;
@@ -845,6 +845,11 @@
return supervisor;
}
+ protected AppWarnings createAppWarnings(
+ Context uiContext, Handler handler, Handler uiHandler, File systemDir) {
+ return new AppWarnings(this, uiContext, handler, uiHandler, systemDir);
+ }
+
public void setWindowManager(WindowManagerService wm) {
synchronized (mGlobalLock) {
mWindowManager = wm;
@@ -1813,11 +1818,9 @@
@Override
public int getRequestedOrientation(IBinder token) {
synchronized (mGlobalLock) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
- }
- return r.getOrientation();
+ final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ return (r != null)
+ ? r.getRequestedOrientation() : ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 66d52cc..93c461f 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -70,8 +70,9 @@
import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
import static com.android.server.wm.AppTransitionProto.APP_TRANSITION_STATE;
import static com.android.server.wm.AppTransitionProto.LAST_USED_APP_TRANSITION;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
@@ -131,6 +132,7 @@
import com.android.internal.util.DumpUtils.Dump;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.AttributeCache;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.animation.ClipRectLRAnimation;
import com.android.server.wm.animation.ClipRectTBAnimation;
import com.android.server.wm.animation.CurvedTranslateAnimation;
@@ -1630,70 +1632,61 @@
a = loadAnimationRes(lp, enter
? com.android.internal.R.anim.voice_activity_open_enter
: com.android.internal.R.anim.voice_activity_open_exit);
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
- "applyAnimation voice:"
- + " anim=" + a + " transit=" + appTransitionToString(transit)
- + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", a,
+ appTransitionToString(transit), enter, Debug.getCallers(3));
} else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE
|| transit == TRANSIT_TASK_CLOSE
|| transit == TRANSIT_TASK_TO_BACK)) {
a = loadAnimationRes(lp, enter
? com.android.internal.R.anim.voice_activity_close_enter
: com.android.internal.R.anim.voice_activity_close_exit);
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
- "applyAnimation voice:"
- + " anim=" + a + " transit=" + appTransitionToString(transit)
- + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", a,
+ appTransitionToString(transit), enter, Debug.getCallers(3));
} else if (transit == TRANSIT_ACTIVITY_RELAUNCH) {
a = createRelaunchAnimation(frame, insets);
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
- "applyAnimation:"
- + " anim=" + a + " nextAppTransition=" + mNextAppTransition
- + " transit=" + appTransitionToString(transit)
- + " Callers=" + Debug.getCallers(3));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: anim=%s nextAppTransition=%d transit=%s Callers=%s", a,
+ mNextAppTransition, appTransitionToString(transit),
+ Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
a = loadAnimationRes(mNextAppTransitionPackage, enter ?
mNextAppTransitionEnter : mNextAppTransitionExit);
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
- "applyAnimation:"
- + " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
- + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
- + " Callers=" + Debug.getCallers(3));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s "
+ + "isEntrance=%b Callers=%s",
+ a, appTransitionToString(transit), enter, Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
- "applyAnimation:"
- + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
- + " transit=" + appTransitionToString(transit)
- + " Callers=" + Debug.getCallers(3));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM_IN_PLACE "
+ + "transit=%s Callers=%s",
+ a, appTransitionToString(transit), Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
a = createClipRevealAnimationLocked(transit, enter, frame, displayFrame);
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
- "applyAnimation:"
- + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL"
- + " transit=" + appTransitionToString(transit)
- + " Callers=" + Debug.getCallers(3));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL "
+ + "transit=%s Callers=%s",
+ a, appTransitionToString(transit), Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
a = createScaleUpAnimationLocked(transit, enter, frame);
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
- "applyAnimation:"
- + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
- + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
- + " Callers=" + Debug.getCallers(3));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: anim=%s nextAppTransition=ANIM_SCALE_UP transit=%s "
+ + "isEntrance=%s Callers=%s",
+ a, appTransitionToString(transit), enter, Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
mNextAppTransitionScaleUp =
(mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
frame, transit, taskId);
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
- String animName = mNextAppTransitionScaleUp ?
- "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
- Slog.v(TAG, "applyAnimation:"
- + " anim=" + a + " nextAppTransition=" + animName
- + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
- + " Callers=" + Debug.getCallers(3));
- }
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b "
+ + "Callers=%s",
+ a, mNextAppTransitionScaleUp
+ ? "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN",
+ appTransitionToString(transit), enter, Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN) {
mNextAppTransitionScaleUp =
@@ -1701,30 +1694,27 @@
a = createAspectScaledThumbnailEnterExitAnimationLocked(
getThumbnailTransitionState(enter), uiMode, orientation, transit, frame,
insets, surfaceInsets, stableInsets, freeform, taskId);
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
- String animName = mNextAppTransitionScaleUp ?
- "ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN";
- Slog.v(TAG, "applyAnimation:"
- + " anim=" + a + " nextAppTransition=" + animName
- + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
- + " Callers=" + Debug.getCallers(3));
- }
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b "
+ + "Callers=%s",
+ a, mNextAppTransitionScaleUp
+ ? "ANIM_THUMBNAIL_ASPECT_SCALE_UP"
+ : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN",
+ appTransitionToString(transit), enter, Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS && enter) {
a = loadAnimationRes("android",
com.android.internal.R.anim.task_open_enter_cross_profile_apps);
- Slog.v(TAG,
- "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS:"
- + " anim=" + a + " transit=" + appTransitionToString(transit)
- + " isEntrance=true" + " Callers=" + Debug.getCallers(3));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: "
+ + "anim=%s transit=%s isEntrance=true Callers=%s",
+ a, appTransitionToString(transit), Debug.getCallers(3));
} else if (transit == TRANSIT_TASK_CHANGE_WINDOWING_MODE) {
// In the absence of a specific adapter, we just want to keep everything stationary.
a = new AlphaAnimation(1.f, 1.f);
a.setDuration(WindowChangeAnimationSpec.ANIMATION_DURATION);
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
- Slog.v(TAG, "applyAnimation:"
- + " anim=" + a + " transit=" + appTransitionToString(transit)
- + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
- }
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: anim=%s transit=%s isEntrance=%b Callers=%s",
+ a, appTransitionToString(transit), enter, Debug.getCallers(3));
} else {
int animAttr = 0;
switch (transit) {
@@ -1787,12 +1777,11 @@
: WindowAnimation_launchTaskBehindTargetAnimation;
}
a = animAttr != 0 ? loadAnimationAttr(lp, animAttr, transit) : null;
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
- "applyAnimation:"
- + " anim=" + a
- + " animAttr=0x" + Integer.toHexString(animAttr)
- + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
- + " Callers=" + Debug.getCallers(3));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b "
+ + "Callers=%s",
+ a, animAttr, appTransitionToString(transit), enter,
+ Debug.getCallers(3));
}
return a;
}
@@ -1941,8 +1930,8 @@
}
void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter) {
- if (DEBUG_APP_TRANSITIONS) Slog.i(TAG, "Override pending remote transitionSet="
- + isTransitionSet() + " adapter=" + remoteAnimationAdapter);
+ ProtoLog.i(WM_DEBUG_APP_TRANSITIONS, "Override pending remote transitionSet=%b adapter=%s",
+ isTransitionSet(), remoteAnimationAdapter);
if (isTransitionSet()) {
clear();
mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE;
@@ -2214,12 +2203,11 @@
*/
boolean prepareAppTransitionLocked(@TransitionType int transit, boolean alwaysKeepCurrent,
@TransitionFlags int flags, boolean forceOverride) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:"
- + " transit=" + appTransitionToString(transit)
- + " " + this
- + " alwaysKeepCurrent=" + alwaysKeepCurrent
- + " displayId=" + mDisplayContent.getDisplayId()
- + " Callers=" + Debug.getCallers(5));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "Prepare app transition: transit=%s %s alwaysKeepCurrent=%b displayId=%d "
+ + "Callers=%s",
+ appTransitionToString(transit), this, alwaysKeepCurrent,
+ mDisplayContent.getDisplayId(), Debug.getCallers(5));
final boolean allowSetCrashing = !isKeyguardTransit(mNextAppTransition)
&& transit == TRANSIT_CRASHING_ACTIVITY_CLOSE;
if (forceOverride || isKeyguardTransit(transit) || !isTransitionSet()
@@ -2305,15 +2293,14 @@
}
if (isTransitionSet() || !dc.mOpeningApps.isEmpty() || !dc.mClosingApps.isEmpty()
|| !dc.mChangingApps.isEmpty()) {
- if (DEBUG_APP_TRANSITIONS) {
- Slog.v(TAG_WM, "*** APP TRANSITION TIMEOUT."
- + " displayId=" + dc.getDisplayId()
- + " isTransitionSet()="
- + dc.mAppTransition.isTransitionSet()
- + " mOpeningApps.size()=" + dc.mOpeningApps.size()
- + " mClosingApps.size()=" + dc.mClosingApps.size()
- + " mChangingApps.size()=" + dc.mChangingApps.size());
- }
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "*** APP TRANSITION TIMEOUT. displayId=%d isTransitionSet()=%b "
+ + "mOpeningApps.size()=%d mClosingApps.size()=%d "
+ + "mChangingApps.size()=%d",
+ dc.getDisplayId(), dc.mAppTransition.isTransitionSet(),
+ dc.mOpeningApps.size(), dc.mClosingApps.size(),
+ dc.mChangingApps.size());
+
setTimeout();
mService.mWindowPlacerLocked.performSurfacePlacement();
}
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 59f086e..20a871b 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -48,7 +48,7 @@
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
import static com.android.server.wm.AppTransition.isKeyguardGoingAwayTransit;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -66,6 +66,7 @@
import android.view.animation.Animation;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.protolog.common.ProtoLog;
import java.util.function.Predicate;
@@ -104,7 +105,7 @@
}
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "**** GOOD TO GO");
final AppTransition appTransition = mDisplayContent.mAppTransition;
int transit = appTransition.getAppTransition();
if (mDisplayContent.mSkipAppTransitionAnimation && !isKeyguardGoingAwayTransit(transit)) {
@@ -348,7 +349,7 @@
final int appsCount = openingApps.size();
for (int i = 0; i < appsCount; i++) {
AppWindowToken wtoken = openingApps.valueAt(i);
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Now opening app %s", wtoken);
if (!wtoken.commitVisibility(animLp, true, transit, false, voiceInteraction)) {
// This token isn't going to be animating. Add it to the list of tokens to
@@ -383,7 +384,7 @@
for (int i = 0; i < appsCount; i++) {
AppWindowToken wtoken = closingApps.valueAt(i);
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Now closing app %s", wtoken);
// TODO: Do we need to add to mNoAnimationNotifyOnTransitionFinished like above if not
// animating?
wtoken.commitVisibility(animLp, false, transit, false, voiceInteraction);
@@ -410,7 +411,7 @@
final int appsCount = apps.size();
for (int i = 0; i < appsCount; i++) {
AppWindowToken wtoken = apps.valueAt(i);
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now changing app" + wtoken);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Now changing app %s", wtoken);
wtoken.cancelAnimationOnly();
wtoken.applyAnimationLocked(null, transit, true, false);
wtoken.updateReportedVisibilityLocked();
@@ -445,10 +446,9 @@
}
private boolean transitionGoodToGo(ArraySet<AppWindowToken> apps, SparseIntArray outReasons) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "Checking " + apps.size() + " opening apps (frozen="
- + mService.mDisplayFrozen + " timeout="
- + mDisplayContent.mAppTransition.isTimeout() + ")...");
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "Checking %d opening apps (frozen=%b timeout=%b)...", apps.size(),
+ mService.mDisplayFrozen, mDisplayContent.mAppTransition.isTimeout());
final ScreenRotationAnimation screenRotationAnimation = mService.mRoot.getDisplayContent(
Display.DEFAULT_DISPLAY).getRotationAnimation();
@@ -463,20 +463,18 @@
// app transition.
if (screenRotationAnimation != null && screenRotationAnimation.isAnimating() &&
mDisplayContent.getDisplayRotation().needsUpdate()) {
- if (DEBUG_APP_TRANSITIONS) {
- Slog.v(TAG, "Delaying app transition for screen rotation animation to finish");
- }
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "Delaying app transition for screen rotation animation to finish");
return false;
}
for (int i = 0; i < apps.size(); i++) {
AppWindowToken wtoken = apps.valueAt(i);
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "Check opening app=" + wtoken + ": allDrawn="
- + wtoken.allDrawn + " startingDisplayed="
- + wtoken.startingDisplayed + " startingMoved="
- + wtoken.startingMoved + " isRelaunching()="
- + wtoken.isRelaunching() + " startingWindow="
- + wtoken.startingWindow);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "Check opening app=%s: allDrawn=%b startingDisplayed=%b "
+ + "startingMoved=%b isRelaunching()=%b startingWindow=%s",
+ wtoken, wtoken.allDrawn, wtoken.startingDisplayed,
+ wtoken.startingMoved, wtoken.isRelaunching(),
+ wtoken.startingWindow);
final boolean allDrawn = wtoken.allDrawn && !wtoken.isRelaunching();
@@ -496,15 +494,13 @@
// We also need to wait for the specs to be fetched, if needed.
if (mDisplayContent.mAppTransition.isFetchingAppTransitionsSpecs()) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "isFetchingAppTransitionSpecs=true");
return false;
}
if (!mDisplayContent.mUnknownAppVisibilityController.allResolved()) {
- if (DEBUG_APP_TRANSITIONS) {
- Slog.v(TAG, "unknownApps is not empty: "
- + mDisplayContent.mUnknownAppVisibilityController.getDebugMessage());
- }
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "unknownApps is not empty: %s",
+ mDisplayContent.mUnknownAppVisibilityController.getDebugMessage());
return false;
}
@@ -549,22 +545,20 @@
true /* ignoreHidden */);
boolean openingCanBeWallpaperTarget = canBeWallpaperTarget(openingApps);
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New wallpaper target=" + wallpaperTarget
- + ", oldWallpaper=" + oldWallpaper
- + ", openingApps=" + openingApps
- + ", closingApps=" + closingApps);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "New wallpaper target=%s, oldWallpaper=%s, openingApps=%s, closingApps=%s",
+ wallpaperTarget, oldWallpaper, openingApps, closingApps);
if (openingCanBeWallpaperTarget && transit == TRANSIT_KEYGUARD_GOING_AWAY) {
transit = TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit: " + AppTransition.appTransitionToString(transit));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "New transit: %s", AppTransition.appTransitionToString(transit));
}
// We never want to change from a Keyguard transit to a non-Keyguard transit, as our logic
// relies on the fact that we always execute a Keyguard transition after preparing one.
else if (!isKeyguardGoingAwayTransit(transit)) {
if (closingAppHasWallpaper && openingAppHasWallpaper) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Wallpaper animation!");
switch (transit) {
case TRANSIT_ACTIVITY_OPEN:
case TRANSIT_TASK_OPEN:
@@ -577,16 +571,17 @@
transit = TRANSIT_WALLPAPER_INTRA_CLOSE;
break;
}
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit: " + AppTransition.appTransitionToString(transit));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "New transit: %s", AppTransition.appTransitionToString(transit));
} else if (oldWallpaper != null && !mDisplayContent.mOpeningApps.isEmpty()
&& !openingApps.contains(oldWallpaper.mAppToken)
&& closingApps.contains(oldWallpaper.mAppToken)
&& topClosingApp == oldWallpaper.mAppToken) {
// We are transitioning from an activity with a wallpaper to one without.
transit = TRANSIT_WALLPAPER_CLOSE;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit away from wallpaper: "
- + AppTransition.appTransitionToString(transit));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "New transit away from wallpaper: %s",
+ AppTransition.appTransitionToString(transit));
} else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw()
&& openingApps.contains(wallpaperTarget.mAppToken)
&& topOpeningApp == wallpaperTarget.mAppToken
@@ -594,8 +589,8 @@
// We are transitioning from an activity without
// a wallpaper to now showing the wallpaper
transit = TRANSIT_WALLPAPER_OPEN;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit into wallpaper: "
- + AppTransition.appTransitionToString(transit));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "New transit into wallpaper: %s",
+ AppTransition.appTransitionToString(transit));
}
}
return transit;
@@ -722,8 +717,7 @@
final WindowState win = mDisplayContent.findFocusedWindow();
if (win != null) {
final AppWindowToken wtoken = win.mAppToken;
- if (DEBUG_APP_TRANSITIONS)
- Slog.v(TAG, "Now animating app in place " + wtoken);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Now animating app in place %s", wtoken);
wtoken.cancelAnimation();
wtoken.applyAnimationLocked(null, transit, false, false);
wtoken.updateReportedVisibilityLocked();
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
index b52ade4..2b05024 100644
--- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java
+++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
@@ -22,7 +22,7 @@
import static com.android.server.wm.AppWindowThumbnailProto.HEIGHT;
import static com.android.server.wm.AppWindowThumbnailProto.SURFACE_ANIMATOR;
import static com.android.server.wm.AppWindowThumbnailProto.WIDTH;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
@@ -31,7 +31,6 @@
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Binder;
-import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -39,6 +38,7 @@
import android.view.SurfaceControl.Transaction;
import android.view.animation.Animation;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.SurfaceAnimator.Animatable;
import java.util.function.Supplier;
@@ -104,9 +104,7 @@
window != null ? window.mOwnerUid : Binder.getCallingUid())
.build();
- if (SHOW_TRANSACTIONS) {
- Slog.i(TAG, " THUMBNAIL " + mSurfaceControl + ": CREATE");
- }
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, " THUMBNAIL %s: CREATE", mSurfaceControl);
// Transfer the thumbnail to the surface
drawSurface.copyFrom(mSurfaceControl);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index fc350cd..721de61 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -21,8 +21,15 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.COLOR_MODE_DEFAULT;
+import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
+import static android.content.pm.ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED;
+import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
+import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
+import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
@@ -62,17 +69,19 @@
import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW;
import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL;
import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.IdentifierProto.HASH_CODE;
+import static com.android.server.wm.IdentifierProto.TITLE;
+import static com.android.server.wm.IdentifierProto.USER_ID;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
@@ -85,12 +94,17 @@
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
import android.annotation.CallSuper;
+import android.annotation.Nullable;
import android.annotation.Size;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Point;
@@ -99,14 +113,13 @@
import android.os.Build;
import android.os.Debug;
import android.os.IBinder;
-import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
+import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayInfo;
-import android.view.IApplicationToken;
import android.view.InputApplicationHandle;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
@@ -124,6 +137,7 @@
import com.android.server.display.color.ColorDisplayService;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.policy.WindowManagerPolicy.StartingSurface;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.RemoteAnimationController.RemoteAnimationRecord;
import com.android.server.wm.WindowManagerService.H;
@@ -140,8 +154,8 @@
* Version of WindowToken that is specifically for a particular application (or
* really activity) that is displaying windows.
*/
-class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener,
- ConfigurationContainerListener {
+// TODO: Fully merge this class into ActivityRecord class since they are really the same thing...
+class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM;
/**
@@ -149,17 +163,36 @@
*/
@VisibleForTesting static final int Z_BOOST_BASE = 800570000;
+ final ActivityTaskManagerService mAtmService;
// Non-null only for application tokens.
- final IApplicationToken appToken;
+ // TODO: rename to mActivityToken
+ final ActivityRecord.Token appToken;
+ // All about me
+ final ActivityInfo mActivityInfo;
+ // Which user is this running for?
+ final int mUserId;
+ // The package implementing intent's component
+ // TODO: rename to mPackageName
+ final String packageName;
+ // the intent component, or target of an alias.
final ComponentName mActivityComponent;
- final boolean mVoiceInteraction;
+ boolean mVoiceInteraction;
/**
* The activity is opaque and fills the entire space of this task.
* @see WindowContainer#fillsParent()
*/
private boolean mOccludesParent;
+ // Has a wallpaper window as a background.
+ // TODO: Rename to mHasWallpaper and also see if it possible to combine this with the
+ // mOccludesParent field.
+ final boolean hasWallpaper;
+ // activity is not displayed?
+ // TODO: rename to mNoDisplay
+ @VisibleForTesting
+ boolean noDisplay;
boolean mShowForAllUsers;
+ // TODO: Make this final
int mTargetSdk;
// Flag set while reparenting to prevent actions normally triggered by an individual parent
@@ -234,10 +267,12 @@
boolean mLaunchTaskBehind;
boolean mEnteringAnimation;
- private boolean mAlwaysFocusable;
-
boolean mAppStopped;
- int mRotationAnimationHint;
+ // A hint to override the window specified rotation animation, or -1 to use the window specified
+ // value. We use this so that we can select the right animation in the cases of starting
+ // windows, where the app hasn't had time to set a value on the window.
+ int mRotationAnimationHint = -1;
+
private int mPendingRelaunchCount;
private boolean mLastContainsShowWhenLockedWindow;
@@ -261,9 +296,6 @@
private Task mLastParent;
- // TODO: Remove after unification
- ActivityRecord mActivityRecord;
-
/**
* @see #currentLaunchCanTurnScreenOn()
*/
@@ -327,6 +359,10 @@
private static final int STARTING_WINDOW_TYPE_SNAPSHOT = 1;
private static final int STARTING_WINDOW_TYPE_SPLASH_SCREEN = 2;
+ private boolean mShowWhenLocked;
+ private boolean mInheritShownWhenLocked;
+ private boolean mTurnScreenOn;
+
private AppSaturationInfo mLastAppSaturationInfo;
private final ColorDisplayService.ColorTransformController mColorTransformController =
@@ -341,23 +377,67 @@
}
});
- AppWindowToken(WindowManagerService service, IApplicationToken token,
- ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
- long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
- int targetSdk, int orientation, int rotationAnimationHint,
- boolean launchTaskBehind, boolean alwaysFocusable,
- ActivityRecord activityRecord) {
- this(service, token, activityComponent, voiceInteraction, dc, fullscreen);
- // TODO: remove after unification
- mActivityRecord = activityRecord;
- mActivityRecord.registerConfigurationChangeListener(this);
- mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
- mShowForAllUsers = showForAllUsers;
- mTargetSdk = targetSdk;
- mOrientation = orientation;
- mLaunchTaskBehind = launchTaskBehind;
- mAlwaysFocusable = alwaysFocusable;
- mRotationAnimationHint = rotationAnimationHint;
+ AppWindowToken(WindowManagerService service, ActivityTaskManagerService atm,
+ ActivityRecord.Token token, ActivityInfo aInfo, ActivityOptions options, Intent intent,
+ DisplayContent dc) {
+ super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
+ false /* ownerCanManageAppTokens */);
+ mAtmService = atm;
+ appToken = token;
+ mActivityInfo = aInfo;
+ mUserId = UserHandle.getUserId(mActivityInfo.applicationInfo.uid);
+ packageName = mActivityInfo.applicationInfo.packageName;
+ mInputApplicationHandle = new InputApplicationHandle(appToken);
+
+ // If the class name in the intent doesn't match that of the target, this is probably an
+ // alias. We have to create a new ComponentName object to keep track of the real activity
+ // name, so that FLAG_ACTIVITY_CLEAR_TOP is handled properly.
+ if (mActivityInfo.targetActivity == null
+ || (mActivityInfo.targetActivity.equals(intent.getComponent().getClassName())
+ && (mActivityInfo.launchMode == LAUNCH_MULTIPLE
+ || mActivityInfo.launchMode == LAUNCH_SINGLE_TOP))) {
+ mActivityComponent = intent.getComponent();
+ } else {
+ mActivityComponent =
+ new ComponentName(mActivityInfo.packageName, mActivityInfo.targetActivity);
+ }
+
+ mTargetSdk = mActivityInfo.applicationInfo.targetSdkVersion;
+ mShowForAllUsers = (mActivityInfo.flags & FLAG_SHOW_FOR_ALL_USERS) != 0;
+ setOrientation(mActivityInfo.screenOrientation);
+ mRotationAnimationHint = mActivityInfo.rotationAnimation;
+
+ mShowWhenLocked = (aInfo.flags & ActivityInfo.FLAG_SHOW_WHEN_LOCKED) != 0;
+ mInheritShownWhenLocked = (aInfo.privateFlags & FLAG_INHERIT_SHOW_WHEN_LOCKED) != 0;
+ mTurnScreenOn = (aInfo.flags & FLAG_TURN_SCREEN_ON) != 0;
+
+ int realTheme = mActivityInfo.getThemeResource();
+ if (realTheme == Resources.ID_NULL) {
+ realTheme = aInfo.applicationInfo.targetSdkVersion < HONEYCOMB
+ ? android.R.style.Theme : android.R.style.Theme_Holo;
+ }
+
+ final AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
+ realTheme, com.android.internal.R.styleable.Window, mUserId);
+
+ if (ent != null) {
+ mOccludesParent = !ActivityInfo.isTranslucentOrFloating(ent.array);
+ hasWallpaper = ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
+ noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
+ } else {
+ hasWallpaper = false;
+ noDisplay = false;
+ }
+
+ if (options != null) {
+ mLaunchTaskBehind = options.getLaunchTaskBehind();
+
+ final int rotationAnimation = options.getRotationAnimationHint();
+ // Only override manifest supplied option if set.
+ if (rotationAnimation >= 0) {
+ mRotationAnimationHint = rotationAnimation;
+ }
+ }
// Application tokens start out hidden.
setHidden(true);
@@ -365,20 +445,19 @@
ColorDisplayService.ColorDisplayServiceInternal cds = LocalServices.getService(
ColorDisplayService.ColorDisplayServiceInternal.class);
- cds.attachColorTransformController(activityRecord.packageName, activityRecord.mUserId,
+ cds.attachColorTransformController(packageName, mUserId,
new WeakReference<>(mColorTransformController));
}
- AppWindowToken(WindowManagerService service, IApplicationToken token,
- ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
- boolean fillsParent) {
- super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
- false /* ownerCanManageAppTokens */);
- appToken = token;
- mActivityComponent = activityComponent;
+ void onAttachToTask(boolean voiceInteraction, DisplayContent dc,
+ long inputDispatchingTimeoutNanos) {
+ mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
mVoiceInteraction = voiceInteraction;
- mOccludesParent = fillsParent;
- mInputApplicationHandle = new InputApplicationHandle(appToken.asBinder());
+ onDisplayChanged(dc);
+
+ // Application tokens start out hidden.
+ setHidden(true);
+ hiddenRequested = true;
}
void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
@@ -388,8 +467,8 @@
removeDeadWindows();
if (startingWindow != null) {
- if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG, "Finish starting "
- + win.mToken + ": first real window is shown, no animation");
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finish starting %s"
+ + ": first real window is shown, no animation", win.mToken);
// If this initial window is animating, stop it -- we will do an animation to reveal
// it from behind the starting window, so there is no need for it to also be doing its
// own stuff.
@@ -433,43 +512,33 @@
if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
+ numInteresting + " visible=" + numVisible);
if (nowDrawn != reportedDrawn) {
- if (mActivityRecord != null) {
- mActivityRecord.onWindowsDrawn(nowDrawn, SystemClock.uptimeMillis());
- }
+ onWindowsDrawn(nowDrawn, SystemClock.uptimeMillis());
reportedDrawn = nowDrawn;
}
if (nowVisible != reportedVisible) {
if (DEBUG_VISIBILITY) Slog.v(TAG,
"Visibility changed in " + this + ": vis=" + nowVisible);
reportedVisible = nowVisible;
- if (mActivityRecord != null) {
- if (nowVisible) {
- onWindowsVisible();
- } else {
- onWindowsGone();
- }
+ if (nowVisible) {
+ onWindowsVisible();
+ } else {
+ onWindowsGone();
}
}
}
- private void onWindowsGone() {
- if (mActivityRecord == null) {
- return;
- }
- if (DEBUG_VISIBILITY) {
- Slog.v(TAG_WM, "Reporting gone in " + mActivityRecord.appToken);
- }
- mActivityRecord.onWindowsGone();
+ // Mostly implemented in ActivityRecord.
+ void onWindowsDrawn(boolean drawn, long timestamp) {
}
- private void onWindowsVisible() {
- if (mActivityRecord == null) {
- return;
- }
- if (DEBUG_VISIBILITY) {
- Slog.v(TAG_WM, "Reporting visible in " + mActivityRecord.appToken);
- }
- mActivityRecord.onWindowsVisible();
+ // Mostly implemented in ActivityRecord. Keeping here for the logpoint.
+ void onWindowsGone() {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting gone in " + appToken);
+ }
+
+ // Mostly implemented in ActivityRecord. Keeping here for the logpoint.
+ void onWindowsVisible() {
+ if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting visible in " + appToken);
}
boolean isClientHidden() {
@@ -480,8 +549,9 @@
if (mClientHidden == hideClient || (hideClient && mDeferHidingClient)) {
return;
}
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setClientHidden: " + this
- + " clientHidden=" + hideClient + " Callers=" + Debug.getCallers(5));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "setClientHidden: %s clientHidden=%b Callers=%s", this, hideClient,
+ Debug.getCallers(5));
mClientHidden = hideClient;
sendAppVisibilityToClients();
}
@@ -507,12 +577,10 @@
return;
}
- if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
- Slog.v(TAG_WM, "setAppVisibility("
- + appToken + ", visible=" + visible + "): " + appTransition
- + " hidden=" + isHidden() + " hiddenRequested="
- + hiddenRequested + " Callers=" + Debug.getCallers(6));
- }
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "setAppVisibility(%s, visible=%b): %s hidden=%b hiddenRequested=%b Callers=%s",
+ appToken, visible, appTransition, isHidden(), hiddenRequested,
+ Debug.getCallers(6));
final DisplayContent displayContent = getDisplayContent();
displayContent.mOpeningApps.remove(this);
@@ -573,7 +641,7 @@
requestUpdateWallpaperIfNeeded();
- if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + this);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "No longer Stopped: %s", this);
mAppStopped = false;
transferStartingWindowFromHiddenAboveTokenIfNeeded();
@@ -596,17 +664,15 @@
if (win != null) {
final AppWindowToken focusedToken = win.mAppToken;
if (focusedToken != null) {
- if (DEBUG_APP_TRANSITIONS) {
- Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, "
- + " adding " + focusedToken + " to mOpeningApps");
- }
+ ProtoLog.d(WM_DEBUG_APP_TRANSITIONS,
+ "TRANSIT_TASK_OPEN_BEHIND, adding %s to mOpeningApps",
+ focusedToken);
+
// Force animation to be loaded.
displayContent.mOpeningApps.add(focusedToken);
}
}
}
- // Changes in opening apps and closing apps may cause orientation change.
- reportDescendantOrientationChangeIfNeeded();
return;
}
@@ -638,8 +704,9 @@
final AccessibilityController accessibilityController =
mWmService.mAccessibilityController;
boolean changed = false;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
- "Changing app " + this + " hidden=" + isHidden() + " performLayout=" + performLayout);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "Changing app %s hidden=%b performLayout=%b", this, isHidden(),
+ performLayout);
boolean runningAppAnimation = false;
@@ -681,10 +748,9 @@
forAllWindows(mWmService::makeWindowFreezingScreenIfNeededLocked, true);
}
- if (DEBUG_APP_TRANSITIONS) {
- Slog.v(TAG_WM, "commitVisibility: " + this
- + ": hidden=" + isHidden() + " hiddenRequested=" + hiddenRequested);
- }
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "commitVisibility: %s: hidden=%b hiddenRequested=%b", this,
+ isHidden(), hiddenRequested);
if (changed) {
displayContent.getInputMonitor().setUpdateInputWindowsNeededLw();
@@ -763,29 +829,27 @@
}
SurfaceControl.closeTransaction();
}
-
- // Visibility changes may cause orientation request change.
- reportDescendantOrientationChangeIfNeeded();
}
return delayed;
}
- private void reportDescendantOrientationChangeIfNeeded() {
+ boolean mayFreezeScreenLocked() {
+ return false;
+ }
+
+ void reportDescendantOrientationChangeIfNeeded() {
// Orientation request is exposed only when we're visible. Therefore visibility change
// will change requested orientation. Notify upward the hierarchy ladder to adjust
// configuration. This is important to cases where activities with incompatible
// orientations launch, or user goes back from an activity of bi-orientation to an
// activity with specified orientation.
- if (mActivityRecord.getRequestedConfigurationOrientation() == getConfiguration().orientation
- || getOrientationIgnoreVisibility() == SCREEN_ORIENTATION_UNSET) {
+ if (getRequestedOrientation() == SCREEN_ORIENTATION_UNSET) {
return;
}
- final IBinder freezeToken =
- mActivityRecord.mayFreezeScreenLocked(mActivityRecord.app)
- ? mActivityRecord.appToken : null;
- onDescendantOrientationChanged(freezeToken, mActivityRecord);
+ final IBinder freezeToken = mayFreezeScreenLocked() ? appToken : null;
+ onDescendantOrientationChanged(freezeToken, this);
}
/**
@@ -835,10 +899,16 @@
return candidate;
}
+ boolean isAlwaysFocusable() {
+ return (mActivityInfo.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
+ }
+
+ // TODO: Does this really need to be different from isAlwaysFocusable()? For the activity side
+ // focusable means resumeable. I guess with that in mind maybe we should rename the other
+ // method to isResumeable() or something like that.
boolean windowsAreFocusable() {
if (mTargetSdk < Build.VERSION_CODES.Q) {
- final int pid = mActivityRecord != null
- ? (mActivityRecord.app != null ? mActivityRecord.app.getPid() : 0) : 0;
+ final int pid = getPid();
final AppWindowToken topFocusedAppOfMyProcess =
mWmService.mRoot.mTopFocusedAppByProcess.get(pid);
if (topFocusedAppOfMyProcess != null && topFocusedAppOfMyProcess != this) {
@@ -847,7 +917,12 @@
return false;
}
}
- return getWindowConfiguration().canReceiveKeys() || mAlwaysFocusable;
+ return getWindowConfiguration().canReceiveKeys() || isAlwaysFocusable();
+ }
+
+ // Mostly implemented in ActivityRecord...
+ int getPid() {
+ return 0;
}
@Override
@@ -860,9 +935,6 @@
@Override
void removeImmediately() {
onRemovedFromDisplay();
- if (mActivityRecord != null) {
- mActivityRecord.unregisterConfigurationChangeListener(this);
- }
super.removeImmediately();
}
@@ -887,7 +959,7 @@
}
mRemovingFromDisplay = true;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Removing app token: %s", this);
boolean delayed = commitVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction);
@@ -903,11 +975,12 @@
delayed = true;
}
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed
- + " animation=" + getAnimation() + " animating=" + isSelfAnimating());
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "Removing app %s delayed=%b animation=%s animating=%b", this, delayed,
+ getAnimation(), isSelfAnimating());
- if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
- + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "removeAppToken: %s"
+ + " delayed=%b Callers=%s", this, delayed, Debug.getCallers(4));
if (mStartingData != null) {
removeStartingWindow();
@@ -923,8 +996,8 @@
final TaskStack stack = getStack();
if (delayed && !isEmpty()) {
// set the token aside because it has an active animation to be finished
- if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
- "removeAppToken make exiting: " + this);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE,
+ "removeAppToken make exiting: %s", this);
if (stack != null) {
stack.mExitingAppTokens.add(this);
}
@@ -944,8 +1017,9 @@
final DisplayContent dc = getDisplayContent();
if (dc.mFocusedApp == this) {
- if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this
- + " displayId=" + dc.getDisplayId());
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
+ "Removing focused app token:%s displayId=%d", this,
+ dc.getDisplayId());
dc.setFocusedApp(null);
mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
}
@@ -1009,8 +1083,8 @@
* up of the surfaces
*/
void notifyAppResumed(boolean wasStopped) {
- if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped
- + " " + this);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "notifyAppResumed: wasStopped=%b %s",
+ wasStopped, this);
mAppStopped = false;
// Allow the window to turn the screen on once the app is resumed again.
setCurrentLaunchCanTurnScreenOn(true);
@@ -1024,7 +1098,7 @@
* keeping alive in case they were still being used.
*/
void notifyAppStopped() {
- if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "notifyAppStopped: %s", this);
mAppStopped = true;
// Reset the last saved PiP snap fraction on app stop.
mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(mActivityComponent);
@@ -1064,7 +1138,9 @@
if (task == null) {
// It is possible we have been marked as a closing app earlier. We must remove ourselves
// from this list so we do not participate in any future animations.
- getDisplayContent().mClosingApps.remove(this);
+ if (getDisplayContent() != null) {
+ getDisplayContent().mClosingApps.remove(this);
+ }
} else if (mLastParent != null && mLastParent.mStack != null) {
task.mStack.mExitingAppTokens.remove(this);
}
@@ -1087,12 +1163,12 @@
void postWindowRemoveStartingWindowCleanup(WindowState win) {
// TODO: Something smells about the code below...Is there a better way?
if (startingWindow == win) {
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Notify removed startingWindow %s", win);
removeStartingWindow();
} else if (mChildren.size() == 0) {
// If this is the last window and we had requested a starting transition window,
// well there is no point now.
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingData");
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Nulling last startingData");
mStartingData = null;
if (mHiddenSetFromTransferredStartingWindow) {
// We set the hidden state to false for the token from a transferred starting window.
@@ -1103,8 +1179,7 @@
} else if (mChildren.size() == 1 && startingSurface != null && !isRelaunching()) {
// If this is the last window except for a starting transition window,
// we need to get rid of the starting transition.
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Last window, removing starting window "
- + win);
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Last window, removing starting window %s", win);
removeStartingWindow();
}
}
@@ -1113,8 +1188,8 @@
for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
WindowState win = mChildren.get(winNdx);
if (win.mAppDied) {
- if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
- "removeDeadWindows: " + win);
+ ProtoLog.w(WM_DEBUG_ADD_REMOVE,
+ "removeDeadWindows: %s", win);
// Set mDestroying, we don't want any animation or delayed removal here.
win.mDestroying = true;
// Also removes child windows.
@@ -1135,8 +1210,8 @@
}
void setWillReplaceWindows(boolean animate) {
- if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
- "Marking app token " + this + " with replacing windows.");
+ ProtoLog.d(WM_DEBUG_ADD_REMOVE,
+ "Marking app token %s with replacing windows.", this);
for (int i = mChildren.size() - 1; i >= 0; i--) {
final WindowState w = mChildren.get(i);
@@ -1145,8 +1220,8 @@
}
void setWillReplaceChildWindows() {
- if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
- + " with replacing child windows.");
+ ProtoLog.d(WM_DEBUG_ADD_REMOVE, "Marking app token %s"
+ + " with replacing child windows.", this);
for (int i = mChildren.size() - 1; i >= 0; i--) {
final WindowState w = mChildren.get(i);
w.setWillReplaceChildWindows();
@@ -1154,8 +1229,8 @@
}
void clearWillReplaceWindows() {
- if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
- "Resetting app token " + this + " of replacing window marks.");
+ ProtoLog.d(WM_DEBUG_ADD_REMOVE,
+ "Resetting app token %s of replacing window marks.", this);
for (int i = mChildren.size() - 1; i >= 0; i--) {
final WindowState w = mChildren.get(i);
@@ -1320,10 +1395,9 @@
}
void reparent(Task task, int position) {
- if (DEBUG_ADD_REMOVE) {
- Slog.i(TAG_WM, "reparent: moving app token=" + this
- + " to task=" + task.mTaskId + " at " + position);
- }
+ ProtoLog.i(WM_DEBUG_ADD_REMOVE, "reparent: moving app token=%s"
+ + " to task=%d at %d", this, task.mTaskId, position);
+
if (task == null) {
throw new IllegalArgumentException("reparent: could not find task");
}
@@ -1339,8 +1413,8 @@
+ " belongs to a different stack than " + task);
}
- if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this
- + " from task=" + currentTask);
+ ProtoLog.i(WM_DEBUG_ADD_REMOVE, "reParentWindowToken: removing window token=%s"
+ + " from task=%s" , this, currentTask);
final DisplayContent prevDisplayContent = getDisplayContent();
mReparenting = true;
@@ -1460,9 +1534,10 @@
}
void startFreezingScreen() {
- if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
- + isHidden() + " freezing=" + mFreezingScreen + " hiddenRequested="
- + hiddenRequested);
+ ProtoLog.i(WM_DEBUG_ORIENTATION,
+ "Set freezing of %s: hidden=%b freezing=%b hiddenRequested=%b. %s",
+ appToken, isHidden(), mFreezingScreen, hiddenRequested,
+ new RuntimeException().fillInStackTrace());
if (!hiddenRequested) {
if (!mFreezingScreen) {
mFreezingScreen = true;
@@ -1486,7 +1561,8 @@
if (!mFreezingScreen) {
return;
}
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Clear freezing of %s force=%b", this, force);
final int count = mChildren.size();
boolean unfrozeWindows = false;
for (int i = 0; i < count; i++) {
@@ -1494,7 +1570,7 @@
unfrozeWindows |= w.onStopFreezingScreen();
}
if (force || unfrozeWindows) {
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "No longer freezing: %s", this);
mFreezingScreen = false;
mWmService.unregisterAppFreezeListener(this);
mWmService.mAppsFreezingScreen--;
@@ -1545,8 +1621,8 @@
// letting windows get shown immediately without any more transitions.
getDisplayContent().mSkipAppTransitionAnimation = true;
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
- + " from " + fromToken + " to " + this);
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Moving existing starting %s"
+ + " from %s to %s", tStartingWindow, fromToken, this);
final long origId = Binder.clearCallingIdentity();
try {
@@ -1564,8 +1640,8 @@
tStartingWindow.mToken = this;
tStartingWindow.mAppToken = this;
- if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
- "Removing starting " + tStartingWindow + " from " + fromToken);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE,
+ "Removing starting %s from %s", tStartingWindow, fromToken);
fromToken.removeChild(tStartingWindow);
fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow);
fromToken.mHiddenSetFromTransferredStartingWindow = false;
@@ -1606,8 +1682,8 @@
} else if (fromToken.mStartingData != null) {
// The previous app was getting ready to show a
// starting window, but hasn't yet done so. Steal it!
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
- "Moving pending starting from " + fromToken + " to " + this);
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
+ "Moving pending starting from %s to %s", fromToken, this);
mStartingData = fromToken.mStartingData;
fromToken.mStartingData = null;
fromToken.startingMoved = true;
@@ -1654,7 +1730,7 @@
}
/** Returns the app's preferred orientation regardless of its currently visibility state. */
- int getOrientationIgnoreVisibility() {
+ int getRequestedOrientation() {
return mOrientation;
}
@@ -1668,15 +1744,6 @@
return inSizeCompatMode() ? mSizeCompatScale : super.getSizeCompatScale();
}
- /**
- * @return Non-empty bounds if the activity has override bounds.
- * @see ActivityRecord#resolveOverrideConfiguration(Configuration)
- */
- Rect getResolvedOverrideBounds() {
- // Get bounds from resolved override configuration because it is computed with orientation.
- return getResolvedOverrideConfiguration().windowConfiguration.getBounds();
- }
-
@Override
public void onConfigurationChanged(Configuration newParentConfig) {
final int prevWinMode = getWindowingMode();
@@ -1707,7 +1774,7 @@
final int winMode = getWindowingMode();
- if (prevWinMode == winMode) {
+ if (prevWinMode == winMode || mDisplayContent == null) {
return;
}
@@ -1879,9 +1946,10 @@
if (mFreezingScreen) {
showAllWindowsLocked();
stopFreezingScreen(false, true);
- if (DEBUG_ORIENTATION) Slog.i(TAG,
- "Setting mOrientationChangeComplete=true because wtoken " + this
- + " numInteresting=" + mNumInterestingWindows + " numDrawn=" + mNumDrawnWindows);
+ ProtoLog.i(WM_DEBUG_ORIENTATION,
+ "Setting mOrientationChangeComplete=true because wtoken %s "
+ + "numInteresting=%d numDrawn=%d",
+ this, mNumInterestingWindows, mNumDrawnWindows);
// This will set mOrientationChangeComplete and cause a pass through layout.
setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER,
"checkAppWindowsReadyToShow: freezingScreen");
@@ -1949,8 +2017,9 @@
}
}
+ // Mostly implemented in ActivityRecord...
boolean keyDispatchingTimedOut(String reason, int windowPid) {
- return mActivityRecord != null && mActivityRecord.keyDispatchingTimedOut(reason, windowPid);
+ return false;
}
/**
@@ -1985,7 +2054,7 @@
boolean isInterestingAndDrawn = false;
if (!allDrawn && w.mightAffectAllDrawn()) {
- if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
+ if (DEBUG_VISIBILITY || WM_DEBUG_ORIENTATION.isLogToLogcat()) {
Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
+ ", isAnimationSet=" + isSelfAnimating());
if (!w.isDrawnLw()) {
@@ -2006,18 +2075,18 @@
if (w.isDrawnLw()) {
mNumDrawnWindows++;
- if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: "
- + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
- + " freezingScreen=" + mFreezingScreen
- + " mAppFreezing=" + w.mAppFreezing);
+ if (DEBUG_VISIBILITY || WM_DEBUG_ORIENTATION.isLogToLogcat()) {
+ Slog.v(TAG, "tokenMayBeDrawn: "
+ + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
+ + " freezingScreen=" + mFreezingScreen
+ + " mAppFreezing=" + w.mAppFreezing);
+ }
isInterestingAndDrawn = true;
}
}
} else if (w.isDrawnLw()) {
- if (mActivityRecord != null) {
- mActivityRecord.onStartingWindowDrawn(SystemClock.uptimeMillis());
- }
+ onStartingWindowDrawn(SystemClock.uptimeMillis());
startingDisplayed = true;
}
}
@@ -2025,6 +2094,14 @@
return isInterestingAndDrawn;
}
+ /** Called when the starting window for this container is drawn. */
+ private void onStartingWindowDrawn(long timestamp) {
+ synchronized (mAtmService.mGlobalLock) {
+ mAtmService.mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
+ getWindowingMode(), timestamp);
+ }
+ }
+
void layoutLetterbox(WindowState winHint) {
final WindowState w = findMainWindow();
if (w == null || winHint != null && w != winHint) {
@@ -2125,9 +2202,7 @@
// If this is a translucent window, then don't show a starting window -- the current
// effect (a full-screen opaque starting window that fades away to the real contents
// when it is ready) does not work for this.
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG, "Checking theme of starting window: 0x" + Integer.toHexString(theme));
- }
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Checking theme of starting window: 0x%x", theme);
if (theme != 0) {
AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
com.android.internal.R.styleable.Window,
@@ -2145,11 +2220,8 @@
com.android.internal.R.styleable.Window_windowShowWallpaper, false);
final boolean windowDisableStarting = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowDisablePreview, false);
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG, "Translucent=" + windowIsTranslucent
- + " Floating=" + windowIsFloating
- + " ShowWallpaper=" + windowShowWallpaper);
- }
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Translucent=%s Floating=%s ShowWallpaper=%s",
+ windowIsTranslucent, windowIsFloating, windowShowWallpaper);
if (windowIsTranslucent) {
return false;
}
@@ -2181,7 +2253,7 @@
return false;
}
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SplashScreenStartingData");
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Creating SplashScreenStartingData");
mStartingData = new SplashScreenStartingData(mWmService, pkg,
theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
getMergedOverrideConfiguration());
@@ -2195,7 +2267,7 @@
return false;
}
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SnapshotStartingData");
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Creating SnapshotStartingData");
mStartingData = new SnapshotStartingData(mWmService, snapshot);
scheduleAddStartingWindow();
return true;
@@ -2206,7 +2278,7 @@
// want to process the message ASAP, before any other queued
// messages.
if (!mWmService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) {
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Enqueueing ADD_STARTING");
mWmService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
}
}
@@ -2223,18 +2295,17 @@
if (mStartingData == null) {
// Animation has been canceled... do nothing.
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG, "startingData was nulled out before handling"
- + " mAddStartingWindow: " + AppWindowToken.this);
- }
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
+ "startingData was nulled out before handling"
+ + " mAddStartingWindow: %s", AppWindowToken.this);
return;
}
startingData = mStartingData;
}
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG, "Add starting " + this + ": startingData=" + startingData);
- }
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Add starting %s: startingData=%s",
+ this, startingData);
+
WindowManagerPolicy.StartingSurface surface = null;
try {
@@ -2248,27 +2319,28 @@
// If the window was successfully added, then
// we need to remove it.
if (removed || mStartingData == null) {
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG, "Aborted starting " + AppWindowToken.this
- + ": removed=" + removed + " startingData=" + mStartingData);
- }
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
+ "Aborted starting %s: removed=%b startingData=%s",
+ AppWindowToken.this, removed, mStartingData);
+
startingWindow = null;
mStartingData = null;
abort = true;
} else {
startingSurface = surface;
}
- if (DEBUG_STARTING_WINDOW && !abort) {
- Slog.v(TAG,
- "Added starting " + AppWindowToken.this + ": startingWindow="
- + startingWindow + " startingView=" + startingSurface);
+ if (!abort) {
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
+ "Added starting %s: startingWindow=%s startingView=%s",
+ AppWindowToken.this, startingWindow, startingSurface);
}
}
if (abort) {
surface.remove();
}
- } else if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG, "Surface returned was null: " + AppWindowToken.this);
+ } else {
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Surface returned was null: %s",
+ AppWindowToken.this);
}
}
};
@@ -2311,9 +2383,7 @@
if (mStartingData != null) {
// Starting window has not been added yet, but it is scheduled to be added.
// Go ahead and cancel the request.
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG_WM, "Clearing startingData for token=" + this);
- }
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Clearing startingData for token=%s", this);
mStartingData = null;
}
return;
@@ -2327,31 +2397,28 @@
startingWindow = null;
startingDisplayed = false;
if (surface == null) {
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
+ "startingWindow was set but startingSurface==null, couldn't "
+ "remove");
- }
+
return;
}
} else {
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
- + this);
- }
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
+ "Tried to remove starting window but startingWindow was null: %s",
+ this);
return;
}
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG_WM, "Schedule remove starting " + this
- + " startingWindow=" + startingWindow
- + " startingView=" + startingSurface
- + " Callers=" + Debug.getCallers(5));
- }
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Schedule remove starting %s startingWindow=%s"
+ + " startingView=%s Callers=%s",
+ this, startingWindow, startingSurface, Debug.getCallers(5));
+
// Use the same thread to remove the window as we used to add it, as otherwise we end up
// with things in the view hierarchy being called from different threads.
mWmService.mAnimationHandler.post(() -> {
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface);
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Removing startingView=%s", surface);
try {
surface.remove();
} catch (Exception e) {
@@ -2419,6 +2486,66 @@
return false;
}
+ void setShowWhenLocked(boolean showWhenLocked) {
+ mShowWhenLocked = showWhenLocked;
+ mAtmService.mRootActivityContainer.ensureActivitiesVisible(null /* starting */,
+ 0 /* configChanges */, false /* preserveWindows */);
+ }
+
+ void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
+ mInheritShownWhenLocked = inheritShowWhenLocked;
+ mAtmService.mRootActivityContainer.ensureActivitiesVisible(null /* starting */,
+ 0 /* configChanges */, false /* preserveWindows */);
+ }
+
+ /**
+ * @return {@code true} if the activity windowing mode is not
+ * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and a) activity
+ * contains windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the
+ * activity has set {@link #mShowWhenLocked}, or b) if the activity has set
+ * {@link #mInheritShownWhenLocked} and the activity behind this satisfies the
+ * conditions a) above.
+ * Multi-windowing mode will be exited if {@code true} is returned.
+ */
+ boolean canShowWhenLocked() {
+ if (!inPinnedWindowingMode() && (mShowWhenLocked || containsShowWhenLockedWindow())) {
+ return true;
+ } else if (mInheritShownWhenLocked) {
+ final AppWindowToken r = getActivityBelow();
+ return r != null && !r.inPinnedWindowingMode() && (r.mShowWhenLocked
+ || r.containsShowWhenLockedWindow());
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @return an {@link ActivityRecord} of the activity below this activity, or {@code null} if no
+ * such activity exists.
+ */
+ @Nullable
+ private AppWindowToken getActivityBelow() {
+ final Task task = getTask();
+ final int pos = task.mChildren.indexOf(this);
+ if (pos == -1) {
+ throw new IllegalStateException("Activity not found in its task");
+ }
+ return pos == 0 ? null : task.getChildAt(pos - 1);
+ }
+
+ void setTurnScreenOn(boolean turnScreenOn) {
+ mTurnScreenOn = turnScreenOn;
+ }
+
+ /** Mostly implemented in ActivityRecord. */
+ boolean canTurnScreenOn() {
+ return mTurnScreenOn;
+ }
+
+ boolean getTurnScreenOnFlag() {
+ return mTurnScreenOn;
+ }
+
void checkKeyguardFlagsChanged() {
final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
@@ -2547,7 +2674,7 @@
* Creates a layer to apply crop to an animation.
*/
private SurfaceControl createAnimationBoundsLayer(Transaction t) {
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.i(TAG, "Creating animation bounds layer");
+ ProtoLog.i(WM_DEBUG_APP_TRANSITIONS_ANIM, "Creating animation bounds layer");
final SurfaceControl.Builder builder = makeAnimationLeash()
.setParent(getAnimationLeashParent())
.setName(getSurfaceControl() + " - animation-bounds");
@@ -2583,10 +2710,9 @@
boolean isVoiceInteraction) {
if (mWmService.mDisableTransitionAnimation || !shouldAnimate(transit)) {
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
- Slog.v(TAG_WM, "applyAnimation: transition animation is disabled or skipped."
- + " atoken=" + this);
- }
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: transition animation is disabled or skipped. "
+ + "atoken=%s", this);
cancelAnimation();
return false;
}
@@ -2686,8 +2812,8 @@
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
final int width = displayInfo.appWidth;
final int height = displayInfo.appHeight;
- if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
- "applyAnimation: atoken=" + this);
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: atoken=%s", this);
// Determine the visible rect to calculate the thumbnail clip
final WindowState win = findMainWindow();
@@ -2727,9 +2853,10 @@
// screen gets the enter animation. Both appear in the mOpeningApps set.
enter = false;
}
- if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition."
- + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
- + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
+ ProtoLog.d(WM_DEBUG_APP_TRANSITIONS,
+ "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s "
+ + "surfaceInsets=%s",
+ AppTransition.appTransitionToString(transit), enter, frame, insets, surfaceInsets);
final Configuration displayConfig = displayContent.getConfiguration();
final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
@@ -2896,7 +3023,21 @@
getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token);
scheduleAnimation();
- mActivityRecord.onAnimationFinished();
+ if (mAtmService.mRootActivityContainer.allResumedActivitiesIdle()
+ || mAtmService.mStackSupervisor.isStoppingNoHistoryActivity()) {
+ // If all activities are already idle or there is an activity that must be
+ // stopped immediately after visible, then we now need to make sure we perform
+ // the full stop of this activity. This is because we won't do that while they are still
+ // waiting for the animation to finish.
+ if (mAtmService.mStackSupervisor.mStoppingActivities.contains(this)) {
+ mAtmService.mStackSupervisor.scheduleIdleLocked();
+ }
+ } else {
+ // Instead of doing the full stop routine here, let's just hide any activities
+ // we now can, and let them stop when the normal idle happens.
+ mAtmService.mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
+ false /* remove */, true /* processPausingActivities */);
+ }
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
@@ -2963,10 +3104,13 @@
}
boolean isWaitingForTransitionStart() {
- return getDisplayContent().mAppTransition.isTransitionSet()
- && (getDisplayContent().mOpeningApps.contains(this)
- || getDisplayContent().mClosingApps.contains(this)
- || getDisplayContent().mChangingApps.contains(this));
+ final DisplayContent dc = getDisplayContent();
+ // TODO: Test for null can be removed once unification is done.
+ if (dc == null) return false;
+ return dc.mAppTransition.isTransitionSet()
+ && (dc.mOpeningApps.contains(this)
+ || dc.mClosingApps.contains(this)
+ || dc.mChangingApps.contains(this));
}
public int getTransit() {
@@ -2985,7 +3129,7 @@
final GraphicBuffer thumbnailHeader =
getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(taskId);
if (thumbnailHeader == null) {
- if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
+ ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "No thumbnail header bitmap for: %d", taskId);
return;
}
clearThumbnail();
@@ -3210,27 +3354,17 @@
}
void writeNameToProto(ProtoOutputStream proto, long fieldId) {
- if (appToken == null) {
- return;
- }
- try {
+ if (appToken != null) {
proto.write(fieldId, appToken.getName());
- } catch (RemoteException e) {
- // This shouldn't happen, but in this case fall back to outputting nothing
- Slog.e(TAG, e.toString());
}
}
- @Override
- public String toString() {
- if (stringName == null) {
- StringBuilder sb = new StringBuilder();
- sb.append("AppWindowToken{");
- sb.append(Integer.toHexString(System.identityHashCode(this)));
- sb.append(" token="); sb.append(token); sb.append('}');
- stringName = sb.toString();
- }
- return stringName + ((mIsExiting) ? " mIsExiting=" : "");
+ void writeIdentifierToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(HASH_CODE, System.identityHashCode(this));
+ proto.write(USER_ID, mUserId);
+ proto.write(TITLE, ((ActivityRecord) this).intent.getComponent().flattenToShortString());
+ proto.end(token);
}
Rect getLetterboxInsets() {
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index a25aab2..b4cecff 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -16,15 +16,14 @@
package com.android.server.wm;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
import android.graphics.Rect;
-import android.util.Slog;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
+import com.android.server.protolog.common.ProtoLog;
+
import java.io.PrintWriter;
import java.util.function.Supplier;
@@ -58,8 +57,8 @@
transaction.setLayer(surface, layer);
transaction.setPosition(surface, left, top);
transaction.show(surface);
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
- " BLACK " + surface + ": CREATE layer=" + layer);
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
+ " BLACK %s: CREATE layer=%d", surface, layer);
}
}
@@ -124,10 +123,7 @@
SurfaceControl.Transaction t = mTransactionFactory.get();
for (int i = 0; i < mBlackSurfaces.length; i++) {
if (mBlackSurfaces[i] != null) {
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
- Slog.i(TAG_WM,
- " BLACK " + mBlackSurfaces[i].surface + ": DESTROY");
- }
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC, " BLACK %s: DESTROY", mBlackSurfaces[i].surface);
t.remove(mBlackSurfaces[i].surface);
mBlackSurfaces[i] = null;
}
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 3886ae1..8afbbdf 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -90,7 +90,8 @@
private ArrayList<ConfigurationContainerListener> mChangeListeners = new ArrayList<>();
// TODO: Can't have ag/2592611 soon enough!
- private final Configuration mTmpConfig = new Configuration();
+ private final Configuration mRequestsTmpConfig = new Configuration();
+ private final Configuration mResolvedTmpConfig = new Configuration();
// Used for setting bounds
private final Rect mTmpRect = new Rect();
@@ -121,12 +122,19 @@
* @see #mFullConfiguration
*/
public void onConfigurationChanged(Configuration newParentConfig) {
- mTmpConfig.setTo(mResolvedOverrideConfiguration);
+ onConfigurationChanged(newParentConfig, true /*forwardToChildren*/);
+ }
+
+ // TODO: Consolidate with onConfigurationChanged() method above once unification is done. This
+ // is only currently need during the process of unification where we don't want configuration
+ // forwarded to a child from both parents.
+ public void onConfigurationChanged(Configuration newParentConfig, boolean forwardToChildren) {
+ mResolvedTmpConfig.setTo(mResolvedOverrideConfiguration);
resolveOverrideConfiguration(newParentConfig);
mFullConfiguration.setTo(newParentConfig);
mLastOverrideConfigurationChanges =
mFullConfiguration.updateFrom(mResolvedOverrideConfiguration);
- if (!mTmpConfig.equals(mResolvedOverrideConfiguration)) {
+ if (!mResolvedTmpConfig.equals(mResolvedOverrideConfiguration)) {
onMergedOverrideConfigurationChanged();
// This depends on the assumption that change-listeners don't do
// their own override resolution. This way, dependent hierarchies
@@ -139,9 +147,11 @@
mResolvedOverrideConfiguration);
}
}
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ConfigurationContainer child = getChildAt(i);
- child.onConfigurationChanged(mFullConfiguration);
+ if (forwardToChildren) {
+ for (int i = getChildCount() - 1; i >= 0; --i) {
+ final ConfigurationContainer child = getChildAt(i);
+ child.onConfigurationChanged(mFullConfiguration);
+ }
}
}
@@ -262,6 +272,11 @@
out.set(bounds.left, bounds.top);
}
+ Rect getResolvedOverrideBounds() {
+ mReturnBounds.set(getResolvedOverrideConfiguration().windowConfiguration.getBounds());
+ return mReturnBounds;
+ }
+
/**
* Returns the bounds requested on this container. These may not be the actual bounds the
* container ends up with due to policy constraints. The {@link Rect} handed back is
@@ -306,9 +321,9 @@
}
- mTmpConfig.setTo(getRequestedOverrideConfiguration());
- mTmpConfig.windowConfiguration.setBounds(bounds);
- onRequestedOverrideConfigurationChanged(mTmpConfig);
+ mRequestsTmpConfig.setTo(getRequestedOverrideConfiguration());
+ mRequestsTmpConfig.windowConfiguration.setBounds(bounds);
+ onRequestedOverrideConfigurationChanged(mRequestsTmpConfig);
return boundsChange;
}
@@ -360,9 +375,9 @@
/** Sets the requested windowing mode override for the configuration container. */
public void setWindowingMode(/*@WindowConfiguration.WindowingMode*/ int windowingMode) {
- mTmpConfig.setTo(getRequestedOverrideConfiguration());
- mTmpConfig.windowConfiguration.setWindowingMode(windowingMode);
- onRequestedOverrideConfigurationChanged(mTmpConfig);
+ mRequestsTmpConfig.setTo(getRequestedOverrideConfiguration());
+ mRequestsTmpConfig.windowConfiguration.setWindowingMode(windowingMode);
+ onRequestedOverrideConfigurationChanged(mRequestsTmpConfig);
}
/** Sets the always on top flag for this configuration container.
@@ -372,16 +387,16 @@
* - {@Link ActivityDisplay#positionChildAtTop(ActivityStack)};
* */
public void setAlwaysOnTop(boolean alwaysOnTop) {
- mTmpConfig.setTo(getRequestedOverrideConfiguration());
- mTmpConfig.windowConfiguration.setAlwaysOnTop(alwaysOnTop);
- onRequestedOverrideConfigurationChanged(mTmpConfig);
+ mRequestsTmpConfig.setTo(getRequestedOverrideConfiguration());
+ mRequestsTmpConfig.windowConfiguration.setAlwaysOnTop(alwaysOnTop);
+ onRequestedOverrideConfigurationChanged(mRequestsTmpConfig);
}
/** Sets the windowing mode for the configuration container. */
void setDisplayWindowingMode(int windowingMode) {
- mTmpConfig.setTo(getRequestedOverrideConfiguration());
- mTmpConfig.windowConfiguration.setDisplayWindowingMode(windowingMode);
- onRequestedOverrideConfigurationChanged(mTmpConfig);
+ mRequestsTmpConfig.setTo(getRequestedOverrideConfiguration());
+ mRequestsTmpConfig.windowConfiguration.setDisplayWindowingMode(windowingMode);
+ onRequestedOverrideConfigurationChanged(mRequestsTmpConfig);
}
/**
@@ -451,9 +466,9 @@
throw new IllegalStateException("Can't change activity type once set: " + this
+ " activityType=" + activityTypeToString(activityType));
}
- mTmpConfig.setTo(getRequestedOverrideConfiguration());
- mTmpConfig.windowConfiguration.setActivityType(activityType);
- onRequestedOverrideConfigurationChanged(mTmpConfig);
+ mRequestsTmpConfig.setTo(getRequestedOverrideConfiguration());
+ mRequestsTmpConfig.windowConfiguration.setActivityType(activityType);
+ onRequestedOverrideConfigurationChanged(mRequestsTmpConfig);
}
public boolean isActivityTypeHome() {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 755180e..3b90b7e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -59,11 +59,10 @@
import static android.view.WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE;
import static android.view.WindowManager.LayoutParams.NEEDS_MENU_UNSET;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
@@ -100,24 +99,21 @@
import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
import static com.android.server.wm.DisplayContentProto.STACKS;
import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.REPORT_FOCUS_CHANGE;
@@ -133,7 +129,6 @@
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
import static com.android.server.wm.WindowManagerService.dipToPixel;
-import static com.android.server.wm.WindowManagerService.logSurface;
import static com.android.server.wm.WindowState.EXCLUSION_LEFT;
import static com.android.server.wm.WindowState.EXCLUSION_RIGHT;
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
@@ -173,6 +168,7 @@
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.Slog;
+import android.util.SparseBooleanArray;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.DisplayCutout;
@@ -202,6 +198,7 @@
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.AnimationThread;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.utils.DisplayRotationUtil;
import com.android.server.wm.utils.RotationCache;
import com.android.server.wm.utils.WmDisplayCutout;
@@ -442,11 +439,6 @@
/** A collection of windows that provide tap exclude regions inside of them. */
final ArraySet<WindowState> mTapExcludeProvidingWindows = new ArraySet<>();
- private boolean mHaveBootMsg = false;
- private boolean mHaveApp = false;
- private boolean mHaveWallpaper = false;
- private boolean mHaveKeyguard = true;
-
private final LinkedList<AppWindowToken> mTmpUpdateAllDrawn = new LinkedList();
private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult =
@@ -599,8 +591,8 @@
private final ToBooleanFunction<WindowState> mFindFocusedWindow = w -> {
final AppWindowToken focusedApp = mFocusedApp;
- if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + w
- + ", flags=" + w.mAttrs.flags + ", canReceive=" + w.canReceiveKeys());
+ ProtoLog.v(WM_DEBUG_FOCUS, "Looking for focus: %s, flags=%d, canReceive=%b",
+ w, w.mAttrs.flags, w.canReceiveKeys());
if (!w.canReceiveKeys()) {
return false;
@@ -610,22 +602,22 @@
// If this window's application has been removed, just skip it.
if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
- if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because "
- + (wtoken.removed ? "removed" : "sendingToBottom"));
+ ProtoLog.v(WM_DEBUG_FOCUS, "Skipping %s because %s", wtoken,
+ (wtoken.removed ? "removed" : "sendingToBottom"));
return false;
}
if (focusedApp == null) {
- if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null"
- + " using new focus @ " + w);
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
+ "findFocusedWindow: focusedApp=null using new focus @ %s", w);
mTmpWindow = w;
return true;
}
if (!focusedApp.windowsAreFocusable()) {
// Current focused app windows aren't focusable...
- if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not"
- + " focusable using new focus @ " + w);
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: focusedApp windows not"
+ + " focusable using new focus @ %s", w);
mTmpWindow = w;
return true;
}
@@ -635,14 +627,14 @@
if (wtoken != null && w.mAttrs.type != TYPE_APPLICATION_STARTING) {
if (focusedApp.compareTo(wtoken) > 0) {
// App stack below focused app stack. No focus for you!!!
- if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM,
- "findFocusedWindow: Reached focused app=" + focusedApp);
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
+ "findFocusedWindow: Reached focused app=%s", focusedApp);
mTmpWindow = null;
return true;
}
}
- if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + w);
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: Found new focus @ %s", w);
mTmpWindow = w;
return true;
};
@@ -1145,7 +1137,8 @@
*/
void initializeDisplayOverrideConfiguration() {
if (mAcitvityDisplay != null) {
- mAcitvityDisplay.onInitializeOverrideConfiguration(getRequestedOverrideConfiguration());
+ mAcitvityDisplay.getRequestedOverrideConfiguration()
+ .updateFrom(getRequestedOverrideConfiguration());
}
}
@@ -1333,7 +1326,7 @@
forAllWindows(w -> {
if (w.mHasSurface && !rotateSeamlessly) {
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Set mOrientationChanging of " + w);
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "Set mOrientationChanging of %s", w);
w.setOrientationChanging(true);
mWmService.mRoot.mOrientationChangeComplete = false;
w.mLastFreezeDuration = 0;
@@ -1997,8 +1990,9 @@
if (mWmService.mDisplayFrozen) {
if (mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
- + " is frozen, return " + mLastWindowForcedOrientation);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Display id=%d is frozen, return %d", mDisplayId,
+ mLastWindowForcedOrientation);
// If the display is frozen, some activities may be in the middle of restarting, and
// thus have removed their old window. If the window has the flag to hide the lock
// screen, then the lock screen can re-appear and inflict its own orientation on us.
@@ -2010,8 +2004,9 @@
// window. We don't want to check the show when locked window directly though as
// things aren't stable while the display is frozen, for example the window could be
// momentarily unavailable due to activity relaunch.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
- + " is frozen while keyguard locked, return " + getLastOrientation());
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Display id=%d is frozen while keyguard locked, return %d",
+ mDisplayId, getLastOrientation());
return getLastOrientation();
}
} else {
@@ -2640,13 +2635,13 @@
mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
}
for (int i = mOpeningApps.size() - 1; i >= 0; i--) {
- mOpeningApps.valueAt(i).mActivityRecord.writeIdentifierToProto(proto, OPENING_APPS);
+ mOpeningApps.valueAt(i).writeIdentifierToProto(proto, OPENING_APPS);
}
for (int i = mClosingApps.size() - 1; i >= 0; i--) {
- mClosingApps.valueAt(i).mActivityRecord.writeIdentifierToProto(proto, CLOSING_APPS);
+ mClosingApps.valueAt(i).writeIdentifierToProto(proto, CLOSING_APPS);
}
for (int i = mChangingApps.size() - 1; i >= 0; i--) {
- mChangingApps.valueAt(i).mActivityRecord.writeIdentifierToProto(proto, CHANGING_APPS);
+ mChangingApps.valueAt(i).writeIdentifierToProto(proto, CHANGING_APPS);
}
proto.end(token);
}
@@ -2871,7 +2866,7 @@
forAllWindows(mFindFocusedWindow, true /* traverseTopToBottom */);
if (mTmpWindow == null) {
- if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows.");
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: No focusable windows.");
return null;
}
return mTmpWindow;
@@ -2917,11 +2912,8 @@
mWmService.mH.obtainMessage(REPORT_FOCUS_CHANGE, this).sendToTarget();
}
- if (DEBUG_FOCUS_LIGHT || DEBUG) {
- Slog.v(TAG_WM, "Changing focus from "
- + mCurrentFocus + " to " + newFocus + " displayId=" + getDisplayId()
- + " Callers=" + Debug.getCallers(4));
- }
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Changing focus from %s to %s displayId=%d Callers=%s",
+ mCurrentFocus, newFocus, getDisplayId(), Debug.getCallers(4));
final WindowState oldFocus = mCurrentFocus;
mCurrentFocus = newFocus;
mLosingFocus.remove(newFocus);
@@ -3058,7 +3050,7 @@
Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
+ w + " surface=" + wsa.mSurfaceController
+ " token=" + w.mAppToken);
- if (SHOW_TRANSACTIONS) logSurface(w, "LEAK DESTROY", false);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE LEAK DESTROY: %s", w);
wsa.destroySurface();
mTmpWindow = w;
}
@@ -3353,34 +3345,38 @@
}, true /* traverseTopToBottom */);
}
- boolean checkWaitingForWindows() {
+ /** @return {@code true} if there is window to wait before enabling the screen. */
+ boolean shouldWaitForSystemDecorWindowsOnBoot() {
+ if (!isDefaultDisplay && !supportsSystemDecorations()) {
+ // Nothing to wait because the secondary display doesn't support system decorations,
+ // there is no wallpaper, keyguard (status bar) or application (home) window to show
+ // during booting.
+ return false;
+ }
- mHaveBootMsg = false;
- mHaveApp = false;
- mHaveWallpaper = false;
- mHaveKeyguard = true;
+ final SparseBooleanArray drawnWindowTypes = new SparseBooleanArray();
+ // Presuppose keyguard is drawn because if its window isn't attached, we don't know if it
+ // wants to be shown or hidden, then it should not delay enabling the screen.
+ drawnWindowTypes.put(TYPE_STATUS_BAR, true);
- final WindowState visibleWindow = getWindow(w -> {
- if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
+ final WindowState visibleNotDrawnWindow = getWindow(w -> {
+ if (w.mViewVisibility == View.VISIBLE && !w.mObscured && !w.isDrawnLw()) {
return true;
}
if (w.isDrawnLw()) {
- if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
- mHaveBootMsg = true;
- } else if (w.mAttrs.type == TYPE_APPLICATION
- || w.mAttrs.type == TYPE_DRAWN_APPLICATION) {
- mHaveApp = true;
- } else if (w.mAttrs.type == TYPE_WALLPAPER) {
- mHaveWallpaper = true;
- } else if (w.mAttrs.type == TYPE_STATUS_BAR) {
- mHaveKeyguard = mWmService.mPolicy.isKeyguardDrawnLw();
+ final int type = w.mAttrs.type;
+ if (type == TYPE_BOOT_PROGRESS || type == TYPE_BASE_APPLICATION
+ || type == TYPE_WALLPAPER) {
+ drawnWindowTypes.put(type, true);
+ } else if (type == TYPE_STATUS_BAR) {
+ drawnWindowTypes.put(TYPE_STATUS_BAR, mWmService.mPolicy.isKeyguardDrawnLw());
}
}
return false;
});
- if (visibleWindow != null) {
- // We have a visible window.
+ if (visibleNotDrawnWindow != null) {
+ // Wait for the visible window to be drawn.
return true;
}
@@ -3392,23 +3388,27 @@
com.android.internal.R.bool.config_checkWallpaperAtBoot)
&& !mWmService.mOnlyCore;
- if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM,
- "******** booted=" + mWmService.mSystemBooted
- + " msg=" + mWmService.mShowingBootMessages
- + " haveBoot=" + mHaveBootMsg + " haveApp=" + mHaveApp
- + " haveWall=" + mHaveWallpaper + " wallEnabled=" + wallpaperEnabled
- + " haveKeyguard=" + mHaveKeyguard);
+ final boolean haveBootMsg = drawnWindowTypes.get(TYPE_BOOT_PROGRESS);
+ final boolean haveApp = drawnWindowTypes.get(TYPE_BASE_APPLICATION);
+ final boolean haveWallpaper = drawnWindowTypes.get(TYPE_WALLPAPER);
+ final boolean haveKeyguard = drawnWindowTypes.get(TYPE_STATUS_BAR);
+
+ ProtoLog.i(WM_DEBUG_SCREEN_ON,
+ "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b "
+ + "wallEnabled=%b haveKeyguard=%b",
+ mWmService.mSystemBooted, mWmService.mShowingBootMessages, haveBootMsg,
+ haveApp, haveWallpaper, wallpaperEnabled, haveKeyguard);
// If we are turning on the screen to show the boot message, don't do it until the boot
// message is actually displayed.
- if (!mWmService.mSystemBooted && !mHaveBootMsg) {
+ if (!mWmService.mSystemBooted && !haveBootMsg) {
return true;
}
// If we are turning on the screen after the boot is completed normally, don't do so until
// we have the application and wallpaper.
if (mWmService.mSystemBooted
- && ((!mHaveApp && !mHaveKeyguard) || (wallpaperEnabled && !mHaveWallpaper))) {
+ && ((!haveApp && !haveKeyguard) || (wallpaperEnabled && !haveWallpaper))) {
return true;
}
@@ -4234,8 +4234,8 @@
// associated with it will be removed as soon as their animations are
// complete.
cancelAnimation();
- if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
- "performLayout: App token exiting now removed" + token);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE,
+ "performLayout: App token exiting now removed %s", token);
token.removeIfPossible();
}
}
@@ -4265,15 +4265,15 @@
final int orientation = super.getOrientation();
if (orientation != SCREEN_ORIENTATION_UNSET
&& orientation != SCREEN_ORIENTATION_BEHIND) {
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
- "App is requesting an orientation, return " + orientation
- + " for display id=" + mDisplayId);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "App is requesting an orientation, return %d for display id=%d",
+ orientation, mDisplayId);
return orientation;
}
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
- "No app is requesting an orientation, return " + getLastOrientation()
- + " for display id=" + mDisplayId);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "No app is requesting an orientation, return %d for display id=%d",
+ getLastOrientation(), mDisplayId);
// The next app has not been requested to be visible, so we keep the current orientation
// to prevent freezing/unfreezing the display too early.
return getLastOrientation();
@@ -4510,8 +4510,9 @@
return SCREEN_ORIENTATION_UNSET;
}
}
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req
- + " for display id=" + mDisplayId);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "%s forcing orientation to %d for display id=%d", win, req,
+ mDisplayId);
return (mLastWindowForcedOrientation = req);
}
@@ -4766,10 +4767,9 @@
void executeAppTransition() {
if (mAppTransition.isTransitionSet()) {
- if (DEBUG_APP_TRANSITIONS) {
- Slog.w(TAG_WM, "Execute app transition: " + mAppTransition + ", displayId: "
- + mDisplayId + " Callers=" + Debug.getCallers(5));
- }
+ ProtoLog.w(WM_DEBUG_APP_TRANSITIONS,
+ "Execute app transition: %s, displayId: %d Callers=%s",
+ mAppTransition, mDisplayId, Debug.getCallers(5));
mAppTransition.setReady();
mWmService.mWindowPlacerLocked.requestTraversal();
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 10d48c4..7be4dbd 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -98,9 +98,9 @@
import static com.android.server.policy.WindowManagerPolicy.TRANSIT_SHOW;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
import static com.android.server.wm.ActivityTaskManagerInternal.SleepToken;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -168,6 +168,7 @@
import com.android.server.policy.WindowManagerPolicy.ScreenOnListener;
import com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs;
import com.android.server.policy.WindowOrientationListener;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wallpaper.WallpaperManagerInternal;
import com.android.server.wm.utils.InsetUtils;
@@ -765,19 +766,19 @@
/** Return false if it is not ready to turn on. */
public boolean finishScreenTurningOn() {
synchronized (mLock) {
- if (DEBUG_SCREEN_ON) Slog.d(TAG,
- "finishScreenTurningOn: mAwake=" + mAwake
- + ", mScreenOnEarly=" + mScreenOnEarly
- + ", mScreenOnFully=" + mScreenOnFully
- + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
- + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
+ ProtoLog.d(WM_DEBUG_SCREEN_ON,
+ "finishScreenTurningOn: mAwake=%b, mScreenOnEarly=%b, "
+ + "mScreenOnFully=%b, mKeyguardDrawComplete=%b, "
+ + "mWindowManagerDrawComplete=%b",
+ mAwake, mScreenOnEarly, mScreenOnFully, mKeyguardDrawComplete,
+ mWindowManagerDrawComplete);
if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete
|| (mAwake && !mKeyguardDrawComplete)) {
return false;
}
- if (DEBUG_SCREEN_ON) Slog.i(TAG, "Finished screen turning on...");
+ ProtoLog.i(WM_DEBUG_SCREEN_ON, "Finished screen turning on...");
mScreenOnListener = null;
mScreenOnFully = true;
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index f08b4fc..414e496 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -23,8 +23,8 @@
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_ACTIVE;
@@ -58,6 +58,7 @@
import com.android.server.UiThread;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.policy.WindowOrientationListener;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.PrintWriter;
@@ -399,7 +400,7 @@
if (mDeferredRotationPauseCount > 0) {
// Rotation updates have been paused temporarily. Defer the update until updates
// have been resumed.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused.");
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "Deferring rotation, rotation is paused.");
return false;
}
@@ -409,14 +410,14 @@
// Rotation updates cannot be performed while the previous rotation change animation
// is still in progress. Skip this update. We will try updating again after the
// animation is finished and the display is unfrozen.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, animation in progress.");
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "Deferring rotation, animation in progress.");
return false;
}
if (mService.mDisplayFrozen) {
// Even if the screen rotation animation has finished (e.g. isAnimating returns
// false), there is still some time where we haven't yet unfrozen the display. We
// also need to abort rotation here.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
"Deferring rotation, still finishing previous rotation");
return false;
}
@@ -424,30 +425,30 @@
if (!mService.mDisplayEnabled) {
// No point choosing a rotation if the display is not enabled.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, display is not enabled.");
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "Deferring rotation, display is not enabled.");
return false;
}
final int oldRotation = mRotation;
final int lastOrientation = mLastOrientation;
final int rotation = rotationForOrientation(lastOrientation, oldRotation);
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Computed rotation=" + rotation + " for display id="
- + displayId + " based on lastOrientation=" + lastOrientation
- + " and oldRotation=" + oldRotation);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Computed rotation=%d for display id=%d based on lastOrientation=%d and "
+ + "oldRotation=%d",
+ rotation, displayId, lastOrientation, oldRotation);
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + displayId
- + " selected orientation " + lastOrientation
- + ", got rotation " + rotation);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Display id=%d selected orientation %d, got rotation %d", displayId,
+ lastOrientation, rotation);
if (oldRotation == rotation) {
// No change.
return false;
}
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + displayId
- + " rotation changed to " + rotation
- + " from " + oldRotation
- + ", lastOrientation=" + lastOrientation);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Display id=%d rotation changed to %d from %d, lastOrientation=%d",
+ displayId, rotation, oldRotation, lastOrientation);
if (DisplayContent.deltaRotation(rotation, oldRotation) != 2) {
mDisplayContent.mWaitingForConfig = true;
@@ -551,9 +552,8 @@
mSeamlessRotationCount--;
}
if (mSeamlessRotationCount == 0) {
- if (DEBUG_ORIENTATION) {
- Slog.i(TAG, "Performing post-rotate rotation after seamless rotation");
- }
+ ProtoLog.i(WM_DEBUG_ORIENTATION,
+ "Performing post-rotate rotation after seamless rotation");
// Finish seamless rotation.
mRotatingSeamlessly = false;
@@ -844,11 +844,12 @@
// Could have been invoked due to screen turning on or off or
// change of the currently visible window's orientation.
- if (DEBUG_ORIENTATION) Slog.v(TAG, "screenOnEarly=" + screenOnEarly
- + ", awake=" + awake + ", currentAppOrientation=" + mCurrentAppOrientation
- + ", orientationSensorEnabled=" + mOrientationListener.mEnabled
- + ", keyguardDrawComplete=" + keyguardDrawComplete
- + ", windowManagerDrawComplete=" + windowManagerDrawComplete);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "screenOnEarly=%b, awake=%b, currentAppOrientation=%d, "
+ + "orientationSensorEnabled=%b, keyguardDrawComplete=%b, "
+ + "windowManagerDrawComplete=%b",
+ screenOnEarly, awake, mCurrentAppOrientation, mOrientationListener.mEnabled,
+ keyguardDrawComplete, windowManagerDrawComplete);
boolean disable = true;
// Note: We postpone the rotating of the screen until the keyguard as well as the
@@ -952,14 +953,11 @@
*/
@VisibleForTesting
int rotationForOrientation(int orientation, int lastRotation) {
- if (DEBUG_ORIENTATION) {
- Slog.v(TAG, "rotationForOrientation(orient="
- + orientation + ", last=" + lastRotation
- + "); user=" + mUserRotation + " "
- + (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
- ? "USER_ROTATION_LOCKED" : "")
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "rotationForOrientation(orient=%d, last=%d); user=%d %s",
+ orientation, lastRotation, mUserRotation,
+ mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
+ ? "USER_ROTATION_LOCKED" : ""
);
- }
if (isFixedToUserRotation()) {
return mUserRotation;
@@ -1059,11 +1057,19 @@
preferredRotation = lastRotation;
}
} else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
- && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
- // Apply rotation lock. Does not apply to NOSENSOR.
+ && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
+ && orientation != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ && orientation != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+ && orientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
+ && orientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT) {
+ // Apply rotation lock. Does not apply to NOSENSOR or specific rotations.
// The idea is that the user rotation expresses a weak preference for the direction
// of gravity and as NOSENSOR is never affected by gravity, then neither should
// NOSENSOR be affected by rotation lock (although it will be affected by docks).
+ // Also avoid setting user rotation when app has preference over one particular rotation
+ // to avoid leaving the rotation to the reverse of it which has the compatible
+ // orientation, but isn't what app wants, when the user rotation is the reverse of the
+ // preferred rotation.
preferredRotation = mUserRotation;
} else {
// No overriding preference.
@@ -1372,7 +1378,7 @@
@Override
public void onProposedRotationChanged(int rotation) {
- if (DEBUG_ORIENTATION) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "onProposedRotationChanged, rotation=%d", rotation);
Runnable r = mRunnableCache.get(rotation, null);
if (r == null) {
r = new UpdateRunnable(rotation);
@@ -1385,14 +1391,14 @@
public void enable(boolean clearCurrentRotation) {
super.enable(clearCurrentRotation);
mEnabled = true;
- if (DEBUG_ORIENTATION) Slog.v(TAG, "Enabling listeners");
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "Enabling listeners");
}
@Override
public void disable() {
super.disable();
mEnabled = false;
- if (DEBUG_ORIENTATION) Slog.v(TAG, "Disabling listeners");
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "Disabling listeners");
}
}
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 3c61694..34820ac 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -19,10 +19,10 @@
import static com.android.server.wm.DragDropController.MSG_ANIMATION_END;
import static com.android.server.wm.DragDropController.MSG_DRAG_END_TIMEOUT;
import static com.android.server.wm.DragDropController.MSG_TEAR_DOWN_DRAG_AND_DROP_INPUT;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.animation.Animator;
@@ -58,6 +58,7 @@
import com.android.internal.view.IDragAndDropPermissions;
import com.android.server.LocalServices;
+import com.android.server.protolog.common.ProtoLog;
import java.util.ArrayList;
@@ -300,9 +301,7 @@
mDragWindowHandle.frameBottom = mDisplaySize.y;
// Pause rotations before a drag.
- if (DEBUG_ORIENTATION) {
- Slog.d(TAG_WM, "Pausing rotation during drag");
- }
+ ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during drag");
mDisplayContent.getDisplayRotation().pause();
}
@@ -319,9 +318,7 @@
mDragApplicationHandle = null;
// Resume rotations after a drag.
- if (DEBUG_ORIENTATION) {
- Slog.d(TAG_WM, "Resuming rotation after drag");
- }
+ ProtoLog.d(WM_DEBUG_ORIENTATION, "Resuming rotation after drag");
mDisplayContent.getDisplayRotation().resume();
}
}
@@ -499,10 +496,9 @@
Slog.i(TAG_WM, ">>> OPEN TRANSACTION notifyMoveLocked");
}
mTransaction.setPosition(mSurfaceControl, x - mThumbOffsetX, y - mThumbOffsetY).apply();
- if (SHOW_TRANSACTIONS) {
- Slog.i(TAG_WM, " DRAG " + mSurfaceControl + ": pos=(" + (int) (x - mThumbOffsetX) + ","
- + (int) (y - mThumbOffsetY) + ")");
- }
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "DRAG %s: pos=(%d,%d)", mSurfaceControl,
+ (int) (x - mThumbOffsetX), (int) (y - mThumbOffsetY));
+
notifyLocationLocked(x, y);
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 8e0531c..932b4fa 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -26,7 +26,7 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -49,6 +49,7 @@
import com.android.server.AnimationThread;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.protolog.common.ProtoLog;
import java.io.PrintWriter;
import java.util.Set;
@@ -331,9 +332,7 @@
* Layer assignment is assumed to be complete by the time this is called.
*/
public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
- if (DEBUG_FOCUS_LIGHT || DEBUG_INPUT) {
- Slog.d(TAG_WM, "Input focus has changed to " + newWindow);
- }
+ ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "Input focus has changed to %s", newWindow);
if (newWindow != mInputFocus) {
if (newWindow != null && newWindow.canReceiveKeys()) {
diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java
index 3db6dcf..b7184a5 100644
--- a/services/core/java/com/android/server/wm/InsetsControlTarget.java
+++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java
@@ -16,9 +16,21 @@
package com.android.server.wm;
+import android.inputmethodservice.InputMethodService;
+import android.view.WindowInsets.Type.InsetType;
+
/**
* Generalization of an object that can control insets state.
*/
interface InsetsControlTarget {
void notifyInsetsControlChanged();
+
+ /**
+ * Instructs the control target to show inset sources.
+ *
+ * @param types to specify which types of insets source window should be shown.
+ * @param fromIme {@code true} if IME show request originated from {@link InputMethodService}.
+ */
+ default void showInsets(@InsetType int types, boolean fromIme) {
+ }
}
diff --git a/services/core/java/com/android/server/wm/ProtoLogGroup.java b/services/core/java/com/android/server/wm/ProtoLogGroup.java
index 313cceb..f5a1884 100644
--- a/services/core/java/com/android/server/wm/ProtoLogGroup.java
+++ b/services/core/java/com/android/server/wm/ProtoLogGroup.java
@@ -27,8 +27,38 @@
* must be included in services.core.wm.protologgroups build target.
*/
public enum ProtoLogGroup implements IProtoLogGroup {
- GENERIC_WM(true, true, false, "WindowManager"),
-
+ WM_ERROR(true, true, true, Consts.TAG_WM),
+ WM_DEBUG_ORIENTATION(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_FOCUS_LIGHT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_BOOT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_RESIZE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_ADD_REMOVE(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_FOCUS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM),
+ WM_DEBUG_STARTING_WINDOW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_SHOW_TRANSACTIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_SHOW_SURFACE_ALLOC(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_APP_TRANSITIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_APP_TRANSITIONS_ANIM(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_RECENTS_ANIMATIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_DRAW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM),
+ WM_DEBUG_REMOTE_ANIMATIONS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_SCREEN_ON(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM),
+ WM_DEBUG_KEEP_SCREEN_ON(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
+ WM_DEBUG_WINDOW_MOVEMENT(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
+ Consts.TAG_WM),
TEST_GROUP(true, true, false, "WindowManagetProtoLogTest");
private final boolean mEnabled;
@@ -95,4 +125,11 @@
"Test completed successfully: %b %d %o %x %e %g %f %% %s.",
true, 1, 2, 3, 0.4, 0.5, 0.6, "ok");
}
+
+ private static class Consts {
+ private static final String TAG_WM = "WindowManager";
+
+ private static final boolean ENABLE_DEBUG = false;
+ private static final boolean ENABLE_LOG_TO_PROTO_DEBUG = true;
+ }
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 5cabbd9..0075c15 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -28,10 +28,10 @@
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.BoundsAnimationController.BOUNDS;
import static com.android.server.wm.BoundsAnimationController.FADE_IN;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
import android.annotation.Nullable;
import android.app.ActivityOptions;
@@ -42,6 +42,7 @@
import android.util.Slog;
import android.view.IRecentsAnimationRunner;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.RecentsAnimationController.RecentsAnimationCallbacks;
/**
@@ -51,7 +52,6 @@
class RecentsAnimation implements RecentsAnimationCallbacks,
ActivityDisplay.OnStackOrderChangedListener {
private static final String TAG = RecentsAnimation.class.getSimpleName();
- private static final boolean DEBUG = DEBUG_RECENTS_ANIMATIONS;
private final ActivityTaskManagerService mService;
private final ActivityStackSupervisor mStackSupervisor;
@@ -101,7 +101,8 @@
* is updated to the current one.
*/
void preloadRecentsActivity() {
- if (DEBUG) Slog.d(TAG, "Preload recents with " + mTargetIntent);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Preload recents with %s",
+ mTargetIntent);
ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
mTargetActivityType);
ActivityRecord targetActivity = getTargetActivity(targetStack);
@@ -116,7 +117,8 @@
// keeps the original stopped state.
targetActivity.ensureActivityConfiguration(0 /* globalChanges */,
false /* preserveWindow */, true /* ignoreVisibility */);
- if (DEBUG) Slog.d(TAG, "Updated config=" + targetActivity.getConfiguration());
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Updated config=%s",
+ targetActivity.getConfiguration());
}
} else {
// Create the activity record. Because the activity is invisible, this doesn't really
@@ -131,13 +133,13 @@
}
if (!targetActivity.attachedToProcess()) {
- if (DEBUG) Slog.d(TAG, "Real start recents");
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Real start recents");
mStackSupervisor.startSpecificActivityLocked(targetActivity, false /* andResume */,
false /* checkConfig */);
// Make sure the activity won't be involved in transition.
- if (targetActivity.mAppWindowToken != null) {
- targetActivity.mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
- .appRemovedOrHidden(targetActivity.mAppWindowToken);
+ if (targetActivity.getDisplayContent() != null) {
+ targetActivity.getDisplayContent().mUnknownAppVisibilityController
+ .appRemovedOrHidden(targetActivity);
}
}
@@ -155,7 +157,7 @@
}
void startRecentsActivity(IRecentsAnimationRunner recentsAnimationRunner) {
- if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + mTargetIntent);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "startRecentsActivity(): intent=%s", mTargetIntent);
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "RecentsAnimation#startRecentsActivity");
// TODO(multi-display) currently only support recents animation in default display.
@@ -163,8 +165,9 @@
mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent;
if (!mWindowManager.canStartRecentsAnimation()) {
notifyAnimationCancelBeforeStart(recentsAnimationRunner);
- if (DEBUG) Slog.d(TAG, "Can't start recents animation, nextAppTransition="
- + dc.mAppTransition.getAppTransition());
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "Can't start recents animation, nextAppTransition=%s",
+ dc.mAppTransition.getAppTransition());
return;
}
@@ -178,7 +181,8 @@
mRestoreTargetBehindStack = display.getStackAbove(targetStack);
if (mRestoreTargetBehindStack == null) {
notifyAnimationCancelBeforeStart(recentsAnimationRunner);
- if (DEBUG) Slog.d(TAG, "No stack above target stack=" + targetStack);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "No stack above target stack=%s", targetStack);
return;
}
}
@@ -201,8 +205,8 @@
if (hasExistingActivity) {
// Move the recents activity into place for the animation if it is not top most
mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack);
- if (DEBUG) Slog.d(TAG, "Moved stack=" + targetStack + " behind stack="
- + mDefaultDisplay.getStackAbove(targetStack));
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Moved stack=%s behind stack=%s",
+ targetStack, mDefaultDisplay.getStackAbove(targetStack));
// If there are multiple tasks in the target stack (ie. the home stack, with 3p
// and default launchers coexisting), then move the task to the top as a part of
@@ -220,17 +224,15 @@
mTargetActivityType);
targetActivity = getTargetActivity(targetStack);
mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack);
- if (DEBUG) {
- Slog.d(TAG, "Moved stack=" + targetStack + " behind stack="
- + mDefaultDisplay.getStackAbove(targetStack));
- }
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Moved stack=%s behind stack=%s",
+ targetStack, mDefaultDisplay.getStackAbove(targetStack));
mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
mWindowManager.executeAppTransition();
// TODO: Maybe wait for app to draw in this particular case?
- if (DEBUG) Slog.d(TAG, "Started intent=" + mTargetIntent);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "Started intent=%s", mTargetIntent);
}
// Mark the target activity as launch-behind to bump its visibility for the
@@ -268,9 +270,9 @@
private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode,
boolean sendUserLeaveHint) {
synchronized (mService.mGlobalLock) {
- if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller="
- + mWindowManager.getRecentsAnimationController()
- + " reorderMode=" + reorderMode);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "onAnimationFinished(): controller=%s reorderMode=%d",
+ mWindowManager.getRecentsAnimationController(), reorderMode);
// Unregister for stack order changes
mDefaultDisplay.unregisterStackOrderChangedListener(this);
@@ -308,9 +310,10 @@
final ActivityRecord targetActivity = targetStack != null
? targetStack.isInStackLocked(mLaunchedTargetActivity)
: null;
- if (DEBUG) Slog.d(TAG, "onAnimationFinished(): targetStack=" + targetStack
- + " targetActivity=" + targetActivity
- + " mRestoreTargetBehindStack=" + mRestoreTargetBehindStack);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "onAnimationFinished(): targetStack=%s targetActivity=%s "
+ + "mRestoreTargetBehindStack=%s",
+ targetStack, targetActivity, mRestoreTargetBehindStack);
if (targetActivity == null) {
return;
}
@@ -333,25 +336,28 @@
targetStack.moveToFront("RecentsAnimation.onAnimationFinished()");
}
- if (DEBUG) {
+ if (WM_DEBUG_RECENTS_ANIMATIONS.isLogToAny()) {
final ActivityStack topStack = getTopNonAlwaysOnTopStack();
if (topStack != targetStack) {
- Slog.w(TAG, "Expected target stack=" + targetStack
- + " to be top most but found stack=" + topStack);
+ ProtoLog.w(WM_DEBUG_RECENTS_ANIMATIONS,
+ "Expected target stack=%s"
+ + " to be top most but found stack=%s",
+ targetStack, topStack);
}
}
} else if (reorderMode == REORDER_MOVE_TO_ORIGINAL_POSITION){
// Restore the target stack to its previous position
final ActivityDisplay display = targetActivity.getDisplay();
display.moveStackBehindStack(targetStack, mRestoreTargetBehindStack);
- if (DEBUG) {
+ if (WM_DEBUG_RECENTS_ANIMATIONS.isLogToAny()) {
final ActivityStack aboveTargetStack =
mDefaultDisplay.getStackAbove(targetStack);
if (mRestoreTargetBehindStack != null
&& aboveTargetStack != mRestoreTargetBehindStack) {
- Slog.w(TAG, "Expected target stack=" + targetStack
- + " to restored behind stack=" + mRestoreTargetBehindStack
- + " but it is behind stack=" + aboveTargetStack);
+ ProtoLog.w(WM_DEBUG_RECENTS_ANIMATIONS,
+ "Expected target stack=%s to restored behind stack=%s but"
+ + " it is behind stack=%s",
+ targetStack, mRestoreTargetBehindStack, aboveTargetStack);
}
}
} else {
@@ -402,7 +408,7 @@
@Override
public void onStackOrderChanged(ActivityStack stack) {
- if (DEBUG) Slog.d(TAG, "onStackOrderChanged(): stack=" + stack);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "onStackOrderChanged(): stack=%s", stack);
if (mDefaultDisplay.getIndexOf(stack) == -1 || !stack.shouldBeVisible(null)) {
// The stack is not visible, so ignore this change
return;
@@ -423,7 +429,7 @@
// 1) The next launching task is not being animated by the recents animation
// 2) The next task is home activity. (i.e. pressing home key to back home in recents).
if ((!controller.isAnimatingTask(stack.getTaskStack().getTopChild())
- || controller.isTargetApp(stack.getTopActivity().mAppWindowToken))
+ || controller.isTargetApp(stack.getTopActivity()))
&& controller.shouldDeferCancelUntilNextTransition()) {
// Always prepare an app transition since we rely on the transition callbacks to cleanup
mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 795a2ca..bd27905 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -29,8 +29,8 @@
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
import static com.android.server.wm.AnimationAdapterProto.REMOTE;
import static com.android.server.wm.BoundsAnimationController.FADE_IN;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
import android.annotation.IntDef;
@@ -57,6 +57,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.inputmethod.InputMethodManagerInternal;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
import com.android.server.wm.utils.InsetUtils;
@@ -65,6 +66,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.stream.Collectors;
/**
* Controls a single instance of the remote driven recents animation. In particular, this allows
@@ -178,8 +180,8 @@
@Override
public TaskSnapshot screenshotTask(int taskId) {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "screenshotTask(" + taskId + "):"
- + " mCanceled=" + mCanceled);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "screenshotTask(%d): mCanceled=%b", taskId, mCanceled);
final long token = Binder.clearCallingIdentity();
try {
synchronized (mService.getWindowManagerLock()) {
@@ -208,8 +210,8 @@
@Override
public void finish(boolean moveHomeToTop, boolean sendUserLeaveHint) {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "finish(" + moveHomeToTop + "):"
- + " mCanceled=" + mCanceled);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "finish(%b): mCanceled=%b", moveHomeToTop, mCanceled);
final long token = Binder.clearCallingIdentity();
try {
synchronized (mService.getWindowManagerLock()) {
@@ -250,8 +252,8 @@
@Override
public void setInputConsumerEnabled(boolean enabled) {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setInputConsumerEnabled(" + enabled + "):"
- + " mCanceled=" + mCanceled);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "setInputConsumerEnabled(%s): mCanceled=%b", enabled, mCanceled);
final long token = Binder.clearCallingIdentity();
try {
synchronized (mService.getWindowManagerLock()) {
@@ -392,8 +394,8 @@
final AppWindowToken recentsComponentAppToken =
targetStack.getTopChild().getTopFullscreenAppToken();
if (recentsComponentAppToken != null) {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setHomeApp("
- + recentsComponentAppToken.getName() + ")");
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "setHomeApp(%s)", recentsComponentAppToken.getName());
mTargetAppToken = recentsComponentAppToken;
if (recentsComponentAppToken.windowsCanBeWallpaperTarget()) {
mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
@@ -418,7 +420,7 @@
@VisibleForTesting
AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "addAnimation(" + task.getName() + ")");
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "addAnimation(%s)", task.getName());
final TaskAnimationAdapter taskAdapter = new TaskAnimationAdapter(task,
isRecentTaskInvisible);
task.startAnimation(task.getPendingTransaction(), taskAdapter, false /* hidden */);
@@ -429,8 +431,8 @@
@VisibleForTesting
void removeAnimation(TaskAnimationAdapter taskAdapter) {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "removeAnimation("
- + taskAdapter.mTask.mTaskId + ")");
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "removeAnimation(%d)", taskAdapter.mTask.mTaskId);
taskAdapter.mTask.setCanAffectSystemUiFlags(true);
taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter);
mPendingAnimations.remove(taskAdapter);
@@ -438,14 +440,14 @@
@VisibleForTesting
void removeWallpaperAnimation(WallpaperAnimationAdapter wallpaperAdapter) {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "removeWallpaperAnimation()");
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "removeWallpaperAnimation()");
wallpaperAdapter.getLeashFinishedCallback().onAnimationFinished(wallpaperAdapter);
mPendingWallpaperAnimations.remove(wallpaperAdapter);
}
void startAnimation() {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "startAnimation(): mPendingStart=" + mPendingStart
- + " mCanceled=" + mCanceled);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "startAnimation(): mPendingStart=%b mCanceled=%b", mPendingStart, mCanceled);
if (!mPendingStart || mCanceled) {
// Skip starting if we've already started or canceled the animation
return;
@@ -483,13 +485,10 @@
}
mRunner.onAnimationStart(mController, appTargets, wallpaperTargets, contentInsets,
minimizedHomeBounds);
- if (DEBUG_RECENTS_ANIMATIONS) {
- Slog.d(TAG, "startAnimation(): Notify animation start:");
- for (int i = 0; i < mPendingAnimations.size(); i++) {
- final Task task = mPendingAnimations.get(i).mTask;
- Slog.d(TAG, "\t" + task.mTaskId);
- }
- }
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "startAnimation(): Notify animation start: %s",
+ mPendingAnimations.stream()
+ .map(anim->anim.mTask.mTaskId).collect(Collectors.toList()));
} catch (RemoteException e) {
Slog.e(TAG, "Failed to start recents animation", e);
}
@@ -513,7 +512,7 @@
}
private RemoteAnimationTarget[] createWallpaperAnimations() {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "createWallpaperAnimations()");
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "createWallpaperAnimations()");
return WallpaperAnimationAdapter.startWallpaperAnimations(mService, 0L, 0L,
adapter -> {
synchronized (mService.mGlobalLock) {
@@ -533,7 +532,7 @@
}
private void cancelAnimation(@ReorderMode int reorderMode, boolean screenshot, String reason) {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "cancelAnimation(): reason=%s", reason);
synchronized (mService.getWindowManagerLock()) {
if (mCanceled) {
// We've already canceled the animation
@@ -627,9 +626,7 @@
mRecentScreenshotAnimator = new SurfaceAnimator(
animatable,
() -> {
- if (DEBUG_RECENTS_ANIMATIONS) {
- Slog.d(TAG, "mRecentScreenshotAnimator finish");
- }
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "mRecentScreenshotAnimator finish");
mCallbacks.onAnimationFinished(reorderMode, false /* sendUserLeaveHint */);
}, mService);
mRecentScreenshotAnimator.transferAnimation(task.mSurfaceAnimator);
@@ -637,9 +634,10 @@
}
void cleanupAnimation(@ReorderMode int reorderMode) {
- if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG,
- "cleanupAnimation(): Notify animation finished mPendingAnimations="
- + mPendingAnimations.size() + " reorderMode=" + reorderMode);
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "cleanupAnimation(): Notify animation finished mPendingAnimations=%d "
+ + "reorderMode=%d",
+ mPendingAnimations.size(), reorderMode);
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 87bda4a..2b2ae92 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -17,9 +17,8 @@
package com.android.server.wm;
import static com.android.server.wm.AnimationAdapterProto.REMOTE;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS;
import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_REMOTE_ANIMATIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -39,6 +38,8 @@
import android.view.SurfaceControl.Transaction;
import com.android.internal.util.FastPrintWriter;
+import com.android.server.protolog.ProtoLogImpl;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
import com.android.server.wm.utils.InsetUtils;
@@ -51,7 +52,6 @@
*/
class RemoteAnimationController implements DeathRecipient {
private static final String TAG = TAG_WITH_CLASS_NAME
- || (DEBUG_REMOTE_ANIMATIONS && !DEBUG_APP_TRANSITIONS)
? "RemoteAnimationController" : TAG_WM;
private static final long TIMEOUT_MS = 2000;
@@ -86,8 +86,8 @@
*/
RemoteAnimationRecord createRemoteAnimationRecord(AppWindowToken appWindowToken,
Point position, Rect stackBounds, Rect startBounds) {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "createAnimationAdapter(): token="
- + appWindowToken);
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAnimationAdapter(): token=%s",
+ appWindowToken);
final RemoteAnimationRecord adapters =
new RemoteAnimationRecord(appWindowToken, position, stackBounds, startBounds);
mPendingAnimations.add(adapters);
@@ -98,11 +98,11 @@
* Called when the transition is ready to be started, and all leashes have been set up.
*/
void goodToGo() {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "goodToGo()");
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo()");
if (mPendingAnimations.isEmpty() || mCanceled) {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "goodToGo(): Animation finished already,"
- + " canceled=" + mCanceled
- + " mPendingAnimations=" + mPendingAnimations.size());
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
+ "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d",
+ mCanceled, mPendingAnimations.size());
onAnimationFinished();
return;
}
@@ -115,7 +115,7 @@
// Create the app targets
final RemoteAnimationTarget[] appTargets = createAppAnimations();
if (appTargets.length == 0) {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "goodToGo(): No apps to animate");
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo(): No apps to animate");
onAnimationFinished();
return;
}
@@ -131,8 +131,8 @@
Slog.e(TAG, "Failed to start remote animation", e);
onAnimationFinished();
}
- if (DEBUG_REMOTE_ANIMATIONS) {
- Slog.d(TAG, "startAnimation(): Notify animation start:");
+ if (ProtoLogImpl.isEnabled(WM_DEBUG_REMOTE_ANIMATIONS)) {
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation(): Notify animation start:");
writeStartDebugStatement();
}
});
@@ -140,7 +140,7 @@
}
void cancelAnimation(String reason) {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason);
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "cancelAnimation(): reason=%s", reason);
synchronized (mService.getWindowManagerLock()) {
if (mCanceled) {
return;
@@ -152,28 +152,28 @@
}
private void writeStartDebugStatement() {
- Slog.i(TAG, "Starting remote animation");
+ ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "Starting remote animation");
final StringWriter sw = new StringWriter();
final FastPrintWriter pw = new FastPrintWriter(sw);
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
mPendingAnimations.get(i).mAdapter.dump(pw, "");
}
pw.close();
- Slog.i(TAG, sw.toString());
+ ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "%s", sw.toString());
}
private RemoteAnimationTarget[] createAppAnimations() {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "createAppAnimations()");
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAppAnimations()");
final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>();
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
final RemoteAnimationRecord wrappers = mPendingAnimations.get(i);
final RemoteAnimationTarget target = wrappers.createRemoteAnimationTarget();
if (target != null) {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\tAdd token=" + wrappers.mAppWindowToken);
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tAdd token=%s", wrappers.mAppWindowToken);
targets.add(target);
} else {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\tRemove token="
- + wrappers.mAppWindowToken);
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tRemove token=%s",
+ wrappers.mAppWindowToken);
// We can't really start an animation but we still need to make sure to finish the
// pending animation that was started by SurfaceAnimator
@@ -194,7 +194,7 @@
}
private RemoteAnimationTarget[] createWallpaperAnimations() {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "createWallpaperAnimations()");
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createWallpaperAnimations()");
return WallpaperAnimationAdapter.startWallpaperAnimations(mService,
mRemoteAnimationAdapter.getDuration(),
mRemoteAnimationAdapter.getStatusBarTransitionDelay(),
@@ -207,15 +207,15 @@
}
private void onAnimationFinished() {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "onAnimationFinished(): mPendingAnimations="
- + mPendingAnimations.size());
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "onAnimationFinished(): mPendingAnimations=%d",
+ mPendingAnimations.size());
mHandler.removeCallbacks(mTimeoutRunnable);
synchronized (mService.mGlobalLock) {
unlinkToDeathOfRunner();
releaseFinishedCallback();
mService.openSurfaceTransaction();
try {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG,
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
"onAnimationFinished(): Notify animation finished:");
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
final RemoteAnimationRecord adapters = mPendingAnimations.get(i);
@@ -228,14 +228,14 @@
.onAnimationFinished(adapters.mThumbnailAdapter);
}
mPendingAnimations.remove(i);
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\tapp=" + adapters.mAppWindowToken);
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tapp=%s", adapters.mAppWindowToken);
}
for (int i = mPendingWallpaperAnimations.size() - 1; i >= 0; i--) {
final WallpaperAnimationAdapter adapter = mPendingWallpaperAnimations.get(i);
adapter.getLeashFinishedCallback().onAnimationFinished(adapter);
mPendingWallpaperAnimations.remove(i);
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "\twallpaper=" + adapter.getToken());
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\twallpaper=%s", adapter.getToken());
}
} catch (Exception e) {
Slog.e(TAG, "Failed to finish remote animation", e);
@@ -245,7 +245,7 @@
}
}
setRunningRemoteAnimation(false);
- if (DEBUG_REMOTE_ANIMATIONS) Slog.i(TAG, "Finishing remote animation");
+ ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "Finishing remote animation");
}
private void invokeAnimationCancelled() {
@@ -306,7 +306,7 @@
@Override
public void onAnimationFinished() throws RemoteException {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "app-onAnimationFinished(): mOuter=" + mOuter);
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "app-onAnimationFinished(): mOuter=%s", mOuter);
final long token = Binder.clearCallingIdentity();
try {
if (mOuter != null) {
@@ -326,7 +326,7 @@
* to prevent memory leak.
*/
void release() {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "app-release(): mOuter=" + mOuter);
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "app-release(): mOuter=%s", mOuter);
mOuter = null;
}
};
@@ -420,7 +420,7 @@
@Override
public void startAnimation(SurfaceControl animationLeash, Transaction t,
OnAnimationFinishedCallback finishCallback) {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "startAnimation");
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation");
// Restore z-layering, position and stack crop until client has a chance to modify it.
t.setLayer(animationLeash, mRecord.mAppWindowToken.getPrefixOrderIndex());
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 734f224..8a47c5a 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -638,10 +638,16 @@
if (displayContent != null) {
config = displayContent.updateOrientation(
getDisplayOverrideConfiguration(displayId),
- starting != null && starting.mayFreezeScreenLocked(starting.app)
+ starting != null && starting.mayFreezeScreenLocked()
? starting.appToken : null,
true /* forceUpdate */);
}
+ // Visibilities may change so let the starting activity have a chance to report. Can't do it
+ // when visibility is changed in each AppWindowToken because it may trigger wrong
+ // configuration push because the visibility of some activities may not be updated yet.
+ if (starting != null) {
+ starting.reportDescendantOrientationChangeIfNeeded();
+ }
if (starting != null && markFrozenIfConfigChanged && config != null) {
starting.frozenBeforeDestroy = true;
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 4365d03..78fcb37 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -29,20 +29,19 @@
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.RootWindowContainerProto.DISPLAYS;
import static com.android.server.wm.RootWindowContainerProto.WINDOWS;
import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
@@ -50,7 +49,6 @@
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
-import static com.android.server.wm.WindowManagerService.logSurface;
import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
@@ -80,6 +78,7 @@
import android.view.WindowManager;
import com.android.server.EventLogTags;
+import com.android.server.protolog.common.ProtoLog;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -195,8 +194,8 @@
mTopFocusedDisplayId = topFocusedDisplayId;
mWmService.mInputManager.setFocusedDisplay(topFocusedDisplayId);
mWmService.mPolicy.setTopFocusedDisplay(topFocusedDisplayId);
- if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "New topFocusedDisplayId="
- + topFocusedDisplayId);
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "New topFocusedDisplayId=%d",
+ topFocusedDisplayId);
}
return changed;
}
@@ -457,13 +456,13 @@
}
void removeReplacedWindows() {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION removeReplacedWindows");
mWmService.openSurfaceTransaction();
try {
forAllWindows(sRemoveReplacedWindowsConsumer, true /* traverseTopToBottom */);
} finally {
mWmService.closeSurfaceTransaction("removeReplacedWindows");
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION removeReplacedWindows");
}
}
@@ -539,8 +538,8 @@
Slog.w(TAG_WM,
"Looks like we have reclaimed some memory, clearing surface for retry.");
if (surfaceController != null) {
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
- "RECOVER DESTROY", false);
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
+ "SURFACE RECOVER DESTROY: %s", winAnimator.mWin);
winAnimator.destroySurface();
if (winAnimator.mWin.mAppToken != null) {
winAnimator.mWin.mAppToken.removeStartingWindow();
@@ -651,8 +650,11 @@
handleResizingWindows();
- if (DEBUG_ORIENTATION && mWmService.mDisplayFrozen) Slog.v(TAG,
- "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
+ if (mWmService.mDisplayFrozen) {
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "With display frozen, orientationChangeComplete=%b",
+ mOrientationChangeComplete);
+ }
if (mOrientationChangeComplete) {
if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
@@ -714,7 +716,7 @@
}
if (mUpdateRotation) {
- if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
+ ProtoLog.d(WM_DEBUG_ORIENTATION, "Performing post-rotate rotation");
mUpdateRotation = updateRotationUnchecked();
}
@@ -868,29 +870,26 @@
final int privateflags = attrs.privateFlags;
boolean displayHasContent = false;
- if (DEBUG_KEEP_SCREEN_ON) {
- Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked w: " + w
- + ", w.mHasSurface: " + w.mHasSurface
- + ", w.isOnScreen(): " + onScreen
- + ", w.isDisplayedLw(): " + w.isDisplayedLw()
- + ", w.mAttrs.userActivityTimeout: " + w.mAttrs.userActivityTimeout);
- }
+ ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,
+ "handleNotObscuredLocked w: %s, w.mHasSurface: %b, w.isOnScreen(): %b, w"
+ + ".isDisplayedLw(): %b, w.mAttrs.userActivityTimeout: %d",
+ w, w.mHasSurface, onScreen, w.isDisplayedLw(), w.mAttrs.userActivityTimeout);
if (w.mHasSurface && onScreen) {
if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
mUserActivityTimeout = w.mAttrs.userActivityTimeout;
- if (DEBUG_KEEP_SCREEN_ON) {
- Slog.d(TAG, "mUserActivityTimeout set to " + mUserActivityTimeout);
- }
+ ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "mUserActivityTimeout set to %d",
+ mUserActivityTimeout);
}
}
if (w.mHasSurface && canBeSeen) {
if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
mHoldScreen = w.mSession;
mHoldScreenWindow = w;
- } else if (DEBUG_KEEP_SCREEN_ON && w == mWmService.mLastWakeLockHoldingWindow) {
- Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
- + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
- + Debug.getCallers(10));
+ } else if (w == mWmService.mLastWakeLockHoldingWindow) {
+ ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,
+ "handleNotObscuredLocked: %s was holding screen wakelock but no longer "
+ + "has FLAG_KEEP_SCREEN_ON!!! called by%s",
+ w, Debug.getCallers(10));
}
if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
mScreenBrightness = w.mAttrs.screenBrightness;
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index c4bfe4b..157bd3b 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -16,10 +16,9 @@
package com.android.server.wm;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
import static com.android.server.wm.ScreenRotationAnimationProto.ANIMATION_RUNNING;
import static com.android.server.wm.ScreenRotationAnimationProto.STARTED;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
@@ -40,6 +39,8 @@
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;
+import com.android.server.protolog.common.ProtoLog;
+
import java.io.PrintWriter;
/**
@@ -215,10 +216,8 @@
Slog.w(TAG, "Unable to allocate freeze surface", e);
}
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
- Slog.i(TAG_WM,
- " FREEZE " + mSurfaceControl + ": CREATE");
- }
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
+ " FREEZE %s: CREATE", mSurfaceControl);
setRotation(t, originalRotation);
t.apply();
}
@@ -481,11 +480,7 @@
mSurfaceRotationAnimationController = null;
}
if (mSurfaceControl != null) {
- if (SHOW_TRANSACTIONS ||
- SHOW_SURFACE_ALLOC) {
- Slog.i(TAG_WM,
- " FREEZE " + mSurfaceControl + ": DESTROY");
- }
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC, " FREEZE %s: DESTROY", mSurfaceControl);
mSurfaceControl = null;
SurfaceControl.Transaction t = mService.mTransactionFactory.get();
if (mRotationLayer != null) {
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 72bb355..b047d8f 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -24,9 +24,9 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.annotation.Nullable;
@@ -56,6 +56,7 @@
import android.view.WindowManager;
import com.android.internal.os.logging.MetricsLoggerWrapper;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.WindowManagerService.H;
import java.io.PrintWriter;
@@ -478,8 +479,7 @@
Slog.v(TAG_WM, "First window added to " + this + ", creating SurfaceSession");
}
mSurfaceSession = new SurfaceSession();
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG_WM, " NEW SURFACE SESSION " + mSurfaceSession);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, " NEW SURFACE SESSION %s", mSurfaceSession);
mService.mSessions.add(this);
if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
mService.dispatchNewAnimatorScaleLocked(this);
@@ -570,7 +570,7 @@
Slog.v(TAG_WM, "Last window removed from " + this
+ ", destroying " + mSurfaceSession);
}
- if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " KILL SURFACE SESSION " + mSurfaceSession);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, " KILL SURFACE SESSION %s", mSurfaceSession);
try {
mSurfaceSession.kill();
} catch (Exception e) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 5e14087..2ad9102 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -20,8 +20,12 @@
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.res.Configuration.EMPTY;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.SurfaceControl.METADATA_TASK_ID;
import static com.android.server.EventLogTags.WM_TASK_REMOVED;
@@ -114,6 +118,13 @@
// TODO: remove after unification
TaskRecord mTaskRecord;
+ // TODO: Remove after unification.
+ @Override
+ public void onConfigurationChanged(Configuration newParentConfig) {
+ // Only forward configuration changes in cases where children won't get it from TaskRecord.
+ onConfigurationChanged(newParentConfig, mTaskRecord == null /*forwardToChildren*/);
+ }
+
Task(int taskId, TaskStack stack, int userId, WindowManagerService service, int resizeMode,
boolean supportsPictureInPicture, TaskDescription taskDescription,
TaskRecord taskRecord) {
@@ -129,11 +140,21 @@
// unification.
mTaskRecord.registerConfigurationChangeListener(this);
}
- setBounds(getRequestedOverrideBounds());
+ setBounds(getResolvedOverrideBounds());
mTaskDescription = taskDescription;
- // Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED).
- setOrientation(SCREEN_ORIENTATION_UNSET);
+ // Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED) not unless
+ // set through the override configuration.
+ int orientation = SCREEN_ORIENTATION_UNSET;
+ switch (getResolvedOverrideConfiguration().orientation) {
+ case ORIENTATION_PORTRAIT:
+ orientation = SCREEN_ORIENTATION_PORTRAIT;
+ break;
+ case ORIENTATION_LANDSCAPE:
+ orientation = SCREEN_ORIENTATION_LANDSCAPE;
+ break;
+ }
+ setOrientation(orientation);
}
@Override
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 1c015d0..9712277 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -398,9 +398,11 @@
return;
}
- final Rect bounds = display.getBounds();
- final int defaultWidth = bounds.width();
- final int defaultHeight = bounds.height();
+ // Use stable frame instead of raw frame to avoid launching freeform windows on top of
+ // stable insets, which usually are system widgets such as sysbar & navbar.
+ final Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable;
+ final int defaultWidth = displayStableBounds.width();
+ final int defaultHeight = displayStableBounds.height();
int width;
int height;
@@ -451,6 +453,7 @@
}
outBounds.set(0, 0, width, height);
+ outBounds.offset(displayStableBounds.left, displayStableBounds.top);
final int xOffset = (int) (fractionOfHorizontalOffset * (defaultWidth - width));
final int yOffset = (int) (fractionOfVerticalOffset * (defaultHeight - height));
outBounds.offset(xOffset, yOffset);
@@ -627,10 +630,14 @@
@NonNull ActivityInfo.WindowLayout layout, int orientation, @NonNull Rect bounds) {
// Default size, which is letterboxing/pillarboxing in display. That's to say the large
// dimension of default size is the small dimension of display size, and the small dimension
- // of default size is calculated to keep the same aspect ratio as the display's.
- Rect displayBounds = display.getBounds();
- final int portraitHeight = Math.min(displayBounds.width(), displayBounds.height());
- final int otherDimension = Math.max(displayBounds.width(), displayBounds.height());
+ // of default size is calculated to keep the same aspect ratio as the display's. Here we use
+ // stable bounds of displays because that indicates the area that isn't occupied by system
+ // widgets (e.g. sysbar and navbar).
+ Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable;
+ final int portraitHeight =
+ Math.min(displayStableBounds.width(), displayStableBounds.height());
+ final int otherDimension =
+ Math.max(displayStableBounds.width(), displayStableBounds.height());
final int portraitWidth = (portraitHeight * portraitHeight) / otherDimension;
final int defaultWidth = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitHeight
: portraitWidth;
@@ -656,16 +663,17 @@
final int height = Math.min(defaultHeight, Math.max(phoneHeight, layoutMinHeight));
bounds.set(0, 0, width, height);
+ bounds.offset(displayStableBounds.left, displayStableBounds.top);
}
/**
* Gets centered bounds of width x height. If inOutBounds is not empty, the result bounds
- * centers at its center or display's center if inOutBounds is empty.
+ * centers at its center or display's app bounds center if inOutBounds is empty.
*/
private void centerBounds(@NonNull ActivityDisplay display, int width, int height,
@NonNull Rect inOutBounds) {
if (inOutBounds.isEmpty()) {
- display.getBounds(inOutBounds);
+ inOutBounds.set(display.mDisplayContent.mDisplayFrames.mStable);
}
final int left = inOutBounds.centerX() - width / 2;
final int top = inOutBounds.centerY() - height / 2;
@@ -674,40 +682,40 @@
private void adjustBoundsToFitInDisplay(@NonNull ActivityDisplay display,
@NonNull Rect inOutBounds) {
- final Rect displayBounds = display.getBounds();
+ final Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable;
- if (displayBounds.width() < inOutBounds.width()
- || displayBounds.height() < inOutBounds.height()) {
+ if (displayStableBounds.width() < inOutBounds.width()
+ || displayStableBounds.height() < inOutBounds.height()) {
// There is no way for us to fit the bounds in the display without changing width
// or height. Just move the start to align with the display.
final int layoutDirection =
mSupervisor.mRootActivityContainer.getConfiguration().getLayoutDirection();
final int left = layoutDirection == View.LAYOUT_DIRECTION_RTL
- ? displayBounds.width() - inOutBounds.width()
- : 0;
- inOutBounds.offsetTo(left, 0 /* newTop */);
+ ? displayStableBounds.right - inOutBounds.right + inOutBounds.left
+ : displayStableBounds.left;
+ inOutBounds.offsetTo(left, displayStableBounds.top);
return;
}
final int dx;
- if (inOutBounds.right > displayBounds.right) {
+ if (inOutBounds.right > displayStableBounds.right) {
// Right edge is out of display.
- dx = displayBounds.right - inOutBounds.right;
- } else if (inOutBounds.left < displayBounds.left) {
+ dx = displayStableBounds.right - inOutBounds.right;
+ } else if (inOutBounds.left < displayStableBounds.left) {
// Left edge is out of display.
- dx = displayBounds.left - inOutBounds.left;
+ dx = displayStableBounds.left - inOutBounds.left;
} else {
// Vertical edges are all in display.
dx = 0;
}
final int dy;
- if (inOutBounds.top < displayBounds.top) {
+ if (inOutBounds.top < displayStableBounds.top) {
// Top edge is out of display.
- dy = displayBounds.top - inOutBounds.top;
- } else if (inOutBounds.bottom > displayBounds.bottom) {
+ dy = displayStableBounds.top - inOutBounds.top;
+ } else if (inOutBounds.bottom > displayStableBounds.bottom) {
// Bottom edge is out of display.
- dy = displayBounds.bottom - inOutBounds.bottom;
+ dy = displayStableBounds.bottom - inOutBounds.bottom;
} else {
// Horizontal edges are all in display.
dy = 0;
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index fc8a27d..b680fa4 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -21,7 +21,7 @@
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -54,6 +54,7 @@
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.protolog.common.ProtoLog;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -297,9 +298,7 @@
mDragWindowHandle.frameBottom = p.y;
// Pause rotations before a drag.
- if (DEBUG_ORIENTATION) {
- Slog.d(TAG, "Pausing rotation during re-position");
- }
+ ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during re-position");
mDisplayContent.getDisplayRotation().pause();
// Notify InputMonitor to take mDragWindowHandle.
@@ -340,9 +339,7 @@
mDisplayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
// Resume rotations after a drag.
- if (DEBUG_ORIENTATION) {
- Slog.d(TAG, "Resuming rotation after re-position");
- }
+ ProtoLog.d(WM_DEBUG_ORIENTATION, "Resuming rotation after re-position");
mDisplayContent.getDisplayRotation().resume();
mDisplayContent = null;
mClientCallback.unlinkToDeath(this, 0 /* flags */);
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 0ea108e..8b2ef7f 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -1251,7 +1251,7 @@
mActivities.add(newTop);
// Make sure window manager is aware of the position change.
- mTask.positionChildAtTop(newTop.mAppWindowToken);
+ mTask.positionChildAtTop(newTop);
updateEffectiveIntent();
}
@@ -1283,7 +1283,7 @@
r.setTask(this);
// Remove r first, and if it wasn't already in the list and it's fullscreen, count it.
- if (!mActivities.remove(r) && r.fullscreen) {
+ if (!mActivities.remove(r) && r.occludesParent()) {
// Was not previously in list.
numFullscreen++;
}
@@ -1327,10 +1327,10 @@
mService.notifyTaskPersisterLocked(this, false);
}
- if (r.mAppWindowToken != null) {
+ if (r.getParent() != null) {
// Only attempt to move in WM if the child has a controller. It is possible we haven't
// created controller for the activity we are starting yet.
- mTask.positionChildAt(r.mAppWindowToken, index);
+ mTask.positionChildAt(r, index);
}
// Make sure the list of display UID whitelists is updated
@@ -1355,7 +1355,7 @@
r.setTask(null /* task */, reparenting /* reparenting */);
- if (mActivities.remove(r) && r.fullscreen) {
+ if (mActivities.remove(r) && r.occludesParent()) {
// Was previously in list.
numFullscreen--;
}
diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
index f291573..adecc36 100644
--- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
+++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
@@ -15,14 +15,15 @@
*/
package com.android.server.wm;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
import android.graphics.GraphicBuffer;
-import android.util.Slog;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
+import com.android.server.protolog.common.ProtoLog;
+
import java.util.function.Function;
/**
@@ -45,10 +46,9 @@
mTask = task;
mWidth = (buffer != null) ? buffer.getWidth() : 1;
mHeight = (buffer != null) ? buffer.getHeight() : 1;
- if (DEBUG_RECENTS_ANIMATIONS) {
- Slog.d(TAG, "Creating TaskScreenshotAnimatable: task: " + task
- + "width: " + mWidth + "height: " + mHeight);
- }
+ ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
+ "Creating TaskScreenshotAnimatable: task: %s width: %d height: %d",
+ task, mWidth, mHeight);
mSurfaceControl = surfaceControlFactory.apply(new SurfaceSession())
.setName("RecentTaskScreenshotSurface")
.setBufferSize(mWidth, mHeight)
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index 7456f0d..d070850 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -42,7 +42,7 @@
import static com.android.internal.policy.DecorView.getColorViewLeftInset;
import static com.android.internal.policy.DecorView.getColorViewTopInset;
import static com.android.internal.policy.DecorView.getNavigationBarRect;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -79,6 +79,7 @@
import com.android.internal.policy.DecorView;
import com.android.internal.view.BaseIWindow;
import com.android.server.policy.WindowManagerPolicy.StartingSurface;
+import com.android.server.protolog.common.ProtoLog;
/**
* This class represents a starting window that shows a snapshot.
@@ -259,14 +260,14 @@
final long now = SystemClock.uptimeMillis();
if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS) {
mHandler.postAtTime(this::remove, mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS);
- if (DEBUG_STARTING_WINDOW) {
- Slog.v(TAG, "Defer removing snapshot surface in " + (now - mShownTime) + "ms");
- }
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
+ "Defer removing snapshot surface in %dms", (now - mShownTime));
+
return;
}
}
try {
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Removing snapshot surface");
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Removing snapshot surface");
mSession.remove(mWindow);
} catch (RemoteException e) {
// Local call.
@@ -286,8 +287,8 @@
private void drawSnapshot() {
mSurface.copyFrom(mSurfaceControl);
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Drawing snapshot surface sizeMismatch="
- + mSizeMismatch);
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Drawing snapshot surface sizeMismatch=%b",
+ mSizeMismatch);
if (mSizeMismatch) {
// The dimensions of the buffer and the window don't match, so attaching the buffer
// will fail. Better create a child window with the exact dimensions and fill the parent
diff --git a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
index 895350b..513008d 100644
--- a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
@@ -16,17 +16,17 @@
package com.android.server.wm;
import static com.android.server.wm.AnimationAdapterProto.REMOTE;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS;
import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_REMOTE_ANIMATIONS;
import android.graphics.Point;
import android.os.SystemClock;
-import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
+import com.android.server.protolog.common.ProtoLog;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.function.Consumer;
@@ -68,15 +68,11 @@
final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>();
service.mRoot.forAllWallpaperWindows(wallpaperWindow -> {
if (!wallpaperWindow.getDisplayContent().mWallpaperController.isWallpaperVisible()) {
- if (DEBUG_REMOTE_ANIMATIONS || DEBUG_RECENTS_ANIMATIONS) {
- Slog.d(TAG, "\tNot visible=" + wallpaperWindow);
- }
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tNot visible=%s", wallpaperWindow);
return;
}
- if (DEBUG_REMOTE_ANIMATIONS || DEBUG_RECENTS_ANIMATIONS) {
- Slog.d(TAG, "\tvisible=" + wallpaperWindow);
- }
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tvisible=%s", wallpaperWindow);
final WallpaperAnimationAdapter wallpaperAdapter = new WallpaperAnimationAdapter(
wallpaperWindow, durationHint, statusBarTransitionDelay,
animationCanceledRunnable);
@@ -129,7 +125,7 @@
@Override
public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t,
SurfaceAnimator.OnAnimationFinishedCallback finishCallback) {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "startAnimation");
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation");
// Restore z-layering until client has a chance to modify it.
t.setLayer(animationLeash, mWallpaperToken.getPrefixOrderIndex());
@@ -139,7 +135,7 @@
@Override
public void onAnimationCancelled(SurfaceControl animationLeash) {
- if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "onAnimationCancelled");
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "onAnimationCancelled");
mAnimationCanceledRunnable.accept(this);
}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 13902ee..e7b09db 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -24,7 +24,6 @@
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
@@ -607,8 +606,9 @@
boolean processWallpaperDrawPendingTimeout() {
if (mWallpaperDrawState == WALLPAPER_DRAW_PENDING) {
mWallpaperDrawState = WALLPAPER_DRAW_TIMEOUT;
- if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
- "*** WALLPAPER DRAW TIMEOUT");
+ if (DEBUG_WALLPAPER) {
+ Slog.v(TAG, "*** WALLPAPER DRAW TIMEOUT");
+ }
// If there was a pending recents animation, start the animation anyways (it's better
// to not see the wallpaper than for the animation to not start)
@@ -641,9 +641,11 @@
WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION);
}
- if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
- "Wallpaper should be visible but has not been drawn yet. " +
- "mWallpaperDrawState=" + mWallpaperDrawState);
+ if (DEBUG_WALLPAPER) {
+ Slog.v(TAG,
+ "Wallpaper should be visible but has not been drawn yet. "
+ + "mWallpaperDrawState=" + mWallpaperDrawState);
+ }
break;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 1e206f6..f437b28 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -16,8 +16,8 @@
package com.android.server.wm;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
@@ -32,6 +32,7 @@
import com.android.server.AnimationThread;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.protolog.common.ProtoLog;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -138,7 +139,7 @@
Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
}
- if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION animate");
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION animate");
mService.openSurfaceTransaction();
try {
final AccessibilityController accessibilityController =
@@ -177,7 +178,7 @@
Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
} finally {
mService.closeSurfaceTransaction("WindowAnimator");
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION animate");
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate");
}
boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index ec43ec5..19fcb1b 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -19,6 +19,11 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
+import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.view.SurfaceControl.Transaction;
import static com.android.server.wm.WindowContainerProto.CONFIGURATION_CONTAINER;
@@ -33,9 +38,11 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
+import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
+import android.os.Debug;
import android.os.IBinder;
import android.util.Pools;
import android.util.Slog;
@@ -106,9 +113,6 @@
private final Pools.SynchronizedPool<ForAllWindowsConsumerWrapper> mConsumerWrapperPool =
new Pools.SynchronizedPool<>(3);
- // The owner/creator for this container. No controller if null.
- WindowContainerController mController;
-
// The display this window container is on.
protected DisplayContent mDisplayContent;
@@ -137,6 +141,8 @@
*/
private boolean mCommittedReparentToAnimationLeash;
+ private final Configuration mTmpConfig = new Configuration();
+
/**
* Callback which is triggered while changing the parent, after setting up the surface but
* before asking the parent to assign child layers.
@@ -263,7 +269,8 @@
if (child.getParent() != null) {
throw new IllegalArgumentException("addChild: container=" + child.getName()
+ " is already a child of container=" + child.getParent().getName()
- + " can't add to container=" + getName());
+ + " can't add to container=" + getName()
+ + "\n callers=" + Debug.getCallers(15, "\n"));
}
if ((index < 0 && index != POSITION_BOTTOM)
@@ -356,11 +363,6 @@
if (mParent != null) {
mParent.removeChild(this);
}
-
- if (mController != null) {
- setController(null);
- }
-
}
/**
@@ -759,6 +761,31 @@
}
/**
+ * Get the configuration orientation by the requested screen orientation
+ * ({@link ActivityInfo.ScreenOrientation}) of this activity.
+ *
+ * @return orientation in ({@link Configuration#ORIENTATION_LANDSCAPE},
+ * {@link Configuration#ORIENTATION_PORTRAIT},
+ * {@link Configuration#ORIENTATION_UNDEFINED}).
+ */
+ int getRequestedConfigurationOrientation() {
+ if (mOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
+ // NOSENSOR means the display's "natural" orientation, so return that.
+ if (mDisplayContent != null) {
+ return mDisplayContent.getNaturalOrientation();
+ }
+ } else if (mOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
+ // LOCKED means the activity's orientation remains unchanged, so return existing value.
+ return getConfiguration().orientation;
+ } else if (isFixedOrientationLandscape(mOrientation)) {
+ return ORIENTATION_LANDSCAPE;
+ } else if (isFixedOrientationPortrait(mOrientation)) {
+ return ORIENTATION_PORTRAIT;
+ }
+ return ORIENTATION_UNDEFINED;
+ }
+
+ /**
* Calls {@link #setOrientation(int, IBinder, ActivityRecord)} with {@code null} to the last 2
* parameters.
*
@@ -788,6 +815,13 @@
}
mOrientation = orientation;
+ final int configOrientation = getRequestedConfigurationOrientation();
+ if (getRequestedOverrideConfiguration().orientation != configOrientation) {
+ mTmpConfig.setTo(getRequestedOverrideConfiguration());
+ mTmpConfig.orientation = configOrientation;
+ onRequestedOverrideConfigurationChanged(mTmpConfig);
+ }
+
final WindowContainer parent = getParent();
if (parent != null) {
onDescendantOrientationChanged(freezeDisplayToken, requestingContainer);
@@ -1005,23 +1039,6 @@
} while (current != null);
}
- WindowContainerController getController() {
- return mController;
- }
-
- void setController(WindowContainerController controller) {
- if (mController != null && controller != null) {
- throw new IllegalArgumentException("Can't set controller=" + mController
- + " for container=" + this + " Already set to=" + mController);
- }
- if (controller != null) {
- controller.setContainer(this);
- } else if (mController != null) {
- mController.setContainer(null);
- }
- mController = controller;
- }
-
SurfaceControl.Builder makeSurface() {
final WindowContainer p = getParent();
return p.makeChildSurface(this);
diff --git a/services/core/java/com/android/server/wm/WindowContainerController.java b/services/core/java/com/android/server/wm/WindowContainerController.java
deleted file mode 100644
index 17bc0e2..0000000
--- a/services/core/java/com/android/server/wm/WindowContainerController.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.wm;
-
-import android.content.res.Configuration;
-
-/**
- * Class that allows the owner/creator of a {@link WindowContainer} to communicate directly with the
- * container and make changes.
- * Note that public calls (mostly in sub-classes) into this class are assumed to be originating from
- * outside the window manager so the window manager lock is held and appropriate permissions are
- * checked before calls are allowed to proceed.
- *
- * Test class: {@link WindowContainerControllerTests}
- */
-class WindowContainerController<E extends WindowContainer, I extends WindowContainerListener>
- implements ConfigurationContainerListener {
-
- final WindowManagerService mService;
- final RootWindowContainer mRoot;
- final WindowManagerGlobalLock mGlobalLock;
-
- // The window container this controller owns.
- E mContainer;
- // Interface for communicating changes back to the owner.
- final I mListener;
-
- WindowContainerController(I listener, WindowManagerService service) {
- mListener = listener;
- mService = service;
- mRoot = mService != null ? mService.mRoot : null;
- mGlobalLock = mService != null ? mService.mGlobalLock : null;
- }
-
- void setContainer(E container) {
- if (mContainer != null && container != null) {
- throw new IllegalArgumentException("Can't set container=" + container
- + " for controller=" + this + " Already set to=" + mContainer);
- }
- mContainer = container;
- if (mContainer != null && mListener != null) {
- mListener.registerConfigurationChangeListener(this);
- }
- }
-
- void removeContainer() {
- // TODO: See if most uses cases should support removeIfPossible here.
- //mContainer.removeIfPossible();
- if (mContainer == null) {
- return;
- }
-
- mContainer.setController(null);
- mContainer = null;
- if (mListener != null) {
- mListener.unregisterConfigurationChangeListener(this);
- }
- }
-
- @Override
- public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
- synchronized (mGlobalLock) {
- if (mContainer == null) {
- return;
- }
- mContainer.onRequestedOverrideConfigurationChanged(overrideConfiguration);
- }
- }
-}
diff --git a/services/core/java/com/android/server/wm/WindowContainerListener.java b/services/core/java/com/android/server/wm/WindowContainerListener.java
deleted file mode 100644
index 3d3d2e0..0000000
--- a/services/core/java/com/android/server/wm/WindowContainerListener.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.wm;
-
-import android.content.res.Configuration;
-
-/**
- * Interface used by the owner/creator of the container to listen to changes with the container.
- * @see WindowContainerController
- */
-public interface WindowContainerListener {
- void registerConfigurationChangeListener(ConfigurationContainerListener listener);
- void unregisterConfigurationChangeListener(ConfigurationContainerListener listener);
- default void onInitializeOverrideConfiguration(Configuration config) {}
-}
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index c366e4d..93b0fd9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -33,32 +33,19 @@
// Default log tag for the window manager package.
static final String TAG_WM = "WindowManager";
- static final boolean DEBUG_RESIZE = false;
static final boolean DEBUG = false;
- static final boolean DEBUG_ADD_REMOVE = false;
- static final boolean DEBUG_FOCUS = false;
- static final boolean DEBUG_FOCUS_LIGHT = DEBUG_FOCUS || false;
static final boolean DEBUG_ANIM = false;
- static final boolean DEBUG_KEYGUARD = false;
static final boolean DEBUG_LAYOUT = false;
static final boolean DEBUG_LAYERS = false;
static final boolean DEBUG_INPUT = false;
static final boolean DEBUG_INPUT_METHOD = false;
static final boolean DEBUG_VISIBILITY = false;
- static final boolean DEBUG_WINDOW_MOVEMENT = false;
- static final boolean DEBUG_TOKEN_MOVEMENT = false;
- static final boolean DEBUG_ORIENTATION = false;
- static final boolean DEBUG_APP_ORIENTATION = false;
static final boolean DEBUG_CONFIGURATION = false;
- static final boolean DEBUG_APP_TRANSITIONS = false;
static final boolean DEBUG_STARTING_WINDOW_VERBOSE = false;
- static final boolean DEBUG_STARTING_WINDOW = DEBUG_STARTING_WINDOW_VERBOSE || false;
static final boolean DEBUG_WALLPAPER = false;
static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
static final boolean DEBUG_DRAG = false;
- static final boolean DEBUG_SCREEN_ON = false;
static final boolean DEBUG_SCREENSHOT = false;
- static final boolean DEBUG_BOOT = false;
static final boolean DEBUG_LAYOUT_REPEATS = false;
static final boolean DEBUG_WINDOW_TRACE = false;
static final boolean DEBUG_TASK_MOVEMENT = false;
@@ -66,17 +53,9 @@
static final boolean DEBUG_STACK = false;
static final boolean DEBUG_DISPLAY = false;
static final boolean DEBUG_POWER = false;
- static final boolean DEBUG_DIM_LAYER = false;
- static final boolean SHOW_SURFACE_ALLOC = false;
- static final boolean SHOW_TRANSACTIONS = false;
- static final boolean SHOW_VERBOSE_TRANSACTIONS = false && SHOW_TRANSACTIONS;
- static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
+ static final boolean SHOW_VERBOSE_TRANSACTIONS = false;
+ static final boolean SHOW_LIGHT_TRANSACTIONS = false;
static final boolean SHOW_STACK_CRAWLS = false;
static final boolean DEBUG_WINDOW_CROP = false;
static final boolean DEBUG_UNKNOWN_APP_VISIBILITY = false;
- static final boolean DEBUG_RECENTS_ANIMATIONS = false;
- static final boolean DEBUG_REMOTE_ANIMATIONS = DEBUG_APP_TRANSITIONS || false;
-
- static final String TAG_KEEP_SCREEN_ON = "DebugKeepScreenOn";
- static final boolean DEBUG_KEEP_SCREEN_ON = false;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 169e415..1f45cfb 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.Manifest.permission.ACCESS_SURFACE_FLINGER;
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_APP_TOKENS;
@@ -81,27 +82,27 @@
import static com.android.server.LockGuard.installLock;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_BOOT;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT;
+import static com.android.server.wm.ProtoLogGroup.WM_ERROR;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerServiceDumpProto.DISPLAY_FROZEN;
@@ -267,6 +268,7 @@
import com.android.server.policy.WindowManagerPolicy.ScreenOffListener;
import com.android.server.power.ShutdownThread;
import com.android.server.protolog.ProtoLogImpl;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.utils.PriorityDump;
import java.io.BufferedWriter;
@@ -973,6 +975,7 @@
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
+
/** Listener to notify activity manager about app transitions. */
final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
= new WindowManagerInternal.AppTransitionListener() {
@@ -989,7 +992,13 @@
if (atoken == null) {
return;
}
- if (atoken.mLaunchTaskBehind) {
+
+ // While running a recents animation, this will get called early because we show the
+ // recents animation target activity immediately when the animation starts. Defer the
+ // mLaunchTaskBehind updates until recents animation finishes.
+ final boolean isRecentsAnimationTarget = getRecentsAnimationController() != null
+ && getRecentsAnimationController().isTargetApp(atoken);
+ if (atoken.mLaunchTaskBehind && !isRecentsAnimationTarget) {
try {
mActivityTaskManager.notifyLaunchTaskBehindComplete(atoken.token);
} catch (RemoteException e) {
@@ -997,20 +1006,13 @@
atoken.mLaunchTaskBehind = false;
} else {
atoken.updateReportedVisibilityLocked();
- if (atoken.mEnteringAnimation) {
- if (getRecentsAnimationController() != null
- && getRecentsAnimationController().isTargetApp(atoken)) {
- // Currently running a recents animation, this will get called early because
- // we show the recents animation target activity immediately when the
- // animation starts. In this case, we should defer sending the finished
- // callback until the animation successfully finishes
- return;
- } else {
- atoken.mEnteringAnimation = false;
- try {
- mActivityTaskManager.notifyEnterAnimationComplete(atoken.token);
- } catch (RemoteException e) {
- }
+ // We should also defer sending the finished callback until the recents animation
+ // successfully finishes.
+ if (atoken.mEnteringAnimation && !isRecentsAnimationTarget) {
+ atoken.mEnteringAnimation = false;
+ try {
+ mActivityTaskManager.notifyEnterAnimationComplete(atoken.token);
+ } catch (RemoteException e) {
}
}
}
@@ -1293,7 +1295,7 @@
// The window manager only throws security exceptions, so let's
// log all others.
if (!(e instanceof SecurityException)) {
- Slog.wtf(TAG_WM, "Window Manager Crash", e);
+ ProtoLog.wtf(WM_ERROR, "Window Manager Crash %s", e);
}
throw e;
}
@@ -1333,38 +1335,41 @@
final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: "
- + displayId + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add window to a display that does "
+ + "not exist: %d. Aborting.", displayId);
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
}
if (!displayContent.hasAccess(session.mUid)) {
- Slog.w(TAG_WM, "Attempted to add window to a display for which the application "
- + "does not have access: " + displayId + ". Aborting.");
+ ProtoLog.w(WM_ERROR,
+ "Attempted to add window to a display for which the application "
+ + "does not have access: %d. Aborting.", displayId);
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
}
if (mWindowMap.containsKey(client.asBinder())) {
- Slog.w(TAG_WM, "Window " + client + " is already added");
+ ProtoLog.w(WM_ERROR, "Window %s is already added", client);
return WindowManagerGlobal.ADD_DUPLICATE_ADD;
}
if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
parentWindow = windowForClientLocked(null, attrs.token, false);
if (parentWindow == null) {
- Slog.w(TAG_WM, "Attempted to add window with token that is not a window: "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add window with token that is not a window: "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
}
if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW
&& parentWindow.mAttrs.type <= LAST_SUB_WINDOW) {
- Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add window with token that is a sub-window: "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
}
}
if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
- Slog.w(TAG_WM, "Attempted to add private presentation window to a non-private display. Aborting.");
+ ProtoLog.w(WM_ERROR,
+ "Attempted to add private presentation window to a non-private display. "
+ + "Aborting.");
return WindowManagerGlobal.ADD_PERMISSION_DENIED;
}
@@ -1382,46 +1387,48 @@
if (token == null) {
if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
- Slog.w(TAG_WM, "Attempted to add application window with unknown token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add application window with unknown token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (rootType == TYPE_INPUT_METHOD) {
- Slog.w(TAG_WM, "Attempted to add input method window with unknown token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add input method window with unknown token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (rootType == TYPE_VOICE_INTERACTION) {
- Slog.w(TAG_WM, "Attempted to add voice interaction window with unknown token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR,
+ "Attempted to add voice interaction window with unknown token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (rootType == TYPE_WALLPAPER) {
- Slog.w(TAG_WM, "Attempted to add wallpaper window with unknown token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add wallpaper window with unknown token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (rootType == TYPE_DREAM) {
- Slog.w(TAG_WM, "Attempted to add Dream window with unknown token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add Dream window with unknown token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (rootType == TYPE_QS_DIALOG) {
- Slog.w(TAG_WM, "Attempted to add QS dialog window with unknown token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add QS dialog window with unknown token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
- Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with unknown token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR,
+ "Attempted to add Accessibility overlay window with unknown token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (type == TYPE_TOAST) {
// Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
if (doesAddToastWindowRequireToken(attrs.packageName, callingUid,
parentWindow)) {
- Slog.w(TAG_WM, "Attempted to add a toast window with unknown token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add a toast window with unknown token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
}
@@ -1430,49 +1437,52 @@
(attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
token = new WindowToken(this, binder, type, false, displayContent,
session.mCanAddInternalSystemWindow, isRoundedCornerOverlay);
- } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
+ } else if (rootType >= FIRST_APPLICATION_WINDOW
+ && rootType <= LAST_APPLICATION_WINDOW) {
atoken = token.asAppWindowToken();
if (atoken == null) {
- Slog.w(TAG_WM, "Attempted to add window with non-application token "
- + token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add window with non-application token "
+ + ".%s Aborting.", token);
return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
} else if (atoken.removed) {
- Slog.w(TAG_WM, "Attempted to add window with exiting application token "
- + token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add window with exiting application token "
+ + ".%s Aborting.", token);
return WindowManagerGlobal.ADD_APP_EXITING;
} else if (type == TYPE_APPLICATION_STARTING && atoken.startingWindow != null) {
- Slog.w(TAG_WM, "Attempted to add starting window to token with already existing"
- + " starting window");
+ ProtoLog.w(WM_ERROR,
+ "Attempted to add starting window to token with already existing"
+ + " starting window");
return WindowManagerGlobal.ADD_DUPLICATE_ADD;
}
} else if (rootType == TYPE_INPUT_METHOD) {
if (token.windowType != TYPE_INPUT_METHOD) {
- Slog.w(TAG_WM, "Attempted to add input method window with bad token "
- + attrs.token + ". Aborting.");
- return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
+ ProtoLog.w(WM_ERROR, "Attempted to add input method window with bad token "
+ + "%s. Aborting.", attrs.token);
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (rootType == TYPE_VOICE_INTERACTION) {
if (token.windowType != TYPE_VOICE_INTERACTION) {
- Slog.w(TAG_WM, "Attempted to add voice interaction window with bad token "
- + attrs.token + ". Aborting.");
- return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
+ ProtoLog.w(WM_ERROR, "Attempted to add voice interaction window with bad token "
+ + "%s. Aborting.", attrs.token);
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (rootType == TYPE_WALLPAPER) {
if (token.windowType != TYPE_WALLPAPER) {
- Slog.w(TAG_WM, "Attempted to add wallpaper window with bad token "
- + attrs.token + ". Aborting.");
- return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
+ ProtoLog.w(WM_ERROR, "Attempted to add wallpaper window with bad token "
+ + "%s. Aborting.", attrs.token);
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (rootType == TYPE_DREAM) {
if (token.windowType != TYPE_DREAM) {
- Slog.w(TAG_WM, "Attempted to add Dream window with bad token "
- + attrs.token + ". Aborting.");
- return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
+ ProtoLog.w(WM_ERROR, "Attempted to add Dream window with bad token "
+ + "%s. Aborting.", attrs.token);
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) {
- Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with bad token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR,
+ "Attempted to add Accessibility overlay window with bad token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (type == TYPE_TOAST) {
@@ -1480,18 +1490,19 @@
addToastWindowRequiresToken = doesAddToastWindowRequireToken(attrs.packageName,
callingUid, parentWindow);
if (addToastWindowRequiresToken && token.windowType != TYPE_TOAST) {
- Slog.w(TAG_WM, "Attempted to add a toast window with bad token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add a toast window with bad token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (type == TYPE_QS_DIALOG) {
if (token.windowType != TYPE_QS_DIALOG) {
- Slog.w(TAG_WM, "Attempted to add QS dialog window with bad token "
- + attrs.token + ". Aborting.");
+ ProtoLog.w(WM_ERROR, "Attempted to add QS dialog window with bad token "
+ + "%s. Aborting.", attrs.token);
return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (token.asAppWindowToken() != null) {
- Slog.w(TAG_WM, "Non-null appWindowToken for system window of rootType=" + rootType);
+ ProtoLog.w(WM_ERROR, "Non-null appWindowToken for system window of rootType=%d",
+ rootType);
// It is not valid to use an app token with other system types; we will
// instead make a new token for it (as if null had been passed in for the token).
attrs.token = null;
@@ -1505,13 +1516,13 @@
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
// continue.
- Slog.w(TAG_WM, "Adding window client " + client.asBinder()
- + " that is dead, aborting.");
+ ProtoLog.w(WM_ERROR, "Adding window client %s"
+ + " that is dead, aborting.", client.asBinder());
return WindowManagerGlobal.ADD_APP_EXITING;
}
if (win.getDisplayContent() == null) {
- Slog.w(TAG_WM, "Adding window to Display that has been removed.");
+ ProtoLog.w(WM_ERROR, "Adding window to Display that has been removed.");
return WindowManagerGlobal.ADD_INVALID_DISPLAY;
}
@@ -1543,7 +1554,7 @@
// schedule hiding all of its toast windows.
if (type == TYPE_TOAST) {
if (!displayContent.canAddToastWindowForUid(callingUid)) {
- Slog.w(TAG_WM, "Adding more than one toast window for UID at a time.");
+ ProtoLog.w(WM_ERROR, "Adding more than one toast window for UID at a time.");
return WindowManagerGlobal.ADD_DUPLICATE_ADD;
}
// Make sure this happens before we moved focus as one can make the
@@ -1589,8 +1600,8 @@
final AppWindowToken aToken = token.asAppWindowToken();
if (type == TYPE_APPLICATION_STARTING && aToken != null) {
aToken.startingWindow = win;
- if (DEBUG_STARTING_WINDOW) Slog.v (TAG_WM, "addWindow: " + aToken
- + " startingWindow=" + win);
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "addWindow: %s startingWindow=%s",
+ aToken, win);
}
boolean imMayMove = true;
@@ -1607,7 +1618,7 @@
if (type == TYPE_WALLPAPER) {
displayContent.mWallpaperController.clearLastWallpaperTimeoutTime();
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
+ } else if ((attrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
} else if (displayContent.mWallpaperController.isBelowWallpaperTarget(win)) {
// If there is currently a wallpaper being shown, and
@@ -1692,10 +1703,9 @@
}
displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/);
- if (DEBUG || DEBUG_ADD_REMOVE) {
- Slog.v(TAG_WM, "addWindow: New client " + client.asBinder()
- + ": window=" + win + " Callers=" + Debug.getCallers(5));
- }
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addWindow: New client %s"
+ + ": window=%s Callers=%s", client.asBinder(), win, Debug.getCallers(5));
+
if (win.isVisibleOrAdding() && displayContent.updateOrientation()) {
displayContent.sendNewConfiguration();
@@ -1858,7 +1868,7 @@
* forgetting to add the wiring when a new parent of WindowState is added.
*/
void postWindowRemoveCleanupLocked(WindowState win) {
- if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "postWindowRemoveCleanupLocked: %s", win);
mWindowMap.remove(win.mClient.asBinder());
final DisplayContent dc = win.getDisplayContent();
@@ -1873,7 +1883,7 @@
mResizingWindows.remove(win);
updateNonSystemOverlayWindowsVisibilityIfNeeded(win, false /* surfaceShown */);
mWindowsChanged = true;
- if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Final remove of window: " + win);
+ ProtoLog.v(WM_DEBUG_WINDOW_MOVEMENT, "Final remove of window: %s", win);
final DisplayContent displayContent = win.getDisplayContent();
if (displayContent.mInputMethodWindow == win) {
@@ -1882,7 +1892,7 @@
final WindowToken token = win.mToken;
final AppWindowToken atoken = win.mAppToken;
- if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Removing " + win + " from " + token);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Removing %s from %s", win, token);
// Window will already be removed from token before this post clean-up method is called.
if (token.isEmpty()) {
if (!token.mPersistOnEmpty) {
@@ -1942,11 +1952,6 @@
}
}
- static void logSurface(SurfaceControl s, String title, String msg) {
- String str = " SURFACE " + s + ": " + msg + " / " + title;
- Slog.i(TAG_WM, str);
- }
-
static void logWithStack(String tag, String s) {
RuntimeException e = null;
if (SHOW_STACK_CRAWLS) {
@@ -1961,8 +1966,8 @@
try {
synchronized (mGlobalLock) {
WindowState w = windowForClientLocked(session, client, false);
- if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
- "transparentRegionHint=" + region, false);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE transparentRegionHint=%s: %s",
+ region, w);
if ((w != null) && w.mHasSurface) {
w.mWinAnimator.setTransparentRegionHintLocked(region);
@@ -2186,12 +2191,10 @@
win.mInRelayout = true;
win.mViewVisibility = viewVisibility;
- if (DEBUG_SCREEN_ON) {
- RuntimeException stack = new RuntimeException();
- stack.fillInStackTrace();
- Slog.i(TAG_WM, "Relayout " + win + ": oldVis=" + oldVisibility
- + " newVis=" + viewVisibility, stack);
- }
+ ProtoLog.i(WM_DEBUG_SCREEN_ON,
+ "Relayout %s: oldVis=%d newVis=%d. %s", win, oldVisibility,
+ viewVisibility, new RuntimeException().fillInStackTrace());
+
win.setDisplayLayoutNeeded();
win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
@@ -2236,9 +2239,9 @@
} catch (Exception e) {
displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
- Slog.w(TAG_WM, "Exception thrown when creating surface for client "
- + client + " (" + win.mAttrs.getTitle() + ")",
- e);
+ ProtoLog.w(WM_ERROR,
+ "Exception thrown when creating surface for client %s (%s). %s",
+ client, win.mAttrs.getTitle(), e);
Binder.restoreCallingIdentity(origId);
return 0;
}
@@ -2362,21 +2365,21 @@
outInsetsState.set(displayContent.getInsetsStateController().getInsetsForDispatch(win));
if (DEBUG) {
Slog.v(TAG_WM, "Relayout given client " + client.asBinder()
- + ", requestedWidth=" + requestedWidth
- + ", requestedHeight=" + requestedHeight
- + ", viewVisibility=" + viewVisibility
- + "\nRelayout returning frame=" + outFrame
- + ", surface=" + outSurfaceControl);
+ + ", requestedWidth=" + requestedWidth
+ + ", requestedHeight=" + requestedHeight
+ + ", viewVisibility=" + viewVisibility
+ + "\nRelayout returning frame=" + outFrame
+ + ", surface=" + outSurfaceControl);
}
- if (DEBUG || DEBUG_FOCUS) {
- Slog.v(TAG_WM, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
- }
+ ProtoLog.v(WM_DEBUG_FOCUS, "Relayout of %s: focusMayChange=%b",
+ win, focusMayChange);
result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;
if (DEBUG_LAYOUT) {
- Slog.v(TAG_WM, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
+ Slog.v(TAG_WM,
+ "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
}
win.mInRelayout = false;
@@ -2454,11 +2457,12 @@
}
if (surfaceController != null) {
surfaceController.getSurfaceControl(outSurfaceControl);
- if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurfaceControl + ": copied");
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);
+
} else {
// For some reason there isn't a surface. Clear the
// caller's object so they see the same state.
- Slog.w(TAG_WM, "Failed to create surface control for " + win);
+ ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win);
outSurfaceControl.release();
}
@@ -2487,8 +2491,8 @@
try {
synchronized (mGlobalLock) {
WindowState win = windowForClientLocked(session, client, false);
- if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "finishDrawingWindow: " + win + " mDrawState="
- + (win != null ? win.mWinAnimator.drawStateToString() : "null"));
+ ProtoLog.d(WM_DEBUG_ADD_REMOVE, "finishDrawingWindow: %s mDrawState=%s",
+ win, (win != null ? win.mWinAnimator.drawStateToString() : "null"));
if (win != null && win.mWinAnimator.finishDrawingLocked(postDrawTransaction)) {
if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
win.getDisplayContent().pendingLayoutChanges |=
@@ -2513,9 +2517,8 @@
== PackageManager.PERMISSION_GRANTED) {
return true;
}
- final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid() + " requires " + permission;
- Slog.w(TAG_WM, msg);
+ ProtoLog.w(WM_ERROR, "Permission Denial: %s from pid=%d, uid=%d requires %s",
+ func, Binder.getCallingPid(), Binder.getCallingUid(), permission);
return false;
}
@@ -2528,16 +2531,16 @@
synchronized (mGlobalLock) {
final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */);
if (dc == null) {
- Slog.w(TAG_WM, "addWindowToken: Attempted to add token: " + binder
- + " for non-exiting displayId=" + displayId);
+ ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add token: %s"
+ + " for non-exiting displayId=%d", binder, displayId);
return;
}
WindowToken token = dc.getWindowToken(binder);
if (token != null) {
- Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder
- + " for already created window token: " + token
- + " displayId=" + displayId);
+ ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add binder token: %s"
+ + " for already created window token: %s"
+ + " displayId=%d", binder, token, displayId);
return;
}
if (type == TYPE_WALLPAPER) {
@@ -2560,15 +2563,16 @@
synchronized (mGlobalLock) {
final DisplayContent dc = mRoot.getDisplayContent(displayId);
if (dc == null) {
- Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder
- + " for non-exiting displayId=" + displayId);
+ ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s"
+ + " for non-exiting displayId=%d", binder, displayId);
return;
}
final WindowToken token = dc.removeWindowToken(binder);
if (token == null) {
- Slog.w(TAG_WM,
- "removeWindowToken: Attempted to remove non-existing token: " + binder);
+ ProtoLog.w(WM_ERROR,
+ "removeWindowToken: Attempted to remove non-existing token: %s",
+ binder);
return;
}
@@ -3208,14 +3212,11 @@
public void enableScreenAfterBoot() {
synchronized (mGlobalLock) {
- if (DEBUG_BOOT) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.i(TAG_WM, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
- + " mForceDisplayEnabled=" + mForceDisplayEnabled
- + " mShowingBootMessages=" + mShowingBootMessages
- + " mSystemBooted=" + mSystemBooted, here);
- }
+ ProtoLog.i(WM_DEBUG_BOOT, "enableScreenAfterBoot: mDisplayEnabled=%b "
+ + "mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. "
+ + "%s",
+ mDisplayEnabled, mForceDisplayEnabled, mShowingBootMessages, mSystemBooted,
+ new RuntimeException("here").fillInStackTrace());
if (mSystemBooted) {
return;
}
@@ -3239,14 +3240,11 @@
}
void enableScreenIfNeededLocked() {
- if (DEBUG_BOOT) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.i(TAG_WM, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
- + " mForceDisplayEnabled=" + mForceDisplayEnabled
- + " mShowingBootMessages=" + mShowingBootMessages
- + " mSystemBooted=" + mSystemBooted, here);
- }
+ ProtoLog.i(WM_DEBUG_BOOT, "enableScreenIfNeededLocked: mDisplayEnabled=%b "
+ + "mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. "
+ + "%s",
+ mDisplayEnabled, mForceDisplayEnabled, mShowingBootMessages, mSystemBooted,
+ new RuntimeException("here").fillInStackTrace());
if (mDisplayEnabled) {
return;
}
@@ -3261,7 +3259,7 @@
if (mDisplayEnabled) {
return;
}
- Slog.w(TAG_WM, "***** BOOT TIMEOUT: forcing display enabled");
+ ProtoLog.w(WM_ERROR, "***** BOOT TIMEOUT: forcing display enabled");
mForceDisplayEnabled = true;
}
performEnableScreen();
@@ -3276,11 +3274,10 @@
private void performEnableScreen() {
synchronized (mGlobalLock) {
- if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
- + " mForceDisplayEnabled=" + mForceDisplayEnabled
- + " mShowingBootMessages=" + mShowingBootMessages
- + " mSystemBooted=" + mSystemBooted
- + " mOnlyCore=" + mOnlyCore,
+ ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: mDisplayEnabled=%b"
+ + " mForceDisplayEnabled=%b" + " mShowingBootMessages=%b"
+ + " mSystemBooted=%b mOnlyCore=%b. %s", mDisplayEnabled,
+ mForceDisplayEnabled, mShowingBootMessages, mSystemBooted, mOnlyCore,
new RuntimeException("here").fillInStackTrace());
if (mDisplayEnabled) {
return;
@@ -3294,10 +3291,12 @@
}
// Don't enable the screen until all existing windows have been drawn.
- if (!mForceDisplayEnabled
- // TODO(multidisplay): Expand to all displays?
- && getDefaultDisplayContentLocked().checkWaitingForWindows()) {
- return;
+ if (!mForceDisplayEnabled) {
+ for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
+ if (mRoot.getChildAt(i).shouldWaitForSystemDecorWindowsOnBoot()) {
+ return;
+ }
+ }
}
if (!mBootAnimationStopped) {
@@ -3310,14 +3309,14 @@
}
if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {
- if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: Waiting for anim complete");
+ ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: Waiting for anim complete");
return;
}
try {
IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
if (surfaceFlinger != null) {
- Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
+ ProtoLog.i(WM_ERROR, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
@@ -3325,13 +3324,13 @@
data.recycle();
}
} catch (RemoteException ex) {
- Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
+ ProtoLog.e(WM_ERROR, "Boot completed: SurfaceFlinger is dead!");
}
EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis());
Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
mDisplayEnabled = true;
- if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM, "******************** ENABLING SCREEN!");
+ ProtoLog.i(WM_DEBUG_SCREEN_ON, "******************** ENABLING SCREEN!");
// Enable input dispatch.
mInputManagerCallback.setEventDispatchingLw(mEventDispatchingEnabled);
@@ -3353,24 +3352,21 @@
mH.removeMessages(H.CHECK_IF_BOOT_ANIMATION_FINISHED);
mH.sendEmptyMessageDelayed(H.CHECK_IF_BOOT_ANIMATION_FINISHED,
BOOT_ANIMATION_POLL_INTERVAL);
- if (DEBUG_BOOT) Slog.i(TAG_WM, "checkBootAnimationComplete: Waiting for anim complete");
+ ProtoLog.i(WM_DEBUG_BOOT, "checkBootAnimationComplete: Waiting for anim complete");
return false;
}
- if (DEBUG_BOOT) Slog.i(TAG_WM, "checkBootAnimationComplete: Animation complete!");
+ ProtoLog.i(WM_DEBUG_BOOT, "checkBootAnimationComplete: Animation complete!");
return true;
}
public void showBootMessage(final CharSequence msg, final boolean always) {
boolean first = false;
synchronized (mGlobalLock) {
- if (DEBUG_BOOT) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.i(TAG_WM, "showBootMessage: msg=" + msg + " always=" + always
- + " mAllowBootMessages=" + mAllowBootMessages
- + " mShowingBootMessages=" + mShowingBootMessages
- + " mSystemBooted=" + mSystemBooted, here);
- }
+ ProtoLog.i(WM_DEBUG_BOOT, "showBootMessage: msg=%s always=%b"
+ + " mAllowBootMessages=%b mShowingBootMessages=%b"
+ + " mSystemBooted=%b. %s", msg, always, mAllowBootMessages,
+ mShowingBootMessages, mSystemBooted,
+ new RuntimeException("here").fillInStackTrace());
if (!mAllowBootMessages) {
return;
}
@@ -3392,14 +3388,11 @@
}
public void hideBootMessagesLocked() {
- if (DEBUG_BOOT) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.i(TAG_WM, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
- + " mForceDisplayEnabled=" + mForceDisplayEnabled
- + " mShowingBootMessages=" + mShowingBootMessages
- + " mSystemBooted=" + mSystemBooted, here);
- }
+ ProtoLog.i(WM_DEBUG_BOOT, "hideBootMessagesLocked: mDisplayEnabled=%b"
+ + " mForceDisplayEnabled=%b mShowingBootMessages=%b"
+ + " mSystemBooted=%b. %s", mDisplayEnabled, mForceDisplayEnabled,
+ mShowingBootMessages, mSystemBooted,
+ new RuntimeException("here").fillInStackTrace());
if (mShowingBootMessages) {
mShowingBootMessages = false;
mPolicy.hideBootMessages();
@@ -3691,8 +3684,7 @@
throw new SecurityException("Requires SET_ORIENTATION permission");
}
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "thawRotation: mRotation="
- + getDefaultDisplayRotation());
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "thawRotation: mRotation=%d", getDefaultDisplayRotation());
long origId = Binder.clearCallingIdentity();
try {
@@ -3741,9 +3733,9 @@
}
private void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
- if(DEBUG_ORIENTATION) Slog.v(TAG_WM, "updateRotationUnchecked:"
- + " alwaysSendConfiguration=" + alwaysSendConfiguration
- + " forceRelayout=" + forceRelayout);
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "updateRotationUnchecked:"
+ + " alwaysSendConfiguration=%b forceRelayout=%b",
+ alwaysSendConfiguration, forceRelayout);
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation");
@@ -3992,7 +3984,7 @@
try {
return mViewServer.start();
} catch (IOException e) {
- Slog.w(TAG_WM, "View server did not start");
+ ProtoLog.w(WM_ERROR, "View server did not start");
}
}
return false;
@@ -4002,7 +3994,7 @@
mViewServer = new ViewServer(this, port);
return mViewServer.start();
} catch (IOException e) {
- Slog.w(TAG_WM, "View server did not start");
+ ProtoLog.w(WM_ERROR, "View server did not start");
}
return false;
}
@@ -4232,7 +4224,8 @@
}
} catch (Exception e) {
- Slog.w(TAG_WM, "Could not send command " + command + " with parameters " + parameters, e);
+ ProtoLog.w(WM_ERROR, "Could not send command %s with parameters %s. %s", command,
+ parameters, e);
success = false;
} finally {
if (data != null) {
@@ -4381,9 +4374,9 @@
public boolean detectSafeMode() {
if (!mInputManagerCallback.waitForInputDevicesReady(
INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
- Slog.w(TAG_WM, "Devices still not ready after waiting "
- + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
- + " milliseconds before attempting to detect safe mode.");
+ ProtoLog.w(WM_ERROR, "Devices still not ready after waiting %d"
+ + " milliseconds before attempting to detect safe mode.",
+ INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS);
}
if (Settings.Global.getInt(
@@ -4411,14 +4404,14 @@
} catch (IllegalArgumentException e) {
}
if (mSafeMode) {
- Log.i(TAG_WM, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
- + " dpad=" + dpadState + " trackball=" + trackballState + ")");
+ ProtoLog.i(WM_ERROR, "SAFE MODE ENABLED (menu=%d s=%d dpad=%d"
+ + " trackball=%d)", menuState, sState, dpadState, trackballState);
// May already be set if (for instance) this process has crashed
if (SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) == 0) {
SystemProperties.set(ShutdownThread.RO_SAFEMODE_PROPERTY, "1");
}
} else {
- Log.i(TAG_WM, "SAFE MODE not enabled");
+ ProtoLog.i(WM_ERROR, "SAFE MODE not enabled");
}
mPolicy.setSafeMode(mSafeMode);
return mSafeMode;
@@ -4577,10 +4570,11 @@
return;
}
displayContent.mLastFocus = newFocus;
- if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Focus moving from " + lastFocus +
- " to " + newFocus + " displayId=" + displayContent.getDisplayId());
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Focus moving from %s"
+ + " to %s displayId=%d", lastFocus, newFocus,
+ displayContent.getDisplayId());
if (newFocus != null && lastFocus != null && !newFocus.isDisplayedLw()) {
- if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Delaying loss of focus...");
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Delaying loss of focus...");
displayContent.mLosingFocus.add(lastFocus);
lastFocus = null;
}
@@ -4594,13 +4588,13 @@
}
if (newFocus != null) {
- if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Gaining focus: " + newFocus);
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Gaining focus: %s", newFocus);
newFocus.reportFocusChangedSerialized(true, mInTouchMode);
notifyFocusChanged();
}
if (lastFocus != null) {
- if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing focus: " + lastFocus);
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing focus: %s", lastFocus);
lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
}
break;
@@ -4617,7 +4611,7 @@
final int N = losers.size();
for (int i = 0; i < N; i++) {
- if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing delayed focus: " +
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing delayed focus: %s",
losers.get(i));
losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
}
@@ -4700,9 +4694,9 @@
case APP_FREEZE_TIMEOUT: {
synchronized (mGlobalLock) {
- Slog.w(TAG_WM, "App freeze timeout expired.");
+ ProtoLog.w(WM_ERROR, "App freeze timeout expired.");
mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
- for (int i = mAppFreezeListeners.size() - 1; i >=0 ; --i) {
+ for (int i = mAppFreezeListeners.size() - 1; i >= 0; --i) {
mAppFreezeListeners.get(i).onAppFreezeTimeout();
}
}
@@ -4743,7 +4737,8 @@
case WAITING_FOR_DRAWN_TIMEOUT: {
Runnable callback = null;
synchronized (mGlobalLock) {
- Slog.w(TAG_WM, "Timeout waiting for drawn: undrawn=" + mWaitingForDrawn);
+ ProtoLog.w(WM_ERROR, "Timeout waiting for drawn: undrawn=%s",
+ mWaitingForDrawn);
mWaitingForDrawn.clear();
callback = mWaitingForDrawnCallback;
mWaitingForDrawnCallback = null;
@@ -4817,7 +4812,7 @@
case CHECK_IF_BOOT_ANIMATION_FINISHED: {
final boolean bootAnimationComplete;
synchronized (mGlobalLock) {
- if (DEBUG_BOOT) Slog.i(TAG_WM, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
+ ProtoLog.i(WM_DEBUG_BOOT, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
bootAnimationComplete = checkBootAnimationCompleteLocked();
}
if (bootAnimationComplete) {
@@ -5031,10 +5026,10 @@
int width, height;
try {
width = Integer.parseInt(sizeStr.substring(0, pos));
- height = Integer.parseInt(sizeStr.substring(pos+1));
+ height = Integer.parseInt(sizeStr.substring(pos + 1));
if (displayContent.mBaseDisplayWidth != width
|| displayContent.mBaseDisplayHeight != height) {
- Slog.i(TAG_WM, "FORCED DISPLAY SIZE: " + width + "x" + height);
+ ProtoLog.i(WM_ERROR, "FORCED DISPLAY SIZE: %dx%d", width, height);
displayContent.updateBaseDisplayMetrics(width, height,
displayContent.mBaseDisplayDensity);
changed = true;
@@ -5055,7 +5050,7 @@
int mode = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.DISPLAY_SCALING_FORCE, 0);
if (displayContent.mDisplayScalingDisabled != (mode != 0)) {
- Slog.i(TAG_WM, "FORCED DISPLAY SCALING DISABLED");
+ ProtoLog.i(WM_ERROR, "FORCED DISPLAY SCALING DISABLED");
displayContent.mDisplayScalingDisabled = true;
changed = true;
}
@@ -5235,7 +5230,7 @@
throw new IllegalArgumentException(
"Requested window " + client + " does not exist");
}
- Slog.w(TAG_WM, "Failed looking up window callers=" + Debug.getCallers(3));
+ ProtoLog.w(WM_ERROR, "Failed looking up window callers=%s", Debug.getCallers(3));
return null;
}
if (session != null && win.mSession != session) {
@@ -5243,7 +5238,7 @@
throw new IllegalArgumentException("Requested window " + client + " is in session "
+ win.mSession + ", not " + session);
}
- Slog.w(TAG_WM, "Failed looking up window callers=" + Debug.getCallers(3));
+ ProtoLog.w(WM_ERROR, "Failed looking up window callers=%s", Debug.getCallers(3));
return null;
}
@@ -5255,7 +5250,7 @@
// it frozen/off until this window draws at its new
// orientation.
if (!w.mToken.okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w);
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "Changing surface while display frozen: %s", w);
w.setOrientationChanging(true);
w.mLastFreezeDuration = 0;
mRoot.mOrientationChangeComplete = false;
@@ -5275,22 +5270,22 @@
}
for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) {
WindowState win = mWaitingForDrawn.get(j);
- if (DEBUG_SCREEN_ON) Slog.i(TAG_WM, "Waiting for drawn " + win +
- ": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() +
- " mHasSurface=" + win.mHasSurface +
- " drawState=" + win.mWinAnimator.mDrawState);
+ ProtoLog.i(WM_DEBUG_SCREEN_ON,
+ "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d",
+ win, win.mRemoved, win.isVisibleLw(), win.mHasSurface,
+ win.mWinAnimator.mDrawState);
if (win.mRemoved || !win.mHasSurface || !win.isVisibleByPolicy()) {
// Window has been removed or hidden; no draw will now happen, so stop waiting.
- if (DEBUG_SCREEN_ON) Slog.w(TAG_WM, "Aborted waiting for drawn: " + win);
+ ProtoLog.w(WM_DEBUG_SCREEN_ON, "Aborted waiting for drawn: %s", win);
mWaitingForDrawn.remove(win);
} else if (win.hasDrawnLw()) {
// Window is now drawn (and shown).
- if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "Window drawn win=" + win);
+ ProtoLog.d(WM_DEBUG_SCREEN_ON, "Window drawn win=%s", win);
mWaitingForDrawn.remove(win);
}
}
if (mWaitingForDrawn.isEmpty()) {
- if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "All windows drawn!");
+ ProtoLog.d(WM_DEBUG_SCREEN_ON, "All windows drawn!");
mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN);
}
@@ -5307,19 +5302,15 @@
final boolean state = mHoldingScreenWakeLock.isHeld();
if (hold != state) {
if (hold) {
- if (DEBUG_KEEP_SCREEN_ON) {
- Slog.d(TAG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to "
- + mRoot.mHoldScreenWindow);
- }
+ ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to %s",
+ mRoot.mHoldScreenWindow);
mLastWakeLockHoldingWindow = mRoot.mHoldScreenWindow;
mLastWakeLockObscuringWindow = null;
mHoldingScreenWakeLock.acquire();
mPolicy.keepScreenOnStartedLw();
} else {
- if (DEBUG_KEEP_SCREEN_ON) {
- Slog.d(TAG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by "
- + mRoot.mObscuringWindow);
- }
+ ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by %s",
+ mRoot.mObscuringWindow);
mLastWakeLockHoldingWindow = null;
mLastWakeLockObscuringWindow = mRoot.mObscuringWindow;
mPolicy.keepScreenOnStoppedLw();
@@ -5363,10 +5354,9 @@
return;
}
- if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
- "startFreezingDisplayLocked: exitAnim="
- + exitAnim + " enterAnim=" + enterAnim
- + " called by " + Debug.getCallers(8));
+ ProtoLog.d(WM_DEBUG_ORIENTATION,
+ "startFreezingDisplayLocked: exitAnim=%d enterAnim=%d called by %s",
+ exitAnim, enterAnim, Debug.getCallers(8));
mScreenFrozenLock.acquire();
mDisplayFrozen = true;
@@ -5418,17 +5408,17 @@
if (waitingForConfig || mAppsFreezingScreen > 0
|| mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE
|| mClientFreezingScreen || numOpeningApps > 0) {
- if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
- "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + waitingForConfig
- + ", mAppsFreezingScreen=" + mAppsFreezingScreen
- + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
- + ", mClientFreezingScreen=" + mClientFreezingScreen
- + ", mOpeningApps.size()=" + numOpeningApps);
+ ProtoLog.d(WM_DEBUG_ORIENTATION,
+ "stopFreezingDisplayLocked: Returning mWaitingForConfig=%b, "
+ + "mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, "
+ + "mClientFreezingScreen=%b, mOpeningApps.size()=%d",
+ waitingForConfig, mAppsFreezingScreen, mWindowsFreezingScreen,
+ mClientFreezingScreen, numOpeningApps);
return;
}
- if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
- "stopFreezingDisplayLocked: Unfreezing now");
+ ProtoLog.d(WM_DEBUG_ORIENTATION,
+ "stopFreezingDisplayLocked: Unfreezing now");
// We must make a local copy of the displayId as it can be potentially overwritten later on
@@ -5446,7 +5436,7 @@
sb.append(" due to ");
sb.append(mLastFinishedFreezeSource);
}
- Slog.i(TAG_WM, sb.toString());
+ ProtoLog.i(WM_ERROR, "%s", sb.toString());
mH.removeMessages(H.APP_FREEZE_TIMEOUT);
mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
if (PROFILE_ORIENTATION) {
@@ -5458,7 +5448,7 @@
ScreenRotationAnimation screenRotationAnimation = displayContent == null ? null
: displayContent.getRotationAnimation();
if (screenRotationAnimation != null && screenRotationAnimation.hasScreenshot()) {
- if (DEBUG_ORIENTATION) Slog.i(TAG_WM, "**** Dismissing screen rotation animation");
+ ProtoLog.i(WM_DEBUG_ORIENTATION, "**** Dismissing screen rotation animation");
DisplayInfo displayInfo = displayContent.getDisplayInfo();
// Get rotation animation again, with new top window
if (!displayContent.getDisplayRotation().validateRotationAnimation(
@@ -5501,7 +5491,7 @@
mScreenFrozenLock.release();
if (updateRotation && displayContent != null) {
- if (DEBUG_ORIENTATION) Slog.d(TAG_WM, "Performing post-rotate rotation");
+ ProtoLog.d(WM_DEBUG_ORIENTATION, "Performing post-rotate rotation");
configChanged |= displayContent.updateRotationUnchecked();
}
@@ -6314,17 +6304,20 @@
/**
* Hint to a token that its activity will relaunch, which will trigger removal and addition of
* a window.
+ *
* @param token Application token for which the activity will be relaunched.
*/
void setWillReplaceWindow(IBinder token, boolean animate) {
final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token);
if (appWindowToken == null) {
- Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token " + token);
+ ProtoLog.w(WM_ERROR, "Attempted to set replacing window on non-existing app token %s",
+ token);
return;
}
if (!appWindowToken.hasContentToDisplay()) {
- Slog.w(TAG_WM, "Attempted to set replacing window on app token with no content"
- + token);
+ ProtoLog.w(WM_ERROR,
+ "Attempted to set replacing window on app token with no content %s",
+ token);
return;
}
appWindowToken.setWillReplaceWindows(animate);
@@ -6346,13 +6339,15 @@
synchronized (mGlobalLock) {
final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token);
if (appWindowToken == null) {
- Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token "
- + token);
+ ProtoLog.w(WM_ERROR,
+ "Attempted to set replacing window on non-existing app token %s",
+ token);
return;
}
if (!appWindowToken.hasContentToDisplay()) {
- Slog.w(TAG_WM, "Attempted to set replacing window on app token with no content"
- + token);
+ ProtoLog.w(WM_ERROR,
+ "Attempted to set replacing window on app token with no content %s",
+ token);
return;
}
@@ -6372,14 +6367,14 @@
*
* If we're not replacing the window, clear the replace window settings of the app.
*
- * @param token Application token for the activity whose window might be replaced.
+ * @param token Application token for the activity whose window might be replaced.
* @param replacing Whether the window is being replaced or not.
*/
void scheduleClearWillReplaceWindows(IBinder token, boolean replacing) {
final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token);
if (appWindowToken == null) {
- Slog.w(TAG_WM, "Attempted to reset replacing window on non-existing app token "
- + token);
+ ProtoLog.w(WM_ERROR, "Attempted to reset replacing window on non-existing app token %s",
+ token);
return;
}
if (replacing) {
@@ -6568,7 +6563,7 @@
}
WindowState callingWin = windowForClientLocked(null, client, false);
if (callingWin == null) {
- Slog.w(TAG_WM, "Bad requesting window " + client);
+ ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
return;
}
final DisplayContent displayContent = callingWin.getDisplayContent();
@@ -6585,7 +6580,7 @@
windowUnderPointer.translateToWindowX(mouseX),
windowUnderPointer.translateToWindowY(mouseY));
} catch (RemoteException e) {
- Slog.w(TAG_WM, "unable to update pointer icon");
+ ProtoLog.w(WM_ERROR, "unable to update pointer icon");
}
}
}
@@ -6602,7 +6597,7 @@
windowUnderPointer.translateToWindowX(latestX),
windowUnderPointer.translateToWindowY(latestY));
} catch (RemoteException e) {
- Slog.w(TAG_WM, "unable to restore pointer icon");
+ ProtoLog.w(WM_ERROR, "unable to restore pointer icon");
}
} else {
InputManager.getInstance().setPointerIconType(PointerIcon.TYPE_DEFAULT);
@@ -6632,7 +6627,7 @@
try {
final WindowState win = windowForClientLocked(null, client, false);
if (win == null) {
- Slog.w(TAG_WM, "Bad requesting window " + client);
+ ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
return;
}
getDisplayContentOrCreate(displayId, null).reparentDisplayContent(win, sc);
@@ -6657,7 +6652,7 @@
try {
final WindowState win = windowForClientLocked(null, client, false);
if (win == null) {
- Slog.w(TAG_WM, "Bad requesting window " + client);
+ ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
return;
}
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
@@ -6684,7 +6679,7 @@
synchronized (mGlobalLock) {
final WindowState callingWin = windowForClientLocked(null, client, false);
if (callingWin == null) {
- Slog.w(TAG_WM, "Bad requesting window " + client);
+ ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
return;
}
callingWin.updateTapExcludeRegion(regionId, region);
@@ -6723,8 +6718,9 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to get windowing mode of a display that does not exist: "
- + displayId);
+ ProtoLog.w(WM_ERROR,
+ "Attempted to get windowing mode of a display that does not exist: %d",
+ displayId);
return WindowConfiguration.WINDOWING_MODE_UNDEFINED;
}
return mDisplayWindowSettings.getWindowingModeLocked(displayContent);
@@ -6740,8 +6736,9 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to set windowing mode to a display that does not exist: "
- + displayId);
+ ProtoLog.w(WM_ERROR,
+ "Attempted to set windowing mode to a display that does not exist: %d",
+ displayId);
return;
}
@@ -6776,8 +6773,9 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to get remove mode of a display that does not exist: "
- + displayId);
+ ProtoLog.w(WM_ERROR,
+ "Attempted to get remove mode of a display that does not exist: %d",
+ displayId);
return REMOVE_CONTENT_MODE_UNDEFINED;
}
return mDisplayWindowSettings.getRemoveContentModeLocked(displayContent);
@@ -6793,8 +6791,9 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to set remove mode to a display that does not exist: "
- + displayId);
+ ProtoLog.w(WM_ERROR,
+ "Attempted to set remove mode to a display that does not exist: %d",
+ displayId);
return;
}
@@ -6813,8 +6812,8 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to get flag of a display that does not exist: "
- + displayId);
+ ProtoLog.w(WM_ERROR, "Attempted to get flag of a display that does not exist: %d",
+ displayId);
return false;
}
return mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(displayContent);
@@ -6831,8 +6830,8 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to set flag to a display that does not exist: "
- + displayId);
+ ProtoLog.w(WM_ERROR, "Attempted to set flag to a display that does not exist: %d",
+ displayId);
return;
}
@@ -6852,8 +6851,8 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to get system decors flag of a display that does "
- + "not exist: " + displayId);
+ ProtoLog.w(WM_ERROR, "Attempted to get system decors flag of a display that does "
+ + "not exist: %d", displayId);
return false;
}
if (displayContent.isUntrustedVirtualDisplay()) {
@@ -6872,8 +6871,8 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to set system decors flag to a display that does "
- + "not exist: " + displayId);
+ ProtoLog.w(WM_ERROR, "Attempted to set system decors flag to a display that does "
+ + "not exist: %d", displayId);
return;
}
if (displayContent.isUntrustedVirtualDisplay()) {
@@ -6896,8 +6895,9 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to get IME flag of a display that does not exist: "
- + displayId);
+ ProtoLog.w(WM_ERROR,
+ "Attempted to get IME flag of a display that does not exist: %d",
+ displayId);
return false;
}
if (displayContent.isUntrustedVirtualDisplay()) {
@@ -6917,8 +6917,9 @@
synchronized (mGlobalLock) {
final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
if (displayContent == null) {
- Slog.w(TAG_WM, "Attempted to set IME flag to a display that does not exist: "
- + displayId);
+ ProtoLog.w(WM_ERROR,
+ "Attempted to set IME flag to a display that does not exist: %d",
+ displayId);
return;
}
if (displayContent.isUntrustedVirtualDisplay()) {
@@ -7135,15 +7136,16 @@
if (removeWindows) {
final DisplayContent dc = mRoot.getDisplayContent(displayId);
if (dc == null) {
- Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder
- + " for non-exiting displayId=" + displayId);
+ ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s"
+ + " for non-exiting displayId=%d", binder, displayId);
return;
}
final WindowToken token = dc.removeWindowToken(binder);
if (token == null) {
- Slog.w(TAG_WM, "removeWindowToken: Attempted to remove non-existing token: "
- + binder);
+ ProtoLog.w(WM_ERROR,
+ "removeWindowToken: Attempted to remove non-existing token: %s",
+ binder);
return;
}
@@ -7746,4 +7748,27 @@
Binder.restoreCallingIdentity(token);
}
}
+
+ @Override
+ public boolean mirrorDisplay(int displayId, SurfaceControl outSurfaceControl) {
+ if (!checkCallingPermission(ACCESS_SURFACE_FLINGER, "mirrorDisplay()")) {
+ throw new SecurityException("Requires ACCESS_SURFACE_FLINGER permission");
+ }
+
+ final SurfaceControl displaySc;
+ synchronized (mGlobalLock) {
+ DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ Slog.e(TAG, "Invalid displayId " + displayId + " for mirrorDisplay");
+ return false;
+ }
+
+ displaySc = displayContent.getSurfaceControl();
+ }
+
+ final SurfaceControl mirror = SurfaceControl.mirrorSurface(displaySc);
+ outSurfaceControl.copyFrom(mirror);
+
+ return true;
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0a65e324..1270658 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -90,20 +90,20 @@
import static com.android.server.wm.MoveAnimationSpecProto.DURATION_MS;
import static com.android.server.wm.MoveAnimationSpecProto.FROM;
import static com.android.server.wm.MoveAnimationSpecProto.TO;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RESIZE;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
@@ -197,6 +197,7 @@
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowInfo;
+import android.view.WindowInsets.Type.InsetType;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -206,6 +207,7 @@
import com.android.internal.policy.KeyInterceptionInfo;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
import com.android.server.wm.utils.InsetUtils;
import com.android.server.wm.utils.WmDisplayCutout;
@@ -781,7 +783,7 @@
mSubLayer = mPolicy.getSubWindowLayerFromTypeLw(a.type);
mIsChildWindow = true;
- if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + parentWindow);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", this, parentWindow);
parentWindow.addChild(this, sWindowSubLayerComparator);
mLayoutAttached = mAttrs.type !=
@@ -1294,14 +1296,11 @@
|| configChanged
|| dragResizingChanged
|| mReportOrientationChanged) {
- if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
- Slog.v(TAG_WM, "Resize reasons for w=" + this + ": "
- + " " + mWindowFrames.getInsetsChangedInfo()
- + " surfaceResized=" + winAnimator.mSurfaceResized
- + " configChanged=" + configChanged
- + " dragResizingChanged=" + dragResizingChanged
- + " reportOrientationChanged=" + mReportOrientationChanged);
- }
+ ProtoLog.v(WM_DEBUG_RESIZE,
+ "Resize reasons for w=%s: %s surfaceResized=%b configChanged=%b "
+ + "dragResizingChanged=%b reportOrientationChanged=%b",
+ this, mWindowFrames.getInsetsChangedInfo(), winAnimator.mSurfaceResized,
+ configChanged, dragResizingChanged, mReportOrientationChanged);
// If it's a dead window left on screen, and the configuration changed, there is nothing
// we can do about it. Remove the window now.
@@ -1318,24 +1317,31 @@
// redrawn; to do that, we need to go through the process of getting informed by the
// application when it has finished drawing.
if (getOrientationChanging() || dragResizingChanged) {
- if (DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
- Slog.v(TAG_WM, "Orientation or resize start waiting for draw"
+ if (getOrientationChanging()) {
+ Slog.v(TAG_WM, "Orientation start waiting for draw"
+ ", mDrawState=DRAW_PENDING in " + this
+ ", surfaceController " + winAnimator.mSurfaceController);
}
+ if (dragResizingChanged) {
+ ProtoLog.v(WM_DEBUG_RESIZE,
+ "Resize start waiting for draw, "
+ + "mDrawState=DRAW_PENDING in %s, surfaceController %s",
+ this, winAnimator.mSurfaceController);
+ }
winAnimator.mDrawState = DRAW_PENDING;
if (mAppToken != null) {
mAppToken.clearAllDrawn();
}
}
if (!mWmService.mResizingWindows.contains(this)) {
- if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG_WM, "Resizing window " + this);
+ ProtoLog.v(WM_DEBUG_RESIZE, "Resizing window %s", this);
mWmService.mResizingWindows.add(this);
}
} else if (getOrientationChanging()) {
if (isDrawnLw()) {
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Orientation not waiting for draw in "
- + this + ", surfaceController " + winAnimator.mSurfaceController);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Orientation not waiting for draw in %s, surfaceController %s", this,
+ winAnimator.mSurfaceController);
setOrientationChanging(false);
mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
- mWmService.mDisplayFreezeTime);
@@ -1705,7 +1711,7 @@
@Override
void onMovedByResize() {
- if (DEBUG_RESIZE) Slog.d(TAG, "onMovedByResize: Moving " + this);
+ ProtoLog.d(WM_DEBUG_RESIZE, "onMovedByResize: Moving %s", this);
mMovedByResize = true;
super.onMovedByResize();
}
@@ -1779,7 +1785,7 @@
void onResize() {
final ArrayList<WindowState> resizingWindows = mWmService.mResizingWindows;
if (mHasSurface && !isGoneForLayoutLw() && !resizingWindows.contains(this)) {
- if (DEBUG_RESIZE) Slog.d(TAG, "onResize: Resizing " + this);
+ ProtoLog.d(WM_DEBUG_RESIZE, "onResize: Resizing %s", this);
resizingWindows.add(this);
}
if (isGoneForLayoutLw()) {
@@ -1922,8 +1928,8 @@
if (mRemoved) {
// Nothing to do.
- if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
- "WS.removeImmediately: " + this + " Already removed...");
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE,
+ "WS.removeImmediately: %s Already removed...", this);
return;
}
@@ -1973,39 +1979,35 @@
private void removeIfPossible(boolean keepVisibleDeadWindow) {
mWindowRemovalAllowed = true;
- if (DEBUG_ADD_REMOVE) Slog.v(TAG,
- "removeIfPossible: " + this + " callers=" + Debug.getCallers(5));
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE,
+ "removeIfPossible: %s callers=%s", this, Debug.getCallers(5));
final boolean startingWindow = mAttrs.type == TYPE_APPLICATION_STARTING;
- if (startingWindow && DEBUG_STARTING_WINDOW) Slog.d(TAG_WM,
- "Starting window removed " + this);
-
- if (DEBUG || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && isFocused()) {
- Slog.v(TAG_WM, "Remove " + this + " client="
- + Integer.toHexString(System.identityHashCode(mClient.asBinder()))
- + ", surfaceController=" + mWinAnimator.mSurfaceController + " Callers="
- + Debug.getCallers(5));
+ if (startingWindow) {
+ ProtoLog.d(WM_DEBUG_STARTING_WINDOW, "Starting window removed %s", this);
}
+ ProtoLog.v(WM_DEBUG_FOCUS, "Remove client=%x, surfaceController=%s Callers=%s",
+ System.identityHashCode(mClient.asBinder()),
+ mWinAnimator.mSurfaceController,
+ Debug.getCallers(5));
+
+
final long origId = Binder.clearCallingIdentity();
try {
disposeInputChannel();
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Remove " + this
- + ": mSurfaceController=" + mWinAnimator.mSurfaceController
- + " mAnimatingExit=" + mAnimatingExit
- + " mRemoveOnExit=" + mRemoveOnExit
- + " mHasSurface=" + mHasSurface
- + " surfaceShowing=" + mWinAnimator.getShown()
- + " animating=" + isAnimating()
- + " app-animation="
- + (mAppToken != null ? mAppToken.isSelfAnimating() : "false")
- + " mWillReplaceWindow=" + mWillReplaceWindow
- + " inPendingTransaction="
- + (mAppToken != null ? mAppToken.inPendingTransaction : false)
- + " mDisplayFrozen=" + mWmService.mDisplayFrozen
- + " callers=" + Debug.getCallers(6));
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
+ "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b "
+ + "mHasSurface=%b surfaceShowing=%b animating=%b app-animation=%b "
+ + "mWillReplaceWindow=%b inPendingTransaction=%b mDisplayFrozen=%b "
+ + "callers=%s",
+ this, mWinAnimator.mSurfaceController, mAnimatingExit, mRemoveOnExit,
+ mHasSurface, mWinAnimator.getShown(), isAnimating(),
+ mAppToken != null && mAppToken.isSelfAnimating(), mWillReplaceWindow,
+ mAppToken != null && mAppToken.inPendingTransaction,
+ mWmService.mDisplayFrozen, Debug.getCallers(6));
// Visibility of the removed window. Will be used later to update orientation later on.
boolean wasVisible = false;
@@ -2017,8 +2019,8 @@
if (mWillReplaceWindow) {
// This window is going to be replaced. We need to keep it around until the new one
// gets added, then we will get rid of this one.
- if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
- "Preserving " + this + " until the new one is " + "added");
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE,
+ "Preserving %s until the new one is added", this);
// TODO: We are overloading mAnimatingExit flag to prevent the window state from
// been removed. We probably need another flag to indicate that window removal
// should be deffered vs. overloading the flag that says we are playing an exit
@@ -2032,8 +2034,8 @@
wasVisible = isWinVisibleLw();
if (keepVisibleDeadWindow) {
- if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
- "Not removing " + this + " because app died while it's visible");
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE,
+ "Not removing %s because app died while it's visible", this);
mAppDied = true;
setDisplayLayoutNeeded();
@@ -2074,8 +2076,8 @@
if (mWinAnimator.getShown() && mAnimatingExit
&& (!lastWindowIsStartingWindow || isAnimating)) {
// The exit animation is running or should run... wait for it!
- if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
- "Not removing " + this + " due to exit animation ");
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE,
+ "Not removing %s due to exit animation", this);
setupWindowForRemoveOnExit();
if (mAppToken != null) {
mAppToken.updateReportedVisibilityLocked();
@@ -2242,7 +2244,7 @@
}
private void removeReplacedWindow() {
- if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replaced window: " + this);
+ ProtoLog.d(WM_DEBUG_ADD_REMOVE, "Removing replaced window: %s", this);
mWillReplaceWindow = false;
mAnimateReplacingWindow = false;
mReplacingRemoveRequested = false;
@@ -2398,7 +2400,7 @@
if (!isVisibleByPolicy()) {
mWinAnimator.hide("checkPolicyVisibilityChange");
if (isFocused()) {
- if (DEBUG_FOCUS_LIGHT) Slog.i(TAG,
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT,
"setAnimationLocked: setting mFocusMayChange true");
mWmService.mFocusMayChange = true;
}
@@ -2422,15 +2424,15 @@
void prepareWindowToDisplayDuringRelayout(boolean wasVisible) {
// We need to turn on screen regardless of visibility.
final boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0
- || (mAppToken != null && mAppToken.mActivityRecord.canTurnScreenOn());
+ || (mAppToken != null && mAppToken.canTurnScreenOn());
// The screen will turn on if the following conditions are met
// 1. The window has the flag FLAG_TURN_SCREEN_ON or ActivityRecord#canTurnScreenOn.
// 2. The WMS allows theater mode.
// 3. No AWT or the AWT allows the screen to be turned on. This should only be true once
// per resume to prevent the screen getting getting turned on for each relayout. Set
- // canTurnScreenOn will be set to false so the window doesn't turn the screen on again
- // during this resume.
+ // currentLaunchCanTurnScreenOn will be set to false so the window doesn't turn the screen
+ // on again during this resume.
// 4. When the screen is not interactive. This is because when the screen is already
// interactive, the value may persist until the next animation, which could potentially
// be occurring while turning off the screen. This would lead to the screen incorrectly
@@ -2615,15 +2617,31 @@
@Override
public boolean canShowWhenLocked() {
final boolean showBecauseOfActivity =
- mAppToken != null && mAppToken.mActivityRecord.canShowWhenLocked();
+ mAppToken != null && mAppToken.canShowWhenLocked();
final boolean showBecauseOfWindow = (getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0;
return showBecauseOfActivity || showBecauseOfWindow;
}
/** @return false if this window desires touch events. */
boolean cantReceiveTouchInput() {
- return mAppToken != null && mAppToken.getTask() != null
- && (mAppToken.getTask().mStack.shouldIgnoreInput() || mAppToken.hiddenRequested);
+ if (mAppToken == null || mAppToken.getTask() == null) {
+ return false;
+ }
+
+ return mAppToken.getTask().mStack.shouldIgnoreInput()
+ || mAppToken.hiddenRequested
+ || isAnimatingToRecents();
+ }
+
+ /**
+ * Returns {@code true} if the window is animating to home as part of the recents animation.
+ */
+ private boolean isAnimatingToRecents() {
+ final RecentsAnimationController recentsAnimationController =
+ mWmService.getRecentsAnimationController();
+ return recentsAnimationController != null
+ && recentsAnimationController.isAnimatingTask(getTask())
+ && !recentsAnimationController.isTargetApp(mAppToken);
}
@Override
@@ -2721,7 +2739,7 @@
// we allow the display to be enabled now.
mWmService.enableScreenIfNeededLocked();
if (isFocused) {
- if (DEBUG_FOCUS_LIGHT) Slog.i(TAG,
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT,
"WindowState.hideLw: setting mFocusMayChange true");
mWmService.mFocusMayChange = true;
}
@@ -2927,7 +2945,8 @@
if (mHasSurface && !getOrientationChanging()
&& mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + this);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "set mOrientationChanging of %s", this);
setOrientationChanging(true);
mWmService.mRoot.mOrientationChangeComplete = false;
}
@@ -2955,10 +2974,11 @@
}
if (mDestroying) {
- if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + this
- + " destroySurfaces: appStopped=" + appStopped
- + " win.mWindowRemovalAllowed=" + mWindowRemovalAllowed
- + " win.mRemoveOnExit=" + mRemoveOnExit);
+ ProtoLog.e(WM_DEBUG_ADD_REMOVE, "win=%s"
+ + " destroySurfaces: appStopped=%b"
+ + " win.mWindowRemovalAllowed=%b"
+ + " win.mRemoveOnExit=%b", this, appStopped,
+ mWindowRemovalAllowed, mRemoveOnExit);
if (!cleanupOnResume || mRemoveOnExit) {
destroySurfaceUnchecked();
}
@@ -3226,16 +3246,19 @@
void reportResized() {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wm.reportResized_" + getWindowTag());
try {
- if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
- + ": " + mWindowFrames.mCompatFrame);
+ ProtoLog.v(WM_DEBUG_RESIZE,
+ "Reporting new frame to %s: %s", this,
+ mWindowFrames.mCompatFrame);
final MergedConfiguration mergedConfiguration =
new MergedConfiguration(mWmService.mRoot.getConfiguration(),
getMergedOverrideConfiguration());
setLastReportedMergedConfiguration(mergedConfiguration);
- if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == DRAW_PENDING)
- Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING");
+ if (mWinAnimator.mDrawState == DRAW_PENDING) {
+ ProtoLog.i(WM_DEBUG_ORIENTATION,
+ "Resizing %s WITH DRAW PENDING", this);
+ }
final Rect frame = mWindowFrames.mCompatFrame;
final Rect overscanInsets = mWindowFrames.mLastOverscanInsets;
@@ -3343,6 +3366,15 @@
}
}
+ @Override
+ public void showInsets(@InsetType int types, boolean fromIme) {
+ try {
+ mClient.showInsets(types, fromIme);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to deliver showInsets", e);
+ }
+ }
+
Rect getBackdropFrame(Rect frame) {
// When the task is docked, we send fullscreen sized backDropFrame as soon as resizing
// start even if we haven't received the relayout window, so that the client requests
@@ -4378,9 +4410,8 @@
return;
}
- if (DEBUG || DEBUG_ADD_REMOVE) {
- Slog.v(TAG, "Exit animation finished in " + this + ": remove=" + mRemoveOnExit);
- }
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Exit animation finished in %s: remove=%b",
+ this, mRemoveOnExit);
mDestroying = true;
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 8fccc8d..3dcf6ec 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -27,17 +27,18 @@
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_DRAW;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
@@ -67,6 +68,7 @@
import android.view.animation.AnimationUtils;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.protolog.common.ProtoLog;
import java.io.PrintWriter;
@@ -312,19 +314,19 @@
boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) {
final boolean startingWindow =
mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
- if (DEBUG_STARTING_WINDOW && startingWindow) {
- Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
- + drawStateToString());
+ if (startingWindow) {
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finishing drawing window %s: mDrawState=%s",
+ mWin, drawStateToString());
}
boolean layoutNeeded = false;
if (mDrawState == DRAW_PENDING) {
- if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
- Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
- + mSurfaceController);
- if (DEBUG_STARTING_WINDOW && startingWindow) {
- Slog.v(TAG, "Draw state now committed in " + mWin);
+ ProtoLog.v(WM_DEBUG_DRAW,
+ "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING %s in %s", mWin,
+ mSurfaceController);
+ if (startingWindow) {
+ ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Draw state now committed in %s", mWin);
}
mDrawState = COMMIT_DRAW_PENDING;
layoutNeeded = true;
@@ -385,7 +387,7 @@
mSurfaceDestroyDeferred = true;
return;
}
- if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "SET FREEZE LAYER", false);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SET FREEZE LAYER: %s", mWin);
if (mSurfaceController != null) {
// Our SurfaceControl is always at layer 0 within the parent Surface managed by
// window-state. We want this old Surface to stay on top of the new one
@@ -456,8 +458,9 @@
w.setHasSurface(false);
- if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
- "createSurface " + this + ": mDrawState=DRAW_PENDING");
+ if (DEBUG_ANIM) {
+ Slog.i(TAG, "createSurface " + this + ": mDrawState=DRAW_PENDING");
+ }
resetDrawState();
@@ -514,15 +517,10 @@
w.setHasSurface(true);
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
- Slog.i(TAG, " CREATE SURFACE "
- + mSurfaceController + " IN SESSION "
- + mSession.mSurfaceSession
- + ": pid=" + mSession.mPid + " format="
- + attrs.format + " flags=0x"
- + Integer.toHexString(flags)
- + " / " + this);
- }
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
+ " CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x / %s",
+ mSurfaceController, mSession.mSurfaceSession, mSession.mPid, attrs.format,
+ flags, this);
} catch (OutOfResourcesException e) {
Slog.w(TAG, "OutOfResourcesException creating surface");
mService.mRoot.reclaimSomeSurfaceMemory(this, "create", true);
@@ -616,17 +614,15 @@
if (mSurfaceDestroyDeferred) {
if (mSurfaceController != null && mPendingDestroySurface != mSurfaceController) {
if (mPendingDestroySurface != null) {
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
- WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
- }
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY PENDING: %s. %s",
+ mWin, new RuntimeException().fillInStackTrace());
mPendingDestroySurface.destroyNotInTransaction();
}
mPendingDestroySurface = mSurfaceController;
}
} else {
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
- WindowManagerService.logSurface(mWin, "DESTROY", true);
- }
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY: %s. %s",
+ mWin, new RuntimeException().fillInStackTrace());
destroySurface();
}
// Don't hide wallpaper if we're deferring the surface destroy
@@ -653,9 +649,8 @@
void destroyDeferredSurfaceLocked() {
try {
if (mPendingDestroySurface != null) {
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
- WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
- }
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY PENDING: %s. %s",
+ mWin, new RuntimeException().fillInStackTrace());
mPendingDestroySurface.destroyNotInTransaction();
// Don't hide wallpaper if we're destroying a deferred surface
// after a surface mode change.
@@ -1088,9 +1083,7 @@
// There is no need to wait for an animation change if our window is gone for layout
// already as we'll never be visible.
if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
- if (DEBUG_ORIENTATION) {
- Slog.v(TAG, "Orientation change skips hidden " + w);
- }
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "Orientation change skips hidden %s", w);
w.setOrientationChanging(false);
}
return;
@@ -1115,8 +1108,8 @@
// before it has drawn for the new orientation.
if (w.getOrientationChanging() && w.isGoneForLayoutLw()) {
w.setOrientationChanging(false);
- if (DEBUG_ORIENTATION) Slog.v(TAG,
- "Orientation change skips hidden " + w);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Orientation change skips hidden %s", w);
}
} else if (mLastAlpha != mShownAlpha
|| mLastDsDx != mDsDx
@@ -1134,13 +1127,10 @@
mLastDtDy = mDtDy;
w.mLastHScale = w.mHScale;
w.mLastVScale = w.mVScale;
- if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
- "controller=" + mSurfaceController +
- "alpha=" + mShownAlpha
- + " matrix=[" + mDsDx + "*" + w.mHScale
- + "," + mDtDx + "*" + w.mVScale
- + "][" + mDtDy + "*" + w.mHScale
- + "," + mDsDy + "*" + w.mVScale + "]", false);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS,
+ "SURFACE controller=%s alpha=%f matrix=[%f*%f,%f*%f][%f*%f,%f*%f]: %s",
+ mSurfaceController, mShownAlpha, mDsDx, w.mHScale, mDtDx, w.mVScale,
+ mDtDy, w.mHScale, mDsDy, w.mVScale, w);
boolean prepared =
mSurfaceController.prepareToShowInTransaction(mShownAlpha,
@@ -1190,11 +1180,11 @@
if (!w.isDrawnLw()) {
mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
mAnimator.mLastWindowFreezeSource = w;
- if (DEBUG_ORIENTATION) Slog.v(TAG,
- "Orientation continue waiting for draw in " + w);
+ ProtoLog.v(WM_DEBUG_ORIENTATION,
+ "Orientation continue waiting for draw in %s", w);
} else {
w.setOrientationChanging(false);
- if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
+ ProtoLog.v(WM_DEBUG_ORIENTATION, "Orientation change complete in %s", w);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 6d813d1..49f27a1 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -21,10 +21,10 @@
import static android.view.SurfaceControl.METADATA_OWNER_UID;
import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowSurfaceControllerProto.LAYER;
@@ -40,6 +40,8 @@
import android.view.SurfaceSession;
import android.view.WindowContentFrameStats;
+import com.android.server.protolog.common.ProtoLog;
+
import java.io.PrintWriter;
class WindowSurfaceController {
@@ -111,31 +113,22 @@
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
- private void logSurface(String msg, RuntimeException where) {
- String str = " SURFACE " + msg + ": " + title;
- if (where != null) {
- Slog.i(TAG, str, where);
- } else {
- Slog.i(TAG, str);
- }
- }
-
void reparentChildrenInTransaction(WindowSurfaceController other) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "REPARENT from: " + this + " to: " + other);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "REPARENT from: %s to: %s", this, other);
if ((mSurfaceControl != null) && (other.mSurfaceControl != null)) {
mSurfaceControl.reparentChildren(other.mSurfaceControl);
}
}
void detachChildren() {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "SEVER CHILDREN");
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SEVER CHILDREN");
if (mSurfaceControl != null) {
mSurfaceControl.detachChildren();
}
}
void hide(SurfaceControl.Transaction transaction, String reason) {
- if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE HIDE ( %s ): %s", reason, title);
mHiddenForOtherReasons = true;
mAnimator.destroyPreservedSurfaceLocked();
@@ -157,9 +150,8 @@
}
void destroyNotInTransaction() {
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
- Slog.i(TAG, "Destroying surface " + this + " called by " + Debug.getCallers(8));
- }
+ ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
+ "Destroying surface %s called by %s", this, Debug.getCallers(8));
try {
if (mSurfaceControl != null) {
mTmpTransaction.remove(mSurfaceControl).apply();
@@ -173,8 +165,7 @@
}
void setCropInTransaction(Rect clipRect, boolean recoveringMemory) {
- if (SHOW_TRANSACTIONS) logSurface(
- "CROP " + clipRect.toShortString(), null);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE CROP %s: %s", clipRect.toShortString(), title);
try {
if (clipRect.width() > 0 && clipRect.height() > 0) {
if (!clipRect.equals(mSurfaceCrop)) {
@@ -198,8 +189,7 @@
}
void clearCropInTransaction(boolean recoveringMemory) {
- if (SHOW_TRANSACTIONS) logSurface(
- "CLEAR CROP", null);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE CLEAR CROP: %s", title);
try {
Rect clipRect = new Rect(0, 0, -1, -1);
if (mSurfaceCrop.equals(clipRect)) {
@@ -227,8 +217,8 @@
mSurfaceY = top;
try {
- if (SHOW_TRANSACTIONS) logSurface(
- "POS (setPositionInTransaction) @ (" + left + "," + top + ")", null);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS,
+ "SURFACE POS (setPositionInTransaction) @ (%f,%f): %s", left, top, title);
if (t == null) {
mSurfaceControl.setPosition(left, top);
@@ -264,8 +254,8 @@
mLastDsdy = dsdy;
try {
- if (SHOW_TRANSACTIONS) logSurface(
- "MATRIX [" + dsdx + "," + dtdx + "," + dtdy + "," + dsdy + "]", null);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE MATRIX [%f,%f,%f,%f]: %s",
+ dsdx, dtdx, dtdy, dsdy, title);
if (t == null) {
mSurfaceControl.setMatrix(dsdx, dtdx, dtdy, dsdy);
} else {
@@ -290,8 +280,7 @@
mSurfaceH = height;
try {
- if (SHOW_TRANSACTIONS) logSurface(
- "SIZE " + width + "x" + height, null);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SIZE %dx%d: %s", width, height, title);
mSurfaceControl.setBufferSize(width, height);
} catch (RuntimeException e) {
// If something goes wrong with the surface (such
@@ -350,8 +339,7 @@
}
void setOpaque(boolean isOpaque) {
- if (SHOW_TRANSACTIONS) logSurface("isOpaque=" + isOpaque,
- null);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isOpaque=%b: %s", isOpaque, title);
if (mSurfaceControl == null) {
return;
@@ -367,8 +355,7 @@
}
void setSecure(boolean isSecure) {
- if (SHOW_TRANSACTIONS) logSurface("isSecure=" + isSecure,
- null);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isSecure=%b: %s", isSecure, title);
if (mSurfaceControl == null) {
return;
@@ -384,9 +371,7 @@
}
void setColorSpaceAgnostic(boolean agnostic) {
- if (SHOW_TRANSACTIONS) {
- logSurface("isColorSpaceAgnostic=" + agnostic, null);
- }
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE isColorSpaceAgnostic=%b: %s", agnostic, title);
if (mSurfaceControl == null) {
return;
@@ -410,8 +395,7 @@
}
boolean showRobustlyInTransaction() {
- if (SHOW_TRANSACTIONS) logSurface(
- "SHOW (performLayout)", null);
+ ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE SHOW (performLayout): %s", title);
if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
+ " during relayout");
mHiddenForOtherReasons = false;
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 8aee0f2..5b362c3 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -19,9 +19,9 @@
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
@@ -35,9 +35,10 @@
import android.annotation.CallSuper;
import android.os.Debug;
import android.os.IBinder;
-import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import com.android.server.protolog.common.ProtoLog;
+
import java.io.PrintWriter;
import java.util.Comparator;
@@ -119,7 +120,9 @@
mPersistOnEmpty = persistOnEmpty;
mOwnerCanManageAppTokens = ownerCanManageAppTokens;
mRoundedCornerOverlay = roundedCornerOverlay;
- onDisplayChanged(dc);
+ if (dc != null) {
+ onDisplayChanged(dc);
+ }
}
void setHidden(boolean hidden) {
@@ -135,8 +138,8 @@
void removeAllWindowsIfPossible() {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowState win = mChildren.get(i);
- if (DEBUG_WINDOW_MOVEMENT) Slog.w(TAG_WM,
- "removeAllWindowsIfPossible: removing win=" + win);
+ ProtoLog.w(WM_DEBUG_WINDOW_MOVEMENT,
+ "removeAllWindowsIfPossible: removing win=%s", win);
win.removeIfPossible();
}
}
@@ -197,15 +200,15 @@
}
void addWindow(final WindowState win) {
- if (DEBUG_FOCUS) Slog.d(TAG_WM,
- "addWindow: win=" + win + " Callers=" + Debug.getCallers(5));
+ ProtoLog.d(WM_DEBUG_FOCUS,
+ "addWindow: win=%s Callers=%s", win, Debug.getCallers(5));
if (win.isChildWindow()) {
// Child windows are added to their parent windows.
return;
}
if (!mChildren.contains(win)) {
- if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this);
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Adding %s to %s", win, this);
addChild(win, mWindowComparator);
mWmService.mWindowsChanged = true;
// TODO: Should we also be setting layout needed here and other places?
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index d9c7fed..bcd1713 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -141,6 +141,7 @@
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
"android.hardware.vibrator@1.3",
+ "android.hardware.vibrator@1.4",
"android.hardware.vr@1.0",
"android.frameworks.schedulerservice@1.0",
"android.frameworks.sensorservice@1.0",
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 7aa9c7c..a8c7682 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -16,17 +16,12 @@
#define LOG_TAG "VibratorService"
-#include <android/hardware/vibrator/1.0/IVibrator.h>
-#include <android/hardware/vibrator/1.0/types.h>
-#include <android/hardware/vibrator/1.0/IVibrator.h>
-#include <android/hardware/vibrator/1.1/types.h>
-#include <android/hardware/vibrator/1.2/IVibrator.h>
-#include <android/hardware/vibrator/1.2/types.h>
-#include <android/hardware/vibrator/1.3/IVibrator.h>
+#include <android/hardware/vibrator/1.4/IVibrator.h>
#include "jni.h"
#include <nativehelper/JNIHelp.h>
#include "android_runtime/AndroidRuntime.h"
+#include "core_jni_helpers.h"
#include <utils/misc.h>
#include <utils/Log.h>
@@ -36,6 +31,7 @@
#include <stdio.h>
using android::hardware::Return;
+using android::hardware::Void;
using android::hardware::vibrator::V1_0::EffectStrength;
using android::hardware::vibrator::V1_0::Status;
using android::hardware::vibrator::V1_1::Effect_1_1;
@@ -44,9 +40,32 @@
namespace V1_1 = android::hardware::vibrator::V1_1;
namespace V1_2 = android::hardware::vibrator::V1_2;
namespace V1_3 = android::hardware::vibrator::V1_3;
+namespace V1_4 = android::hardware::vibrator::V1_4;
namespace android {
+static jmethodID sMethodIdOnComplete;
+
+class VibratorCallback : public V1_4::IVibratorCallback {
+ public:
+ VibratorCallback(JNIEnv *env, jobject vibration) :
+ mVibration(MakeGlobalRefOrDie(env, vibration)) {}
+
+ ~VibratorCallback() {
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ env->DeleteGlobalRef(mVibration);
+ }
+
+ Return<void> onComplete() override {
+ auto env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mVibration, sMethodIdOnComplete);
+ return Void();
+ }
+
+ private:
+ jobject mVibration;
+};
+
static constexpr int NUM_TRIES = 2;
// Creates a Return<R> with STATUS::EX_NULL_POINTER.
@@ -119,17 +138,17 @@
return val >= *iter.begin() && val <= *std::prev(iter.end());
}
-static void vibratorInit(JNIEnv /* env */, jobject /* clazz */)
+static void vibratorInit(JNIEnv *env, jclass clazz)
{
halCall(&V1_0::IVibrator::ping).isOk();
}
-static jboolean vibratorExists(JNIEnv* /* env */, jobject /* clazz */)
+static jboolean vibratorExists(JNIEnv* /* env */, jclass /* clazz */)
{
return halCall(&V1_0::IVibrator::ping).isOk() ? JNI_TRUE : JNI_FALSE;
}
-static void vibratorOn(JNIEnv* /* env */, jobject /* clazz */, jlong timeout_ms)
+static void vibratorOn(JNIEnv* /* env */, jclass /* clazz */, jlong timeout_ms)
{
Status retStatus = halCall(&V1_0::IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR);
if (retStatus != Status::OK) {
@@ -137,7 +156,7 @@
}
}
-static void vibratorOff(JNIEnv* /* env */, jobject /* clazz */)
+static void vibratorOff(JNIEnv* /* env */, jclass /* clazz */)
{
Status retStatus = halCall(&V1_0::IVibrator::off).withDefault(Status::UNKNOWN_ERROR);
if (retStatus != Status::OK) {
@@ -145,11 +164,11 @@
}
}
-static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jobject) {
+static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jclass) {
return halCall(&V1_0::IVibrator::supportsAmplitudeControl).withDefault(false);
}
-static void vibratorSetAmplitude(JNIEnv*, jobject, jint amplitude) {
+static void vibratorSetAmplitude(JNIEnv*, jclass, jint amplitude) {
Status status = halCall(&V1_0::IVibrator::setAmplitude, static_cast<uint32_t>(amplitude))
.withDefault(Status::UNKNOWN_ERROR);
if (status != Status::OK) {
@@ -158,11 +177,11 @@
}
}
-static jboolean vibratorSupportsExternalControl(JNIEnv*, jobject) {
+static jboolean vibratorSupportsExternalControl(JNIEnv*, jclass) {
return halCall(&V1_3::IVibrator::supportsExternalControl).withDefault(false);
}
-static void vibratorSetExternalControl(JNIEnv*, jobject, jboolean enabled) {
+static void vibratorSetExternalControl(JNIEnv*, jclass, jboolean enabled) {
Status status = halCall(&V1_3::IVibrator::setExternalControl, static_cast<uint32_t>(enabled))
.withDefault(Status::UNKNOWN_ERROR);
if (status != Status::OK) {
@@ -171,7 +190,8 @@
}
}
-static jlong vibratorPerformEffect(JNIEnv*, jobject, jlong effect, jint strength) {
+static jlong vibratorPerformEffect(JNIEnv* env, jclass, jlong effect, jint strength,
+ jobject vibration) {
Status status;
uint32_t lengthMs;
auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
@@ -181,7 +201,11 @@
EffectStrength effectStrength(static_cast<EffectStrength>(strength));
Return<void> ret;
- if (isValidEffect<V1_0::Effect>(effect)) {
+ if (auto hal = getHal<V1_4::IVibrator>(); hal && isValidEffect<V1_3::Effect>(effect)) {
+ sp<VibratorCallback> effectCallback = new VibratorCallback(env, vibration);
+ ret = hal->call(&V1_4::IVibrator::perform_1_4, static_cast<V1_3::Effect>(effect),
+ effectStrength, effectCallback, callback);
+ } else if (isValidEffect<V1_0::Effect>(effect)) {
ret = halCall(&V1_0::IVibrator::perform, static_cast<V1_0::Effect>(effect),
effectStrength, callback);
} else if (isValidEffect<Effect_1_1>(effect)) {
@@ -218,6 +242,10 @@
return -1;
}
+static jlong vibratorGetCapabilities(JNIEnv*, jclass) {
+ return halCall(&V1_4::IVibrator::getCapabilities).withDefault(0);
+}
+
static const JNINativeMethod method_table[] = {
{ "vibratorExists", "()Z", (void*)vibratorExists },
{ "vibratorInit", "()V", (void*)vibratorInit },
@@ -225,13 +253,18 @@
{ "vibratorOff", "()V", (void*)vibratorOff },
{ "vibratorSupportsAmplitudeControl", "()Z", (void*)vibratorSupportsAmplitudeControl},
{ "vibratorSetAmplitude", "(I)V", (void*)vibratorSetAmplitude},
- { "vibratorPerformEffect", "(JJ)J", (void*)vibratorPerformEffect},
+ { "vibratorPerformEffect", "(JJLcom/android/server/VibratorService$Vibration;)J",
+ (void*)vibratorPerformEffect},
{ "vibratorSupportsExternalControl", "()Z", (void*)vibratorSupportsExternalControl},
{ "vibratorSetExternalControl", "(Z)V", (void*)vibratorSetExternalControl},
+ { "vibratorGetCapabilities", "()J", (void*)vibratorGetCapabilities},
};
int register_android_server_VibratorService(JNIEnv *env)
{
+ sMethodIdOnComplete = GetMethodIDOrDie(env,
+ FindClassOrDie(env, "com/android/server/VibratorService$Vibration"),
+ "onComplete", "()V");
return jniRegisterNativeMethods(env, "com/android/server/VibratorService",
method_table, NELEM(method_table));
}
diff --git a/services/devicepolicy/TEST_MAPPING b/services/devicepolicy/TEST_MAPPING
index a5ee3e2..3d86cf3 100644
--- a/services/devicepolicy/TEST_MAPPING
+++ b/services/devicepolicy/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit": [
+ "presubmit-devicepolicy": [
{
"name": "CtsDevicePolicyManagerTestCases",
"options": [
@@ -12,7 +12,7 @@
]
}
],
- "postsubmit": [
+ "postsubmit-devicepolicy": [
{
"name": "CtsDevicePolicyManagerTestCases"
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index c3ff285..b118cdf 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11902,10 +11902,13 @@
try {
int uid = packageManager.getPackageUidAsUser(packageName,
user.getIdentifier());
-
- // TODO: Prevent noting the app-op
- granted = PermissionChecker.checkPermission(mContext, permission, -1,
- uid, packageName);
+ if (PermissionChecker.checkPermissionForPreflight(mContext, permission,
+ PermissionChecker.PID_UNKNOWN, uid, packageName)
+ != PermissionChecker.PERMISSION_GRANTED) {
+ granted = PackageManager.PERMISSION_DENIED;
+ } else {
+ granted = PackageManager.PERMISSION_GRANTED;
+ }
} catch (NameNotFoundException e) {
throw new RemoteException(
"Cannot check if " + permission + "is a runtime permission", e,
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 1685b04..8b3c85e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -82,6 +82,7 @@
import android.os.IBinder;
import android.os.PowerManagerInternal;
import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.SparseArray;
@@ -103,6 +104,7 @@
* Build/Install/Run:
* atest MockingOomAdjusterTests
*/
+@Presubmit
public class MockingOomAdjusterTests {
private static final int MOCKAPP_PID = 12345;
private static final int MOCKAPP_UID = 12345;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
index 73dcb98..43f251a 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
@@ -46,6 +46,7 @@
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -140,6 +141,8 @@
private final List<AccessibilityWindowInfo> mA11yWindowInfosOnSecondDisplay = new ArrayList<>();
private Callable[] mFindA11yNodesFunctions;
private Callable<Boolean> mPerformA11yAction;
+ private ArrayList<Integer> mDisplayList = new ArrayList<>(Arrays.asList(
+ Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID));
// To mock package-private class.
@Rule public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
@@ -184,6 +187,7 @@
addA11yWindowInfo(mA11yWindowInfos, PIP_WINDOWID, true, Display.DEFAULT_DISPLAY);
addA11yWindowInfo(mA11yWindowInfosOnSecondDisplay, WINDOWID_ONSECONDDISPLAY, false,
SECONDARY_DISPLAY_ID);
+ when(mMockA11yWindowManager.getDisplayListLocked()).thenReturn(mDisplayList);
when(mMockA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY))
.thenReturn(mA11yWindowInfos);
when(mMockA11yWindowManager.findA11yWindowInfoByIdLocked(WINDOWID))
@@ -285,7 +289,14 @@
@Test
public void getWindows() {
- assertThat(mServiceConnection.getWindows(), is(mA11yWindowInfos));
+ final AccessibilityWindowInfo.WindowListSparseArray allWindows =
+ mServiceConnection.getWindows();
+
+ assertEquals(2, allWindows.size());
+ assertThat(allWindows.get(Display.DEFAULT_DISPLAY), is(mA11yWindowInfos));
+ assertEquals(2, allWindows.get(Display.DEFAULT_DISPLAY).size());
+ assertThat(allWindows.get(SECONDARY_DISPLAY_ID), is(mA11yWindowInfosOnSecondDisplay));
+ assertEquals(1, allWindows.get(SECONDARY_DISPLAY_ID).size());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index b7b5a4e..b5e5deb 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -67,6 +67,7 @@
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -104,6 +105,9 @@
// List of callback, mapping from displayId -> callback.
private final SparseArray<WindowsForAccessibilityCallback> mCallbackOfWindows =
new SparseArray<>();
+ // List of display ID.
+ private final ArrayList<Integer> mExpectedDisplayList = new ArrayList<>(Arrays.asList(
+ Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID));
private final MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
@@ -692,6 +696,15 @@
assertTrue(windowId >= 0);
}
+ @Test
+ public void getDisplayList() throws RemoteException {
+ // Starts tracking window of second display.
+ startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
+
+ final ArrayList<Integer> displayList = mA11yWindowManager.getDisplayListLocked();
+ assertTrue(displayList.equals(mExpectedDisplayList));
+ }
+
private void startTrackingPerDisplay(int displayId) throws RemoteException {
ArrayList<WindowInfo> windowInfosForDisplay = new ArrayList<>();
// Adds RemoteAccessibilityConnection into AccessibilityWindowManager, and copy
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
index f1142fd..36e854c 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
@@ -46,7 +46,6 @@
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
-import android.util.Log;
import android.view.Display;
import android.view.InputDevice;
import android.view.KeyEvent;
@@ -55,6 +54,8 @@
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.accessibility.utils.MotionEventMatcher;
+
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
@@ -761,56 +762,6 @@
return next;
}
- static class MotionEventMatcher extends TypeSafeMatcher<MotionEvent> {
- long mDownTime;
- long mEventTime;
- long mActionMasked;
- int mX;
- int mY;
-
- MotionEventMatcher(long downTime, long eventTime, int actionMasked, int x, int y) {
- mDownTime = downTime;
- mEventTime = eventTime;
- mActionMasked = actionMasked;
- mX = x;
- mY = y;
- }
-
- MotionEventMatcher(MotionEvent event) {
- this(event.getDownTime(), event.getEventTime(), event.getActionMasked(),
- (int) event.getX(), (int) event.getY());
- }
-
- void offsetTimesBy(long timeOffset) {
- mDownTime += timeOffset;
- mEventTime += timeOffset;
- }
-
- @Override
- public boolean matchesSafely(MotionEvent event) {
- if ((event.getDownTime() == mDownTime) && (event.getEventTime() == mEventTime)
- && (event.getActionMasked() == mActionMasked) && ((int) event.getX() == mX)
- && ((int) event.getY() == mY)) {
- return true;
- }
- Log.e(LOG_TAG, "MotionEvent match failed");
- Log.e(LOG_TAG, "event.getDownTime() = " + event.getDownTime()
- + ", expected " + mDownTime);
- Log.e(LOG_TAG, "event.getEventTime() = " + event.getEventTime()
- + ", expected " + mEventTime);
- Log.e(LOG_TAG, "event.getActionMasked() = " + event.getActionMasked()
- + ", expected " + mActionMasked);
- Log.e(LOG_TAG, "event.getX() = " + event.getX() + ", expected " + mX);
- Log.e(LOG_TAG, "event.getY() = " + event.getY() + ", expected " + mY);
- return false;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("Motion event matcher");
- }
- }
-
private static class MotionEventActionMatcher extends TypeSafeMatcher<MotionEvent> {
int mAction;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
index 104aacb..4b1ec6f 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/gestures/TouchExplorerTest.java
@@ -21,6 +21,7 @@
import static com.android.server.accessibility.gestures.TouchState.STATE_DRAGGING;
import static com.android.server.accessibility.gestures.TouchState.STATE_TOUCH_EXPLORING;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
@@ -36,6 +37,7 @@
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accessibility.EventStreamTransformation;
+import com.android.server.accessibility.utils.MotionEventMatcher;
import org.junit.Before;
import org.junit.Rule;
@@ -49,6 +51,7 @@
@RunWith(AndroidJUnit4.class)
public class TouchExplorerTest {
+ private static final String LOG_TAG = "TouchExplorerTest";
private static final int FLAG_1FINGER = 0x8000;
private static final int FLAG_2FINGERS = 0x0100;
private static final int FLAG_3FINGERS = 0x0200;
@@ -86,7 +89,9 @@
@Override
public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+ MotionEventMatcher lastEventMatcher = new MotionEventMatcher(mLastEvent);
mEvents.add(0, event.copy());
+ assertThat(rawEvent, lastEventMatcher);
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/utils/MotionEventMatcher.java b/services/tests/servicestests/src/com/android/server/accessibility/utils/MotionEventMatcher.java
new file mode 100644
index 0000000..2b6d385
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/utils/MotionEventMatcher.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 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.server.accessibility.utils;
+
+import android.util.Log;
+import android.view.MotionEvent;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * This class compares two motion events using a subset of their attributes: actionMasked, downTime,
+ * eventTime, and location. If two events match they are considered to be effectively equal.
+ */
+public class MotionEventMatcher extends TypeSafeMatcher<MotionEvent> {
+ private static final String LOG_TAG = "MotionEventMatcher";
+ long mDownTime;
+ long mEventTime;
+ long mActionMasked;
+ int mX;
+ int mY;
+
+ MotionEventMatcher(long downTime, long eventTime, int actionMasked, int x, int y) {
+ mDownTime = downTime;
+ mEventTime = eventTime;
+ mActionMasked = actionMasked;
+ mX = x;
+ mY = y;
+ }
+
+ public MotionEventMatcher(MotionEvent event) {
+ this(
+ event.getDownTime(),
+ event.getEventTime(),
+ event.getActionMasked(),
+ (int) event.getX(),
+ (int) event.getY());
+ }
+
+ void offsetTimesBy(long timeOffset) {
+ mDownTime += timeOffset;
+ mEventTime += timeOffset;
+ }
+
+ @Override
+ public boolean matchesSafely(MotionEvent event) {
+ if ((event.getDownTime() == mDownTime)
+ && (event.getEventTime() == mEventTime)
+ && (event.getActionMasked() == mActionMasked)
+ && ((int) event.getX() == mX)
+ && ((int) event.getY() == mY)) {
+ return true;
+ }
+ Log.e(LOG_TAG, "MotionEvent match failed");
+ Log.e(LOG_TAG, "event.getDownTime() = " + event.getDownTime() + ", expected " + mDownTime);
+ Log.e(
+ LOG_TAG,
+ "event.getEventTime() = " + event.getEventTime() + ", expected " + mEventTime);
+ Log.e(
+ LOG_TAG,
+ "event.getActionMasked() = "
+ + event.getActionMasked()
+ + ", expected "
+ + mActionMasked);
+ Log.e(LOG_TAG, "event.getX() = " + event.getX() + ", expected " + mX);
+ Log.e(LOG_TAG, "event.getY() = " + event.getY() + ", expected " + mY);
+ return false;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Motion event matcher");
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index d4b7e7e9..79cc3db 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -25,8 +25,8 @@
import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG;
-import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG;
-import static com.android.server.am.UserController.SYSTEM_USER_START_MSG;
+import static com.android.server.am.UserController.USER_CURRENT_MSG;
+import static com.android.server.am.UserController.USER_START_MSG;
import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
import static com.google.android.collect.Lists.newArrayList;
@@ -53,11 +53,13 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.annotation.UserIdInt;
import android.app.IUserSwitchObserver;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.pm.UserInfo;
+import android.content.pm.UserInfo.UserInfoFlag;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -106,6 +108,10 @@
private static final int TEST_USER_ID1 = 101;
private static final int TEST_USER_ID2 = 102;
private static final int NONEXIST_USER_ID = 2;
+ private static final int TEST_PRE_CREATED_USER_ID = 103;
+
+ private static final int NO_USERINFO_FLAGS = 0;
+
private static final String TAG = UserControllerTest.class.getSimpleName();
private static final long HANDLER_WAIT_TIME_MS = 100;
@@ -127,11 +133,11 @@
private static final Set<Integer> START_FOREGROUND_USER_MESSAGE_CODES = newHashSet(
REPORT_USER_SWITCH_MSG,
USER_SWITCH_TIMEOUT_MSG,
- SYSTEM_USER_START_MSG,
- SYSTEM_USER_CURRENT_MSG);
+ USER_START_MSG,
+ USER_CURRENT_MSG);
private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES = newHashSet(
- SYSTEM_USER_START_MSG,
+ USER_START_MSG,
REPORT_LOCKED_BOOT_COMPLETE_MSG);
@Before
@@ -148,7 +154,8 @@
doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt());
doNothing().when(mInjector).stackSupervisorRemoveUser(anyInt());
mUserController = new UserController(mInjector);
- setUpUser(TEST_USER_ID, 0);
+ setUpUser(TEST_USER_ID, NO_USERINFO_FLAGS);
+ setUpUser(TEST_PRE_CREATED_USER_ID, NO_USERINFO_FLAGS, /* preCreated=*/ true);
});
}
@@ -188,6 +195,31 @@
startForegroundUserAssertions();
}
+ @Test
+ public void testStartPreCreatedUser_foreground() {
+ assertFalse(mUserController.startUser(TEST_PRE_CREATED_USER_ID, /* foreground= */ true));
+ }
+
+ @Test
+ public void testStartPreCreatedUser_background() throws Exception {
+ assertTrue(mUserController.startUser(TEST_PRE_CREATED_USER_ID, /* foreground= */ false));
+
+ verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
+ verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
+ verify(mInjector, never()).clearAllLockedTasks(anyString());
+
+ assertWithMessage("should not have received intents")
+ .that(getActions(mInjector.mSentIntents)).isEmpty();
+ // TODO(b/140868593): should have received a USER_UNLOCK_MSG message as well, but it doesn't
+ // because StorageManager.isUserKeyUnlocked(TEST_PRE_CREATED_USER_ID) returns false - to
+ // properly fix it, we'd need to move this class to FrameworksMockingServicesTests so we can
+ // mock static methods (but moving this class would involve changing the presubmit tests,
+ // and the cascade effect goes on...). In fact, a better approach would to not assert the
+ // binder calls, but their side effects (in this case, that the user is stopped right away)
+ assertWithMessage("wrong binder message calls").that(mInjector.mHandler.getMessageCodes())
+ .containsExactly(USER_START_MSG);
+ }
+
private void startUserAssertions(
List<String> expectedActions, Set<Integer> expectedMessageCodes) {
assertEquals(expectedActions, getActions(mInjector.mSentIntents));
@@ -467,9 +499,15 @@
continueUserSwitchAssertions(newUserId, expectOldUserStopping);
}
- private void setUpUser(int userId, int flags) {
+ private void setUpUser(@UserIdInt int userId, @UserInfoFlag int flags) {
+ setUpUser(userId, flags, /* preCreated= */ false);
+ }
+
+ private void setUpUser(@UserIdInt int userId, @UserInfoFlag int flags, boolean preCreated) {
UserInfo userInfo = new UserInfo(userId, "User" + userId, flags);
+ userInfo.preCreated = preCreated;
when(mInjector.mUserManagerMock.getUserInfo(eq(userId))).thenReturn(userInfo);
+ when(mInjector.mUserManagerMock.isPreCreated(userId)).thenReturn(preCreated);
}
private static List<String> getActions(List<Intent> intents) {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index ccf3a90..4aeeb0a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -39,6 +39,7 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.hardware.biometrics.Authenticator;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
@@ -55,6 +56,9 @@
import android.os.IBinder;
import android.security.KeyStore;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
import com.android.internal.R;
import com.android.internal.statusbar.IStatusBarService;
@@ -66,9 +70,6 @@
import java.util.List;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-
@SmallTest
public class BiometricServiceTest {
@@ -82,6 +83,7 @@
private static final String ERROR_CANCELED = "error_canceled";
private static final String ERROR_UNABLE_TO_PROCESS = "error_unable_to_process";
private static final String ERROR_USER_CANCELED = "error_user_canceled";
+ private static final String ERROR_LOCKOUT = "error_lockout";
private static final String FINGERPRINT_ACQUIRED_SENSOR_DIRTY = "sensor_dirty";
@@ -179,7 +181,8 @@
mBiometricService = new BiometricService(mContext, new MockInjector());
mBiometricService.onStart();
- invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
+ false /* allowDeviceCredential */);
waitForIdle();
verify(mReceiver1).onError(
eq(BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT), eq(ERROR_HW_UNAVAILABLE));
@@ -193,7 +196,8 @@
mBiometricService = new BiometricService(mContext, new MockInjector());
mBiometricService.onStart();
- invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
+ false /* allowDeviceCredential */);
waitForIdle();
verify(mReceiver1).onError(
eq(BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS), any());
@@ -208,7 +212,8 @@
mBiometricService = new BiometricService(mContext, new MockInjector());
mBiometricService.onStart();
- invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
+ false /* allowDeviceCredential */);
waitForIdle();
verify(mReceiver1).onError(
eq(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE), eq(ERROR_HW_UNAVAILABLE));
@@ -226,7 +231,8 @@
// Disabled in user settings receives onError
when(mBiometricService.mSettingObserver.getFaceEnabledForApps(anyInt())).thenReturn(false);
- invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
+ false /* allowDeviceCredential */);
waitForIdle();
verify(mReceiver1).onError(
eq(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE), eq(ERROR_HW_UNAVAILABLE));
@@ -236,7 +242,8 @@
when(mBiometricService.mSettingObserver.getFaceEnabledForApps(anyInt())).thenReturn(true);
when(mBiometricService.mSettingObserver.getFaceAlwaysRequireConfirmation(anyInt()))
.thenReturn(true);
- invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
+ false /* allowDeviceCredential */);
waitForIdle();
verify(mReceiver1, never()).onError(anyInt(), any(String.class));
verify(mBiometricService.mFaceService).prepareForAuthentication(
@@ -255,7 +262,8 @@
resetReceiver();
when(mBiometricService.mSettingObserver.getFaceAlwaysRequireConfirmation(anyInt()))
.thenReturn(false);
- invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
+ false /* allowDeviceCredential */);
waitForIdle();
verify(mBiometricService.mFaceService).prepareForAuthentication(
eq(false) /* requireConfirmation */,
@@ -277,7 +285,8 @@
mBiometricService.onStart();
// Start testing the happy path
- invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
+ false /* allowDeviceCredential */);
waitForIdle();
// Creates a pending auth session with the correct initial states
@@ -311,7 +320,7 @@
.startPreparedClient(cookieCaptor.getValue());
// StatusBar showBiometricDialog invoked
- verify(mBiometricService.mStatusBarService).showBiometricDialog(
+ verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
eq(mBiometricService.mCurrentAuthSession.mBundle),
any(IBiometricServiceReceiverInternal.class),
eq(BiometricAuthenticator.TYPE_FINGERPRINT),
@@ -333,7 +342,7 @@
// SystemUI sends callback with dismissed reason
mBiometricService.mInternalReceiver.onDialogDismissed(
- BiometricPrompt.DISMISSED_REASON_CONFIRM_NOT_REQUIRED);
+ BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED);
waitForIdle();
// HAT sent to keystore
verify(mBiometricService.mKeyStore).addAuthToken(any(byte[].class));
@@ -344,10 +353,32 @@
}
@Test
+ public void testAuthenticate_noBiometrics_credentialAllowed() throws Exception {
+ setupAuthForOnly(BiometricAuthenticator.TYPE_FACE);
+ when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(false);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
+ true /* requireConfirmation */, true /* allowDeviceCredential */);
+ waitForIdle();
+
+ assertEquals(BiometricService.STATE_SHOWING_DEVICE_CREDENTIAL,
+ mBiometricService.mCurrentAuthSession.mState);
+ assertEquals(Authenticator.TYPE_CREDENTIAL,
+ mBiometricService.mCurrentAuthSession.mBundle
+ .getInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED));
+ verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
+ eq(mBiometricService.mCurrentAuthSession.mBundle),
+ any(IBiometricServiceReceiverInternal.class),
+ eq(0 /* biometricModality */),
+ anyBoolean() /* requireConfirmation */,
+ anyInt() /* userId */,
+ eq(TEST_PACKAGE_NAME));
+ }
+
+ @Test
public void testAuthenticate_happyPathWithConfirmation() throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FACE);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- true /* requireConfirmation */);
+ true /* requireConfirmation */, false /* allowDeviceCredential */);
// Test authentication succeeded goes to PENDING_CONFIRMATION and that the HAT is not
// sent to KeyStore yet
@@ -362,7 +393,7 @@
// SystemUI sends confirm, HAT is sent to keystore and client is notified.
mBiometricService.mInternalReceiver.onDialogDismissed(
- BiometricPrompt.DISMISSED_REASON_CONFIRMED);
+ BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED);
waitForIdle();
verify(mBiometricService.mKeyStore).addAuthToken(any(byte[].class));
verify(mReceiver1).onAuthenticationSucceeded();
@@ -373,7 +404,7 @@
throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FACE);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- false /* requireConfirmation */);
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
mBiometricService.mInternalReceiver.onAuthenticationFailed();
waitForIdle();
@@ -390,7 +421,7 @@
throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- false /* requireConfirmation */);
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
mBiometricService.mInternalReceiver.onAuthenticationFailed();
waitForIdle();
@@ -406,13 +437,14 @@
public void testErrorCanceled_whenAuthenticating_notifiesSystemUIAndClient() throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- false /* requireConfirmation */);
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
// Create a new pending auth session but don't start it yet. HAL contract is that previous
// one must get ERROR_CANCELED. Simulate that here by creating the pending auth session,
// sending ERROR_CANCELED to the current auth session, and then having the second one
// onReadyForAuthentication.
- invokeAuthenticate(mBiometricService.mImpl, mReceiver2, false /* requireConfirmation */);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver2, false /* requireConfirmation */,
+ false /* allowDeviceCredential */);
waitForIdle();
assertEquals(mBiometricService.mCurrentAuthSession.mState,
@@ -430,7 +462,7 @@
verify(mReceiver2, never()).onError(anyInt(), any(String.class));
// SystemUI dialog closed
- verify(mBiometricService.mStatusBarService).hideBiometricDialog();
+ verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
// After SystemUI notifies that the animation has completed
mBiometricService.mInternalReceiver
@@ -446,7 +478,7 @@
public void testErrorHalTimeout_whenAuthenticating_entersPausedState() throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FACE);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- false /* requireConfirmation */);
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
@@ -479,7 +511,7 @@
resetStatusBar();
startPendingAuthSession(mBiometricService);
waitForIdle();
- verify(mBiometricService.mStatusBarService, never()).showBiometricDialog(
+ verify(mBiometricService.mStatusBarService, never()).showAuthenticationDialog(
any(Bundle.class),
any(IBiometricServiceReceiverInternal.class),
anyInt(),
@@ -492,7 +524,7 @@
public void testErrorFromHal_whenPaused_notifiesSystemUIAndClient() throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FACE);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- false /* requireCOnfirmation */);
+ false /* requireCOnfirmation */, false /* allowDeviceCredential */);
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
@@ -509,7 +541,7 @@
eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
eq(ERROR_CANCELED));
// Dialog is hidden immediately
- verify(mBiometricService.mStatusBarService).hideBiometricDialog();
+ verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
// Auth session is over
assertNull(mBiometricService.mCurrentAuthSession);
}
@@ -522,7 +554,7 @@
// session is done.
setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- false /* requireConfirmation */);
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
@@ -533,9 +565,10 @@
// Sends error to SystemUI and does not notify client yet
assertEquals(mBiometricService.mCurrentAuthSession.mState,
BiometricService.STATE_ERROR_PENDING_SYSUI);
- verify(mBiometricService.mStatusBarService)
- .onBiometricError(eq(ERROR_UNABLE_TO_PROCESS));
- verify(mBiometricService.mStatusBarService, never()).hideBiometricDialog();
+ verify(mBiometricService.mStatusBarService).onBiometricError(
+ eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
+ eq(ERROR_UNABLE_TO_PROCESS));
+ verify(mBiometricService.mStatusBarService, never()).hideAuthenticationDialog();
verify(mReceiver1, never()).onError(anyInt(), anyString());
// SystemUI animation completed, client is notified, auth session is over
@@ -549,11 +582,177 @@
}
@Test
+ public void testErrorFromHal_whilePreparingAuthentication_credentialAllowed() throws Exception {
+ setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
+ false /* requireConfirmation */, true /* allowDeviceCredential */);
+ waitForIdle();
+
+ mBiometricService.mInternalReceiver.onError(
+ getCookieForPendingSession(mBiometricService.mPendingAuthSession),
+ BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
+ ERROR_LOCKOUT);
+ waitForIdle();
+
+ // Pending auth session becomes current auth session, since device credential should
+ // be shown now.
+ assertNull(mBiometricService.mPendingAuthSession);
+ assertNotNull(mBiometricService.mCurrentAuthSession);
+ assertEquals(BiometricService.STATE_SHOWING_DEVICE_CREDENTIAL,
+ mBiometricService.mCurrentAuthSession.mState);
+ assertEquals(Authenticator.TYPE_CREDENTIAL,
+ mBiometricService.mCurrentAuthSession.mBundle.getInt(
+ BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED));
+ verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
+ eq(mBiometricService.mCurrentAuthSession.mBundle),
+ any(IBiometricServiceReceiverInternal.class),
+ eq(0 /* biometricModality */),
+ anyBoolean() /* requireConfirmation */,
+ anyInt() /* userId */,
+ eq(TEST_PACKAGE_NAME));
+ }
+
+ @Test
+ public void testErrorFromHal_whilePreparingAuthentication_credentialNotAllowed()
+ throws Exception {
+ setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
+ invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
+ waitForIdle();
+
+ mBiometricService.mInternalReceiver.onError(
+ getCookieForPendingSession(mBiometricService.mPendingAuthSession),
+ BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
+ ERROR_LOCKOUT);
+ waitForIdle();
+
+ // Error is sent to client
+ assertNull(mBiometricService.mPendingAuthSession);
+ assertNull(mBiometricService.mCurrentAuthSession);
+ }
+
+ @Test
+ public void testCombineAuthenticatorBundle_keyAllowDeviceCredentialAlwaysRemoved() {
+ Bundle bundle;
+ int authenticators;
+
+ // In:
+ // KEY_ALLOW_DEVICE_CREDENTIAL = true
+ // KEY_AUTHENTICATORS_ALLOWED = TYPE_BIOMETRIC | TYPE_CREDENTIAL
+ // Out:
+ // KEY_ALLOW_DEVICE_CREDENTIAL = null
+ // KEY_AUTHENTICATORS_ALLOWED = TYPE_BIOMETRIC | TYPE_CREDENTIAL
+ bundle = new Bundle();
+ bundle.putBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL, true);
+ authenticators = Authenticator.TYPE_CREDENTIAL | Authenticator.TYPE_BIOMETRIC;
+ bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED, authenticators);
+ Utils.combineAuthenticatorBundles(bundle);
+ assertNull(bundle.get(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL));
+ assertEquals(authenticators, bundle.getInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED));
+
+ // In:
+ // KEY_ALLOW_DEVICE_CREDENTIAL = true
+ // KEY_AUTHENTICATORS_ALLOWED = TYPE_BIOMETRIC
+ // Out:
+ // KEY_ALLOW_DEVICE_CREDENTIAL = null
+ // KEY_AUTHENTICATORS_ALLOWED = TYPE_BIOMETRIC | TYPE_CREDENTIAL
+ bundle = new Bundle();
+ bundle.putBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL, true);
+ authenticators = Authenticator.TYPE_BIOMETRIC;
+ bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED, authenticators);
+ Utils.combineAuthenticatorBundles(bundle);
+ assertNull(bundle.get(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL));
+ assertEquals(authenticators, bundle.getInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED));
+
+ // In:
+ // KEY_ALLOW_DEVICE_CREDENTIAL = null
+ // KEY_AUTHENTICATORS_ALLOWED = TYPE_BIOMETRIC | TYPE_CREDENTIAL
+ // Out:
+ // KEY_ALLOW_DEVICE_CREDENTIAL = null
+ // KEY_AUTHENTICATORS_ALLOWED = TYPE_BIOMETRIC | TYPE_CREDENTIAL
+ bundle = new Bundle();
+ authenticators = Authenticator.TYPE_BIOMETRIC | Authenticator.TYPE_CREDENTIAL;
+ bundle.putInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED, authenticators);
+ Utils.combineAuthenticatorBundles(bundle);
+ assertNull(bundle.get(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL));
+ assertEquals(authenticators, bundle.getInt(BiometricPrompt.KEY_AUTHENTICATORS_ALLOWED));
+ }
+
+ @Test
+ public void testErrorFromHal_whileShowingDeviceCredential_doesntNotifySystemUI()
+ throws Exception {
+ setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
+ invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
+ false /* requireConfirmation */, true /* allowDeviceCredential */);
+
+ mBiometricService.mInternalReceiver.onDeviceCredentialPressed();
+ waitForIdle();
+
+ assertEquals(BiometricService.STATE_SHOWING_DEVICE_CREDENTIAL,
+ mBiometricService.mCurrentAuthSession.mState);
+ verify(mReceiver1, never()).onError(anyInt(), anyString());
+
+ mBiometricService.mInternalReceiver.onError(
+ getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricConstants.BIOMETRIC_ERROR_CANCELED,
+ ERROR_CANCELED);
+ waitForIdle();
+
+ assertEquals(BiometricService.STATE_SHOWING_DEVICE_CREDENTIAL,
+ mBiometricService.mCurrentAuthSession.mState);
+ verify(mReceiver1, never()).onError(anyInt(), anyString());
+ }
+
+ @Test
+ public void testLockout_whileAuthenticating_credentialAllowed() throws Exception {
+ setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
+ invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
+ false /* requireConfirmation */, true /* allowDeviceCredential */);
+
+ assertEquals(BiometricService.STATE_AUTH_STARTED,
+ mBiometricService.mCurrentAuthSession.mState);
+
+ mBiometricService.mInternalReceiver.onError(
+ getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
+ ERROR_LOCKOUT);
+ waitForIdle();
+
+ assertEquals(BiometricService.STATE_SHOWING_DEVICE_CREDENTIAL,
+ mBiometricService.mCurrentAuthSession.mState);
+ verify(mBiometricService.mStatusBarService).onBiometricError(
+ eq(BiometricConstants.BIOMETRIC_ERROR_LOCKOUT),
+ eq(ERROR_LOCKOUT));
+ }
+
+ @Test
+ public void testLockout_whenAuthenticating_credentialNotAllowed() throws Exception {
+ setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
+ invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
+
+ assertEquals(BiometricService.STATE_AUTH_STARTED,
+ mBiometricService.mCurrentAuthSession.mState);
+
+ mBiometricService.mInternalReceiver.onError(
+ getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+ BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS,
+ ERROR_UNABLE_TO_PROCESS);
+ waitForIdle();
+
+ assertEquals(BiometricService.STATE_ERROR_PENDING_SYSUI,
+ mBiometricService.mCurrentAuthSession.mState);
+ verify(mBiometricService.mStatusBarService).onBiometricError(
+ eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
+ eq(ERROR_UNABLE_TO_PROCESS));
+ }
+
+ @Test
public void testDismissedReasonUserCancel_whileAuthenticating_cancelsHalAuthentication()
throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- false /* requireConfirmation */);
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
mBiometricService.mInternalReceiver
.onDialogDismissed(BiometricPrompt.DISMISSED_REASON_USER_CANCEL);
@@ -575,7 +774,7 @@
public void testDismissedReasonNegative_whilePaused_doesntInvokeHalCancel() throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FACE);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- false /* requireConfirmation */);
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
@@ -598,7 +797,7 @@
public void testDismissedReasonUserCancel_whilePaused_doesntInvokeHalCancel() throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FACE);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- false /* requireConfirmation */);
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
mBiometricService.mInternalReceiver.onError(
getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
@@ -621,7 +820,7 @@
public void testDismissedReasonUserCancel_whenPendingConfirmation() throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FACE);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- true /* requireConfirmation */);
+ true /* requireConfirmation */, false /* allowDeviceCredential */);
mBiometricService.mInternalReceiver.onAuthenticationSucceeded(
true /* requireConfirmation */,
@@ -648,7 +847,7 @@
public void testAcquire_whenAuthenticating_sentToSystemUI() throws Exception {
setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT);
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
- false /* requireConfirmation */);
+ false /* requireConfirmation */, false /* allowDeviceCredential */);
mBiometricService.mInternalReceiver.onAcquired(
FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY,
@@ -698,9 +897,10 @@
}
private void invokeAuthenticateAndStart(IBiometricService.Stub service,
- IBiometricServiceReceiver receiver, boolean requireConfirmation) throws Exception {
+ IBiometricServiceReceiver receiver, boolean requireConfirmation,
+ boolean allowDeviceCredential) throws Exception {
// Request auth, creates a pending session
- invokeAuthenticate(service, receiver, requireConfirmation);
+ invokeAuthenticate(service, receiver, requireConfirmation, allowDeviceCredential);
waitForIdle();
startPendingAuthSession(mBiometricService);
@@ -720,20 +920,25 @@
}
private static void invokeAuthenticate(IBiometricService.Stub service,
- IBiometricServiceReceiver receiver, boolean requireConfirmation) throws Exception {
+ IBiometricServiceReceiver receiver, boolean requireConfirmation,
+ boolean allowDeviceCredential) throws Exception {
service.authenticate(
new Binder() /* token */,
0 /* sessionId */,
0 /* userId */,
receiver,
TEST_PACKAGE_NAME /* packageName */,
- createTestBiometricPromptBundle(requireConfirmation),
- null /* IBiometricConfirmDeviceCredentialCallback */);
+ createTestBiometricPromptBundle(requireConfirmation, allowDeviceCredential));
}
- private static Bundle createTestBiometricPromptBundle(boolean requireConfirmation) {
+ private static Bundle createTestBiometricPromptBundle(boolean requireConfirmation,
+ boolean allowDeviceCredential) {
final Bundle bundle = new Bundle();
bundle.putBoolean(BiometricPrompt.KEY_REQUIRE_CONFIRMATION, requireConfirmation);
+
+ if (allowDeviceCredential) {
+ bundle.putBoolean(BiometricPrompt.KEY_ALLOW_DEVICE_CREDENTIAL, true);
+ }
return bundle;
}
@@ -742,6 +947,11 @@
return session.mModalitiesMatched.values().iterator().next();
}
+ private static int getCookieForPendingSession(BiometricService.AuthSession session) {
+ assertEquals(session.mModalitiesWaiting.values().size(), 1);
+ return session.mModalitiesWaiting.values().iterator().next();
+ }
+
private static void waitForIdle() {
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
index 11bd29d..ad3e040 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -28,6 +28,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -114,6 +115,7 @@
}
@Test
+ @Ignore("b/120845532")
public void testSendMessage_notSuccess() {
mSendCecCommandSuccess = false;
mShouldDispatchReportArcTerminated = false;
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index a89198a..0a1899b 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -232,6 +232,7 @@
}
@Test
+ @Ignore("b/120845532")
public void handleGiveSystemAudioModeStatus_originalOff() throws Exception {
HdmiCecMessage expectedMessage =
HdmiCecMessageBuilder.buildReportSystemAudioMode(
@@ -301,6 +302,7 @@
}
@Test
+ @Ignore("b/120845532")
public void handleSetSystemAudioMode_setOn_orignalOff() throws Exception {
mMusicMute = true;
HdmiCecMessage messageSet =
@@ -328,6 +330,7 @@
}
@Test
+ @Ignore("b/120845532")
public void handleSystemAudioModeRequest_turnOffByTv() throws Exception {
assertThat(mMusicMute).isFalse();
// Check if feature correctly turned off
@@ -497,6 +500,7 @@
}
@Test
+ @Ignore("b/120845532")
public void handleRequestArcTerminate_arcIsNotOn() throws Exception {
assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse();
HdmiCecMessage message =
@@ -671,6 +675,7 @@
}
@Test
+ @Ignore("b/120845532")
public void handleReportPhysicalAddress_differentPath_addDevice() {
assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_ADD_DEVICE);
HdmiDeviceInfo oldDevice = new HdmiDeviceInfo(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index b8799c3..0062a17 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -99,6 +99,7 @@
}
@Test
+ @Ignore("b/120845532")
public void handleSetSystemAudioModeOn_audioSystemBroadcast() {
mHdmiControlService.setSystemAudioActivated(false);
assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
@@ -110,6 +111,7 @@
}
@Test
+ @Ignore("b/120845532")
public void handleSetSystemAudioModeOff_audioSystemToPlayback() {
mHdmiCecLocalDevicePlayback.mService.setSystemAudioActivated(true);
assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
@@ -123,6 +125,7 @@
}
@Test
+ @Ignore("b/120845532")
public void handleSystemAudioModeStatusOn_DirectltToLocalDeviceFromAudioSystem() {
mHdmiControlService.setSystemAudioActivated(false);
assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java
new file mode 100644
index 0000000..c6cf9b1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2019 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.server.hdmi;
+
+import static android.os.SystemClock.sleep;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
+import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.Assert.assertEquals;
+
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiPortInfo;
+import android.hardware.hdmi.IHdmiControlCallback;
+import android.os.Looper;
+import android.os.SystemProperties;
+import android.os.test.TestLooper;
+import android.util.Slog;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import java.util.ArrayList;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for {@link HdmiControlServiceBinderAPITest} class.
+ */
+@SmallTest
+@RunWith(JUnit4.class)
+public class HdmiControlServiceBinderAPITest {
+
+ private class HdmiCecLocalDeviceMyDevice extends HdmiCecLocalDevice {
+
+ private boolean mCanGoToStandby;
+ private boolean mIsStandby;
+ private boolean mIsDisabled;
+
+ protected HdmiCecLocalDeviceMyDevice(HdmiControlService service, int deviceType) {
+ super(service, deviceType);
+ }
+
+ @Override
+ protected void onAddressAllocated(int logicalAddress, int reason) {
+ }
+
+ @Override
+ protected int getPreferredAddress() {
+ return 0;
+ }
+
+ @Override
+ protected void setPreferredAddress(int addr) {
+ }
+
+ @Override
+ protected boolean canGoToStandby() {
+ return mCanGoToStandby;
+ }
+
+ @Override
+ protected void disableDevice(
+ boolean initiatedByCec, final PendingActionClearedCallback originalCallback) {
+ mIsDisabled = true;
+ originalCallback.onCleared(this);
+ }
+
+ @Override
+ protected void onStandby(boolean initiatedByCec, int standbyAction) {
+ mIsStandby = true;
+ }
+
+ protected boolean isStandby() {
+ return mIsStandby;
+ }
+
+ protected boolean isDisabled() {
+ return mIsDisabled;
+ }
+
+ protected void setCanGoToStandby(boolean canGoToStandby) {
+ mCanGoToStandby = canGoToStandby;
+ }
+ }
+
+ private static final String TAG = "HdmiControlServiceBinderAPITest";
+ private HdmiControlService mHdmiControlService;
+ private HdmiCecController mHdmiCecController;
+ private HdmiCecLocalDevicePlayback mPlaybackDevice;
+ private FakeNativeWrapper mNativeWrapper;
+ private Looper mMyLooper;
+ private TestLooper mTestLooper = new TestLooper();
+ private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
+ private HdmiPortInfo[] mHdmiPortInfo;
+ private int mResult;
+ private int mPowerStatus;
+
+ @Before
+ public void SetUp() {
+ mHdmiControlService =
+ new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
+ @Override
+ void sendCecCommand(HdmiCecMessage command) {
+ switch (command.getOpcode()) {
+ case Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS:
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildReportPowerStatus(
+ Constants.ADDR_TV,
+ Constants.ADDR_PLAYBACK_1,
+ HdmiControlManager.POWER_STATUS_ON);
+ handleCecCommand(message);
+ break;
+ default:
+ return;
+ }
+ }
+
+ @Override
+ boolean isPowerStandby() {
+ return mPowerStatus == HdmiControlManager.POWER_STATUS_STANDBY;
+ }
+ };
+ mMyLooper = mTestLooper.getLooper();
+
+ mPlaybackDevice = new HdmiCecLocalDevicePlayback(mHdmiControlService) {
+ @Override
+ void setIsActiveSource(boolean on) {
+ mIsActiveSource = on;
+ }
+
+ @Override
+ protected void wakeUpIfActiveSource() {}
+
+ @Override
+ protected void setPreferredAddress(int addr) {}
+
+ @Override
+ protected int getPreferredAddress() {
+ return Constants.ADDR_PLAYBACK_1;
+ }
+ };
+ mPlaybackDevice.init();
+
+ mHdmiControlService.setIoLooper(mMyLooper);
+
+ mNativeWrapper = new FakeNativeWrapper();
+ mHdmiCecController =
+ HdmiCecController.createWithNativeWrapper(mHdmiControlService, mNativeWrapper);
+ mHdmiControlService.setCecController(mHdmiCecController);
+ mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
+ mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
+
+ mLocalDevices.add(mPlaybackDevice);
+ mHdmiPortInfo = new HdmiPortInfo[1];
+ mHdmiPortInfo[0] =
+ new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x2100, true, false, false);
+ mNativeWrapper.setPortInfo(mHdmiPortInfo);
+ mHdmiControlService.initPortInfo();
+ mResult = -1;
+ mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
+
+ mTestLooper.dispatchAll();
+ }
+
+ @Test
+ public void oneTouchPlay_addressNotAllocated() {
+ assertThat(mHdmiControlService.isAddressAllocated()).isFalse();
+ mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
+ @Override
+ public void onComplete(int result) {
+ mResult = result;
+ }
+ });
+ assertEquals(mResult, -1);
+ assertThat(mPlaybackDevice.mIsActiveSource).isFalse();
+
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiControlService.isAddressAllocated()).isTrue();
+ assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS);
+ assertThat(mPlaybackDevice.mIsActiveSource).isTrue();
+ }
+
+ @Test
+ public void oneTouchPlay_addressAllocated() {
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiControlService.isAddressAllocated()).isTrue();
+ mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
+ @Override
+ public void onComplete(int result) {
+ mResult = result;
+ }
+ });
+ assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS);
+ assertThat(mPlaybackDevice.mIsActiveSource).isTrue();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
index 440a49a..6dcff35 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
@@ -221,6 +221,7 @@
}
@Test
+ @Ignore("b/120845532")
public void testTvSupport() {
resetTestVariables();
mShouldDispatchActiveSource = true;
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java
new file mode 100644
index 0000000..1cb2fb3
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 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.server.integrity.model;
+
+import static com.android.server.testutils.TestUtils.assertExpectException;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class AtomicFormulaTest {
+
+ @Test
+ public void testValidAtomicFormula_stringValue() {
+ AtomicFormula atomicFormula = new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME,
+ AtomicFormula.Operator.EQ, "com.test.app");
+
+ assertEquals(AtomicFormula.Key.PACKAGE_NAME, atomicFormula.getKey());
+ assertEquals(AtomicFormula.Operator.EQ, atomicFormula.getOperator());
+ assertEquals("com.test.app", atomicFormula.getStringValue());
+ }
+
+ @Test
+ public void testValidAtomicFormula_intValue() {
+ AtomicFormula atomicFormula = new AtomicFormula(AtomicFormula.Key.VERSION_CODE,
+ AtomicFormula.Operator.LE, 1);
+
+ assertEquals(AtomicFormula.Key.VERSION_CODE, atomicFormula.getKey());
+ assertEquals(AtomicFormula.Operator.LE, atomicFormula.getOperator());
+ assertEquals(1, atomicFormula.getIntValue().intValue());
+ }
+
+ @Test
+ public void testValidAtomicFormula_boolValue() {
+ AtomicFormula atomicFormula = new AtomicFormula(AtomicFormula.Key.PRE_INSTALLED,
+ AtomicFormula.Operator.EQ, true);
+
+ assertEquals(AtomicFormula.Key.PRE_INSTALLED, atomicFormula.getKey());
+ assertEquals(AtomicFormula.Operator.EQ, atomicFormula.getOperator());
+ assertEquals(true, atomicFormula.getBoolValue());
+ }
+
+ @Test
+ public void testInvalidAtomicFormula_stringValue() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Key %s cannot have string value", AtomicFormula.Key.VERSION_CODE),
+ () -> new AtomicFormula(AtomicFormula.Key.VERSION_CODE, AtomicFormula.Operator.EQ,
+ "test-value"));
+ }
+
+ @Test
+ public void testInvalidAtomicFormula_intValue() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Key %s cannot have integer value", AtomicFormula.Key.PACKAGE_NAME),
+ () -> new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ,
+ 1));
+ }
+
+ @Test
+ public void testInvalidAtomicFormula_boolValue() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Key %s cannot have boolean value", AtomicFormula.Key.PACKAGE_NAME),
+ () -> new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ,
+ true));
+ }
+
+ @Test
+ public void testValidateOperator_invalidKeyOperatorPair() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Invalid operator %s used for key %s",
+ AtomicFormula.Operator.LE, AtomicFormula.Key.PACKAGE_NAME),
+ () -> new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.LE,
+ "test-value"));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java
new file mode 100644
index 0000000..1a3dde0
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 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.server.integrity.model;
+
+import static com.android.server.testutils.TestUtils.assertExpectException;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class OpenFormulaTest {
+
+ private static final AtomicFormula ATOMIC_FORMULA_1 = new AtomicFormula(
+ AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ, "test1");
+ private static final AtomicFormula ATOMIC_FORMULA_2 = new AtomicFormula(
+ AtomicFormula.Key.VERSION_CODE, AtomicFormula.Operator.EQ, 1);
+
+ @Test
+ public void testValidOpenFormula() {
+ OpenFormula openFormula = new OpenFormula(OpenFormula.Connector.AND, ATOMIC_FORMULA_1,
+ ATOMIC_FORMULA_2);
+
+ assertEquals(OpenFormula.Connector.AND, openFormula.getConnector());
+ assertEquals(ATOMIC_FORMULA_1, openFormula.getMainFormula());
+ assertEquals(ATOMIC_FORMULA_2, openFormula.getAuxiliaryFormula());
+ }
+
+ @Test
+ public void testValidateAuxiliaryFormula_binaryConnectors() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Invalid formulas used for connector %s", OpenFormula.Connector.AND),
+ () -> new OpenFormula(OpenFormula.Connector.AND, ATOMIC_FORMULA_1,
+ null));
+ }
+
+ @Test
+ public void testValidateAuxiliaryFormula_unaryConnectors() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ /* expectedExceptionMessageRegex */
+ String.format("Invalid formulas used for connector %s", OpenFormula.Connector.NOT),
+ () -> new OpenFormula(OpenFormula.Connector.NOT, ATOMIC_FORMULA_1,
+ ATOMIC_FORMULA_2));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java
new file mode 100644
index 0000000..cf001be
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 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.server.integrity.model;
+
+import static com.android.server.testutils.TestUtils.assertExpectException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class RuleTest {
+
+ private static final Rule.Effect DENY_EFFECT = Rule.Effect.DENY;
+ private static final Formula SIMPLE_FORMULA =
+ new AtomicFormula(AtomicFormula.Key.PACKAGE_NAME, AtomicFormula.Operator.EQ,
+ "com.test.app");
+
+ @Test
+ public void testEmptyRule() {
+ Rule emptyRule = Rule.EMPTY;
+
+ assertNull(emptyRule.getFormula());
+ assertNull(emptyRule.getEffect());
+ }
+
+ @Test
+ public void testValidRule() {
+ Rule validRule = new Rule(SIMPLE_FORMULA, DENY_EFFECT);
+
+ assertEquals(SIMPLE_FORMULA, validRule.getFormula());
+ assertEquals(DENY_EFFECT, validRule.getEffect());
+ }
+
+ @Test
+ public void testInvalidRule_invalidEffect() {
+ assertExpectException(
+ NullPointerException.class,
+ /* expectedExceptionMessageRegex */ null,
+ () -> new Rule(SIMPLE_FORMULA, null));
+ }
+
+ @Test
+ public void testInvalidRule_invalidFormula() {
+ assertExpectException(
+ NullPointerException.class,
+ /* expectedExceptionMessageRegex */ null,
+ () -> new Rule(null, DENY_EFFECT));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index 7cece1f..f9ac022 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -32,8 +32,11 @@
import android.app.admin.DeviceStateCache;
import android.app.trust.TrustManager;
import android.content.ComponentName;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.hardware.authsecret.V1_0.IAuthSecret;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.FileUtils;
import android.os.IProgressListener;
import android.os.RemoteException;
@@ -95,6 +98,9 @@
RecoverableKeyStoreManager mRecoverableKeyStoreManager;
UserManagerInternal mUserManagerInternal;
DeviceStateCache mDeviceStateCache;
+ FingerprintManager mFingerprintManager;
+ FaceManager mFaceManager;
+ PackageManager mPackageManager;
protected boolean mHasSecureLockScreen;
@Override
@@ -114,6 +120,9 @@
mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class);
mUserManagerInternal = mock(UserManagerInternal.class);
mDeviceStateCache = mock(DeviceStateCache.class);
+ mFingerprintManager = mock(FingerprintManager.class);
+ mFaceManager = mock(FaceManager.class);
+ mPackageManager = mock(PackageManager.class);
LocalServices.removeServiceForTest(LockSettingsInternal.class);
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
@@ -123,7 +132,7 @@
mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class),
- mock(KeyguardManager.class));
+ mock(KeyguardManager.class), mFingerprintManager, mFaceManager, mPackageManager);
mStorage = new LockSettingsStorageTestable(mContext,
new File(getContext().getFilesDir(), "locksettings"));
File storageDir = mStorage.mStorageDir;
@@ -181,6 +190,8 @@
new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
when(mUserManagerInternal.isDeviceManaged()).thenReturn(true);
when(mDeviceStateCache.isDeviceProvisioned()).thenReturn(true);
+ mockBiometricsHardwareFingerprintsAndTemplates(PRIMARY_USER_ID);
+ mockBiometricsHardwareFingerprintsAndTemplates(MANAGED_PROFILE_USER_ID);
mLocalService = LocalServices.getService(LockSettingsInternal.class);
}
@@ -233,6 +244,18 @@
return sm;
}
+ private void mockBiometricsHardwareFingerprintsAndTemplates(int userId) {
+ // Hardware must be detected and fingerprints must be enrolled
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
+ when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+ when(mFingerprintManager.hasEnrolledFingerprints(userId)).thenReturn(true);
+
+ // Hardware must be detected and templates must be enrolled
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
+ when(mFaceManager.isHardwareDetected()).thenReturn(true);
+ when(mFaceManager.hasEnrolledTemplates(userId)).thenReturn(true);
+ }
+
@Override
protected void tearDown() throws Exception {
super.tearDown();
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 65d6f45..fcd98e0 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -23,7 +23,6 @@
import android.content.Context;
import android.hardware.authsecret.V1_0.IAuthSecret;
import android.os.Handler;
-import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserManagerInternal;
@@ -32,6 +31,7 @@
import android.security.keystore.KeyPermanentlyInvalidatedException;
import com.android.internal.widget.LockPatternUtils;
+import com.android.server.ServiceThread;
import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
import java.io.FileNotFoundException;
@@ -70,8 +70,8 @@
}
@Override
- public Handler getHandler() {
- return new Handler(Looper.getMainLooper());
+ public Handler getHandler(ServiceThread handlerThread) {
+ return new Handler(handlerThread.getLooper());
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 7354ad4..5818133 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -330,6 +330,27 @@
.lockScreenSecretChanged(CREDENTIAL_TYPE_NONE, null, MANAGED_PROFILE_USER_ID);
}
+ public void testSetLockCredential_nullCredential_removeBiometrics() throws RemoteException {
+ final String oldCredential = "oldPassword";
+
+ initializeStorageWithCredential(
+ PRIMARY_USER_ID,
+ oldCredential,
+ CREDENTIAL_TYPE_PATTERN,
+ PASSWORD_QUALITY_SOMETHING);
+ mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+
+ mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, oldCredential.getBytes(),
+ PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
+
+ // Verify fingerprint is removed
+ verify(mFingerprintManager).remove(any(), eq(PRIMARY_USER_ID), any());
+ verify(mFaceManager).remove(any(), eq(PRIMARY_USER_ID), any());
+
+ verify(mFingerprintManager).remove(any(), eq(MANAGED_PROFILE_USER_ID), any());
+ verify(mFaceManager).remove(any(), eq(MANAGED_PROFILE_USER_ID), any());
+ }
+
public void testSetLockCredential_forUnifiedToSeparateChallengeProfile_sendsNewCredentials()
throws Exception {
final String parentPassword = "parentPassword";
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
index 8e0d7be..2a169b7 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -24,8 +24,11 @@
import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.database.sqlite.SQLiteDatabase;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.FileUtils;
import android.os.SystemClock;
import android.os.UserManager;
@@ -86,7 +89,9 @@
MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
mock(NotificationManager.class), mock(DevicePolicyManager.class),
- mock(StorageManager.class), mock(TrustManager.class), mock(KeyguardManager.class));
+ mock(StorageManager.class), mock(TrustManager.class), mock(KeyguardManager.class),
+ mock(FingerprintManager.class), mock(FaceManager.class),
+ mock(PackageManager.class));
mStorage = new LockSettingsStorageTestable(context,
new File(getContext().getFilesDir(), "locksettings"));
mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
index b332532..2b9a05c 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
@@ -23,6 +23,8 @@
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.UserManager;
import android.os.storage.StorageManager;
@@ -34,11 +36,15 @@
private StorageManager mStorageManager;
private TrustManager mTrustManager;
private KeyguardManager mKeyguardManager;
+ private FingerprintManager mFingerprintManager;
+ private FaceManager mFaceManager;
+ private PackageManager mPackageManager;
public MockLockSettingsContext(Context base, UserManager userManager,
NotificationManager notificationManager, DevicePolicyManager devicePolicyManager,
StorageManager storageManager, TrustManager trustManager,
- KeyguardManager keyguardManager) {
+ KeyguardManager keyguardManager, FingerprintManager fingerprintManager,
+ FaceManager faceManager, PackageManager packageManager) {
super(base);
mUserManager = userManager;
mNotificationManager = notificationManager;
@@ -46,6 +52,9 @@
mStorageManager = storageManager;
mTrustManager = trustManager;
mKeyguardManager = keyguardManager;
+ mFingerprintManager = fingerprintManager;
+ mFaceManager = faceManager;
+ mPackageManager = packageManager;
}
@Override
@@ -62,12 +71,21 @@
return mTrustManager;
} else if (KEYGUARD_SERVICE.equals(name)) {
return mKeyguardManager;
+ } else if (FINGERPRINT_SERVICE.equals(name)) {
+ return mFingerprintManager;
+ } else if (FACE_SERVICE.equals(name)) {
+ return mFaceManager;
} else {
throw new RuntimeException("System service not mocked: " + name);
}
}
@Override
+ public PackageManager getPackageManager() {
+ return mPackageManager;
+ }
+
+ @Override
public void enforceCallingOrSelfPermission(String permission, String message) {
// Skip permission checks for unit tests.
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
index 806c71a..6d5b994 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
@@ -132,6 +132,7 @@
user.profileBadge = 2;
user.partial = true;
user.guestToRemove = true;
+ user.preCreated = true;
return user;
}
@@ -147,5 +148,6 @@
assertEquals("profile badge not preseved", one.profileBadge, two.profileBadge);
assertEquals("partial not preseved", one.partial, two.partial);
assertEquals("guestToRemove not preseved", one.guestToRemove, two.guestToRemove);
+ assertEquals("preCreated not preseved", one.preCreated, two.preCreated);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java
new file mode 100644
index 0000000..ee3b15a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2019 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.server.rollback;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.pm.VersionedPackage;
+import android.content.rollback.PackageRollbackInfo;
+import android.util.IntArray;
+import android.util.SparseLongArray;
+
+import com.google.common.truth.Correspondence;
+
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.File;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+@RunWith(JUnit4.class)
+public class RollbackStoreTest {
+
+ private static final int ID = 123;
+
+ private static final Correspondence<VersionedPackage, VersionedPackage> VER_PKG_CORR =
+ new Correspondence<VersionedPackage, VersionedPackage>() {
+ @Override
+ public boolean compare(VersionedPackage a, VersionedPackage b) {
+ if (a == null || b == null) {
+ return a == b;
+ }
+ return a.getLongVersionCode() == b.getLongVersionCode()
+ && Objects.equals(a.getPackageName(), b.getPackageName());
+ }
+
+ @Override
+ public String toString() {
+ return "is the same as";
+ }
+ };
+
+ private static final Correspondence<PackageRollbackInfo.RestoreInfo,
+ PackageRollbackInfo.RestoreInfo>
+ RESTORE_INFO_CORR =
+ new Correspondence<PackageRollbackInfo.RestoreInfo, PackageRollbackInfo.RestoreInfo>() {
+ @Override
+ public boolean compare(PackageRollbackInfo.RestoreInfo a,
+ PackageRollbackInfo.RestoreInfo b) {
+ if (a == null || b == null) {
+ return a == b;
+ }
+ return a.userId == b.userId
+ && a.appId == b.appId
+ && Objects.equals(a.seInfo, b.seInfo);
+ }
+
+ @Override
+ public String toString() {
+ return "is the same as";
+ }
+ };
+
+ private static final String JSON_ROLLBACK = "{'info':{'rollbackId':123,'packages':"
+ + "[{'versionRolledBackFrom':{'packageName':'blah','longVersionCode':55},"
+ + "'versionRolledBackTo':{'packageName':'blah1','longVersionCode':50},'pendingBackups':"
+ + "[59,1245,124544],'pendingRestores':[{'userId':498,'appId':32322,'seInfo':'wombles'},"
+ + "{'userId':-895,'appId':1,'seInfo':'pingu'}],'isApex':false,'installedUsers':"
+ + "[498468432,1111,98464],'ceSnapshotInodes':[{'userId':1,'ceSnapshotInode':-6},"
+ + "{'userId':2222,'ceSnapshotInode':81641654445},{'userId':546546,"
+ + "'ceSnapshotInode':345689375}]},{'versionRolledBackFrom':{'packageName':'chips',"
+ + "'longVersionCode':28},'versionRolledBackTo':{'packageName':'com.chips.test',"
+ + "'longVersionCode':48},'pendingBackups':[5],'pendingRestores':[{'userId':18,"
+ + "'appId':-12,'seInfo':''}],'isApex':false,'installedUsers':[55,79],"
+ + "'ceSnapshotInodes':[]}],'isStaged':false,'causePackages':[{'packageName':'hello',"
+ + "'longVersionCode':23},{'packageName':'something','longVersionCode':999}],"
+ + "'committedSessionId':45654465},'timestamp':'2019-10-01T12:29:08.855Z',"
+ + "'stagedSessionId':-1,'state':'enabling','apkSessionId':-1,"
+ + "'restoreUserDataInProgress':true}";
+
+ @Rule
+ public TemporaryFolder mFolder = new TemporaryFolder();
+
+ private File mRollbackDir;
+
+ private RollbackStore mRollbackStore;
+
+ @Before
+ public void setUp() throws Exception {
+ mRollbackStore = new RollbackStore(mFolder.getRoot());
+ mRollbackDir = mFolder.newFolder(ID + "");
+ mFolder.newFile("rollback.json");
+ }
+
+ @Test
+ public void createNonStaged() {
+ Rollback rollback = mRollbackStore.createNonStagedRollback(ID);
+
+ assertThat(rollback.getBackupDir().getAbsolutePath())
+ .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID);
+
+ assertThat(rollback.isStaged()).isFalse();
+ assertThat(rollback.info.getRollbackId()).isEqualTo(ID);
+ assertThat(rollback.info.getPackages()).isEmpty();
+ assertThat(rollback.isEnabling()).isTrue();
+ }
+
+ @Test
+ public void createStaged() {
+ Rollback rollback = mRollbackStore.createStagedRollback(ID, 897);
+
+ assertThat(rollback.getBackupDir().getAbsolutePath())
+ .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID);
+
+ assertThat(rollback.isStaged()).isTrue();
+ assertThat(rollback.getStagedSessionId()).isEqualTo(897);
+
+ assertThat(rollback.info.getRollbackId()).isEqualTo(ID);
+ assertThat(rollback.info.getPackages()).isEmpty();
+ assertThat(rollback.isEnabling()).isTrue();
+ }
+
+ @Test
+ public void saveAndLoadRollback() {
+ Rollback origRb = mRollbackStore.createNonStagedRollback(ID);
+
+ origRb.setRestoreUserDataInProgress(true);
+ origRb.info.getCausePackages().add(new VersionedPackage("com.made.up", 2));
+ origRb.info.getCausePackages().add(new VersionedPackage("com.pack.age", 99));
+ origRb.info.setCommittedSessionId(123456);
+
+ PackageRollbackInfo pkgInfo1 =
+ new PackageRollbackInfo(new VersionedPackage("com.made.up", 18),
+ new VersionedPackage("com.something.else", 5), new IntArray(),
+ new ArrayList<>(), false, new IntArray(), new SparseLongArray());
+ pkgInfo1.getPendingBackups().add(8);
+ pkgInfo1.getPendingBackups().add(888);
+ pkgInfo1.getPendingBackups().add(88885);
+ pkgInfo1.getCeSnapshotInodes().put(12, 424);
+ pkgInfo1.getCeSnapshotInodes().put(222772, 10000000000L);
+ pkgInfo1.getCeSnapshotInodes().put(10, -67);
+
+ pkgInfo1.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(4980, 3442322, "seInfo"));
+ pkgInfo1.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(-89, 15, "otherSeInfo"));
+
+ pkgInfo1.getSnapshottedUsers().add(11);
+ pkgInfo1.getSnapshottedUsers().add(1);
+ pkgInfo1.getSnapshottedUsers().add(0);
+
+ PackageRollbackInfo pkgInfo2 = new PackageRollbackInfo(
+ new VersionedPackage("another.package", 2),
+ new VersionedPackage("com.test.ing", 48888), new IntArray(), new ArrayList<>(),
+ false, new IntArray(), new SparseLongArray());
+ pkgInfo2.getPendingBackups().add(57);
+
+ pkgInfo2.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(180, -120, ""));
+
+ origRb.info.getPackages().add(pkgInfo1);
+ origRb.info.getPackages().add(pkgInfo2);
+
+ RollbackStore.saveRollback(origRb);
+
+ List<Rollback> loadedRollbacks = mRollbackStore.loadRollbacks();
+ assertThat(loadedRollbacks).hasSize(1);
+ Rollback loadedRb = loadedRollbacks.get(0);
+
+ assertRollbacksAreEquivalent(loadedRb, origRb);
+ }
+
+ @Test
+ public void loadFromJson() throws Exception {
+ Rollback expectedRb = mRollbackStore.createNonStagedRollback(ID);
+
+ expectedRb.setTimestamp(Instant.parse("2019-10-01T12:29:08.855Z"));
+ expectedRb.setRestoreUserDataInProgress(true);
+ expectedRb.info.getCausePackages().add(new VersionedPackage("hello", 23));
+ expectedRb.info.getCausePackages().add(new VersionedPackage("something", 999));
+ expectedRb.info.setCommittedSessionId(45654465);
+
+ PackageRollbackInfo pkgInfo1 = new PackageRollbackInfo(new VersionedPackage("blah", 55),
+ new VersionedPackage("blah1", 50), new IntArray(), new ArrayList<>(),
+ false, new IntArray(), new SparseLongArray());
+ pkgInfo1.getPendingBackups().add(59);
+ pkgInfo1.getPendingBackups().add(1245);
+ pkgInfo1.getPendingBackups().add(124544);
+ pkgInfo1.getCeSnapshotInodes().put(546546, 345689375);
+ pkgInfo1.getCeSnapshotInodes().put(2222, 81641654445L);
+ pkgInfo1.getCeSnapshotInodes().put(1, -6);
+
+ pkgInfo1.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(498, 32322, "wombles"));
+ pkgInfo1.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(-895, 1, "pingu"));
+
+ pkgInfo1.getSnapshottedUsers().add(498468432);
+ pkgInfo1.getSnapshottedUsers().add(1111);
+ pkgInfo1.getSnapshottedUsers().add(98464);
+
+ PackageRollbackInfo pkgInfo2 = new PackageRollbackInfo(new VersionedPackage("chips", 28),
+ new VersionedPackage("com.chips.test", 48), new IntArray(), new ArrayList<>(),
+ false, new IntArray(), new SparseLongArray());
+ pkgInfo2.getPendingBackups().add(5);
+
+ pkgInfo2.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(18, -12, ""));
+
+ pkgInfo2.getSnapshottedUsers().add(55);
+ pkgInfo2.getSnapshottedUsers().add(79);
+
+ expectedRb.info.getPackages().add(pkgInfo1);
+ expectedRb.info.getPackages().add(pkgInfo2);
+
+ Rollback parsedRb = RollbackStore.rollbackFromJson(
+ new JSONObject(JSON_ROLLBACK), expectedRb.getBackupDir());
+
+ assertRollbacksAreEquivalent(parsedRb, expectedRb);
+ }
+
+ @Test
+ public void saveAndDelete() {
+ Rollback rollback = mRollbackStore.createNonStagedRollback(ID);
+
+ RollbackStore.saveRollback(rollback);
+
+ File expectedFile = new File(mRollbackDir.getAbsolutePath() + "/rollback.json");
+
+ assertThat(expectedFile.exists()).isTrue();
+
+ RollbackStore.deleteRollback(rollback);
+
+ assertThat(expectedFile.exists()).isFalse();
+ }
+
+ private void assertRollbacksAreEquivalent(Rollback b, Rollback a) {
+ assertThat(b.info.getRollbackId()).isEqualTo(ID);
+
+ assertThat(b.getBackupDir()).isEqualTo(a.getBackupDir());
+
+ assertThat(b.isRestoreUserDataInProgress())
+ .isEqualTo(a.isRestoreUserDataInProgress());
+
+ assertThat(b.getTimestamp()).isEqualTo(a.getTimestamp());
+
+ assertThat(b.isEnabling()).isEqualTo(a.isEnabling());
+ assertThat(b.isAvailable()).isEqualTo(a.isAvailable());
+ assertThat(b.isCommitted()).isEqualTo(a.isCommitted());
+
+ assertThat(b.isStaged()).isEqualTo(a.isStaged());
+
+ assertThat(b.getApexPackageNames())
+ .containsExactlyElementsIn(a.getApexPackageNames());
+
+ assertThat(b.getStagedSessionId()).isEqualTo(a.getStagedSessionId());
+
+ assertThat(b.info.getCommittedSessionId()).isEqualTo(a.info.getCommittedSessionId());
+
+ assertThat(b.info.getCausePackages()).comparingElementsUsing(VER_PKG_CORR)
+ .containsExactlyElementsIn(a.info.getCausePackages());
+
+ assertThat(b.info.getPackages()).hasSize(a.info.getPackages().size());
+
+ for (int i = 0; i < b.info.getPackages().size(); i++) {
+ assertPackageRollbacksAreEquivalent(
+ b.info.getPackages().get(i), a.info.getPackages().get(i));
+ }
+ }
+
+ private void assertPackageRollbacksAreEquivalent(PackageRollbackInfo b, PackageRollbackInfo a) {
+ assertThat(b.getPackageName()).isEqualTo(a.getPackageName());
+
+ assertThat(b.getVersionRolledBackFrom().getLongVersionCode())
+ .isEqualTo(a.getVersionRolledBackFrom().getLongVersionCode());
+ assertThat(b.getVersionRolledBackFrom().getPackageName())
+ .isEqualTo(a.getVersionRolledBackFrom().getPackageName());
+
+ assertThat(b.getVersionRolledBackTo().getLongVersionCode())
+ .isEqualTo(a.getVersionRolledBackTo().getLongVersionCode());
+ assertThat(b.getVersionRolledBackTo().getPackageName())
+ .isEqualTo(a.getVersionRolledBackTo().getPackageName());
+
+ assertThat(b.getPendingBackups().toArray()).isEqualTo(a.getPendingBackups().toArray());
+
+ assertThat(b.getPendingRestores()).comparingElementsUsing(RESTORE_INFO_CORR)
+ .containsExactlyElementsIn(a.getPendingRestores());
+
+ assertThat(b.isApex()).isEqualTo(a.isApex());
+
+ assertThat(b.getSnapshottedUsers().toArray()).isEqualTo(a.getSnapshottedUsers().toArray());
+
+ assertThat(b.getCeSnapshotInodes().toString())
+ .isEqualTo(a.getCeSnapshotInodes().toString());
+ }
+
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
old mode 100644
new mode 100755
index 2de8d05..2072ee5
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -44,6 +44,7 @@
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION_CODES.O_MR1;
import static android.os.Build.VERSION_CODES.P;
+import static android.os.UserHandle.USER_SYSTEM;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
@@ -129,6 +130,7 @@
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.testing.TestablePermissions;
+import android.testing.TestableResources;
import android.text.Html;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -3278,7 +3280,7 @@
@Test
public void testRestore() throws Exception {
int systemChecks = mService.countSystemChecks;
- mBinderService.applyRestore(null, UserHandle.USER_SYSTEM);
+ mBinderService.applyRestore(null, USER_SYSTEM);
assertEquals(1, mService.countSystemChecks - systemChecks);
}
@@ -3347,7 +3349,7 @@
reset(mUgmInternal);
when(mUgmInternal.newUriPermissionOwner(any())).thenReturn(new Binder());
mService.updateUriPermissions(recordA, null, mContext.getPackageName(),
- UserHandle.USER_SYSTEM);
+ USER_SYSTEM);
verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
@@ -3363,21 +3365,21 @@
// Update means we drop access to first
reset(mUgmInternal);
mService.updateUriPermissions(recordB, recordA, mContext.getPackageName(),
- UserHandle.USER_SYSTEM);
+ USER_SYSTEM);
verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(),
eq(message1.getDataUri()), anyInt(), anyInt());
// Update back means we grant access to first again
reset(mUgm);
mService.updateUriPermissions(recordA, recordB, mContext.getPackageName(),
- UserHandle.USER_SYSTEM);
+ USER_SYSTEM);
verify(mUgm, times(1)).grantUriPermissionFromOwner(any(), anyInt(), any(),
eq(message1.getDataUri()), anyInt(), anyInt(), anyInt());
// And update to empty means we drop everything
reset(mUgmInternal);
mService.updateUriPermissions(null, recordB, mContext.getPackageName(),
- UserHandle.USER_SYSTEM);
+ USER_SYSTEM);
verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(), eq(null),
anyInt(), anyInt());
}
@@ -3864,7 +3866,9 @@
mService.simulatePackageDistractionBroadcast(
PackageManager.RESTRICTION_HIDE_NOTIFICATIONS, new String[] {"a", "b"});
ArgumentCaptor<List<NotificationRecord>> captorHide = ArgumentCaptor.forClass(List.class);
- verify(mListeners, times(2)).notifyHiddenLocked(captorHide.capture());
+
+ // should be called only once.
+ verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
assertEquals(2, captorHide.getValue().size());
assertEquals("a", captorHide.getValue().get(0).sbn.getPackageName());
assertEquals("b", captorHide.getValue().get(1).sbn.getPackageName());
@@ -3873,7 +3877,9 @@
mService.simulatePackageDistractionBroadcast(
PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS, new String[] {"a", "b"});
ArgumentCaptor<List<NotificationRecord>> captorUnhide = ArgumentCaptor.forClass(List.class);
- verify(mListeners, times(2)).notifyUnhiddenLocked(captorUnhide.capture());
+
+ // should be called only once.
+ verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
assertEquals(2, captorUnhide.getValue().size());
assertEquals("a", captorUnhide.getValue().get(0).sbn.getPackageName());
assertEquals("b", captorUnhide.getValue().get(1).sbn.getPackageName());
@@ -4073,7 +4079,7 @@
public void testIsCallerInstantApp_userAllNotification() throws Exception {
ApplicationInfo info = new ApplicationInfo();
info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
- when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(UserHandle.USER_SYSTEM)))
+ when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(USER_SYSTEM)))
.thenReturn(info);
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{"any"});
@@ -5662,4 +5668,33 @@
StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
assertEquals(1, notifsAfter.length);
}
+
+ @Test
+ public void testLoadDefaultApprovedServices_emptyResources() {
+ TestableResources tr = mContext.getOrCreateTestableResources();
+ tr.addOverride(com.android.internal.R.string.config_defaultListenerAccessPackages, "");
+ tr.addOverride(com.android.internal.R.string.config_defaultDndAccessPackages, "");
+ tr.addOverride(com.android.internal.R.string.config_defaultAssistantAccessComponent, "");
+ setDefaultAssistantInDeviceConfig("");
+
+ mService.loadDefaultApprovedServices(USER_SYSTEM);
+
+ verify(mListeners, never()).addDefaultComponentOrPackage(anyString());
+ verify(mConditionProviders, never()).addDefaultComponentOrPackage(anyString());
+ verify(mAssistants, never()).addDefaultComponentOrPackage(anyString());
+ }
+
+ @Test
+ public void testLoadDefaultApprovedServices_dnd() {
+ TestableResources tr = mContext.getOrCreateTestableResources();
+ tr.addOverride(com.android.internal.R.string.config_defaultDndAccessPackages, "test");
+ when(mListeners.queryPackageForServices(anyString(), anyInt(), anyInt()))
+ .thenReturn(new ArraySet<>());
+
+ mService.loadDefaultApprovedServices(USER_SYSTEM);
+
+ verify(mConditionProviders, times(1)).addDefaultComponentOrPackage("test");
+ }
+
+ // TODO: add tests for the rest of the non-empty cases
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index 6c78f6f..69cc9b2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -24,11 +24,9 @@
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.clearInvocations;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
@@ -49,6 +47,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
@@ -62,6 +61,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class ActivityDisplayTests extends ActivityTestsBase {
@Test
@@ -142,30 +142,24 @@
// Create a display which supports system decoration and allows reparenting stacks to
// another display when the display is removed.
final ActivityDisplay display = createNewActivityDisplay();
- spyOn(display);
doReturn(false).when(display).shouldDestroyContentOnRemove();
doReturn(true).when(display).supportsSystemDecorations();
mRootActivityContainer.addChild(display, ActivityDisplay.POSITION_TOP);
// Put home stack on the display.
- final ActivityStack homeStack = display.createStack(
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
- final TaskRecord task = new TaskBuilder(mSupervisor).setStack(homeStack).build();
- new ActivityBuilder(mService).setTask(task).build();
- display.removeChild(homeStack);
- final ActivityStack spiedHomeStack = spy(homeStack);
- display.addChild(spiedHomeStack, ActivityDisplay.POSITION_TOP);
- reset(spiedHomeStack);
+ final ActivityStack homeStack = new StackBuilder(mRootActivityContainer)
+ .setDisplay(display).setActivityType(ACTIVITY_TYPE_HOME).build();
// Put a finishing standard activity which will be reparented.
final ActivityStack stack = createFullscreenStackWithSimpleActivityAt(display);
stack.topRunningActivityLocked().makeFinishingLocked();
+ clearInvocations(homeStack);
display.remove();
// The removed display should have no focused stack and its home stack should never resume.
assertNull(display.getFocusedStack());
- verify(spiedHomeStack, never()).resumeTopActivityUncheckedLocked(any(), any());
+ verify(homeStack, never()).resumeTopActivityUncheckedLocked(any(), any());
}
private ActivityStack createFullscreenStackWithSimpleActivityAt(ActivityDisplay display) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 30c8eb3..bf1508a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -103,8 +103,6 @@
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
-import java.util.concurrent.TimeUnit;
-
/**
* Tests for the {@link ActivityRecord} class.
*
@@ -289,22 +287,6 @@
}
@Test
- public void testNotifiesSeqIncrementToAppToken() {
- final Configuration appWindowTokenRequestedOrientation = mock(Configuration.class);
- mActivity.mAppWindowToken = mock(AppWindowToken.class);
- doReturn(appWindowTokenRequestedOrientation).when(mActivity.mAppWindowToken)
- .getRequestedOverrideConfiguration();
-
- final Configuration newConfig = new Configuration();
- newConfig.orientation = ORIENTATION_PORTRAIT;
-
- final int prevSeq = mActivity.getMergedOverrideConfiguration().seq;
- mActivity.onRequestedOverrideConfigurationChanged(newConfig);
- assertEquals(prevSeq + 1, appWindowTokenRequestedOrientation.seq);
- verify(mActivity.mAppWindowToken).onMergedOverrideConfigurationChanged();
- }
-
- @Test
public void testSetsRelaunchReason_NotDragResizing() {
mActivity.setState(ActivityStack.ActivityState.RESUMED, "Testing");
@@ -521,7 +503,7 @@
anyInt() /* height */, any() /* displayCutout */, any() /* outInsets */);
doReturn(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
- .when(mActivity.mAppWindowToken).getOrientationIgnoreVisibility();
+ .when(mActivity).getRequestedOrientation();
mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
mActivity.info.minAspectRatio = mActivity.info.maxAspectRatio = 1;
ensureActivityConfiguration();
@@ -573,7 +555,7 @@
// Move the non-resizable activity to the new display.
mStack.reparent(newDisplay, true /* onTop */, false /* displayRemoved */);
- assertEquals(originalBounds, mActivity.getBounds());
+ assertEquals(originalBounds, mActivity.getWindowConfiguration().getBounds());
assertEquals(originalDpi, mActivity.getConfiguration().densityDpi);
assertTrue(mActivity.inSizeCompatMode());
}
@@ -581,7 +563,7 @@
@Test
public void testSizeCompatMode_FixedScreenBoundsWhenDisplaySizeChanged() {
setupDisplayContentForCompatDisplayInsets();
- when(mActivity.mAppWindowToken.getOrientationIgnoreVisibility()).thenReturn(
+ when(mActivity.getRequestedOrientation()).thenReturn(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
mTask.getWindowConfiguration().setAppBounds(mStack.getDisplay().getBounds());
mTask.getConfiguration().orientation = ORIENTATION_PORTRAIT;
@@ -594,7 +576,7 @@
setupDisplayAndParentSize(1000, 2000);
ensureActivityConfiguration();
- assertEquals(originalBounds, mActivity.getBounds());
+ assertEquals(originalBounds, mActivity.getWindowConfiguration().getBounds());
assertTrue(mActivity.inSizeCompatMode());
}
@@ -629,7 +611,7 @@
mActivity.visible = false;
mActivity.app.setReportedProcState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY);
// Make the parent bounds to be different so the activity is in size compatibility mode.
- mTask.getWindowConfiguration().setAppBounds(new Rect(0, 0, 600, 1200));
+ setupDisplayAndParentSize(600, 1200);
// Simulate the display changes orientation.
doReturn(ActivityInfo.CONFIG_SCREEN_SIZE | CONFIG_ORIENTATION
@@ -646,7 +628,7 @@
// The override configuration should be reset and the activity's process will be killed.
assertFalse(mActivity.inSizeCompatMode());
verify(mActivity).restartProcessIfVisible();
- mLockRule.runWithScissors(mService.mH, () -> { }, TimeUnit.SECONDS.toMillis(3));
+ waitHandlerIdle(mService.mH);
verify(mService.mAmInternal).killProcess(
eq(mActivity.app.mName), eq(mActivity.app.mUid), anyString());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index 9583b8ac..9e1df91 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -44,6 +44,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for the {@link ActivityStackSupervisor} class.
@@ -53,6 +54,7 @@
*/
@MediumTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class ActivityStackSupervisorTests extends ActivityTestsBase {
private ActivityStack mFullscreenStack;
@@ -79,32 +81,28 @@
/**
* Ensures that waiting results are notified of launches.
*/
- @SuppressWarnings("SynchronizeOnNonFinalField")
@Test
public void testReportWaitingActivityLaunchedIfNeeded() {
final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
.setStack(mFullscreenStack).build();
- // #notifyAll will be called on the ActivityManagerService. we must hold the object lock
- // when this happens.
- synchronized (mService.mGlobalLock) {
- final WaitResult taskToFrontWait = new WaitResult();
- mSupervisor.mWaitingActivityLaunched.add(taskToFrontWait);
- mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity, START_TASK_TO_FRONT);
+ final WaitResult taskToFrontWait = new WaitResult();
+ mSupervisor.mWaitingActivityLaunched.add(taskToFrontWait);
+ // #notifyAll will be called on the ActivityTaskManagerService#mGlobalLock. The lock is hold
+ // implicitly by WindowManagerGlobalLockRule.
+ mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity, START_TASK_TO_FRONT);
- assertThat(mSupervisor.mWaitingActivityLaunched).isEmpty();
- assertEquals(taskToFrontWait.result, START_TASK_TO_FRONT);
- assertNull(taskToFrontWait.who);
+ assertThat(mSupervisor.mWaitingActivityLaunched).isEmpty();
+ assertEquals(taskToFrontWait.result, START_TASK_TO_FRONT);
+ assertNull(taskToFrontWait.who);
- final WaitResult deliverToTopWait = new WaitResult();
- mSupervisor.mWaitingActivityLaunched.add(deliverToTopWait);
- mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity,
- START_DELIVERED_TO_TOP);
+ final WaitResult deliverToTopWait = new WaitResult();
+ mSupervisor.mWaitingActivityLaunched.add(deliverToTopWait);
+ mSupervisor.reportWaitingActivityLaunchedIfNeeded(firstActivity, START_DELIVERED_TO_TOP);
- assertThat(mSupervisor.mWaitingActivityLaunched).isEmpty();
- assertEquals(deliverToTopWait.result, START_DELIVERED_TO_TOP);
- assertEquals(deliverToTopWait.who, firstActivity.mActivityComponent);
- }
+ assertThat(mSupervisor.mWaitingActivityLaunched).isEmpty();
+ assertEquals(deliverToTopWait.result, START_DELIVERED_TO_TOP);
+ assertEquals(deliverToTopWait.who, firstActivity.mActivityComponent);
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 2a8b4c8..c2a05c24 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -67,6 +67,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for the {@link ActivityStack} class.
@@ -76,6 +77,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class ActivityStackTests extends ActivityTestsBase {
private ActivityDisplay mDefaultDisplay;
private ActivityStack mStack;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
index a7bbe6e..11aac3c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
@@ -38,6 +38,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Random;
@@ -49,6 +50,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class ActivityStartControllerTests extends ActivityTestsBase {
private ActivityStartController mController;
private Factory mFactory;
@@ -71,7 +73,9 @@
final Random random = new Random();
final ActivityRecord activity = new ActivityBuilder(mService).build();
- final ActivityRecord source = new ActivityBuilder(mService).build();
+ final ActivityRecord source = new ActivityBuilder(mService)
+ .setCreateTask(true)
+ .build();
final int startFlags = random.nextInt();
final ActivityStack stack = mService.mRootActivityContainer.getDefaultDisplay().createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 1f672c0..8a9423a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -57,6 +57,7 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyObject;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import android.app.ActivityOptions;
@@ -368,6 +369,7 @@
doReturn(false).when(mockPackageManager).isPermissionsReviewRequired(any(), anyInt());
doNothing().when(mockPackageManager).grantImplicitAccess(
anyInt(), any(), anyInt(), anyInt());
+ doNothing().when(mockPackageManager).notifyPackageUse(anyString(), anyInt());
final Intent intent = new Intent();
intent.addFlags(launchFlags);
@@ -753,7 +755,7 @@
false /* mockGetLaunchStack */);
// Create a secondary display at bottom.
- final TestActivityDisplay secondaryDisplay = spy(createNewActivityDisplay());
+ final TestActivityDisplay secondaryDisplay = createNewActivityDisplay();
mRootActivityContainer.addChild(secondaryDisplay, POSITION_BOTTOM);
final ActivityStack stack = secondaryDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_STANDARD, true /* onTop */);
@@ -791,7 +793,7 @@
false /* mockGetLaunchStack */);
// Create a secondary display with an activity.
- final TestActivityDisplay secondaryDisplay = spy(createNewActivityDisplay());
+ final TestActivityDisplay secondaryDisplay = createNewActivityDisplay();
mRootActivityContainer.addChild(secondaryDisplay, POSITION_TOP);
final ActivityRecord singleTaskActivity = createSingleTaskActivityOn(
secondaryDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 297aa7e..7b7e6e7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -26,6 +26,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for the {@link ActivityTaskManagerService} class.
@@ -34,6 +35,7 @@
* atest WmTests:ActivityTaskManagerServiceTests
*/
@MediumTest
+@RunWith(WindowTestRunner.class)
public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
@Before
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index d311dfc..668ad78 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -27,6 +27,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -38,33 +39,22 @@
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
+import android.os.Build;
import android.os.UserHandle;
import android.service.voice.IVoiceInteractionSession;
import android.testing.DexmakerShareClassLoaderRule;
+import android.util.Pair;
import android.view.DisplayInfo;
import com.android.server.AttributeCache;
import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.Rule;
/**
* A base class to handle common operations in activity related unit tests.
*/
-class ActivityTestsBase {
-
- @Rule
- public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
- new DexmakerShareClassLoaderRule();
-
- @Rule
- public final SystemServicesTestRule mSystemServicesTestRule = new SystemServicesTestRule();
-
- @WindowTestRunner.MethodWrapperRule
- public final WindowManagerGlobalLockRule mLockRule =
- new WindowManagerGlobalLockRule(mSystemServicesTestRule);
-
+class ActivityTestsBase extends SystemServiceTestsBase {
final Context mContext = getInstrumentation().getTargetContext();
ActivityTaskManagerService mService;
@@ -226,6 +216,23 @@
return this;
}
+ static Pair<Intent, ActivityInfo> createIntentAndActivityInfo() {
+ // TODO: Look into consolidating with dup. code in build() method below.
+ final int id = sCurrentActivityId++;
+ final ComponentName component = ComponentName.createRelative(
+ DEFAULT_COMPONENT_PACKAGE_NAME, DEFAULT_COMPONENT_CLASS_NAME + id);
+
+ final Intent intent = new Intent();
+ intent.setComponent(component);
+
+ final ActivityInfo aInfo = new ActivityInfo();
+ aInfo.applicationInfo = new ApplicationInfo();
+ aInfo.applicationInfo.packageName = component.getPackageName();
+ aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+ aInfo.packageName = component.getPackageName();
+ return new Pair<>(intent, aInfo);
+ }
+
ActivityRecord build() {
if (mComponent == null) {
final int id = sCurrentActivityId++;
@@ -271,12 +278,10 @@
if (mTaskRecord != null) {
// fullscreen value is normally read from resources in ctor, so for testing we need
// to set it somewhere else since we can't mock resources.
- activity.fullscreen = true;
+ doReturn(true).when(activity).occludesParent();
activity.setTask(mTaskRecord);
- activity.createAppWindowToken();
- spyOn(activity.mAppWindowToken);
// Make visible by default...
- activity.mAppWindowToken.setHidden(false);
+ activity.setHidden(false);
}
final WindowProcessController wpc = new WindowProcessController(mService,
@@ -285,6 +290,8 @@
mock(WindowProcessListener.class));
wpc.setThread(mock(IApplicationThread.class));
activity.setProcess(wpc);
+ doReturn(wpc).when(mService).getProcessController(
+ activity.processName, activity.info.applicationInfo.uid);
// Resume top activities to make sure all other signals in the system are connected.
mService.mRootActivityContainer.resumeFocusedStacksTopActivities();
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index 629a954..650a911 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -42,6 +42,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for change transitions
@@ -51,11 +52,12 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class AppChangeTransitionTests extends WindowTestsBase {
private TaskStack mStack;
private Task mTask;
- private WindowTestUtils.TestAppWindowToken mToken;
+ private AppWindowToken mToken;
public void setUpOnDisplay(DisplayContent dc) {
mStack = createTaskStackOnDisplay(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, dc);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index e71c8f4..605d520 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -36,6 +36,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Build/Install/Run:
@@ -43,6 +44,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class AppTransitionControllerTest extends WindowTestsBase {
private AppTransitionController mAppTransitionController;
@@ -55,73 +57,63 @@
@Test
@FlakyTest(bugId = 131005232)
public void testTranslucentOpen() {
- synchronized (mWm.mGlobalLock) {
- final AppWindowToken behind = createAppWindowToken(mDisplayContent,
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
- final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent,
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
- translucentOpening.setOccludesParent(false);
- translucentOpening.setHidden(true);
- mDisplayContent.mOpeningApps.add(behind);
- mDisplayContent.mOpeningApps.add(translucentOpening);
- assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN,
- mAppTransitionController.maybeUpdateTransitToTranslucentAnim(
- TRANSIT_TASK_OPEN));
- }
+ final AppWindowToken behind = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ translucentOpening.setOccludesParent(false);
+ translucentOpening.setHidden(true);
+ mDisplayContent.mOpeningApps.add(behind);
+ mDisplayContent.mOpeningApps.add(translucentOpening);
+ assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN,
+ mAppTransitionController.maybeUpdateTransitToTranslucentAnim(TRANSIT_TASK_OPEN));
}
@Test
@FlakyTest(bugId = 131005232)
public void testTranslucentClose() {
- synchronized (mWm.mGlobalLock) {
- final AppWindowToken behind = createAppWindowToken(mDisplayContent,
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
- final AppWindowToken translucentClosing = createAppWindowToken(mDisplayContent,
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
- translucentClosing.setOccludesParent(false);
- mDisplayContent.mClosingApps.add(translucentClosing);
- assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE,
- mAppTransitionController.maybeUpdateTransitToTranslucentAnim(
- TRANSIT_TASK_CLOSE));
- }
+ final AppWindowToken behind = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ final AppWindowToken translucentClosing = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ translucentClosing.setOccludesParent(false);
+ mDisplayContent.mClosingApps.add(translucentClosing);
+ assertEquals(WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE,
+ mAppTransitionController.maybeUpdateTransitToTranslucentAnim(TRANSIT_TASK_CLOSE));
}
@Test
@FlakyTest(bugId = 131005232)
public void testChangeIsNotOverwritten() {
- synchronized (mWm.mGlobalLock) {
- final AppWindowToken behind = createAppWindowToken(mDisplayContent,
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
- final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent,
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
- translucentOpening.setOccludesParent(false);
- translucentOpening.setHidden(true);
- mDisplayContent.mOpeningApps.add(behind);
- mDisplayContent.mOpeningApps.add(translucentOpening);
- assertEquals(TRANSIT_TASK_CHANGE_WINDOWING_MODE,
- mAppTransitionController.maybeUpdateTransitToTranslucentAnim(
- TRANSIT_TASK_CHANGE_WINDOWING_MODE));
- }
+ final AppWindowToken behind = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ translucentOpening.setOccludesParent(false);
+ translucentOpening.setHidden(true);
+ mDisplayContent.mOpeningApps.add(behind);
+ mDisplayContent.mOpeningApps.add(translucentOpening);
+ assertEquals(TRANSIT_TASK_CHANGE_WINDOWING_MODE,
+ mAppTransitionController.maybeUpdateTransitToTranslucentAnim(
+ TRANSIT_TASK_CHANGE_WINDOWING_MODE));
}
@Test
@FlakyTest(bugId = 131005232)
public void testTransitWithinTask() {
- synchronized (mWm.mGlobalLock) {
- final AppWindowToken opening = createAppWindowToken(mDisplayContent,
- WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
- opening.setOccludesParent(false);
- final AppWindowToken closing = createAppWindowToken(mDisplayContent,
- WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
- closing.setOccludesParent(false);
- Task task = opening.getTask();
- mDisplayContent.mOpeningApps.add(opening);
- mDisplayContent.mClosingApps.add(closing);
- assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task));
- closing.getTask().removeChild(closing);
- task.addChild(closing, 0);
- assertTrue(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task));
- assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_TASK_OPEN, task));
- }
+ final AppWindowToken opening = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
+ opening.setOccludesParent(false);
+ final AppWindowToken closing = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD);
+ closing.setOccludesParent(false);
+ final Task task = opening.getTask();
+ mDisplayContent.mOpeningApps.add(opening);
+ mDisplayContent.mClosingApps.add(closing);
+ assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task));
+ closing.getTask().removeChild(closing);
+ task.addChild(closing, 0);
+ assertTrue(mAppTransitionController.isTransitWithinTask(TRANSIT_ACTIVITY_OPEN, task));
+ assertFalse(mAppTransitionController.isTransitWithinTask(TRANSIT_TASK_OPEN, task));
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 45e6890..72d9bd0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -31,7 +31,6 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -55,6 +54,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Test class for {@link AppTransition}.
@@ -64,16 +64,13 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class AppTransitionTests extends WindowTestsBase {
private DisplayContent mDc;
@Before
public void setUp() throws Exception {
- synchronized (mWm.mGlobalLock) {
- // Hold the lock to protect the stubbing from being accessed by other threads.
- spyOn(mWm.mRoot);
- doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean());
- }
+ doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean());
mDc = mWm.getDefaultDisplayContentLocked();
}
@@ -125,9 +122,9 @@
final DisplayContent dc2 = createNewDisplay(Display.STATE_ON);
// Create 2 app window tokens to represent 2 activity window.
- final WindowTestUtils.TestAppWindowToken token1 = createTestAppWindowToken(dc1,
+ final AppWindowToken token1 = createTestAppWindowToken(dc1,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
- final WindowTestUtils.TestAppWindowToken token2 = createTestAppWindowToken(dc2,
+ final AppWindowToken token2 = createTestAppWindowToken(dc2,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
token1.allDrawn = true;
@@ -162,7 +159,7 @@
final TaskStack stack1 = createTaskStackOnDisplay(dc1);
final Task task1 = createTaskInStack(stack1, 0 /* userId */);
- final WindowTestUtils.TestAppWindowToken token1 =
+ final AppWindowToken token1 =
WindowTestUtils.createTestAppWindowToken(dc1);
task1.addChild(token1, 0);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
index b8f8e21..aacdeb2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
@@ -17,8 +17,8 @@
package com.android.server.wm;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
-
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -26,12 +26,12 @@
import android.graphics.PixelFormat;
import android.platform.test.annotations.Presubmit;
import android.view.Surface;
-import android.view.SurfaceControl;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Test class for {@link TaskSnapshotSurface}.
@@ -42,6 +42,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class AppWindowThumbnailTest extends WindowTestsBase {
private AppWindowThumbnail buildThumbnail() {
final GraphicBuffer buffer = GraphicBuffer.create(1, 1, PixelFormat.RGBA_8888,
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
index 70d9b5f..66ba81d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
@@ -33,10 +33,9 @@
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import com.android.server.wm.WindowTestUtils.TestAppWindowToken;
-
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -50,9 +49,10 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class AppWindowTokenAnimationTests extends WindowTestsBase {
- private TestAppWindowToken mToken;
+ private AppWindowToken mToken;
@Mock
private AnimationAdapter mSpec;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index 1f634b1..fcda494 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -53,7 +53,6 @@
import android.content.res.Configuration;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
-import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
@@ -62,6 +61,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mockito;
/**
@@ -72,11 +72,12 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class AppWindowTokenTests extends WindowTestsBase {
TaskStack mStack;
Task mTask;
- WindowTestUtils.TestAppWindowToken mToken;
+ AppWindowToken mToken;
private final String mPackageName = getInstrumentation().getTargetContext().getPackageName();
@@ -92,7 +93,7 @@
@Test
@Presubmit
public void testAddWindow_Order() {
- assertEquals(0, mToken.getWindowsCount());
+ assertEquals(0, mToken.getChildCount());
final WindowState win1 = createWindow(null, TYPE_APPLICATION, mToken, "win1");
final WindowState startingWin = createWindow(null, TYPE_APPLICATION_STARTING, mToken,
@@ -101,17 +102,17 @@
final WindowState win4 = createWindow(null, TYPE_APPLICATION, mToken, "win4");
// Should not contain the windows that were added above.
- assertEquals(4, mToken.getWindowsCount());
- assertTrue(mToken.hasWindow(win1));
- assertTrue(mToken.hasWindow(startingWin));
- assertTrue(mToken.hasWindow(baseWin));
- assertTrue(mToken.hasWindow(win4));
+ assertEquals(4, mToken.getChildCount());
+ assertTrue(mToken.mChildren.contains(win1));
+ assertTrue(mToken.mChildren.contains(startingWin));
+ assertTrue(mToken.mChildren.contains(baseWin));
+ assertTrue(mToken.mChildren.contains(win4));
// The starting window should be on-top of all other windows.
- assertEquals(startingWin, mToken.getLastChild());
+ assertEquals(startingWin, mToken.mChildren.peekLast());
// The base application window should be below all other windows.
- assertEquals(baseWin, mToken.getFirstChild());
+ assertEquals(baseWin, mToken.mChildren.peekFirst());
mToken.removeImmediately();
}
@@ -323,41 +324,14 @@
}
@Test
- public void testReportOrientationChangeOnVisibilityChange() {
- synchronized (mWm.mGlobalLock) {
- mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+ public void testReportOrientationChange() {
+ mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
- mDisplayContent.getDisplayRotation().setFixedToUserRotation(
- DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED);
+ mDisplayContent.getDisplayRotation().setFixedToUserRotation(
+ DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED);
- doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord)
- .getRequestedConfigurationOrientation();
-
- mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS);
- mToken.commitVisibility(null, false /* visible */, TRANSIT_UNSET,
- true /* performLayout */, false /* isVoiceInteraction */);
- }
-
- verify(mTask.mTaskRecord).onConfigurationChanged(any(Configuration.class));
- }
-
- @Test
- public void testReportOrientationChangeOnOpeningClosingAppChange() {
- synchronized (mWm.mGlobalLock) {
- mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
-
- mDisplayContent.getDisplayRotation().setFixedToUserRotation(
- DisplayRotation.FIXED_TO_USER_ROTATION_ENABLED);
- mDisplayContent.getDisplayInfo().state = Display.STATE_ON;
- mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_CLOSE,
- false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */);
-
- doReturn(Configuration.ORIENTATION_LANDSCAPE).when(mToken.mActivityRecord)
- .getRequestedConfigurationOrientation();
-
- mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS);
- mToken.setVisibility(false, false);
- }
+ mTask.mTaskRecord = Mockito.mock(TaskRecord.class, RETURNS_DEEP_STUBS);
+ mToken.reportDescendantOrientationChangeIfNeeded();
verify(mTask.mTaskRecord).onConfigurationChanged(any(Configuration.class));
}
@@ -380,7 +354,7 @@
public void testAddRemoveRace() {
// There was once a race condition between adding and removing starting windows
for (int i = 0; i < 1000; i++) {
- final WindowTestUtils.TestAppWindowToken appToken = createIsolatedTestAppWindowToken();
+ final AppWindowToken appToken = createIsolatedTestAppWindowToken();
appToken.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
@@ -395,8 +369,8 @@
@Test
public void testTransferStartingWindow() {
- final WindowTestUtils.TestAppWindowToken token1 = createIsolatedTestAppWindowToken();
- final WindowTestUtils.TestAppWindowToken token2 = createIsolatedTestAppWindowToken();
+ final AppWindowToken token1 = createIsolatedTestAppWindowToken();
+ final AppWindowToken token2 = createIsolatedTestAppWindowToken();
token1.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
false, false);
@@ -411,8 +385,8 @@
@Test
public void testTransferStartingWindowWhileCreating() {
- final WindowTestUtils.TestAppWindowToken token1 = createIsolatedTestAppWindowToken();
- final WindowTestUtils.TestAppWindowToken token2 = createIsolatedTestAppWindowToken();
+ final AppWindowToken token1 = createIsolatedTestAppWindowToken();
+ final AppWindowToken token2 = createIsolatedTestAppWindowToken();
((TestWindowManagerPolicy) token1.mWmService.mPolicy).setRunnableWhenAddingSplashScreen(
() -> {
// Surprise, ...! Transfer window in the middle of the creation flow.
@@ -429,14 +403,14 @@
assertHasStartingWindow(token2);
}
- private WindowTestUtils.TestAppWindowToken createIsolatedTestAppWindowToken() {
+ private AppWindowToken createIsolatedTestAppWindowToken() {
final TaskStack taskStack = createTaskStackOnDisplay(mDisplayContent);
final Task task = createTaskInStack(taskStack, 0 /* userId */);
return createTestAppWindowTokenForGivenTask(task);
}
- private WindowTestUtils.TestAppWindowToken createTestAppWindowTokenForGivenTask(Task task) {
- final WindowTestUtils.TestAppWindowToken appToken =
+ private AppWindowToken createTestAppWindowTokenForGivenTask(Task task) {
+ final AppWindowToken appToken =
WindowTestUtils.createTestAppWindowToken(mDisplayContent);
task.addChild(appToken, 0);
waitUntilHandlersIdle();
@@ -446,8 +420,8 @@
@Test
public void testTryTransferStartingWindowFromHiddenAboveToken() {
// Add two tasks on top of each other.
- final WindowTestUtils.TestAppWindowToken tokenTop = createIsolatedTestAppWindowToken();
- final WindowTestUtils.TestAppWindowToken tokenBottom =
+ final AppWindowToken tokenTop = createIsolatedTestAppWindowToken();
+ final AppWindowToken tokenBottom =
createTestAppWindowTokenForGivenTask(tokenTop.getTask());
// Add a starting window.
diff --git a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
index bb574ce..2e85897 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AssistDataRequesterTest.java
@@ -22,6 +22,8 @@
import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
import static android.graphics.Bitmap.Config.ARGB_8888;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -71,7 +73,7 @@
*/
@MediumTest
@Presubmit
-public class AssistDataRequesterTest extends ActivityTestsBase {
+public class AssistDataRequesterTest {
private static final String TAG = AssistDataRequesterTest.class.getSimpleName();
@@ -111,8 +113,9 @@
mHandler = new Handler(Looper.getMainLooper());
mCallbacksLock = new Object();
mCallbacks = new Callbacks();
- mDataRequester = new AssistDataRequester(mContext, mWm, mAppOpsManager, mCallbacks,
- mCallbacksLock, OP_ASSIST_STRUCTURE, OP_ASSIST_SCREENSHOT);
+ mDataRequester = new AssistDataRequester(getInstrumentation().getTargetContext(), mWm,
+ mAppOpsManager, mCallbacks, mCallbacksLock, OP_ASSIST_STRUCTURE,
+ OP_ASSIST_SCREENSHOT);
mDataRequester.mActivityTaskManager = mAtm;
// Gate the continuation of the assist data callbacks until we are ready within the tests
mGate = new CountDownLatch(1);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 44f3ee41..c48dc25 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -39,6 +39,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
@@ -46,8 +47,8 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.same;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
@@ -72,7 +73,6 @@
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
-import android.util.MutableBoolean;
import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.ISystemGestureExclusionListener;
@@ -88,6 +88,7 @@
import com.android.server.wm.utils.WmDisplayCutout;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@@ -105,6 +106,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class DisplayContentTests extends WindowTestsBase {
@Test
@@ -239,8 +241,7 @@
assertEquals(dc, stack.getDisplayContent());
final Task task = createTaskInStack(stack, 0 /* userId */);
- final WindowTestUtils.TestAppWindowToken token = WindowTestUtils.createTestAppWindowToken(
- dc);
+ final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(dc);
task.addChild(token, 0);
assertEquals(dc, task.getDisplayContent());
assertEquals(dc, token.getDisplayContent());
@@ -312,7 +313,7 @@
// Add stack with activity.
final TaskStack stack0 = createTaskStackOnDisplay(dc0);
final Task task0 = createTaskInStack(stack0, 0 /* userId */);
- final WindowTestUtils.TestAppWindowToken token =
+ final AppWindowToken token =
WindowTestUtils.createTestAppWindowToken(dc0);
task0.addChild(token, 0);
dc0.configureDisplayPolicy();
@@ -320,7 +321,7 @@
final TaskStack stack1 = createTaskStackOnDisplay(dc1);
final Task task1 = createTaskInStack(stack1, 0 /* userId */);
- final WindowTestUtils.TestAppWindowToken token1 =
+ final AppWindowToken token1 =
WindowTestUtils.createTestAppWindowToken(dc0);
task1.addChild(token1, 0);
dc1.configureDisplayPolicy();
@@ -396,6 +397,59 @@
mWm.mRoot.getTopFocusedDisplayContent().getDisplayId());
}
+ @Test
+ public void testShouldWaitForSystemDecorWindowsOnBoot_OnDefaultDisplay() {
+ mWm.mSystemBooted = true;
+ final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
+ final WindowState[] windows = createNotDrawnWindowsOn(defaultDisplay,
+ TYPE_WALLPAPER, TYPE_APPLICATION);
+
+ // Verify waiting for windows to be drawn.
+ assertTrue(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot());
+
+ // Verify not waiting for drawn windows.
+ makeWindowsDrawn(windows);
+ assertFalse(defaultDisplay.shouldWaitForSystemDecorWindowsOnBoot());
+ }
+
+ @Test
+ public void testShouldWaitForSystemDecorWindowsOnBoot_OnSecondaryDisplay() {
+ mWm.mSystemBooted = true;
+ final DisplayContent secondaryDisplay = createNewDisplay();
+ final WindowState[] windows = createNotDrawnWindowsOn(secondaryDisplay,
+ TYPE_WALLPAPER, TYPE_APPLICATION);
+
+ // Verify not waiting for display without system decorations.
+ doReturn(false).when(secondaryDisplay).supportsSystemDecorations();
+ assertFalse(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot());
+
+ // Verify waiting for non-drawn windows on display with system decorations.
+ reset(secondaryDisplay);
+ doReturn(true).when(secondaryDisplay).supportsSystemDecorations();
+ assertTrue(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot());
+
+ // Verify not waiting for drawn windows on display with system decorations.
+ makeWindowsDrawn(windows);
+ assertFalse(secondaryDisplay.shouldWaitForSystemDecorWindowsOnBoot());
+ }
+
+ private WindowState[] createNotDrawnWindowsOn(DisplayContent displayContent, int... types) {
+ final WindowState[] windows = new WindowState[types.length];
+ for (int i = 0; i < types.length; i++) {
+ final int type = types[i];
+ windows[i] = createWindow(null /* parent */, type, displayContent, "window-" + type);
+ windows[i].mHasSurface = false;
+ }
+ return windows;
+ }
+
+ private static void makeWindowsDrawn(WindowState[] windows) {
+ for (WindowState window : windows) {
+ window.mHasSurface = true;
+ window.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
+ }
+ }
+
/**
* This tests setting the maximum ui width on a display.
*/
@@ -435,78 +489,70 @@
@Test
public void testDisplayCutout_rot0() {
- synchronized (mWm.getWindowManagerLock()) {
- final DisplayContent dc = createNewDisplay();
- dc.mInitialDisplayWidth = 200;
- dc.mInitialDisplayHeight = 400;
- Rect r = new Rect(80, 0, 120, 10);
- final DisplayCutout cutout = new WmDisplayCutout(
- fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_TOP), null)
- .computeSafeInsets(200, 400).getDisplayCutout();
+ final DisplayContent dc = createNewDisplay();
+ dc.mInitialDisplayWidth = 200;
+ dc.mInitialDisplayHeight = 400;
+ final Rect r = new Rect(80, 0, 120, 10);
+ final DisplayCutout cutout = new WmDisplayCutout(
+ fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_TOP), null)
+ .computeSafeInsets(200, 400).getDisplayCutout();
- dc.mInitialDisplayCutout = cutout;
- dc.getDisplayRotation().setRotation(Surface.ROTATION_0);
- dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
+ dc.mInitialDisplayCutout = cutout;
+ dc.getDisplayRotation().setRotation(Surface.ROTATION_0);
+ dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
- assertEquals(cutout, dc.getDisplayInfo().displayCutout);
- }
+ assertEquals(cutout, dc.getDisplayInfo().displayCutout);
}
@Test
public void testDisplayCutout_rot90() {
- synchronized (mWm.getWindowManagerLock()) {
- // Prevent mInitialDisplayCutout from being updated from real display (e.g. null
- // if the device has no cutout).
- final DisplayContent dc = createDisplayNoUpdateDisplayInfo();
- // Rotation may use real display info to compute bound, so here also uses the
- // same width and height.
- final int displayWidth = dc.mInitialDisplayWidth;
- final int displayHeight = dc.mInitialDisplayHeight;
- final int cutoutWidth = 40;
- final int cutoutHeight = 10;
- final int left = (displayWidth - cutoutWidth) / 2;
- final int top = 0;
- final int right = (displayWidth + cutoutWidth) / 2;
- final int bottom = cutoutHeight;
+ // Prevent mInitialDisplayCutout from being updated from real display (e.g. null
+ // if the device has no cutout).
+ final DisplayContent dc = createDisplayNoUpdateDisplayInfo();
+ // Rotation may use real display info to compute bound, so here also uses the
+ // same width and height.
+ final int displayWidth = dc.mInitialDisplayWidth;
+ final int displayHeight = dc.mInitialDisplayHeight;
+ final int cutoutWidth = 40;
+ final int cutoutHeight = 10;
+ final int left = (displayWidth - cutoutWidth) / 2;
+ final int top = 0;
+ final int right = (displayWidth + cutoutWidth) / 2;
+ final int bottom = cutoutHeight;
- final Rect r1 = new Rect(left, top, right, bottom);
- final DisplayCutout cutout = new WmDisplayCutout(
- fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP),
- null)
- .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
+ final Rect r1 = new Rect(left, top, right, bottom);
+ final DisplayCutout cutout = new WmDisplayCutout(
+ fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP), null)
+ .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
- dc.mInitialDisplayCutout = cutout;
- dc.getDisplayRotation().setRotation(Surface.ROTATION_90);
- dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
+ dc.mInitialDisplayCutout = cutout;
+ dc.getDisplayRotation().setRotation(Surface.ROTATION_90);
+ dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
- // ----o---------- -------------
- // | | | | |
- // | ------o | o---
- // | | | |
- // | | -> | |
- // | | ---o
- // | | |
- // | | -------------
- final Rect r = new Rect(top, left, bottom, right);
- assertEquals(new WmDisplayCutout(
- fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_LEFT), null)
- .computeSafeInsets(displayHeight, displayWidth)
- .getDisplayCutout(), dc.getDisplayInfo().displayCutout);
- }
+ // ----o---------- -------------
+ // | | | | |
+ // | ------o | o---
+ // | | | |
+ // | | -> | |
+ // | | ---o
+ // | | |
+ // | | -------------
+ final Rect r = new Rect(top, left, bottom, right);
+ assertEquals(new WmDisplayCutout(
+ fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_LEFT), null)
+ .computeSafeInsets(displayHeight, displayWidth).getDisplayCutout(),
+ dc.getDisplayInfo().displayCutout);
}
@Test
public void testLayoutSeq_assignedDuringLayout() {
- synchronized (mWm.getWindowManagerLock()) {
+ final DisplayContent dc = createNewDisplay();
+ final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
- final DisplayContent dc = createNewDisplay();
- final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
+ dc.setLayoutNeeded();
+ dc.performLayout(true /* initial */, false /* updateImeWindows */);
- dc.setLayoutNeeded();
- dc.performLayout(true /* initial */, false /* updateImeWindows */);
-
- assertThat(win.mLayoutSeq, is(dc.mLayoutSeq));
- }
+ assertThat(win.mLayoutSeq, is(dc.mLayoutSeq));
}
@Test
@@ -751,7 +797,7 @@
win.setHasSurface(true);
dc.updateSystemGestureExclusion();
- final MutableBoolean invoked = new MutableBoolean(false);
+ final boolean[] invoked = { false };
final ISystemGestureExclusionListener.Stub verifier =
new ISystemGestureExclusionListener.Stub() {
@Override
@@ -760,7 +806,7 @@
Region expected = Region.obtain();
expected.set(10, 20, 30, 40);
assertEquals(expected, actual);
- invoked.value = true;
+ invoked[0] = true;
}
};
try {
@@ -768,7 +814,7 @@
} finally {
dc.unregisterSystemGestureExclusionListener(verifier);
}
- assertTrue("SystemGestureExclusionListener was not invoked", invoked.value);
+ assertTrue("SystemGestureExclusionListener was not invoked", invoked[0]);
}
@Test
@@ -826,30 +872,28 @@
@Test
public void testCalculateSystemGestureExclusion_immersiveStickyLegacyWindow() throws Exception {
- synchronized (mWm.mGlobalLock) {
- mWm.mSystemGestureExcludedByPreQStickyImmersive = true;
+ mWm.mSystemGestureExcludedByPreQStickyImmersive = true;
- final DisplayContent dc = createNewDisplay();
- final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
- win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
- win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
- win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility =
- SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION
- | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
- win.mAppToken.mTargetSdk = P;
+ final DisplayContent dc = createNewDisplay();
+ final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
+ win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+ win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+ win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
+ win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility =
+ SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ win.mAppToken.mTargetSdk = P;
- dc.setLayoutNeeded();
- dc.performLayout(true /* initial */, false /* updateImeWindows */);
+ dc.setLayoutNeeded();
+ dc.performLayout(true /* initial */, false /* updateImeWindows */);
- win.setHasSurface(true);
+ win.setHasSurface(true);
- final Region expected = Region.obtain();
- expected.set(dc.getBounds());
- assertEquals(expected, calculateSystemGestureExclusion(dc));
+ final Region expected = Region.obtain();
+ expected.set(dc.getBounds());
+ assertEquals(expected, calculateSystemGestureExclusion(dc));
- win.setHasSurface(false);
- }
+ win.setHasSurface(false);
}
@Test
@@ -860,7 +904,7 @@
Configuration newConfig = new Configuration();
newConfig.orientation = Configuration.ORIENTATION_PORTRAIT;
- final DisplayContent displayContent = spy(createNewDisplay());
+ final DisplayContent displayContent = createNewDisplay();
Mockito.doReturn(mockLogger).when(displayContent).getMetricsLogger();
Mockito.doReturn(oldConfig).doReturn(newConfig).when(displayContent).getConfiguration();
@@ -886,9 +930,7 @@
}
private void updateFocusedWindow() {
- synchronized (mWm.mGlobalLock) {
- mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false);
- }
+ mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /* updateInputWindows */);
}
/**
@@ -896,7 +938,7 @@
* the values set by test.
*/
private DisplayContent createDisplayNoUpdateDisplayInfo() {
- final DisplayContent displayContent = spy(createNewDisplay());
+ final DisplayContent displayContent = createNewDisplay();
doNothing().when(displayContent).updateDisplayInfo();
return displayContent;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index de184b8..2a3731a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -63,9 +63,11 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
private DisplayFrames mFrames;
@@ -118,458 +120,415 @@
@Test
public void layoutWindowLw_appDrawsBars() {
- synchronized (mWm.mGlobalLock) {
- mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- addWindow(mWindow);
+ mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
- }
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
}
@Test
public void layoutWindowLw_appWontDrawBars() {
- synchronized (mWm.mGlobalLock) {
- mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- addWindow(mWindow);
+ mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
- }
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
}
@Test
public void layoutWindowLw_appWontDrawBars_forceStatusAndNav() throws Exception {
- synchronized (mWm.mGlobalLock) {
- mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
- addWindow(mWindow);
+ mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
- }
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
}
@Test
public void layoutWindowLw_keyguardDialog_hideNav() {
- synchronized (mWm.mGlobalLock) {
- mWindow.mAttrs.type = TYPE_KEYGUARD_DIALOG;
- mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- mWindow.mAttrs.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
- addWindow(mWindow);
+ mWindow.mAttrs.type = TYPE_KEYGUARD_DIALOG;
+ mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* uiMode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null /* attached */, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* uiMode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null /* attached */, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
- }
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout() {
- synchronized (mWm.mGlobalLock) {
- addDisplayCutout();
+ addDisplayCutout();
- addWindow(mWindow);
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
- }
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_never() {
- synchronized (mWm.mGlobalLock) {
- addDisplayCutout();
+ addDisplayCutout();
- mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
- addWindow(mWindow);
+ mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
- }
+ assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_layoutFullscreen() {
- synchronized (mWm.mGlobalLock) {
- addDisplayCutout();
+ addDisplayCutout();
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
- addWindow(mWindow);
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
- }
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_fullscreen() {
- synchronized (mWm.mGlobalLock) {
- addDisplayCutout();
+ addDisplayCutout();
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
- addWindow(mWindow);
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
- }
+ assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_fullscreenInCutout() {
- synchronized (mWm.mGlobalLock) {
- addDisplayCutout();
+ addDisplayCutout();
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
- mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- addWindow(mWindow);
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
+ mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
- }
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_landscape() {
- synchronized (mWm.mGlobalLock) {
- addDisplayCutout();
- setRotation(ROTATION_90);
- addWindow(mWindow);
+ addDisplayCutout();
+ setRotation(ROTATION_90);
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
- DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- }
+ assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+ assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getContentFrameLw(),
+ DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_seascape() {
- synchronized (mWm.mGlobalLock) {
- addDisplayCutout();
- setRotation(ROTATION_270);
- addWindow(mWindow);
+ addDisplayCutout();
+ setRotation(ROTATION_270);
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
- assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
- NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
- }
+ assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+ assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
+ assertInsetBy(mWindow.getContentFrameLw(),
+ NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
+ assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_fullscreen_landscape() {
- synchronized (mWm.mGlobalLock) {
- addDisplayCutout();
- setRotation(ROTATION_90);
+ addDisplayCutout();
+ setRotation(ROTATION_90);
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
- addWindow(mWindow);
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
- DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- }
+ assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+ assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getContentFrameLw(),
+ DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
}
@Test
public void layoutWindowLw_withDisplayCutout_floatingInScreen() {
- synchronized (mWm.mGlobalLock) {
- addDisplayCutout();
+ addDisplayCutout();
- mWindow.mAttrs.flags = FLAG_LAYOUT_IN_SCREEN;
- mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY;
- mWindow.mAttrs.width = DISPLAY_WIDTH;
- mWindow.mAttrs.height = DISPLAY_HEIGHT;
- addWindow(mWindow);
+ mWindow.mAttrs.flags = FLAG_LAYOUT_IN_SCREEN;
+ mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY;
+ mWindow.mAttrs.width = DISPLAY_WIDTH;
+ mWindow.mAttrs.height = DISPLAY_HEIGHT;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- }
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
}
@Test
public void layoutWindowLw_withDisplayCutout_fullscreenInCutout_landscape() {
- synchronized (mWm.mGlobalLock) {
- addDisplayCutout();
- setRotation(ROTATION_90);
+ addDisplayCutout();
+ setRotation(ROTATION_90);
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
- mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- addWindow(mWindow);
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
- DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- }
+ assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getContentFrameLw(),
+ DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
}
@Test
public void layoutWindowLw_withForwardInset_SoftInputAdjustResize() {
- synchronized (mWm.mGlobalLock) {
- mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE;
- addWindow(mWindow);
+ mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE;
+ addWindow(mWindow);
- final int forwardedInsetBottom = 50;
- mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom));
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ final int forwardedInsetBottom = 50;
+ mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom));
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(),
- STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(),
- STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
- }
+ assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(),
+ STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom);
+ assertInsetByTopBottom(mWindow.getVisibleFrameLw(),
+ STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom);
+ assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
}
@Test
public void layoutWindowLw_withForwardInset_SoftInputAdjustNothing() {
- synchronized (mWm.mGlobalLock) {
- mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_NOTHING;
- addWindow(mWindow);
+ mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_NOTHING;
+ addWindow(mWindow);
- final int forwardedInsetBottom = 50;
- mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom));
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ final int forwardedInsetBottom = 50;
+ mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom));
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
- }
+ assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
}
@Test
public void layoutHint_appWindow() {
- synchronized (mWm.mGlobalLock) {
- // Initialize DisplayFrames
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ // Initialize DisplayFrames
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- final Rect outFrame = new Rect();
- final Rect outContentInsets = new Rect();
- final Rect outStableInsets = new Rect();
- final Rect outOutsets = new Rect();
- final DisplayCutout.ParcelableWrapper outDisplayCutout =
- new DisplayCutout.ParcelableWrapper();
+ final Rect outFrame = new Rect();
+ final Rect outContentInsets = new Rect();
+ final Rect outStableInsets = new Rect();
+ final Rect outOutsets = new Rect();
+ final DisplayCutout.ParcelableWrapper outDisplayCutout =
+ new DisplayCutout.ParcelableWrapper();
- mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, null, mFrames,
- false /* floatingStack */, outFrame, outContentInsets, outStableInsets,
- outOutsets, outDisplayCutout);
+ mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, null, mFrames,
+ false /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+ outOutsets, outDisplayCutout);
- assertThat(outFrame, is(mFrames.mUnrestricted));
- assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
- assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
- assertThat(outOutsets, is(new Rect()));
- assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
- }
+ assertThat(outFrame, is(mFrames.mUnrestricted));
+ assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
+ assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
+ assertThat(outOutsets, is(new Rect()));
+ assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
}
@Test
public void layoutHint_appWindowInTask() {
- synchronized (mWm.mGlobalLock) {
- // Initialize DisplayFrames
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ // Initialize DisplayFrames
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- final Rect taskBounds = new Rect(100, 100, 200, 200);
+ final Rect taskBounds = new Rect(100, 100, 200, 200);
- final Rect outFrame = new Rect();
- final Rect outContentInsets = new Rect();
- final Rect outStableInsets = new Rect();
- final Rect outOutsets = new Rect();
- final DisplayCutout.ParcelableWrapper outDisplayCutout =
- new DisplayCutout.ParcelableWrapper();
+ final Rect outFrame = new Rect();
+ final Rect outContentInsets = new Rect();
+ final Rect outStableInsets = new Rect();
+ final Rect outOutsets = new Rect();
+ final DisplayCutout.ParcelableWrapper outDisplayCutout =
+ new DisplayCutout.ParcelableWrapper();
- mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
- false /* floatingStack */, outFrame, outContentInsets, outStableInsets,
- outOutsets, outDisplayCutout);
+ mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
+ false /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+ outOutsets, outDisplayCutout);
- assertThat(outFrame, is(taskBounds));
- assertThat(outContentInsets, is(new Rect()));
- assertThat(outStableInsets, is(new Rect()));
- assertThat(outOutsets, is(new Rect()));
- assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
- }
+ assertThat(outFrame, is(taskBounds));
+ assertThat(outContentInsets, is(new Rect()));
+ assertThat(outStableInsets, is(new Rect()));
+ assertThat(outOutsets, is(new Rect()));
+ assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
}
@Test
public void layoutHint_appWindowInTask_outsideContentFrame() {
- synchronized (mWm.mGlobalLock) {
- // Initialize DisplayFrames
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ // Initialize DisplayFrames
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- // Task is in the nav bar area (usually does not happen, but this is similar enough to
- // the possible overlap with the IME)
- final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1,
- 200, mFrames.mContent.bottom + 10);
+ // Task is in the nav bar area (usually does not happen, but this is similar enough to
+ // the possible overlap with the IME)
+ final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1,
+ 200, mFrames.mContent.bottom + 10);
- final Rect outFrame = new Rect();
- final Rect outContentInsets = new Rect();
- final Rect outStableInsets = new Rect();
- final Rect outOutsets = new Rect();
- final DisplayCutout.ParcelableWrapper outDisplayCutout =
- new DisplayCutout.ParcelableWrapper();
+ final Rect outFrame = new Rect();
+ final Rect outContentInsets = new Rect();
+ final Rect outStableInsets = new Rect();
+ final Rect outOutsets = new Rect();
+ final DisplayCutout.ParcelableWrapper outDisplayCutout =
+ new DisplayCutout.ParcelableWrapper();
- mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
- true /* floatingStack */, outFrame, outContentInsets, outStableInsets,
- outOutsets, outDisplayCutout);
+ mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
+ true /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+ outOutsets, outDisplayCutout);
- assertThat(outFrame, is(taskBounds));
- assertThat(outContentInsets, is(new Rect()));
- assertThat(outStableInsets, is(new Rect()));
- assertThat(outOutsets, is(new Rect()));
- assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
- }
+ assertThat(outFrame, is(taskBounds));
+ assertThat(outContentInsets, is(new Rect()));
+ assertThat(outStableInsets, is(new Rect()));
+ assertThat(outOutsets, is(new Rect()));
+ assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
}
@Test
public void forceShowSystemBars_clearsSystemUIFlags() {
- synchronized (mWm.mGlobalLock) {
- mDisplayPolicy.mLastSystemUiFlags |= SYSTEM_UI_FLAG_FULLSCREEN;
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
- mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- mWindow.mSystemUiVisibility = SYSTEM_UI_FLAG_FULLSCREEN;
- mDisplayPolicy.setForceShowSystemBars(true);
- addWindow(mWindow);
+ mDisplayPolicy.mLastSystemUiFlags |= SYSTEM_UI_FLAG_FULLSCREEN;
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mSystemUiVisibility = SYSTEM_UI_FLAG_FULLSCREEN;
+ mDisplayPolicy.setForceShowSystemBars(true);
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- // triggers updateSystemUiVisibilityLw which will reset the flags as needed
- int finishPostLayoutPolicyLw = mDisplayPolicy.focusChangedLw(mWindow, mWindow);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ // triggers updateSystemUiVisibilityLw which will reset the flags as needed
+ int finishPostLayoutPolicyLw = mDisplayPolicy.focusChangedLw(mWindow, mWindow);
- assertEquals(WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT, finishPostLayoutPolicyLw);
- assertEquals(0, mDisplayPolicy.mLastSystemUiFlags);
- assertEquals(0, mWindow.mAttrs.systemUiVisibility);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- }
+ assertEquals(WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT, finishPostLayoutPolicyLw);
+ assertEquals(0, mDisplayPolicy.mLastSystemUiFlags);
+ assertEquals(0, mWindow.mAttrs.systemUiVisibility);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
}
@Test
public void testScreenDecorWindows() {
- synchronized (mWm.mGlobalLock) {
- final WindowState decorWindow = createWindow(null, TYPE_APPLICATION_OVERLAY,
- "decorWindow");
- decorWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
- decorWindow.mAttrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR;
- addWindow(decorWindow);
- addWindow(mWindow);
+ final WindowState decorWindow = createWindow(null, TYPE_APPLICATION_OVERLAY, "decorWindow");
+ decorWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
+ decorWindow.mAttrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR;
+ addWindow(decorWindow);
+ addWindow(mWindow);
- // Decor on top
- updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, TOP);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, NAV_BAR_HEIGHT);
+ // Decor on top
+ updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, TOP);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, NAV_BAR_HEIGHT);
- // Decor on bottom
- updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, BOTTOM);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT,
- DECOR_WINDOW_INSET);
+ // Decor on bottom
+ updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, BOTTOM);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT,
+ DECOR_WINDOW_INSET);
- // Decor on the left
- updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, LEFT);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, STATUS_BAR_HEIGHT, 0,
- NAV_BAR_HEIGHT);
+ // Decor on the left
+ updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, LEFT);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ assertInsetBy(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, STATUS_BAR_HEIGHT, 0,
+ NAV_BAR_HEIGHT);
- // Decor on the right
- updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, RIGHT);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, DECOR_WINDOW_INSET,
- NAV_BAR_HEIGHT);
+ // Decor on the right
+ updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, RIGHT);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, DECOR_WINDOW_INSET,
+ NAV_BAR_HEIGHT);
- // Decor not allowed as inset
- updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, DECOR_WINDOW_INSET, TOP);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- }
+ // Decor not allowed as inset
+ updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, DECOR_WINDOW_INSET, TOP);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
}
private void updateDecorWindow(WindowState decorWindow, int width, int height, int gravity) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 3ead977..e699b52 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -54,9 +54,11 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class DisplayPolicyTests extends WindowTestsBase {
private WindowState createOpaqueFullscreen(boolean hasLightNavBar) {
@@ -225,13 +227,10 @@
final WindowState activity = createApplicationWindow();
final WindowState toast = createToastWindow();
- synchronized (mWm.mGlobalLock) {
- policy.adjustWindowParamsLw(
- toast, toast.mAttrs, 0 /* callingPid */, 0 /* callingUid */);
+ policy.adjustWindowParamsLw(toast, toast.mAttrs, 0 /* callingPid */, 0 /* callingUid */);
- assertTrue(policy.canToastShowWhenLocked(0 /* callingUid */));
- assertNotEquals(0, toast.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED);
- }
+ assertTrue(policy.canToastShowWhenLocked(0 /* callingUid */));
+ assertNotEquals(0, toast.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED);
}
private WindowState createToastWindow() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index 059ff3d..480c468 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -68,6 +68,7 @@
import com.android.server.wm.utils.WmDisplayCutout;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -122,6 +123,12 @@
sMockWm.mPolicy = mock(WindowManagerPolicy.class);
}
+ @AfterClass
+ public static void tearDownOnce() {
+ // Make sure the fake settings are cleared after the last test method.
+ FakeSettingsProvider.clearSettingsProvider();
+ }
+
@Before
public void setUp() {
FakeSettingsProvider.clearSettingsProvider();
@@ -238,15 +245,55 @@
}
@Test
- public void testReturnsUserRotation_UserRotationLocked_CompatibleAppRequest()
+ public void testReturnsLandscape_UserRotationLockedSeascape_AppRequestsLandscape()
throws Exception {
mBuilder.build();
- configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false, false);
+ configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */,
+ false /* isTv */);
+
+ freezeRotation(Surface.ROTATION_180);
+
+ assertEquals(Surface.ROTATION_0, mTarget.rotationForOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, Surface.ROTATION_90));
+ }
+
+ @Test
+ public void testReturnsSeascape_UserRotationLockedSeascape_AppRequestsSeascape()
+ throws Exception {
+ mBuilder.build();
+ configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */,
+ false /* isTv */);
freezeRotation(Surface.ROTATION_180);
assertEquals(Surface.ROTATION_180, mTarget.rotationForOrientation(
- ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, Surface.ROTATION_90));
+ ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE, Surface.ROTATION_90));
+ }
+
+ @Test
+ public void testReturnsPortrait_UserRotationLockedPortrait_AppRequestsPortrait()
+ throws Exception {
+ mBuilder.build();
+ configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */,
+ false /* isTv */);
+
+ freezeRotation(Surface.ROTATION_270);
+
+ assertEquals(Surface.ROTATION_270, mTarget.rotationForOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, Surface.ROTATION_0));
+ }
+
+ @Test
+ public void testReturnsUpsideDown_UserRotationLockedUpsideDown_AppRequestsUpsideDown()
+ throws Exception {
+ mBuilder.build();
+ configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */,
+ false /* isTv */);
+
+ freezeRotation(Surface.ROTATION_90);
+
+ assertEquals(Surface.ROTATION_90, mTarget.rotationForOrientation(
+ ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, Surface.ROTATION_0));
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
index bb80e5e..304df22 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
@@ -23,7 +23,6 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static org.junit.Assert.assertNotNull;
@@ -51,6 +50,7 @@
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -59,10 +59,11 @@
* Tests for the {@link DragDropController} class.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:DragDropControllerTests
+ * atest WmTests:DragDropControllerTests
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class DragDropControllerTests extends WindowTestsBase {
private static final int TIMEOUT_MS = 3000;
private TestDragDropController mTarget;
@@ -95,7 +96,7 @@
* Creates a window state which can be used as a drop target.
*/
private WindowState createDropTargetWindow(String name, int ownerId) {
- final WindowTestUtils.TestAppWindowToken token = WindowTestUtils.createTestAppWindowToken(
+ final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(
mDisplayContent);
final TaskStack stack = createTaskStackOnDisplay(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent);
@@ -123,30 +124,25 @@
@Before
public void setUp() throws Exception {
mTarget = new TestDragDropController(mWm, mWm.mH.getLooper());
- mDisplayContent = spy(mDisplayContent);
mWindow = createDropTargetWindow("Drag test window", 0);
doReturn(mWindow).when(mDisplayContent).getTouchableWinAtPointLocked(0, 0);
when(mWm.mInputManager.transferTouchFocus(any(), any())).thenReturn(true);
- synchronized (mWm.mGlobalLock) {
- mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
- }
+ mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
}
@After
public void tearDown() throws Exception {
final CountDownLatch latch;
- synchronized (mWm.mGlobalLock) {
- if (!mTarget.dragDropActiveLocked()) {
- return;
- }
- if (mToken != null) {
- mTarget.cancelDragAndDrop(mToken, false);
- }
- latch = new CountDownLatch(1);
- mTarget.setOnClosedCallbackLocked(latch::countDown);
+ if (!mTarget.dragDropActiveLocked()) {
+ return;
}
- assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ if (mToken != null) {
+ mTarget.cancelDragAndDrop(mToken, false);
+ }
+ latch = new CountDownLatch(1);
+ mTarget.setOnClosedCallbackLocked(latch::countDown);
+ assertTrue(awaitInWmLock(() -> latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)));
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 94abd34..445a5cc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -63,7 +63,6 @@
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
-import android.util.MutableLong;
import android.util.SparseBooleanArray;
import androidx.test.filters.MediumTest;
@@ -72,6 +71,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.io.File;
import java.util.ArrayList;
@@ -86,6 +86,7 @@
*/
@MediumTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class RecentTasksTest extends ActivityTestsBase {
private static final int TEST_USER_0_ID = 0;
private static final int TEST_USER_1_ID = 10;
@@ -95,10 +96,7 @@
private static final int INVALID_STACK_ID = 999;
private ActivityDisplay mDisplay;
- private ActivityDisplay mOtherDisplay;
- private ActivityDisplay mSingleTaskDisplay;
private ActivityStack mStack;
- private ActivityStack mHomeStack;
private TestTaskPersister mTaskPersister;
private TestRecentTasks mRecentTasks;
private TestRunningTasks mRunningTasks;
@@ -111,15 +109,7 @@
@Before
public void setUp() throws Exception {
mTaskPersister = new TestTaskPersister(mContext.getFilesDir());
-
- // Set testing displays
mDisplay = mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY);
- mOtherDisplay = createNewActivityDisplay();
- mSingleTaskDisplay = createNewActivityDisplay();
- mSingleTaskDisplay.setDisplayToSingleTaskInstance();
- mRootActivityContainer.addChild(mOtherDisplay, ActivityDisplay.POSITION_TOP);
- mRootActivityContainer.addChild(mDisplay, ActivityDisplay.POSITION_TOP);
- mRootActivityContainer.addChild(mSingleTaskDisplay, ActivityDisplay.POSITION_TOP);
// Set the recent tasks we should use for testing in this class.
mRecentTasks = new TestRecentTasks(mService, mTaskPersister);
@@ -131,8 +121,6 @@
mRunningTasks = new TestRunningTasks();
mService.mStackSupervisor.setRunningTasks(mRunningTasks);
- mHomeStack = mDisplay.getOrCreateStack(
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
mStack = mDisplay.createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
mCallbacksRecorder = new CallbacksRecorder();
@@ -269,7 +257,7 @@
// other task
TaskRecord task1 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
- .setStack(mHomeStack).build();
+ .setStack(mDisplay.getHomeStack()).build();
TaskRecord task2 = createTaskBuilder(".Task1")
.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK)
.setStack(mStack).build();
@@ -446,12 +434,12 @@
mRecentTasks.add(task3);
mRecentTasks.add(task4);
- MutableLong prevLastActiveTime = new MutableLong(0);
+ long prevLastActiveTime = 0;
final ArrayList<TaskRecord> tasks = mRecentTasks.getRawTasks();
for (int i = 0; i < tasks.size(); i++) {
final TaskRecord task = tasks.get(i);
- assertThat(prevLastActiveTime.value).isLessThan(task.lastActiveTime);
- prevLastActiveTime.value = task.lastActiveTime;
+ assertThat(prevLastActiveTime).isLessThan(task.lastActiveTime);
+ prevLastActiveTime = task.lastActiveTime;
}
}
@@ -618,7 +606,10 @@
mRecentTasks.setOnlyTestVisibleRange();
mRecentTasks.setParameters(-1 /* min */, 3 /* max */, -1 /* ms */);
- ActivityStack singleTaskStack = mSingleTaskDisplay.createStack(
+ final ActivityDisplay singleTaskDisplay =
+ addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
+ singleTaskDisplay.setDisplayToSingleTaskInstance();
+ ActivityStack singleTaskStack = singleTaskDisplay.createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1")
@@ -795,7 +786,8 @@
mRecentTasks.setParameters(-1 /* min */, 1 /* max */, -1 /* ms */);
final ActivityStack homeStack = mDisplay.getHomeStack();
- final ActivityStack otherDisplayStack = mOtherDisplay.createStack(
+ final ActivityDisplay otherDisplay = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
+ final ActivityStack otherDisplayStack = otherDisplay.createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
// Add a number of tasks (beyond the max) on each display, ensure that the tasks are not
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index f792b0d..6b28135 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -66,15 +66,17 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Build/Install/Run:
- * atest FrameworksServicesTests:RecentsAnimationControllerTest
+ * atest WmTests:RecentsAnimationControllerTest
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class RecentsAnimationControllerTest extends WindowTestsBase {
@Mock SurfaceControl mMockLeash;
@@ -88,12 +90,8 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- synchronized (mWm.mGlobalLock) {
- // Hold the lock to protect the stubbing from being accessed by other threads.
- spyOn(mWm.mRoot);
- doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean());
- doReturn(mDisplayContent).when(mWm.mRoot).getDisplayContent(anyInt());
- }
+ doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean());
+ doReturn(mDisplayContent).when(mWm.mRoot).getDisplayContent(anyInt());
when(mMockRunner.asBinder()).thenReturn(new Binder());
mController = spy(new RecentsAnimationController(mWm, mMockRunner, mAnimationCallbacks,
DEFAULT_DISPLAY));
@@ -146,8 +144,7 @@
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
.setStack(homeStack)
.setCreateTask(true)
- .build()
- .mAppWindowToken;
+ .build();
final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
final AppWindowToken hiddenAppWindow = createAppWindowToken(mDisplayContent,
@@ -172,8 +169,7 @@
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
.setStack(homeStack)
.setCreateTask(true)
- .build()
- .mAppWindowToken;
+ .build();
final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, appWindow, "win1");
@@ -202,8 +198,7 @@
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
.setStack(homeStack)
.setCreateTask(true)
- .build()
- .mAppWindowToken;
+ .build();
final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, appWindow, "win1");
@@ -234,8 +229,7 @@
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
.setStack(homeStack)
.setCreateTask(true)
- .build()
- .mAppWindowToken;
+ .build();
final WindowState hwin1 = createWindow(null, TYPE_BASE_APPLICATION, homeAppWindow, "hwin1");
homeAppWindow.addWindow(hwin1);
final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index b4ccd50..c6ffc46 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -97,7 +97,6 @@
.setStack(recentsStack)
.build();
ActivityRecord topActivity = new ActivityBuilder(mService).setCreateTask(true).build();
- topActivity.fullscreen = true;
topActivity.getActivityStack().moveToFront("testRecentsActivityVisiblility");
doCallRealMethod().when(mRootActivityContainer).ensureActivitiesVisible(
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index db105dd..afe18c3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -31,6 +31,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for RootWindowContainer.
@@ -40,6 +41,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class RootWindowContainerTests extends WindowTestsBase {
private static final int FAKE_CALLING_UID = 667;
@@ -91,18 +93,16 @@
@Test
public void testUpdateDefaultDisplayWindowingModeOnSettingsRetrieved() {
- synchronized (mWm.mGlobalLock) {
- assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
- mWm.getDefaultDisplayContentLocked().getWindowingMode());
+ assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
+ mWm.getDefaultDisplayContentLocked().getWindowingMode());
- mWm.mIsPc = true;
- mWm.mAtmService.mSupportsFreeformWindowManagement = true;
+ mWm.mIsPc = true;
+ mWm.mAtmService.mSupportsFreeformWindowManagement = true;
- mWm.mRoot.onSettingsRetrieved();
+ mWm.mRoot.onSettingsRetrieved();
- assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
- mWm.getDefaultDisplayContentLocked().getWindowingMode());
- }
+ assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
+ mWm.getDefaultDisplayContentLocked().getWindowingMode());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index 3e316f6..8326ad8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -35,6 +35,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.ArrayList;
@@ -44,6 +45,7 @@
*/
@MediumTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class RunningTasksTest extends ActivityTestsBase {
private static final ArraySet<Integer> PROFILE_IDS = new ArraySet<>();
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java
new file mode 100644
index 0000000..d1b6f6f
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServiceTestsBase.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 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.server.wm;
+
+import android.os.Handler;
+import android.testing.DexmakerShareClassLoaderRule;
+
+import org.junit.Rule;
+
+import java.util.concurrent.Callable;
+
+/** The base class which provides the common rule for test classes under wm package. */
+class SystemServiceTestsBase {
+ @Rule
+ public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
+ new DexmakerShareClassLoaderRule();
+ @Rule
+ public final SystemServicesTestRule mSystemServicesTestRule = new SystemServicesTestRule();
+
+ @WindowTestRunner.MethodWrapperRule
+ public final WindowManagerGlobalLockRule mLockRule =
+ new WindowManagerGlobalLockRule(mSystemServicesTestRule);
+
+ /** Waits until the main handler for WM has processed all messages. */
+ void waitUntilHandlersIdle() {
+ mLockRule.waitForLocked(mSystemServicesTestRule::waitUntilWindowManagerHandlersIdle);
+ }
+
+ boolean waitHandlerIdle(Handler handler) {
+ return waitHandlerIdle(handler, 0 /* timeout */);
+ }
+
+ boolean waitHandlerIdle(Handler handler, long timeout) {
+ return runWithScissors(handler, () -> { }, timeout);
+ }
+
+ boolean runWithScissors(Handler handler, Runnable r, long timeout) {
+ return mLockRule.runWithScissors(handler, r, timeout);
+ }
+
+ /** It is used when we want to wait for a result inside {@link WindowManagerGlobalLock}. */
+ <T> T awaitInWmLock(Callable<T> callable) {
+ return mLockRule.waitForLocked(callable);
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 5a4d399..ef9821b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -18,7 +18,6 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.os.Process.THREAD_PRIORITY_DEFAULT;
import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -36,7 +35,6 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.nullable;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
@@ -68,11 +66,12 @@
import com.android.server.DisplayThread;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
-import com.android.server.ServiceThread;
+import com.android.server.UiThread;
import com.android.server.Watchdog;
import com.android.server.am.ActivityManagerService;
import com.android.server.appop.AppOpsService;
import com.android.server.display.color.ColorDisplayService;
+import com.android.server.firewall.IntentFirewall;
import com.android.server.input.InputManagerService;
import com.android.server.pm.UserManagerService;
import com.android.server.policy.PermissionPolicyInternal;
@@ -105,13 +104,13 @@
private Context mContext;
private StaticMockitoSession mMockitoSession;
- ServiceThread mHandlerThread;
private ActivityManagerService mAmService;
private ActivityTaskManagerService mAtmService;
private WindowManagerService mWmService;
private TestWindowManagerPolicy mWMPolicy;
private WindowState.PowerManagerWrapper mPowerManagerWrapper;
private InputManagerService mImService;
+ private InputChannel mInputChannel;
/**
* Spied {@link SurfaceControl.Transaction} class than can be used to verify calls.
*/
@@ -147,10 +146,6 @@
}
private void setUpSystemCore() {
- mHandlerThread = new ServiceThread(
- "WmTestsThread", THREAD_PRIORITY_DEFAULT, true /* allowIo */);
- mHandlerThread.start();
-
doReturn(mock(Watchdog.class)).when(Watchdog::getInstance);
mContext = getInstrumentation().getTargetContext();
@@ -181,6 +176,11 @@
final AppOpsManager aom = mock(AppOpsManager.class);
doReturn(aom).when(mContext).getSystemService(eq(Context.APP_OPS_SERVICE));
+ // Prevent "WakeLock finalized while still held: SCREEN_FROZEN".
+ final PowerManager pm = mock(PowerManager.class);
+ doReturn(pm).when(mContext).getSystemService(eq(Context.POWER_SERVICE));
+ doReturn(mock(PowerManager.WakeLock.class)).when(pm).newWakeLock(anyInt(), anyString());
+
// DisplayManagerInternal
final DisplayManagerInternal dmi = mock(DisplayManagerInternal.class);
doReturn(dmi).when(() -> LocalServices.getService(eq(DisplayManagerInternal.class)));
@@ -214,11 +214,11 @@
// InputManagerService
mImService = mock(InputManagerService.class);
- // InputChannel is final and can't be mocked.
- final InputChannel[] input = InputChannel.openInputChannelPair(TAG_WM);
- if (input != null && input.length > 1) {
- doReturn(input[1]).when(mImService).monitorInput(anyString(), anyInt());
- }
+ // InputChannel cannot be mocked because it may pass to InputEventReceiver.
+ final InputChannel[] inputChannels = InputChannel.openInputChannelPair(TAG);
+ inputChannels[0].dispose();
+ mInputChannel = inputChannels[1];
+ doReturn(mInputChannel).when(mImService).monitorInput(anyString(), anyInt());
// StatusBarManagerInternal
final StatusBarManagerInternal sbmi = mock(StatusBarManagerInternal.class);
@@ -227,8 +227,7 @@
private void setUpActivityTaskManagerService() {
// ActivityManagerService
- mAmService = new ActivityManagerService(
- new AMTestInjector(mContext, mHandlerThread), mHandlerThread);
+ mAmService = new ActivityManagerService(new AMTestInjector(mContext), null /* thread */);
spyOn(mAmService);
doReturn(mock(IPackageManager.class)).when(mAmService).getPackageManager();
doNothing().when(mAmService).grantImplicitAccess(
@@ -246,6 +245,15 @@
doNothing().when(amInternal).startProcess(
any(), any(), anyBoolean(), anyBoolean(), any(), any());
doNothing().when(amInternal).updateOomLevelsForDisplay(anyInt());
+ doNothing().when(amInternal).broadcastGlobalConfigurationChanged(anyInt(), anyBoolean());
+ doNothing().when(amInternal).cleanUpServices(anyInt(), any(), any());
+ doReturn(UserHandle.USER_SYSTEM).when(amInternal).getCurrentUserId();
+ doReturn(TEST_USER_PROFILE_IDS).when(amInternal).getCurrentProfileIds();
+ doReturn(true).when(amInternal).isCurrentProfile(anyInt());
+ doReturn(true).when(amInternal).isUserRunning(anyInt(), anyInt());
+ doReturn(true).when(amInternal).hasStartedUserState(anyInt());
+ doReturn(false).when(amInternal).shouldConfirmCredentials(anyInt());
+ doReturn(false).when(amInternal).isActivityStartsLoggingEnabled();
LocalServices.addService(ActivityManagerInternal.class, amInternal);
mAtmService = new TestActivityTaskManagerService(mContext, mAmService);
@@ -289,7 +297,6 @@
}
private void tearDown() {
- waitUntilWindowManagerHandlersIdle();
// Unregister display listener from root to avoid issues with subsequent tests.
mContext.getSystemService(DisplayManager.class)
.unregisterDisplayListener(mAtmService.mRootActivityContainer);
@@ -297,37 +304,23 @@
// a static object, so we need to clean it up in tearDown(), even though we didn't set up
// in tests.
DeviceConfig.removeOnPropertiesChangedListener(mWmService.mPropertiesChangedListener);
- mWmService = null;
- mWMPolicy = null;
- mPowerManagerWrapper = null;
- tearDownLocalServices();
- tearDownSystemCore();
-
+ waitUntilWindowManagerHandlersIdle();
// Needs to explicitly dispose current static threads because there could be messages
// scheduled at a later time, and all mocks are invalid when it's executed.
DisplayThread.dispose();
AnimationThread.dispose();
+ UiThread.dispose();
+ mInputChannel.dispose();
+
+ tearDownLocalServices();
// Reset priority booster because animation thread has been changed.
WindowManagerService.sThreadPriorityBooster = new WindowManagerThreadPriorityBooster();
+ mMockitoSession.finishMocking();
Mockito.framework().clearInlineMocks();
}
- private void tearDownSystemCore() {
- if (mMockitoSession != null) {
- mMockitoSession.finishMocking();
- mMockitoSession = null;
- }
-
- if (mHandlerThread != null) {
- // Make sure there are no running messages and then quit the thread so the next test
- // won't be affected.
- mHandlerThread.getThreadHandler().runWithScissors(mHandlerThread::quit,
- 0 /* timeout */);
- }
- }
-
private static void tearDownLocalServices() {
LocalServices.removeServiceForTest(DisplayManagerInternal.class);
LocalServices.removeServiceForTest(PowerManagerInternal.class);
@@ -375,7 +368,6 @@
waitHandlerIdle(wm.mH);
waitHandlerIdle(wm.mAnimationHandler);
waitHandlerIdle(SurfaceAnimationThread.getHandler());
- waitHandlerIdle(mHandlerThread.getThreadHandler());
}
private void waitHandlerIdle(Handler handler) {
@@ -435,8 +427,12 @@
ams.mActivityTaskManager = this;
ams.mAtmInternal = mInternal;
onActivityManagerInternalAdded();
- initialize(
- ams.mIntentFirewall, ams.mPendingIntentController, mHandlerThread.getLooper());
+
+ final IntentFirewall intentFirewall = mock(IntentFirewall.class);
+ doReturn(true).when(intentFirewall).checkStartActivity(
+ any(), anyInt(), anyInt(), nullable(String.class), any());
+ initialize(intentFirewall, null /* intentController */,
+ DisplayThread.getHandler().getLooper());
spyOn(getLifecycleManager());
spyOn(getLockTaskController());
spyOn(getTaskChangeNotificationController());
@@ -493,11 +489,9 @@
// TODO: Can we just mock this?
private static class AMTestInjector extends ActivityManagerService.Injector {
- private ServiceThread mHandlerThread;
- AMTestInjector(Context context, ServiceThread handlerThread) {
+ AMTestInjector(Context context) {
super(context);
- mHandlerThread = handlerThread;
}
@Override
@@ -512,7 +506,7 @@
@Override
public Handler getUiHandler(ActivityManagerService service) {
- return mHandlerThread.getThreadHandler();
+ return UiThread.getHandler();
}
@Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index e6c9b9f..dd85f69 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -29,6 +29,8 @@
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
@@ -65,6 +67,10 @@
@SmallTest
@Presubmit
public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
+ private static final Rect DISPLAY_BOUNDS = new Rect(/* left */ 0, /* top */ 0,
+ /* right */ 1920, /* bottom */ 1080);
+ private static final Rect DISPLAY_STABLE_BOUNDS = new Rect(/* left */ 100,
+ /* top */ 200, /* right */ 1620, /* bottom */ 680);
private ActivityRecord mActivity;
@@ -614,7 +620,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(0, mResult.mBounds.left);
+ assertEquals(DISPLAY_STABLE_BOUNDS.left, mResult.mBounds.left);
}
@Test
@@ -630,7 +636,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(0, mResult.mBounds.top);
+ assertEquals(DISPLAY_STABLE_BOUNDS.top, mResult.mBounds.top);
}
@Test
@@ -646,8 +652,8 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(0, mResult.mBounds.left);
- assertEquals(0, mResult.mBounds.top);
+ assertEquals(DISPLAY_STABLE_BOUNDS.left, mResult.mBounds.left);
+ assertEquals(DISPLAY_STABLE_BOUNDS.top, mResult.mBounds.top);
}
@Test
@@ -663,7 +669,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(1920, mResult.mBounds.right);
+ assertEquals(DISPLAY_STABLE_BOUNDS.right, mResult.mBounds.right);
}
@Test
@@ -679,7 +685,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(1080, mResult.mBounds.bottom);
+ assertEquals(DISPLAY_STABLE_BOUNDS.bottom, mResult.mBounds.bottom);
}
@Test
@@ -695,8 +701,8 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(1920, mResult.mBounds.right);
- assertEquals(1080, mResult.mBounds.bottom);
+ assertEquals(DISPLAY_STABLE_BOUNDS.right, mResult.mBounds.right);
+ assertEquals(DISPLAY_STABLE_BOUNDS.bottom, mResult.mBounds.bottom);
}
@Test
@@ -712,7 +718,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(new Rect(900, 500, 1020, 580), mResult.mBounds);
+ assertEquals(new Rect(800, 400, 920, 480), mResult.mBounds);
}
@Test
@@ -728,7 +734,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(new Rect(0, 500, 120, 580), mResult.mBounds);
+ assertEquals(new Rect(100, 400, 220, 480), mResult.mBounds);
}
@Test
@@ -744,7 +750,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(new Rect(900, 0, 1020, 80), mResult.mBounds);
+ assertEquals(new Rect(800, 200, 920, 280), mResult.mBounds);
}
@Test
@@ -760,7 +766,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(new Rect(0, 0, 120, 80), mResult.mBounds);
+ assertEquals(new Rect(100, 200, 220, 280), mResult.mBounds);
}
@Test
@@ -776,7 +782,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(new Rect(1800, 500, 1920, 580), mResult.mBounds);
+ assertEquals(new Rect(1500, 400, 1620, 480), mResult.mBounds);
}
@Test
@@ -792,7 +798,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(new Rect(900, 1000, 1020, 1080), mResult.mBounds);
+ assertEquals(new Rect(800, 600, 920, 680), mResult.mBounds);
}
@Test
@@ -808,7 +814,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(new Rect(1800, 1000, 1920, 1080), mResult.mBounds);
+ assertEquals(new Rect(1500, 600, 1620, 680), mResult.mBounds);
}
@Test
@@ -819,12 +825,12 @@
mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
- .setWidthFraction(0.0625f).setHeightFraction(0.1f).build();
+ .setWidthFraction(0.125f).setHeightFraction(0.1f).build();
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
/* source */ null, /* options */ null, mCurrent, mResult));
- assertEquals(new Rect(900, 486, 1020, 594), mResult.mBounds);
+ assertEquals(new Rect(765, 416, 955, 464), mResult.mBounds);
}
@Test
@@ -952,13 +958,12 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
mActivity, /* source */ null, options, mCurrent, mResult));
- final Rect displayBounds = freeformDisplay.getBounds();
assertEquals("Distance to left and right should be equal.",
- mResult.mBounds.left - displayBounds.left,
- displayBounds.right - mResult.mBounds.right);
+ mResult.mBounds.left - DISPLAY_STABLE_BOUNDS.left,
+ DISPLAY_STABLE_BOUNDS.right - mResult.mBounds.right, /* delta */ 1);
assertEquals("Distance to top and bottom should be equal.",
- mResult.mBounds.top - displayBounds.top,
- displayBounds.bottom - mResult.mBounds.bottom);
+ mResult.mBounds.top - DISPLAY_STABLE_BOUNDS.top,
+ DISPLAY_STABLE_BOUNDS.bottom - mResult.mBounds.bottom, /* delta */ 1);
}
@Test
@@ -1041,15 +1046,16 @@
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
- mCurrent.mBounds.set(100, 200, 2120, 1380);
+ mCurrent.mBounds.set(100, 300, 1820, 1380);
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
mActivity, /* source */ null, options, mCurrent, mResult));
- assertTrue("Result bounds should start from origin, but it's " + mResult.mBounds,
- mResult.mBounds.left == 0 && mResult.mBounds.top == 0);
+ assertTrue("Result bounds should start from app bounds's origin, but it's "
+ + mResult.mBounds,
+ mResult.mBounds.left == 100 && mResult.mBounds.top == 200);
}
@Test
@@ -1067,15 +1073,16 @@
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
- mCurrent.mBounds.set(100, 200, 2120, 1380);
+ mCurrent.mBounds.set(100, 300, 1820, 1380);
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
mActivity, /* source */ null, options, mCurrent, mResult));
- assertTrue("Result bounds should start from origin, but it's " + mResult.mBounds,
- mResult.mBounds.left == -100 && mResult.mBounds.top == 0);
+ assertTrue("Result bounds should start from top-right corner of app bounds, but "
+ + "it's " + mResult.mBounds,
+ mResult.mBounds.left == -100 && mResult.mBounds.top == 200);
}
@Test
@@ -1083,6 +1090,11 @@
final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
WINDOWING_MODE_FREEFORM);
+ // This test case requires a relatively big app bounds to ensure the default size calculated
+ // by letterbox won't be too small to hold the minimum width/height.
+ freeformDisplay.mDisplayContent.mDisplayFrames.mStable.set(/* left */ 10, /* top */ 10,
+ /* right */ 1910, /* top */ 1070);
+
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
@@ -1245,7 +1257,7 @@
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
mActivity, /* source */ null, options, mCurrent, mResult));
- assertEquals(new Rect(0, 0, 300, 300), mResult.mBounds);
+ assertEquals(new Rect(100, 200, 400, 500), mResult.mBounds);
}
@Test
@@ -1301,9 +1313,15 @@
private TestActivityDisplay createNewActivityDisplay(int windowingMode) {
final TestActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
display.setWindowingMode(windowingMode);
- display.setBounds(/* left */ 0, /* top */ 0, /* right */ 1920, /* bottom */ 1080);
+ display.setBounds(DISPLAY_BOUNDS);
display.getConfiguration().densityDpi = DENSITY_DEFAULT;
display.getConfiguration().orientation = ORIENTATION_LANDSCAPE;
+ display.mDisplayContent.mDisplayFrames.mStable.set(DISPLAY_STABLE_BOUNDS);
+ spyOn(display.mDisplayContent.mDisplayFrames);
+
+ // We didn't set up the overall environment for this test, so we need to mute the side
+ // effect of layout passes that loosen the stable frame.
+ doNothing().when(display.mDisplayContent.mDisplayFrames).onBeginLayout();
return display;
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
index eb351b6..dc89f50 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -22,7 +22,6 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static org.junit.Assert.assertFalse;
@@ -38,6 +37,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for the {@link TaskPositioningController} class.
@@ -47,6 +47,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskPositioningControllerTests extends WindowTestsBase {
private static final int TIMEOUT_MS = 1000;
@@ -64,30 +65,23 @@
mWindow = createWindow(null, TYPE_BASE_APPLICATION, "window");
mWindow.mInputChannel = new InputChannel();
- synchronized (mWm.mGlobalLock) {
- mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
- spyOn(mDisplayContent);
- doReturn(mock(InputMonitor.class)).when(mDisplayContent).getInputMonitor();
- }
+ mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
+ doReturn(mock(InputMonitor.class)).when(mDisplayContent).getInputMonitor();
}
@Test
public void testStartAndFinishPositioning() {
- synchronized (mWm.mGlobalLock) {
- assertFalse(mTarget.isPositioningLocked());
- assertNull(mTarget.getDragWindowHandleLocked());
- }
+ assertFalse(mTarget.isPositioningLocked());
+ assertNull(mTarget.getDragWindowHandleLocked());
assertTrue(mTarget.startMovingTask(mWindow.mClient, 0, 0));
- synchronized (mWm.mGlobalLock) {
- assertTrue(mTarget.isPositioningLocked());
- assertNotNull(mTarget.getDragWindowHandleLocked());
- }
+ assertTrue(mTarget.isPositioningLocked());
+ assertNotNull(mTarget.getDragWindowHandleLocked());
mTarget.finishTaskPositioning();
// Wait until the looper processes finishTaskPositioning.
- assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS));
+ assertTrue(waitHandlerIdle(mWm.mH, TIMEOUT_MS));
assertFalse(mTarget.isPositioningLocked());
assertNull(mTarget.getDragWindowHandleLocked());
@@ -96,21 +90,17 @@
@FlakyTest(bugId = 129507487)
@Test
public void testFinishPositioningWhenAppRequested() {
- synchronized (mWm.mGlobalLock) {
- assertFalse(mTarget.isPositioningLocked());
- assertNull(mTarget.getDragWindowHandleLocked());
- }
+ assertFalse(mTarget.isPositioningLocked());
+ assertNull(mTarget.getDragWindowHandleLocked());
assertTrue(mTarget.startMovingTask(mWindow.mClient, 0, 0));
- synchronized (mWm.mGlobalLock) {
- assertTrue(mTarget.isPositioningLocked());
- assertNotNull(mTarget.getDragWindowHandleLocked());
- }
+ assertTrue(mTarget.isPositioningLocked());
+ assertNotNull(mTarget.getDragWindowHandleLocked());
mTarget.finishTaskPositioning(mWindow.mClient);
// Wait until the looper processes finishTaskPositioning.
- assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS));
+ assertTrue(waitHandlerIdle(mWm.mH, TIMEOUT_MS));
assertFalse(mTarget.isPositioningLocked());
assertNull(mTarget.getDragWindowHandleLocked());
@@ -118,27 +108,23 @@
@Test
public void testHandleTapOutsideTask() {
- synchronized (mWm.mGlobalLock) {
- assertFalse(mTarget.isPositioningLocked());
- assertNull(mTarget.getDragWindowHandleLocked());
- }
+ assertFalse(mTarget.isPositioningLocked());
+ assertNull(mTarget.getDragWindowHandleLocked());
final DisplayContent content = mock(DisplayContent.class);
- when(content.findTaskForResizePoint(anyInt(), anyInt())).thenReturn(mWindow.getTask());
+ doReturn(mWindow.getTask()).when(content).findTaskForResizePoint(anyInt(), anyInt());
assertNotNull(mWindow.getTask().getTopVisibleAppMainWindow());
mTarget.handleTapOutsideTask(content, 0, 0);
// Wait until the looper processes finishTaskPositioning.
- assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS));
+ assertTrue(waitHandlerIdle(mWm.mH, TIMEOUT_MS));
- synchronized (mWm.mGlobalLock) {
- assertTrue(mTarget.isPositioningLocked());
- assertNotNull(mTarget.getDragWindowHandleLocked());
- }
+ assertTrue(mTarget.isPositioningLocked());
+ assertNotNull(mTarget.getDragWindowHandleLocked());
mTarget.finishTaskPositioning();
// Wait until the looper processes finishTaskPositioning.
- assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS));
+ assertTrue(waitHandlerIdle(mWm.mH, TIMEOUT_MS));
assertFalse(mTarget.isPositioningLocked());
assertNull(mTarget.getDragWindowHandleLocked());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index c83401b..86e307b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -51,7 +51,6 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import android.app.ActivityManager;
@@ -78,6 +77,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -98,6 +98,7 @@
*/
@MediumTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskRecordTests extends ActivityTestsBase {
private static final String TASK_TAG = "task";
@@ -237,7 +238,7 @@
ActivityStack stack = new StackBuilder(mRootActivityContainer).setDisplay(display)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
TaskRecord task = stack.getChildAt(0);
- task.getRootActivity().mAppWindowToken.setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
+ task.getRootActivity().setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
DisplayInfo info = new DisplayInfo();
display.mDisplay.getDisplayInfo(info);
final Rect fullScreenBounds = new Rect(0, 0, info.logicalWidth, info.logicalHeight);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
index 74ccccc..92ddb35 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -32,15 +32,17 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for the {@link DisplayContent.TaskStackContainers} container in {@link DisplayContent}.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:TaskStackContainersTests
+ * atest WmTests:TaskStackContainersTests
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskStackContainersTests extends WindowTestsBase {
private TaskStack mPinnedStack;
@@ -52,7 +54,7 @@
// Stack should contain visible app window to be considered visible.
final Task pinnedTask = createTaskInStack(mPinnedStack, 0 /* userId */);
assertFalse(mPinnedStack.isVisible());
- final WindowTestUtils.TestAppWindowToken pinnedApp =
+ final AppWindowToken pinnedApp =
WindowTestUtils.createTestAppWindowToken(mDisplayContent);
pinnedTask.addChild(pinnedApp, 0 /* addPos */);
assertTrue(mPinnedStack.isVisible());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
index 70ed62a..2eb6ea4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
@@ -34,15 +34,17 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for the {@link TaskStack} class.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:TaskStackTests
+ * atest WmTests:TaskStackTests
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskStackTests extends WindowTestsBase {
@Test
@@ -66,13 +68,13 @@
public void testClosingAppDifferentStackOrientation() {
final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
final Task task1 = createTaskInStack(stack, 0 /* userId */);
- WindowTestUtils.TestAppWindowToken appWindowToken1 =
+ AppWindowToken appWindowToken1 =
WindowTestUtils.createTestAppWindowToken(mDisplayContent);
task1.addChild(appWindowToken1, 0);
appWindowToken1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
final Task task2 = createTaskInStack(stack, 1 /* userId */);
- WindowTestUtils.TestAppWindowToken appWindowToken2 =
+ AppWindowToken appWindowToken2 =
WindowTestUtils.createTestAppWindowToken(mDisplayContent);
task2.addChild(appWindowToken2, 0);
appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
@@ -86,13 +88,13 @@
public void testMoveTaskToBackDifferentStackOrientation() {
final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
final Task task1 = createTaskInStack(stack, 0 /* userId */);
- WindowTestUtils.TestAppWindowToken appWindowToken1 =
+ AppWindowToken appWindowToken1 =
WindowTestUtils.createTestAppWindowToken(mDisplayContent);
task1.addChild(appWindowToken1, 0);
appWindowToken1.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
final Task task2 = createTaskInStack(stack, 1 /* userId */);
- WindowTestUtils.TestAppWindowToken appWindowToken2 =
+ AppWindowToken appWindowToken2 =
WindowTestUtils.createTestAppWindowToken(mDisplayContent);
task2.addChild(appWindowToken2, 0);
appWindowToken2.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
@@ -149,7 +151,6 @@
// After removing, the task will be isolated.
assertNull(task.getParent());
assertEquals(0, task.getChildCount());
- assertNull(task.getController());
}
@Test
@@ -176,13 +177,8 @@
public void testStackOutset() {
final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
final int stackOutset = 10;
- // Clear the handler and hold the lock for mock, to prevent multi-thread issue.
- waitUntilHandlersIdle();
- synchronized (mWm.mGlobalLock) {
- spyOn(stack);
-
- doReturn(stackOutset).when(stack).getStackOutset();
- }
+ spyOn(stack);
+ doReturn(stackOutset).when(stack).getStackOutset();
final Rect stackBounds = new Rect(200, 200, 800, 1000);
// Update surface position and size by the given bounds.
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 4184201..f117ff0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -29,22 +29,24 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Test class for {@link Task}.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:TaskTests
+ * atest WmTests:TaskTests
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class TaskTests extends WindowTestsBase {
@Test
public void testRemoveContainer() {
final TaskStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
final WindowTestUtils.TestTask task = WindowTestUtils.createTestTask(stackController1);
- final WindowTestUtils.TestAppWindowToken appToken =
+ final AppWindowToken appToken =
WindowTestUtils.createAppWindowTokenInTask(mDisplayContent, task);
task.removeIfPossible();
@@ -58,7 +60,7 @@
public void testRemoveContainer_deferRemoval() {
final TaskStack stackController1 = createTaskStackOnDisplay(mDisplayContent);
final WindowTestUtils.TestTask task = WindowTestUtils.createTestTask(stackController1);
- final WindowTestUtils.TestAppWindowToken appToken =
+ final AppWindowToken appToken =
WindowTestUtils.createAppWindowTokenInTask(mDisplayContent, task);
task.mShouldDeferRemoval = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
index a758681..09e5027 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
@@ -111,4 +111,8 @@
@Override
public void dispatchPointerCaptureChanged(boolean hasCapture) {
}
+
+ @Override
+ public void showInsets(int types, boolean fromIme) throws RemoteException {
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index a91daf0..2e86178 100644
--- a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -24,15 +24,17 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Test class for {@link AppTransition}.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:UnknownAppVisibilityControllerTest
+ * atest WmTests:UnknownAppVisibilityControllerTest
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class UnknownAppVisibilityControllerTest extends WindowTestsBase {
@Before
@@ -48,7 +50,7 @@
mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(token);
// Make sure our handler processed the message.
- mWm.mH.runWithScissors(() -> { }, 0);
+ waitHandlerIdle(mWm.mH);
assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
}
@@ -64,7 +66,7 @@
mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(token2);
// Make sure our handler processed the message.
- mWm.mH.runWithScissors(() -> { }, 0);
+ waitHandlerIdle(mWm.mH);
assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 6249bde..14d8a9d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -30,6 +30,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for the {@link WallpaperController} class.
@@ -39,37 +40,36 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class WallpaperControllerTests extends WindowTestsBase {
@Test
public void testWallpaperScreenshot() {
WindowSurfaceController windowSurfaceController = mock(WindowSurfaceController.class);
- synchronized (mWm.mGlobalLock) {
- // No wallpaper
- final DisplayContent dc = createNewDisplay();
- assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
+ // No wallpaper
+ final DisplayContent dc = createNewDisplay();
+ assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
- // No wallpaper WSA Surface
- WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
- true, dc, true /* ownerCanManageAppTokens */);
- WindowState wallpaperWindow = createWindow(null /* parent */, TYPE_WALLPAPER,
- wallpaperWindowToken, "wallpaperWindow");
- assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
+ // No wallpaper WSA Surface
+ WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
+ true, dc, true /* ownerCanManageAppTokens */);
+ WindowState wallpaperWindow = createWindow(null /* parent */, TYPE_WALLPAPER,
+ wallpaperWindowToken, "wallpaperWindow");
+ assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
- // Wallpaper with not visible WSA surface.
- wallpaperWindow.mWinAnimator.mSurfaceController = windowSurfaceController;
- wallpaperWindow.mWinAnimator.mLastAlpha = 1;
- assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
+ // Wallpaper with not visible WSA surface.
+ wallpaperWindow.mWinAnimator.mSurfaceController = windowSurfaceController;
+ wallpaperWindow.mWinAnimator.mLastAlpha = 1;
+ assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
- when(windowSurfaceController.getShown()).thenReturn(true);
+ when(windowSurfaceController.getShown()).thenReturn(true);
- // Wallpaper with WSA alpha set to 0.
- wallpaperWindow.mWinAnimator.mLastAlpha = 0;
- assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
+ // Wallpaper with WSA alpha set to 0.
+ wallpaperWindow.mWinAnimator.mLastAlpha = 0;
+ assertFalse(dc.mWallpaperController.canScreenshotWallpaper());
- // Wallpaper window with WSA Surface
- wallpaperWindow.mWinAnimator.mLastAlpha = 1;
- assertTrue(dc.mWallpaperController.canScreenshotWallpaper());
- }
+ // Wallpaper window with WSA Surface
+ wallpaperWindow.mWinAnimator.mLastAlpha = 1;
+ assertTrue(dc.mWallpaperController.canScreenshotWallpaper());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
deleted file mode 100644
index fc78635..0000000
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.content.res.Configuration.EMPTY;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.content.res.Configuration;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-
-/**
- * Test class for {@link WindowContainerController}.
- *
- * Build/Install/Run:
- * atest WmTests:WindowContainerControllerTests
- */
-@SmallTest
-@Presubmit
-public class WindowContainerControllerTests extends WindowTestsBase {
-
- @Test
- public void testCreation() {
- final WindowContainerController controller = new WindowContainerController<>(null, mWm);
- final WindowContainer container = new WindowContainer(mWm);
-
- container.setController(controller);
- assertEquals(controller, container.getController());
- assertEquals(controller.mContainer, container);
- }
-
- @Test
- public void testSetContainer() {
- final WindowContainerController controller = new WindowContainerController<>(null, mWm);
- final WindowContainer container = new WindowContainer(mWm);
-
- controller.setContainer(container);
- assertEquals(controller.mContainer, container);
-
- // Assert we can't change the container to another one once set
- boolean gotException = false;
- try {
- controller.setContainer(new WindowContainer(mWm));
- } catch (IllegalArgumentException e) {
- gotException = true;
- }
- assertTrue(gotException);
-
- // Assert that we can set the container to null.
- controller.setContainer(null);
- assertNull(controller.mContainer);
- }
-
- @Test
- public void testRemoveContainer() {
- final WindowContainerController controller = new WindowContainerController<>(null, mWm);
- final WindowContainer container = new WindowContainer(mWm);
-
- controller.setContainer(container);
- assertEquals(controller.mContainer, container);
-
- controller.removeContainer();
- assertNull(controller.mContainer);
- }
-
- @Test
- public void testOnOverrideConfigurationChanged() {
- final WindowContainerController controller = new WindowContainerController<>(null, mWm);
- final WindowContainer container = new WindowContainer(mWm);
-
- controller.setContainer(container);
- assertEquals(controller.mContainer, container);
- assertEquals(EMPTY, container.getRequestedOverrideConfiguration());
-
- final Configuration config = new Configuration();
- config.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
- config.windowConfiguration.setAppBounds(10, 10, 10, 10);
-
- // Assert that the config change through the controller is propagated to the container.
- controller.onRequestedOverrideConfigurationChanged(config);
- assertEquals(config, container.getRequestedOverrideConfiguration());
-
- // Assert the container configuration isn't changed after removal from the controller.
- controller.removeContainer();
- controller.onRequestedOverrideConfigurationChanged(EMPTY);
- assertEquals(config, container.getRequestedOverrideConfiguration());
- }
-}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 921f105..8117ff6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -216,44 +216,6 @@
}
@Test
- public void testRemoveImmediately_WithController() {
- final WindowContainer container = new WindowContainer(mWm);
- final WindowContainerController controller = new WindowContainerController<>(null, mWm);
-
- container.setController(controller);
- assertEquals(controller, container.getController());
- assertEquals(container, controller.mContainer);
-
- container.removeImmediately();
- assertNull(container.getController());
- assertNull(controller.mContainer);
- }
-
- @Test
- public void testSetController() {
- final WindowContainerController controller = new WindowContainerController<>(null, mWm);
- final WindowContainer container = new WindowContainer(mWm);
-
- container.setController(controller);
- assertEquals(controller, container.getController());
- assertEquals(container, controller.mContainer);
-
- // Assert we can't change the controller to another one once set
- boolean gotException = false;
- try {
- container.setController(new WindowContainerController<>(null, mWm));
- } catch (IllegalArgumentException e) {
- gotException = true;
- }
- assertTrue(gotException);
-
- // Assert that we can set the controller to null.
- container.setController(null);
- assertNull(container.getController());
- assertNull(controller.mContainer);
- }
-
- @Test
public void testAddChildByIndex() {
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index 60cefe8..3563feb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -43,16 +43,18 @@
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mockito;
/**
* Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:WindowFrameTests
+ * atest WmTests:WindowFrameTests
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class WindowFrameTests extends WindowTestsBase {
private final IWindow mIWindow = new TestIWindow();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerGlobalLockRule.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerGlobalLockRule.java
index e0c314f..c5f13e0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerGlobalLockRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerGlobalLockRule.java
@@ -27,6 +27,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -59,34 +62,41 @@
return base;
}
- void waitUntilHandlersIdle() {
- if (!mIsLocked) {
- mSystemServicesTestRule.waitUntilWindowManagerHandlersIdle();
- return;
- }
-
- waitForLocked(mSystemServicesTestRule::waitUntilWindowManagerHandlersIdle);
+ boolean runWithScissors(Handler handler, Runnable r, long timeout) {
+ return waitForLocked(() -> handler.runWithScissors(r, timeout));
}
- void runWithScissors(Handler handler, Runnable r, long timeout) {
- if (!mIsLocked) {
- handler.runWithScissors(r, timeout);
- return;
- }
-
- waitForLocked(() -> handler.runWithScissors(r, timeout));
+ void waitForLocked(Runnable r) {
+ waitForLocked(() -> {
+ r.run();
+ return null;
+ });
}
/**
* If the test holds the lock, we need to invoke {@link Object#wait} to release it so other
* threads won't be blocked when we are waiting.
*/
- private void waitForLocked(Runnable r) {
+ <T> T waitForLocked(Callable<T> callable) {
+ if (!mIsLocked) {
+ try {
+ return callable.call();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
final Object lock = mSystemServicesTestRule.getWindowManagerService().mGlobalLock;
final AtomicBoolean done = new AtomicBoolean(false);
+ final List<T> result = Arrays.asList((T) null);
+ final Exception[] exception = { null };
AsyncTask.SERIAL_EXECUTOR.execute(() -> {
- r.run();
+ try {
+ result.set(0, callable.call());
+ } catch (Exception e) {
+ exception[0] = e;
+ }
synchronized (lock) {
lock.notifyAll();
done.set(true);
@@ -101,6 +111,11 @@
}
}
}
+ if (exception[0] != null) {
+ throw new RuntimeException(exception[0]);
+ }
+
+ return result.get(0);
}
/** Wraps methods annotated with {@link org.junit.Test}. */
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 8c56ffa..cc90ca1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -26,13 +26,13 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
import android.content.pm.ApplicationInfo;
import android.platform.test.annotations.Presubmit;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Mockito;
@@ -43,6 +43,7 @@
* atest WmTests:WindowProcessControllerTests
*/
@Presubmit
+@RunWith(WindowTestRunner.class)
public class WindowProcessControllerTests extends ActivityTestsBase {
WindowProcessController mWpc;
@@ -97,7 +98,7 @@
public void testSetRunningRecentsAnimation() {
mWpc.setRunningRecentsAnimation(true);
mWpc.setRunningRecentsAnimation(false);
- mService.mH.runWithScissors(() -> {}, 0);
+ waitHandlerIdle(mService.mH);
InOrder orderVerifier = Mockito.inOrder(mMockListener);
orderVerifier.verify(mMockListener).setRunningRemoteAnimation(eq(true));
@@ -108,7 +109,7 @@
public void testSetRunningRemoteAnimation() {
mWpc.setRunningRemoteAnimation(true);
mWpc.setRunningRemoteAnimation(false);
- mService.mH.runWithScissors(() -> {}, 0);
+ waitHandlerIdle(mService.mH);
InOrder orderVerifier = Mockito.inOrder(mMockListener);
orderVerifier.verify(mMockListener).setRunningRemoteAnimation(eq(true));
@@ -122,7 +123,7 @@
mWpc.setRunningRecentsAnimation(false);
mWpc.setRunningRemoteAnimation(false);
- mService.mH.runWithScissors(() -> {}, 0);
+ waitHandlerIdle(mService.mH);
InOrder orderVerifier = Mockito.inOrder(mMockListener);
orderVerifier.verify(mMockListener, times(3)).setRunningRemoteAnimation(eq(true));
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index f41f126..e5fb28d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -57,6 +57,7 @@
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
import android.graphics.Insets;
import android.graphics.Matrix;
@@ -329,7 +330,7 @@
// turn on the screen.
appWindowToken.setCurrentLaunchCanTurnScreenOn(true);
first.mAttrs.flags &= ~WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
- doReturn(true).when(appWindowToken.mActivityRecord).canTurnScreenOn();
+ doReturn(true).when(appWindowToken).canTurnScreenOn();
testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
false /* expectedCurrentLaunchCanTurnScreenOn */);
@@ -547,4 +548,29 @@
assertEquals(OFFSET_SUM, values[Matrix.MTRANS_X], 0f);
assertEquals(0f, values[Matrix.MTRANS_Y], 0f);
}
+
+ @Test
+ public void testCantReceiveTouchDuringRecentsAnimation() {
+ final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
+
+ // Mock active recents animation
+ RecentsAnimationController recentsController = mock(RecentsAnimationController.class);
+ when(recentsController.isAnimatingTask(win0.mAppToken.getTask())).thenReturn(true);
+ mWm.setRecentsAnimationController(recentsController);
+ assertTrue(win0.cantReceiveTouchInput());
+ }
+
+ @Test
+ public void testCantReceiveTouchWhenAppTokenHiddenRequested() {
+ final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
+ win0.mAppToken.hiddenRequested = true;
+ assertTrue(win0.cantReceiveTouchInput());
+ }
+
+ @Test
+ public void testCantReceiveTouchWhenShouldIgnoreInput() {
+ final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
+ win0.mAppToken.getStack().setAdjustedForMinimizedDock(1 /* Any non 0 value works */);
+ assertTrue(win0.cantReceiveTouchInput());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
index a7a785d..c627c19 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
@@ -19,14 +19,17 @@
import static android.app.AppOpsManager.OP_NONE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.ActivityTestsBase.ActivityBuilder.createIntentAndActivityInfo;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import android.app.ActivityManager;
-import android.content.ComponentName;
-import android.os.Build;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.os.IBinder;
-import android.view.IApplicationToken;
+import android.util.Pair;
import android.view.IWindow;
import android.view.WindowManager;
@@ -48,57 +51,26 @@
}
/** Creates an {@link AppWindowToken} and adds it to the specified {@link Task}. */
- static TestAppWindowToken createAppWindowTokenInTask(DisplayContent dc, Task task) {
- final TestAppWindowToken newToken = createTestAppWindowToken(dc);
+ static AppWindowToken createAppWindowTokenInTask(DisplayContent dc, Task task) {
+ final AppWindowToken newToken = createTestAppWindowToken(dc);
task.addChild(newToken, POSITION_TOP);
return newToken;
}
- static TestAppWindowToken createTestAppWindowToken(DisplayContent dc) {
+ static AppWindowToken createTestAppWindowToken(DisplayContent dc) {
synchronized (dc.mWmService.mGlobalLock) {
- return new TestAppWindowToken(dc);
+ Pair<Intent, ActivityInfo> pair = createIntentAndActivityInfo();
+ final AppWindowToken token = new AppWindowToken(dc.mWmService,
+ dc.mWmService.mAtmService, new ActivityRecord.Token(pair.first), pair.second,
+ null, pair.first, dc);
+ token.setOccludesParent(true);
+ token.setHidden(false);
+ token.hiddenRequested = false;
+ spyOn(token);
+ return token;
}
}
- /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
- static class TestAppWindowToken extends AppWindowToken {
- boolean mOnTop = false;
-
- private TestAppWindowToken(DisplayContent dc) {
- super(dc.mWmService, new IApplicationToken.Stub() {
- @Override
- public String getName() {
- return null;
- }
- }, new ComponentName("", ""), false, dc, true /* fillsParent */);
- mTargetSdk = Build.VERSION_CODES.CUR_DEVELOPMENT;
- mActivityRecord = mock(ActivityRecord.class);
- mActivityRecord.app = mock(WindowProcessController.class);
- }
-
- int getWindowsCount() {
- return mChildren.size();
- }
-
- boolean hasWindow(WindowState w) {
- return mChildren.contains(w);
- }
-
- WindowState getFirstChild() {
- return mChildren.peekFirst();
- }
-
- WindowState getLastChild() {
- return mChildren.peekLast();
- }
-
- @Override
- boolean isOnTop() {
- return mOnTop;
- }
-
- }
-
static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {
return createTestWindowToken(type, dc, false /* persistOnEmpty */);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 8930e5a..4c4b21e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -42,7 +42,6 @@
import android.content.Context;
import android.content.res.Configuration;
-import android.testing.DexmakerShareClassLoaderRule;
import android.util.Log;
import android.view.Display;
import android.view.DisplayInfo;
@@ -55,7 +54,6 @@
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.Rule;
import java.util.HashSet;
import java.util.LinkedList;
@@ -65,7 +63,7 @@
*
* Make sure any requests to WM hold the WM lock if needed b/73966377
*/
-class WindowTestsBase {
+class WindowTestsBase extends SystemServiceTestsBase {
private static final String TAG = WindowTestsBase.class.getSimpleName();
WindowManagerService mWm;
@@ -92,16 +90,6 @@
*/
Transaction mTransaction;
- @Rule
- public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
- new DexmakerShareClassLoaderRule();
- @Rule
- public final SystemServicesTestRule mSystemServicesTestRule = new SystemServicesTestRule();
-
- @WindowTestRunner.MethodWrapperRule
- public final WindowManagerGlobalLockRule mLockRule =
- new WindowManagerGlobalLockRule(mSystemServicesTestRule);
-
@BeforeClass
public static void setUpOnceBase() {
AttributeCache.init(getInstrumentation().getTargetContext());
@@ -205,13 +193,6 @@
}
}
- /**
- * Waits until the main handler for WM has processed all messages.
- */
- void waitUntilHandlersIdle() {
- mLockRule.waitUntilHandlersIdle();
- }
-
private WindowToken createWindowToken(
DisplayContent dc, int windowingMode, int activityType, int type) {
synchronized (mWm.mGlobalLock) {
@@ -227,11 +208,11 @@
return createTestAppWindowToken(dc, windowingMode, activityType);
}
- WindowTestUtils.TestAppWindowToken createTestAppWindowToken(DisplayContent dc, int
+ AppWindowToken createTestAppWindowToken(DisplayContent dc, int
windowingMode, int activityType) {
final TaskStack stack = createTaskStackOnDisplay(windowingMode, activityType, dc);
final Task task = createTaskInStack(stack, 0 /* userId */);
- final WindowTestUtils.TestAppWindowToken appWindowToken =
+ final AppWindowToken appWindowToken =
WindowTestUtils.createTestAppWindowToken(dc);
task.addChild(appWindowToken, 0);
return appWindowToken;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index 2105ab0..63b50b5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -47,6 +47,7 @@
import org.junit.After;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.HashMap;
@@ -61,6 +62,7 @@
*/
@SmallTest
@Presubmit
+@RunWith(WindowTestRunner.class)
public class ZOrderingTests extends WindowTestsBase {
private static class LayerRecordingTransaction extends SurfaceControl.Transaction {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index e3183e3..34eb3f1 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -97,6 +97,8 @@
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
@@ -159,7 +161,7 @@
int mUsageSource;
/** Manages the standby state of apps. */
- AppStandbyController mAppStandby;
+ AppStandbyInternal mAppStandby;
/** Manages app time limit observers */
AppTimeLimitController mAppTimeLimit;
@@ -208,7 +210,9 @@
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mHandler = new H(BackgroundThread.get().getLooper());
- mAppStandby = new AppStandbyController(getContext(), BackgroundThread.get().getLooper());
+ mAppStandby = AppStandbyInternal.newAppStandbyController(
+ UsageStatsService.class.getClassLoader(), getContext(),
+ BackgroundThread.get().getLooper());
mAppTimeLimit = new AppTimeLimitController(
new AppTimeLimitController.TimeLimitCallbackListener() {
@@ -977,7 +981,9 @@
continue;
}
UserUsageStatsService service = mUserState.get(userId);
- service.persistActiveStats();
+ if (service != null) {
+ service.persistActiveStats();
+ }
mAppStandby.flushToDisk(userId);
}
mAppStandby.flushDurationsToDisk();
@@ -1008,7 +1014,7 @@
pw.println("Flushed stats to disk");
return;
} else if ("is-app-standby-enabled".equals(arg)) {
- pw.println(mAppStandby.mAppIdleEnabled);
+ pw.println(mAppStandby.isAppIdleEnabled());
return;
} else if ("apptimelimit".equals(arg)) {
if (i + 1 >= args.length) {
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index e899dff..047fcec 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -386,7 +386,7 @@
return false;
}
- UsbDevice.Builder newDeviceBuilder = parser.toAndroidUsbDevice();
+ UsbDevice.Builder newDeviceBuilder = parser.toAndroidUsbDeviceBuilder();
if (newDeviceBuilder == null) {
Slog.e(TAG, "Couldn't create UsbDevice object.");
// Tracking
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
index 6ffbd43..8e7babb 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -309,17 +309,17 @@
/**
* @hide
*/
- public UsbDevice.Builder toAndroidUsbDevice() {
+ public UsbDevice.Builder toAndroidUsbDeviceBuilder() {
if (mDeviceDescriptor == null) {
Log.e(TAG, "toAndroidUsbDevice() ERROR - No Device Descriptor");
return null;
}
- UsbDevice.Builder device = mDeviceDescriptor.toAndroid(this);
- if (device == null) {
+ UsbDevice.Builder builder = mDeviceDescriptor.toAndroid(this);
+ if (builder == null) {
Log.e(TAG, "toAndroidUsbDevice() ERROR Creating Device");
}
- return device;
+ return builder;
}
/**
@@ -524,6 +524,37 @@
/**
* @hide
*/
+ public boolean hasAudioTerminal(int subType) {
+ for (UsbDescriptor descriptor : mDescriptors) {
+ if (descriptor instanceof UsbACInterface) {
+ if (((UsbACInterface) descriptor).getSubclass()
+ == UsbDescriptor.AUDIO_AUDIOCONTROL
+ && ((UsbACInterface) descriptor).getSubtype()
+ == subType) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @hide
+ */
+ public boolean hasAudioPlayback() {
+ return hasAudioTerminal(UsbACInterface.ACI_OUTPUT_TERMINAL);
+ }
+
+ /**
+ * @hide
+ */
+ public boolean hasAudioCapture() {
+ return hasAudioTerminal(UsbACInterface.ACI_INPUT_TERMINAL);
+ }
+
+ /**
+ * @hide
+ */
public boolean hasHIDInterface() {
ArrayList<UsbDescriptor> descriptors =
getInterfaceDescriptorsForClass(UsbDescriptor.CLASSID_HID);
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
index e6e10fe..9739243 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
@@ -156,11 +156,11 @@
for (int index = 0; index < mConfigDescriptors.size(); index++) {
configs[index] = mConfigDescriptors.get(index).toAndroid(parser);
}
- UsbDevice.Builder device = new UsbDevice.Builder(parser.getDeviceAddr(), mVendorID,
- mProductID, mDevClass, mDevSubClass, mProtocol, mfgName, prodName, versionString,
- configs, serialStr);
- return device;
+ return new UsbDevice.Builder(parser.getDeviceAddr(), mVendorID,
+ mProductID, mDevClass, mDevSubClass, mProtocol, mfgName, prodName, versionString,
+ configs, serialStr, parser.hasAudioPlayback(), parser.hasAudioCapture(),
+ parser.hasMIDIInterface());
}
@Override
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 1822cee..5e71416 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.net.Uri;
import android.os.Build;
@@ -119,6 +120,20 @@
public static final int STATE_PULLING_CALL = 11;
/**
+ * The state of a call that is active with the network, but the audio from the call is
+ * being intercepted by an app on the local device. Telecom does not hold audio focus in this
+ * state, and the call will be invisible to the user except for a persistent notification.
+ */
+ public static final int STATE_AUDIO_PROCESSING = 12;
+
+ /**
+ * The state of a call that is being presented to the user after being in
+ * {@link #STATE_AUDIO_PROCESSING}. The call is still active with the network in this case, and
+ * Telecom will hold audio focus and play a ringtone if appropriate.
+ */
+ public static final int STATE_SIMULATED_RINGING = 13;
+
+ /**
* The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
* extras. Used to pass the phone accounts to display on the front end to the user in order to
* select phone accounts to (for example) place a call.
@@ -1479,6 +1494,49 @@
}
/**
+ * Instructs Telecom to put the call into the background audio processing state.
+ *
+ * This method can be called either when the call is in {@link #STATE_RINGING} or
+ * {@link #STATE_ACTIVE}. After Telecom acknowledges the request by setting the call's state to
+ * {@link #STATE_AUDIO_PROCESSING}, your app may setup the audio paths with the audio stack in
+ * order to capture and play audio on the call stream.
+ *
+ * This method can only be called by the default dialer app.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ //@RequiresPermission(android.Manifest.permission.BACKGROUND_CALL_AUDIO)
+ public void enterBackgroundAudioProcessing() {
+ if (mState != STATE_ACTIVE && mState != STATE_RINGING) {
+ throw new IllegalStateException("Call must be active or ringing");
+ }
+ mInCallAdapter.enterBackgroundAudioProcessing(mTelecomCallId);
+ }
+
+ /**
+ * Instructs Telecom to come out of the background audio processing state requested by
+ * {@link #enterBackgroundAudioProcessing()} or from the call screening service.
+ *
+ * This method can only be called when the call is in {@link #STATE_AUDIO_PROCESSING}.
+ *
+ * @param shouldRing If true, Telecom will put the call into the
+ * {@link #STATE_SIMULATED_RINGING} state and notify other apps that there is
+ * a ringing call. Otherwise, the call will go into {@link #STATE_ACTIVE}
+ * immediately.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ //@RequiresPermission(android.Manifest.permission.BACKGROUND_CALL_AUDIO)
+ public void exitBackgroundAudioProcessing(boolean shouldRing) {
+ if (mState != STATE_AUDIO_PROCESSING) {
+ throw new IllegalStateException("Call must in the audio processing state");
+ }
+ mInCallAdapter.exitBackgroundAudioProcessing(mTelecomCallId, shouldRing);
+ }
+
+ /**
* Instructs this {@code Call} to play a dual-tone multi-frequency signaling (DTMF) tone.
*
* Any other currently playing DTMF tone in the specified call is immediately stopped.
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index e4f8d11..0d97567 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -18,6 +18,8 @@
import android.annotation.NonNull;
import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
@@ -136,23 +138,30 @@
private final boolean mShouldSilenceCall;
private final boolean mShouldSkipCallLog;
private final boolean mShouldSkipNotification;
+ private final boolean mShouldScreenCallFurther;
private CallResponse(
boolean shouldDisallowCall,
boolean shouldRejectCall,
boolean shouldSilenceCall,
boolean shouldSkipCallLog,
- boolean shouldSkipNotification) {
+ boolean shouldSkipNotification,
+ boolean shouldScreenCallFurther) {
if (!shouldDisallowCall
&& (shouldRejectCall || shouldSkipCallLog || shouldSkipNotification)) {
throw new IllegalStateException("Invalid response state for allowed call.");
}
+ if (shouldDisallowCall && shouldScreenCallFurther) {
+ throw new IllegalStateException("Invalid response state for allowed call.");
+ }
+
mShouldDisallowCall = shouldDisallowCall;
mShouldRejectCall = shouldRejectCall;
mShouldSkipCallLog = shouldSkipCallLog;
mShouldSkipNotification = shouldSkipNotification;
mShouldSilenceCall = shouldSilenceCall;
+ mShouldScreenCallFurther = shouldScreenCallFurther;
}
/*
@@ -191,12 +200,22 @@
return mShouldSkipNotification;
}
+ /**
+ * @return Whether we should enter the {@link Call#STATE_AUDIO_PROCESSING} state to allow
+ * for further screening of the call.
+ * @hide
+ */
+ public boolean getShouldScreenCallFurther() {
+ return mShouldScreenCallFurther;
+ }
+
public static class Builder {
private boolean mShouldDisallowCall;
private boolean mShouldRejectCall;
private boolean mShouldSilenceCall;
private boolean mShouldSkipCallLog;
private boolean mShouldSkipNotification;
+ private boolean mShouldScreenCallFurther;
/**
* Sets whether the incoming call should be blocked.
@@ -252,13 +271,32 @@
return this;
}
+ /**
+ * Sets whether to request background audio processing so that the in-call service can
+ * screen the call further. If set to {@code true}, {@link #setDisallowCall} should be
+ * called with {@code false}, and all other parameters in this builder will be ignored.
+ *
+ * This request will only be honored if the {@link CallScreeningService} shares the same
+ * uid as the default dialer app. Otherwise, the call will go through as usual.
+ *
+ * @param shouldScreenCallFurther Whether to request further call screening.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public Builder setShouldScreenCallFurther(boolean shouldScreenCallFurther) {
+ mShouldScreenCallFurther = shouldScreenCallFurther;
+ return this;
+ }
+
public CallResponse build() {
return new CallResponse(
mShouldDisallowCall,
mShouldRejectCall,
mShouldSilenceCall,
mShouldSkipCallLog,
- mShouldSkipNotification);
+ mShouldSkipNotification,
+ mShouldScreenCallFurther);
}
}
}
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index cd5fd97..d90f46d 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -24,6 +24,7 @@
import android.os.Bundle;
import android.os.SystemClock;
import android.telecom.Connection.VideoProvider;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
@@ -687,7 +688,7 @@
*
* @hide
*/
- public final void setCallRadioTech(@ServiceState.RilRadioTechnology int vrat) {
+ public final void setCallRadioTech(@RilRadioTechnology int vrat) {
putExtra(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
ServiceState.rilRadioTechnologyToNetworkType(vrat));
}
@@ -700,7 +701,7 @@
*
* @hide
*/
- public final @ServiceState.RilRadioTechnology int getCallRadioTech() {
+ public final @RilRadioTechnology int getCallRadioTech() {
int voiceNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
Bundle extras = getExtras();
if (extras != null) {
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 0983eea..525b938 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -34,6 +34,7 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
@@ -1958,7 +1959,7 @@
*
* @hide
*/
- public final @ServiceState.RilRadioTechnology int getCallRadioTech() {
+ public final @RilRadioTechnology int getCallRadioTech() {
int voiceNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
Bundle extras = getExtras();
if (extras != null) {
@@ -2409,7 +2410,7 @@
*
* @hide
*/
- public final void setCallRadioTech(@ServiceState.RilRadioTechnology int vrat) {
+ public final void setCallRadioTech(@RilRadioTechnology int vrat) {
putExtra(TelecomManager.EXTRA_CALL_NETWORK_TYPE,
ServiceState.rilRadioTechnologyToNetworkType(vrat));
// Propagates the call radio technology to its parent {@link android.telecom.Conference}
diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java
index 8678e33..2612468 100644
--- a/telecomm/java/android/telecom/InCallAdapter.java
+++ b/telecomm/java/android/telecom/InCallAdapter.java
@@ -16,8 +16,8 @@
package android.telecom;
-import android.net.Uri;
import android.bluetooth.BluetoothDevice;
+import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
@@ -149,6 +149,26 @@
}
/**
+ * @see Call#enterBackgroundAudioProcessing()
+ */
+ public void enterBackgroundAudioProcessing(String callId) {
+ try {
+ mAdapter.enterBackgroundAudioProcessing(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * @see Call#exitBackgroundAudioProcessing(boolean)
+ */
+ public void exitBackgroundAudioProcessing(String callId, boolean shouldRing) {
+ try {
+ mAdapter.exitBackgroundAudioProcessing(callId, shouldRing);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
* Request audio routing to a specific bluetooth device. Calling this method may result in
* the device routing audio to a different bluetooth device than the one specified. A list of
* available devices can be obtained via {@link CallAudioState#getSupportedBluetoothDevices()}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 6409203..2bc20d5 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -33,6 +33,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.telephony.Annotation.CallState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -1412,7 +1413,7 @@
* @hide
*/
@SystemApi
- public @TelephonyManager.CallState int getCallState() {
+ public @CallState int getCallState() {
try {
if (isServiceConnected()) {
return getTelecomService().getCallState();
@@ -2059,12 +2060,13 @@
/**
* Handles {@link Intent#ACTION_CALL} intents trampolined from UserCallActivity.
* @param intent The {@link Intent#ACTION_CALL} intent to handle.
+ * @param callingPackageProxy The original package that called this before it was trampolined.
* @hide
*/
- public void handleCallIntent(Intent intent) {
+ public void handleCallIntent(Intent intent, String callingPackageProxy) {
try {
if (isServiceConnected()) {
- getTelecomService().handleCallIntent(intent);
+ getTelecomService().handleCallIntent(intent, callingPackageProxy);
}
} catch (RemoteException e) {
Log.e(TAG, "RemoteException handleCallIntent: " + e);
diff --git a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
index 3ee3285..83c8f62 100644
--- a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
@@ -30,6 +30,8 @@
void silenceCall(String callId);
+ void screenCallFurther(String callId);
+
void disallowCall(
String callId,
boolean shouldReject,
diff --git a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
index 57df5c1..60745e4 100644
--- a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl
@@ -44,6 +44,10 @@
void setAudioRoute(int route, String bluetoothAddress);
+ void enterBackgroundAudioProcessing(String callId);
+
+ void exitBackgroundAudioProcessing(String callId, boolean shouldRing);
+
void playDtmfTone(String callId, char digit);
void stopDtmfTone(String callId);
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 7047498..6a1b78f 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -282,6 +282,11 @@
void acceptHandover(in Uri srcAddr, int videoState, in PhoneAccountHandle destAcct);
/**
+ * @see TelecomServiceImpl#setTestEmergencyPhoneAccountPackageNameFilter
+ */
+ void setTestEmergencyPhoneAccountPackageNameFilter(String packageName);
+
+ /**
* @see TelecomServiceImpl#isInEmergencyCall
*/
boolean isInEmergencyCall();
@@ -289,7 +294,7 @@
/**
* @see TelecomServiceImpl#handleCallIntent
*/
- void handleCallIntent(in Intent intent);
+ void handleCallIntent(in Intent intent, in String callingPackageProxy);
void setTestDefaultCallRedirectionApp(String packageName);
@@ -302,9 +307,9 @@
void setTestAutoModeApp(String packageName);
/**
- * @see TelecomServiceImpl#setSystemDialerPackage
+ * @see TelecomServiceImpl#setSystemDialer
*/
- void setSystemDialerPackage(in String packageName);
+ void setSystemDialer(in ComponentName testComponentName);
/**
* @see TelecomServiceImpl#setTestDefaultDialer
diff --git a/telephony/common/com/android/internal/telephony/HbpcdLookup.java b/telephony/common/com/android/internal/telephony/HbpcdLookup.java
new file mode 100644
index 0000000..d9a3e72
--- /dev/null
+++ b/telephony/common/com/android/internal/telephony/HbpcdLookup.java
@@ -0,0 +1,124 @@
+/*
+**
+** Copyright 2014, 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.internal.telephony;
+
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+/**
+ * @hide
+ */
+public class HbpcdLookup {
+ public static final String AUTHORITY = "hbpcd_lookup";
+
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY);
+
+ public static final String PATH_MCC_IDD = "idd";
+ public static final String PATH_MCC_LOOKUP_TABLE = "lookup";
+ public static final String PATH_MCC_SID_CONFLICT = "conflict";
+ public static final String PATH_MCC_SID_RANGE = "range";
+ public static final String PATH_NANP_AREA_CODE = "nanp";
+ public static final String PATH_ARBITRARY_MCC_SID_MATCH = "arbitrary";
+ public static final String PATH_USERADD_COUNTRY = "useradd";
+
+ public static final String ID = "_id";
+ public static final int IDINDEX = 0;
+
+ /**
+ * @hide
+ */
+ public static class MccIdd implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_MCC_IDD);
+ public static final String DEFAULT_SORT_ORDER = "MCC ASC";
+
+ public static final String MCC = "MCC";
+ public static final String IDD = "IDD";
+
+ }
+
+ /**
+ * @hide
+ */
+ public static class MccLookup implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_MCC_LOOKUP_TABLE);
+ public static final String DEFAULT_SORT_ORDER = "MCC ASC";
+
+ public static final String MCC = "MCC";
+ public static final String COUNTRY_CODE = "Country_Code";
+ public static final String COUNTRY_NAME = "Country_Name";
+ public static final String NDD = "NDD";
+ public static final String NANPS = "NANPS";
+ public static final String GMT_OFFSET_LOW = "GMT_Offset_Low";
+ public static final String GMT_OFFSET_HIGH = "GMT_Offset_High";
+ public static final String GMT_DST_LOW = "GMT_DST_Low";
+ public static final String GMT_DST_HIGH = "GMT_DST_High";
+
+ }
+
+ /**
+ * @hide
+ */
+ public static class MccSidConflicts implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_MCC_SID_CONFLICT);
+ public static final String DEFAULT_SORT_ORDER = "MCC ASC";
+
+ public static final String MCC = "MCC";
+ public static final String SID_CONFLICT = "SID_Conflict";
+
+ }
+
+ /**
+ * @hide
+ */
+ public static class MccSidRange implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_MCC_SID_RANGE);
+ public static final String DEFAULT_SORT_ORDER = "MCC ASC";
+
+ public static final String MCC = "MCC";
+ public static final String RANGE_LOW = "SID_Range_Low";
+ public static final String RANGE_HIGH = "SID_Range_High";
+ }
+
+ /**
+ * @hide
+ */
+ public static class ArbitraryMccSidMatch implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_ARBITRARY_MCC_SID_MATCH);
+ public static final String DEFAULT_SORT_ORDER = "MCC ASC";
+
+ public static final String MCC = "MCC";
+ public static final String SID = "SID";
+
+ }
+
+ /**
+ * @hide
+ */
+ public static class NanpAreaCode implements BaseColumns {
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://" + AUTHORITY + "/" + PATH_NANP_AREA_CODE);
+ public static final String DEFAULT_SORT_ORDER = "Area_Code ASC";
+
+ public static final String AREA_CODE = "Area_Code";
+ }
+}
diff --git a/telephony/common/com/android/internal/telephony/HbpcdUtils.java b/telephony/common/com/android/internal/telephony/HbpcdUtils.java
new file mode 100644
index 0000000..2f31942
--- /dev/null
+++ b/telephony/common/com/android/internal/telephony/HbpcdUtils.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2014 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.internal.telephony;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.telephony.Rlog;
+
+import com.android.internal.telephony.HbpcdLookup.ArbitraryMccSidMatch;
+import com.android.internal.telephony.HbpcdLookup.MccIdd;
+import com.android.internal.telephony.HbpcdLookup.MccLookup;
+import com.android.internal.telephony.HbpcdLookup.MccSidConflicts;
+import com.android.internal.telephony.HbpcdLookup.MccSidRange;
+
+public final class HbpcdUtils {
+ private static final String LOG_TAG = "HbpcdUtils";
+ private static final boolean DBG = false;
+ private ContentResolver resolver = null;
+
+ public HbpcdUtils(Context context) {
+ resolver = context.getContentResolver();
+ }
+
+ /**
+ * Resolves the unknown MCC with SID and Timezone information.
+ */
+ public int getMcc(int sid, int tz, int DSTflag, boolean isNitzTimeZone) {
+ int tmpMcc = 0;
+
+ // check if SID exists in arbitrary_mcc_sid_match table.
+ // these SIDs are assigned to more than 1 operators, but they are known to
+ // be used by a specific operator, other operators having the same SID are
+ // not using it currently, if that SID is in this table, we don't need to
+ // check other tables.
+ String projection2[] = {ArbitraryMccSidMatch.MCC};
+ Cursor c2 = resolver.query(ArbitraryMccSidMatch.CONTENT_URI, projection2,
+ ArbitraryMccSidMatch.SID + "=" + sid, null, null);
+
+ if (c2 != null) {
+ int c2Counter = c2.getCount();
+ if (DBG) {
+ Rlog.d(LOG_TAG, "Query unresolved arbitrary table, entries are " + c2Counter);
+ }
+ if (c2Counter == 1) {
+ if (DBG) {
+ Rlog.d(LOG_TAG, "Query Unresolved arbitrary returned the cursor " + c2);
+ }
+ c2.moveToFirst();
+ tmpMcc = c2.getInt(0);
+ if (DBG) {
+ Rlog.d(LOG_TAG, "MCC found in arbitrary_mcc_sid_match: " + tmpMcc);
+ }
+ c2.close();
+ return tmpMcc;
+ }
+ c2.close();
+ }
+
+ // Then check if SID exists in mcc_sid_conflict table.
+ // and use the timezone in mcc_lookup table to check which MCC matches.
+ String projection3[] = {MccSidConflicts.MCC};
+ Cursor c3 = resolver.query(MccSidConflicts.CONTENT_URI, projection3,
+ MccSidConflicts.SID_CONFLICT + "=" + sid + " and (((" +
+ MccLookup.GMT_OFFSET_LOW + "<=" + tz + ") and (" + tz + "<=" +
+ MccLookup.GMT_OFFSET_HIGH + ") and (" + "0=" + DSTflag + ")) or ((" +
+ MccLookup.GMT_DST_LOW + "<=" + tz + ") and (" + tz + "<=" +
+ MccLookup.GMT_DST_HIGH + ") and (" + "1=" + DSTflag + ")))",
+ null, null);
+ if (c3 != null) {
+ int c3Counter = c3.getCount();
+ if (c3Counter > 0) {
+ if (c3Counter > 1) {
+ Rlog.w(LOG_TAG, "something wrong, get more results for 1 conflict SID: " + c3);
+ }
+ if (DBG) Rlog.d(LOG_TAG, "Query conflict sid returned the cursor " + c3);
+ c3.moveToFirst();
+ tmpMcc = c3.getInt(0);
+ if (DBG) {
+ Rlog.d(LOG_TAG, "MCC found in mcc_lookup_table. Return tmpMcc = " + tmpMcc);
+ }
+ if (!isNitzTimeZone) {
+ // time zone is not accurate, it may get wrong mcc, ignore it.
+ if (DBG) {
+ Rlog.d(LOG_TAG, "time zone is not accurate, mcc may be " + tmpMcc);
+ }
+ tmpMcc = 0;
+ }
+ c3.close();
+ return tmpMcc;
+ } else {
+ c3.close();
+ }
+ }
+
+ // if there is no conflict, then check if SID is in mcc_sid_range.
+ String projection5[] = {MccSidRange.MCC};
+ Cursor c5 = resolver.query(MccSidRange.CONTENT_URI, projection5,
+ MccSidRange.RANGE_LOW + "<=" + sid + " and " +
+ MccSidRange.RANGE_HIGH + ">=" + sid,
+ null, null);
+ if (c5 != null) {
+ if (c5.getCount() > 0) {
+ if (DBG) Rlog.d(LOG_TAG, "Query Range returned the cursor " + c5);
+ c5.moveToFirst();
+ tmpMcc = c5.getInt(0);
+ if (DBG) Rlog.d(LOG_TAG, "SID found in mcc_sid_range. Return tmpMcc = " + tmpMcc);
+ c5.close();
+ return tmpMcc;
+ }
+ c5.close();
+ }
+ if (DBG) Rlog.d(LOG_TAG, "SID NOT found in mcc_sid_range.");
+
+ if (DBG) Rlog.d(LOG_TAG, "Exit getMccByOtherFactors. Return tmpMcc = " + tmpMcc);
+ // If unknown MCC still could not be resolved,
+ return tmpMcc;
+ }
+
+ /**
+ * Gets country information with given MCC.
+ */
+ public String getIddByMcc(int mcc) {
+ if (DBG) Rlog.d(LOG_TAG, "Enter getHbpcdInfoByMCC.");
+ String idd = "";
+
+ Cursor c = null;
+
+ String projection[] = {MccIdd.IDD};
+ Cursor cur = resolver.query(MccIdd.CONTENT_URI, projection,
+ MccIdd.MCC + "=" + mcc, null, null);
+ if (cur != null) {
+ if (cur.getCount() > 0) {
+ if (DBG) Rlog.d(LOG_TAG, "Query Idd returned the cursor " + cur);
+ // TODO: for those country having more than 1 IDDs, need more information
+ // to decide which IDD would be used. currently just use the first 1.
+ cur.moveToFirst();
+ idd = cur.getString(0);
+ if (DBG) Rlog.d(LOG_TAG, "IDD = " + idd);
+
+ }
+ cur.close();
+ }
+ if (c != null) c.close();
+
+ if (DBG) Rlog.d(LOG_TAG, "Exit getHbpcdInfoByMCC.");
+ return idd;
+ }
+}
diff --git a/telephony/common/com/android/internal/telephony/SmsNumberUtils.java b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
new file mode 100644
index 0000000..0d33af6
--- /dev/null
+++ b/telephony/common/com/android/internal/telephony/SmsNumberUtils.java
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2014 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.internal.telephony;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.os.Binder;
+import android.os.Build;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.android.internal.telephony.HbpcdLookup.MccIdd;
+import com.android.internal.telephony.HbpcdLookup.MccLookup;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+
+/**
+ * This class implements handle the MO SMS target address before sending.
+ * This is special for VZW requirement. Follow the specifications of assisted dialing
+ * of MO SMS while traveling on VZW CDMA, international CDMA or GSM markets.
+ * {@hide}
+ */
+public class SmsNumberUtils {
+ private static final String TAG = "SmsNumberUtils";
+ private static final boolean DBG = Build.IS_DEBUGGABLE;
+
+ private static final String PLUS_SIGN = "+";
+
+ private static final int NANP_SHORT_LENGTH = 7;
+ private static final int NANP_MEDIUM_LENGTH = 10;
+ private static final int NANP_LONG_LENGTH = 11;
+
+ private static final int NANP_CC = 1;
+ private static final String NANP_NDD = "1";
+ private static final String NANP_IDD = "011";
+
+ private static final int MIN_COUNTRY_AREA_LOCAL_LENGTH = 10;
+
+ private static final int GSM_UMTS_NETWORK = 0;
+ private static final int CDMA_HOME_NETWORK = 1;
+ private static final int CDMA_ROAMING_NETWORK = 2;
+
+ private static final int NP_NONE = 0;
+ private static final int NP_NANP_BEGIN = 1;
+
+ /* <Phone Number>, <NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_LOCAL = NP_NANP_BEGIN;
+
+ /* <Area_code>-<Phone Number>, <NXX>-<NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_AREA_LOCAL = NP_NANP_BEGIN + 1;
+
+ /* <1>-<Area_code>-<Phone Number>, 1-<NXX>-<NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_NDD_AREA_LOCAL = NP_NANP_BEGIN + 2;
+
+ /* <+><U.S.Country_code><Area_code><Phone Number>, +1-<NXX>-<NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_NBPCD_CC_AREA_LOCAL = NP_NANP_BEGIN + 3;
+
+ /* <Local_IDD><Country_code><Area_code><Phone Number>, 001-1-<NXX>-<NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_LOCALIDD_CC_AREA_LOCAL = NP_NANP_BEGIN + 4;
+
+ /* <+><Home_IDD><Country_code><Area_code><Phone Number>, +011-1-<NXX>-<NXX>-<XXXX> N[2-9] */
+ private static final int NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL = NP_NANP_BEGIN + 5;
+
+ private static final int NP_INTERNATIONAL_BEGIN = 100;
+ /* <+>-<Home_IDD>-<Country_code>-<Area_code>-<Phone Number>, +011-86-25-86281234 */
+ private static final int NP_NBPCD_HOMEIDD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN;
+
+ /* <Home_IDD>-<Country_code>-<Area_code>-<Phone Number>, 011-86-25-86281234 */
+ private static final int NP_HOMEIDD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 1;
+
+ /* <NBPCD>-<Country_code>-<Area_code>-<Phone Number>, +1-86-25-86281234 */
+ private static final int NP_NBPCD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 2;
+
+ /* <Local_IDD>-<Country_code>-<Area_code>-<Phone Number>, 00-86-25-86281234 */
+ private static final int NP_LOCALIDD_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 3;
+
+ /* <Country_code>-<Area_code>-<Phone Number>, 86-25-86281234*/
+ private static final int NP_CC_AREA_LOCAL = NP_INTERNATIONAL_BEGIN + 4;
+
+ private static int[] ALL_COUNTRY_CODES = null;
+ private static int MAX_COUNTRY_CODES_LENGTH;
+ private static HashMap<String, ArrayList<String>> IDDS_MAPS =
+ new HashMap<String, ArrayList<String>>();
+
+ private static class NumberEntry {
+ public String number;
+ public String IDD;
+ public int countryCode;
+ public NumberEntry(String number) {
+ this.number = number;
+ }
+ }
+
+ /**
+ * Breaks the given number down and formats it according to the rules
+ * for different number plans and different network.
+ *
+ * @param number destination number which need to be format
+ * @param activeMcc current network's mcc
+ * @param networkType current network type
+ *
+ * @return the number after formatting.
+ */
+ private static String formatNumber(Context context, String number,
+ String activeMcc,
+ int networkType) {
+ if (number == null ) {
+ throw new IllegalArgumentException("number is null");
+ }
+
+ if (activeMcc == null || activeMcc.trim().length() == 0) {
+ throw new IllegalArgumentException("activeMcc is null or empty!");
+ }
+
+ String networkPortionNumber = PhoneNumberUtils.extractNetworkPortion(number);
+ if (networkPortionNumber == null || networkPortionNumber.length() == 0) {
+ throw new IllegalArgumentException("Number is invalid!");
+ }
+
+ NumberEntry numberEntry = new NumberEntry(networkPortionNumber);
+ ArrayList<String> allIDDs = getAllIDDs(context, activeMcc);
+
+ // First check whether the number is a NANP number.
+ int nanpState = checkNANP(numberEntry, allIDDs);
+ if (DBG) Rlog.d(TAG, "NANP type: " + getNumberPlanType(nanpState));
+
+ if ((nanpState == NP_NANP_LOCAL)
+ || (nanpState == NP_NANP_AREA_LOCAL)
+ || (nanpState == NP_NANP_NDD_AREA_LOCAL)) {
+ return networkPortionNumber;
+ } else if (nanpState == NP_NANP_NBPCD_CC_AREA_LOCAL) {
+ if (networkType == CDMA_HOME_NETWORK
+ || networkType == CDMA_ROAMING_NETWORK) {
+ // Remove "+"
+ return networkPortionNumber.substring(1);
+ } else {
+ return networkPortionNumber;
+ }
+ } else if (nanpState == NP_NANP_LOCALIDD_CC_AREA_LOCAL) {
+ if (networkType == CDMA_HOME_NETWORK) {
+ return networkPortionNumber;
+ } else if (networkType == GSM_UMTS_NETWORK) {
+ // Remove the local IDD and replace with "+"
+ int iddLength = numberEntry.IDD != null ? numberEntry.IDD.length() : 0;
+ return PLUS_SIGN + networkPortionNumber.substring(iddLength);
+ } else if (networkType == CDMA_ROAMING_NETWORK) {
+ // Remove the local IDD
+ int iddLength = numberEntry.IDD != null ? numberEntry.IDD.length() : 0;
+ return networkPortionNumber.substring(iddLength);
+ }
+ }
+
+ int internationalState = checkInternationalNumberPlan(context, numberEntry, allIDDs,
+ NANP_IDD);
+ if (DBG) Rlog.d(TAG, "International type: " + getNumberPlanType(internationalState));
+ String returnNumber = null;
+
+ switch (internationalState) {
+ case NP_NBPCD_HOMEIDD_CC_AREA_LOCAL:
+ if (networkType == GSM_UMTS_NETWORK) {
+ // Remove "+"
+ returnNumber = networkPortionNumber.substring(1);
+ }
+ break;
+
+ case NP_NBPCD_CC_AREA_LOCAL:
+ // Replace "+" with "011"
+ returnNumber = NANP_IDD + networkPortionNumber.substring(1);
+ break;
+
+ case NP_LOCALIDD_CC_AREA_LOCAL:
+ if (networkType == GSM_UMTS_NETWORK || networkType == CDMA_ROAMING_NETWORK) {
+ int iddLength = numberEntry.IDD != null ? numberEntry.IDD.length() : 0;
+ // Replace <Local IDD> to <Home IDD>("011")
+ returnNumber = NANP_IDD + networkPortionNumber.substring(iddLength);
+ }
+ break;
+
+ case NP_CC_AREA_LOCAL:
+ int countryCode = numberEntry.countryCode;
+
+ if (!inExceptionListForNpCcAreaLocal(numberEntry)
+ && networkPortionNumber.length() >= 11 && countryCode != NANP_CC) {
+ // Add "011"
+ returnNumber = NANP_IDD + networkPortionNumber;
+ }
+ break;
+
+ case NP_HOMEIDD_CC_AREA_LOCAL:
+ returnNumber = networkPortionNumber;
+ break;
+
+ default:
+ // Replace "+" with 011 in CDMA network if the number's country
+ // code is not in the HbpcdLookup database.
+ if (networkPortionNumber.startsWith(PLUS_SIGN)
+ && (networkType == CDMA_HOME_NETWORK || networkType == CDMA_ROAMING_NETWORK)) {
+ if (networkPortionNumber.startsWith(PLUS_SIGN + NANP_IDD)) {
+ // Only remove "+"
+ returnNumber = networkPortionNumber.substring(1);
+ } else {
+ // Replace "+" with "011"
+ returnNumber = NANP_IDD + networkPortionNumber.substring(1);
+ }
+ }
+ }
+
+ if (returnNumber == null) {
+ returnNumber = networkPortionNumber;
+ }
+ return returnNumber;
+ }
+
+ /**
+ * Query International direct dialing from HbpcdLookup.db
+ * for specified country code
+ *
+ * @param mcc current network's country code
+ *
+ * @return the IDD array list.
+ */
+ private static ArrayList<String> getAllIDDs(Context context, String mcc) {
+ ArrayList<String> allIDDs = IDDS_MAPS.get(mcc);
+ if (allIDDs != null) {
+ return allIDDs;
+ } else {
+ allIDDs = new ArrayList<String>();
+ }
+
+ String projection[] = {MccIdd.IDD, MccIdd.MCC};
+ String where = null;
+
+ // if mcc is null : return all rows
+ // if mcc is empty-string : return those rows whose mcc is emptry-string
+ String[] selectionArgs = null;
+ if (mcc != null) {
+ where = MccIdd.MCC + "=?";
+ selectionArgs = new String[] {mcc};
+ }
+
+ Cursor cursor = null;
+ try {
+ cursor = context.getContentResolver().query(MccIdd.CONTENT_URI, projection,
+ where, selectionArgs, null);
+ if (cursor.getCount() > 0) {
+ while (cursor.moveToNext()) {
+ String idd = cursor.getString(0);
+ if (!allIDDs.contains(idd)) {
+ allIDDs.add(idd);
+ }
+ }
+ }
+ } catch (SQLException e) {
+ Rlog.e(TAG, "Can't access HbpcdLookup database", e);
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+
+ IDDS_MAPS.put(mcc, allIDDs);
+
+ if (DBG) Rlog.d(TAG, "MCC = " + mcc + ", all IDDs = " + allIDDs);
+ return allIDDs;
+ }
+
+
+ /**
+ * Verify if the the destination number is a NANP number
+ *
+ * @param numberEntry including number and IDD array
+ * @param allIDDs the IDD array list of the current network's country code
+ *
+ * @return the number plan type related NANP
+ */
+ private static int checkNANP(NumberEntry numberEntry, ArrayList<String> allIDDs) {
+ boolean isNANP = false;
+ String number = numberEntry.number;
+
+ if (number.length() == NANP_SHORT_LENGTH) {
+ // 7 digits - Seven digit phone numbers
+ char firstChar = number.charAt(0);
+ if (firstChar >= '2' && firstChar <= '9') {
+ isNANP = true;
+ for (int i=1; i< NANP_SHORT_LENGTH; i++ ) {
+ char c= number.charAt(i);
+ if (!PhoneNumberUtils.isISODigit(c)) {
+ isNANP = false;
+ break;
+ }
+ }
+ }
+ if (isNANP) {
+ return NP_NANP_LOCAL;
+ }
+ } else if (number.length() == NANP_MEDIUM_LENGTH) {
+ // 10 digits - Three digit area code followed by seven digit phone numbers/
+ if (isNANP(number)) {
+ return NP_NANP_AREA_LOCAL;
+ }
+ } else if (number.length() == NANP_LONG_LENGTH) {
+ // 11 digits - One digit U.S. NDD(National Direct Dial) prefix '1',
+ // followed by three digit area code and seven digit phone numbers
+ if (isNANP(number)) {
+ return NP_NANP_NDD_AREA_LOCAL;
+ }
+ } else if (number.startsWith(PLUS_SIGN)) {
+ number = number.substring(1);
+ if (number.length() == NANP_LONG_LENGTH) {
+ // '+' and 11 digits -'+', followed by NANP CC prefix '1' followed by
+ // three digit area code and seven digit phone numbers
+ if (isNANP(number)) {
+ return NP_NANP_NBPCD_CC_AREA_LOCAL;
+ }
+ } else if (number.startsWith(NANP_IDD) && number.length() == NANP_LONG_LENGTH + 3) {
+ // '+' and 14 digits -'+', followed by NANP IDD "011" followed by NANP CC
+ // prefix '1' followed by three digit area code and seven digit phone numbers
+ number = number.substring(3);
+ if (isNANP(number)) {
+ return NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL;
+ }
+ }
+ } else {
+ // Check whether it's NP_NANP_LOCALIDD_CC_AREA_LOCAL
+ for (String idd : allIDDs) {
+ if (number.startsWith(idd)) {
+ String number2 = number.substring(idd.length());
+ if(number2 !=null && number2.startsWith(String.valueOf(NANP_CC))){
+ if (isNANP(number2)) {
+ numberEntry.IDD = idd;
+ return NP_NANP_LOCALIDD_CC_AREA_LOCAL;
+ }
+ }
+ }
+ }
+ }
+
+ return NP_NONE;
+ }
+
+ private static boolean isNANP(String number) {
+ if (number.length() == NANP_MEDIUM_LENGTH
+ || (number.length() == NANP_LONG_LENGTH && number.startsWith(NANP_NDD))) {
+ if (number.length() == NANP_LONG_LENGTH) {
+ number = number.substring(1);
+ }
+ return (PhoneNumberUtils.isNanp(number));
+ }
+ return false;
+ }
+
+ /**
+ * Verify if the the destination number is an internal number
+ *
+ * @param numberEntry including number and IDD array
+ * @param allIDDs the IDD array list of the current network's country code
+ *
+ * @return the number plan type related international number
+ */
+ private static int checkInternationalNumberPlan(Context context, NumberEntry numberEntry,
+ ArrayList<String> allIDDs,String homeIDD) {
+ String number = numberEntry.number;
+ int countryCode = -1;
+
+ if (number.startsWith(PLUS_SIGN)) {
+ // +xxxxxxxxxx
+ String numberNoNBPCD = number.substring(1);
+ if (numberNoNBPCD.startsWith(homeIDD)) {
+ // +011xxxxxxxx
+ String numberCountryAreaLocal = numberNoNBPCD.substring(homeIDD.length());
+ if ((countryCode = getCountryCode(context, numberCountryAreaLocal)) > 0) {
+ numberEntry.countryCode = countryCode;
+ return NP_NBPCD_HOMEIDD_CC_AREA_LOCAL;
+ }
+ } else if ((countryCode = getCountryCode(context, numberNoNBPCD)) > 0) {
+ numberEntry.countryCode = countryCode;
+ return NP_NBPCD_CC_AREA_LOCAL;
+ }
+
+ } else if (number.startsWith(homeIDD)) {
+ // 011xxxxxxxxx
+ String numberCountryAreaLocal = number.substring(homeIDD.length());
+ if ((countryCode = getCountryCode(context, numberCountryAreaLocal)) > 0) {
+ numberEntry.countryCode = countryCode;
+ return NP_HOMEIDD_CC_AREA_LOCAL;
+ }
+ } else {
+ for (String exitCode : allIDDs) {
+ if (number.startsWith(exitCode)) {
+ String numberNoIDD = number.substring(exitCode.length());
+ if ((countryCode = getCountryCode(context, numberNoIDD)) > 0) {
+ numberEntry.countryCode = countryCode;
+ numberEntry.IDD = exitCode;
+ return NP_LOCALIDD_CC_AREA_LOCAL;
+ }
+ }
+ }
+
+ if (!number.startsWith("0") && (countryCode = getCountryCode(context, number)) > 0) {
+ numberEntry.countryCode = countryCode;
+ return NP_CC_AREA_LOCAL;
+ }
+ }
+ return NP_NONE;
+ }
+
+ /**
+ * Returns the country code from the given number.
+ */
+ private static int getCountryCode(Context context, String number) {
+ int countryCode = -1;
+ if (number.length() >= MIN_COUNTRY_AREA_LOCAL_LENGTH) {
+ // Check Country code
+ int[] allCCs = getAllCountryCodes(context);
+ if (allCCs == null) {
+ return countryCode;
+ }
+
+ int[] ccArray = new int[MAX_COUNTRY_CODES_LENGTH];
+ for (int i = 0; i < MAX_COUNTRY_CODES_LENGTH; i ++) {
+ ccArray[i] = Integer.parseInt(number.substring(0, i+1));
+ }
+
+ for (int i = 0; i < allCCs.length; i ++) {
+ int tempCC = allCCs[i];
+ for (int j = 0; j < MAX_COUNTRY_CODES_LENGTH; j ++) {
+ if (tempCC == ccArray[j]) {
+ if (DBG) Rlog.d(TAG, "Country code = " + tempCC);
+ return tempCC;
+ }
+ }
+ }
+ }
+
+ return countryCode;
+ }
+
+ /**
+ * Gets all country Codes information with given MCC.
+ */
+ private static int[] getAllCountryCodes(Context context) {
+ if (ALL_COUNTRY_CODES != null) {
+ return ALL_COUNTRY_CODES;
+ }
+
+ Cursor cursor = null;
+ try {
+ String projection[] = {MccLookup.COUNTRY_CODE};
+ cursor = context.getContentResolver().query(MccLookup.CONTENT_URI,
+ projection, null, null, null);
+
+ if (cursor.getCount() > 0) {
+ ALL_COUNTRY_CODES = new int[cursor.getCount()];
+ int i = 0;
+ while (cursor.moveToNext()) {
+ int countryCode = cursor.getInt(0);
+ ALL_COUNTRY_CODES[i++] = countryCode;
+ int length = String.valueOf(countryCode).trim().length();
+ if (length > MAX_COUNTRY_CODES_LENGTH) {
+ MAX_COUNTRY_CODES_LENGTH = length;
+ }
+ }
+ }
+ } catch (SQLException e) {
+ Rlog.e(TAG, "Can't access HbpcdLookup database", e);
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ return ALL_COUNTRY_CODES;
+ }
+
+ private static boolean inExceptionListForNpCcAreaLocal(NumberEntry numberEntry) {
+ int countryCode = numberEntry.countryCode;
+ boolean result = (numberEntry.number.length() == 12
+ && (countryCode == 7 || countryCode == 20
+ || countryCode == 65 || countryCode == 90));
+ return result;
+ }
+
+ private static String getNumberPlanType(int state) {
+ String numberPlanType = "Number Plan type (" + state + "): ";
+
+ if (state == NP_NANP_LOCAL) {
+ numberPlanType = "NP_NANP_LOCAL";
+ } else if (state == NP_NANP_AREA_LOCAL) {
+ numberPlanType = "NP_NANP_AREA_LOCAL";
+ } else if (state == NP_NANP_NDD_AREA_LOCAL) {
+ numberPlanType = "NP_NANP_NDD_AREA_LOCAL";
+ } else if (state == NP_NANP_NBPCD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_NANP_NBPCD_CC_AREA_LOCAL";
+ } else if (state == NP_NANP_LOCALIDD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_NANP_LOCALIDD_CC_AREA_LOCAL";
+ } else if (state == NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_NANP_NBPCD_HOMEIDD_CC_AREA_LOCAL";
+ } else if (state == NP_NBPCD_HOMEIDD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_NBPCD_HOMEIDD_CC_AREA_LOCAL";
+ } else if (state == NP_HOMEIDD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_HOMEIDD_CC_AREA_LOCAL";
+ } else if (state == NP_NBPCD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_NBPCD_CC_AREA_LOCAL";
+ } else if (state == NP_LOCALIDD_CC_AREA_LOCAL) {
+ numberPlanType = "NP_LOCALIDD_CC_AREA_LOCAL";
+ } else if (state == NP_CC_AREA_LOCAL) {
+ numberPlanType = "NP_CC_AREA_LOCAL";
+ } else {
+ numberPlanType = "Unknown type";
+ }
+ return numberPlanType;
+ }
+
+ /**
+ * Filter the destination number if using VZW sim card.
+ */
+ public static String filterDestAddr(Context context, int subId, String destAddr) {
+ if (DBG) Rlog.d(TAG, "enter filterDestAddr. destAddr=\"" + Rlog.pii(TAG, destAddr) + "\"" );
+
+ if (destAddr == null || !PhoneNumberUtils.isGlobalPhoneNumber(destAddr)) {
+ Rlog.w(TAG, "destAddr" + Rlog.pii(TAG, destAddr) +
+ " is not a global phone number! Nothing changed.");
+ return destAddr;
+ }
+
+ final TelephonyManager telephonyManager = ((TelephonyManager) context
+ .getSystemService(Context.TELEPHONY_SERVICE)).createForSubscriptionId(subId);
+ final String networkOperator = telephonyManager.getNetworkOperator();
+ String result = null;
+
+ if (needToConvert(context, subId)) {
+ final int networkType = getNetworkType(telephonyManager);
+ if (networkType != -1 && !TextUtils.isEmpty(networkOperator)) {
+ String networkMcc = networkOperator.substring(0, 3);
+ if (networkMcc != null && networkMcc.trim().length() > 0) {
+ result = formatNumber(context, destAddr, networkMcc, networkType);
+ }
+ }
+ }
+
+ if (DBG) {
+ Rlog.d(TAG, "destAddr is " + ((result != null)?"formatted.":"not formatted."));
+ Rlog.d(TAG, "leave filterDestAddr, new destAddr=\"" + (result != null ? Rlog.pii(TAG,
+ result) : Rlog.pii(TAG, destAddr)) + "\"");
+ }
+ return result != null ? result : destAddr;
+ }
+
+ /**
+ * Returns the current network type
+ */
+ private static int getNetworkType(TelephonyManager telephonyManager) {
+ int networkType = -1;
+ int phoneType = telephonyManager.getPhoneType();
+
+ if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+ networkType = GSM_UMTS_NETWORK;
+ } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+ if (isInternationalRoaming(telephonyManager)) {
+ networkType = CDMA_ROAMING_NETWORK;
+ } else {
+ networkType = CDMA_HOME_NETWORK;
+ }
+ } else {
+ if (DBG) Rlog.w(TAG, "warning! unknown mPhoneType value=" + phoneType);
+ }
+
+ return networkType;
+ }
+
+ private static boolean isInternationalRoaming(TelephonyManager telephonyManager) {
+ String operatorIsoCountry = telephonyManager.getNetworkCountryIso();
+ String simIsoCountry = telephonyManager.getSimCountryIso();
+ boolean internationalRoaming = !TextUtils.isEmpty(operatorIsoCountry)
+ && !TextUtils.isEmpty(simIsoCountry)
+ && !simIsoCountry.equals(operatorIsoCountry);
+ if (internationalRoaming) {
+ if ("us".equals(simIsoCountry)) {
+ internationalRoaming = !"vi".equals(operatorIsoCountry);
+ } else if ("vi".equals(simIsoCountry)) {
+ internationalRoaming = !"us".equals(operatorIsoCountry);
+ }
+ }
+ return internationalRoaming;
+ }
+
+ private static boolean needToConvert(Context context, int subId) {
+ // Calling package may not have READ_PHONE_STATE which is required for getConfig().
+ // Clear the calling identity so that it is called as self.
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager != null) {
+ PersistableBundle bundle = configManager.getConfigForSubId(subId);
+ if (bundle != null) {
+ return bundle.getBoolean(CarrierConfigManager
+ .KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ // by default this value is false
+ return false;
+ }
+}
diff --git a/telephony/java/com/google/android/mms/ContentType.java b/telephony/common/com/google/android/mms/ContentType.java
similarity index 100%
rename from telephony/java/com/google/android/mms/ContentType.java
rename to telephony/common/com/google/android/mms/ContentType.java
diff --git a/telephony/java/com/google/android/mms/InvalidHeaderValueException.java b/telephony/common/com/google/android/mms/InvalidHeaderValueException.java
similarity index 100%
rename from telephony/java/com/google/android/mms/InvalidHeaderValueException.java
rename to telephony/common/com/google/android/mms/InvalidHeaderValueException.java
diff --git a/telephony/java/com/google/android/mms/MmsException.java b/telephony/common/com/google/android/mms/MmsException.java
similarity index 100%
rename from telephony/java/com/google/android/mms/MmsException.java
rename to telephony/common/com/google/android/mms/MmsException.java
diff --git a/telephony/java/com/google/android/mms/package.html b/telephony/common/com/google/android/mms/package.html
similarity index 100%
rename from telephony/java/com/google/android/mms/package.html
rename to telephony/common/com/google/android/mms/package.html
diff --git a/telephony/java/com/google/android/mms/pdu/AcknowledgeInd.java b/telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/AcknowledgeInd.java
rename to telephony/common/com/google/android/mms/pdu/AcknowledgeInd.java
diff --git a/telephony/java/com/google/android/mms/pdu/Base64.java b/telephony/common/com/google/android/mms/pdu/Base64.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/Base64.java
rename to telephony/common/com/google/android/mms/pdu/Base64.java
diff --git a/telephony/java/com/google/android/mms/pdu/CharacterSets.java b/telephony/common/com/google/android/mms/pdu/CharacterSets.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/CharacterSets.java
rename to telephony/common/com/google/android/mms/pdu/CharacterSets.java
diff --git a/telephony/java/com/google/android/mms/pdu/DeliveryInd.java b/telephony/common/com/google/android/mms/pdu/DeliveryInd.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/DeliveryInd.java
rename to telephony/common/com/google/android/mms/pdu/DeliveryInd.java
diff --git a/telephony/java/com/google/android/mms/pdu/EncodedStringValue.java b/telephony/common/com/google/android/mms/pdu/EncodedStringValue.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/EncodedStringValue.java
rename to telephony/common/com/google/android/mms/pdu/EncodedStringValue.java
diff --git a/telephony/java/com/google/android/mms/pdu/GenericPdu.java b/telephony/common/com/google/android/mms/pdu/GenericPdu.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/GenericPdu.java
rename to telephony/common/com/google/android/mms/pdu/GenericPdu.java
diff --git a/telephony/java/com/google/android/mms/pdu/MultimediaMessagePdu.java b/telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/MultimediaMessagePdu.java
rename to telephony/common/com/google/android/mms/pdu/MultimediaMessagePdu.java
diff --git a/telephony/java/com/google/android/mms/pdu/NotificationInd.java b/telephony/common/com/google/android/mms/pdu/NotificationInd.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/NotificationInd.java
rename to telephony/common/com/google/android/mms/pdu/NotificationInd.java
diff --git a/telephony/java/com/google/android/mms/pdu/NotifyRespInd.java b/telephony/common/com/google/android/mms/pdu/NotifyRespInd.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/NotifyRespInd.java
rename to telephony/common/com/google/android/mms/pdu/NotifyRespInd.java
diff --git a/telephony/java/com/google/android/mms/pdu/PduBody.java b/telephony/common/com/google/android/mms/pdu/PduBody.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/PduBody.java
rename to telephony/common/com/google/android/mms/pdu/PduBody.java
diff --git a/telephony/java/com/google/android/mms/pdu/PduComposer.java b/telephony/common/com/google/android/mms/pdu/PduComposer.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/PduComposer.java
rename to telephony/common/com/google/android/mms/pdu/PduComposer.java
diff --git a/telephony/java/com/google/android/mms/pdu/PduContentTypes.java b/telephony/common/com/google/android/mms/pdu/PduContentTypes.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/PduContentTypes.java
rename to telephony/common/com/google/android/mms/pdu/PduContentTypes.java
diff --git a/telephony/java/com/google/android/mms/pdu/PduHeaders.java b/telephony/common/com/google/android/mms/pdu/PduHeaders.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/PduHeaders.java
rename to telephony/common/com/google/android/mms/pdu/PduHeaders.java
diff --git a/telephony/java/com/google/android/mms/pdu/PduParser.java b/telephony/common/com/google/android/mms/pdu/PduParser.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/PduParser.java
rename to telephony/common/com/google/android/mms/pdu/PduParser.java
diff --git a/telephony/java/com/google/android/mms/pdu/PduPart.java b/telephony/common/com/google/android/mms/pdu/PduPart.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/PduPart.java
rename to telephony/common/com/google/android/mms/pdu/PduPart.java
diff --git a/telephony/java/com/google/android/mms/pdu/PduPersister.java b/telephony/common/com/google/android/mms/pdu/PduPersister.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/PduPersister.java
rename to telephony/common/com/google/android/mms/pdu/PduPersister.java
diff --git a/telephony/java/com/google/android/mms/pdu/QuotedPrintable.java b/telephony/common/com/google/android/mms/pdu/QuotedPrintable.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/QuotedPrintable.java
rename to telephony/common/com/google/android/mms/pdu/QuotedPrintable.java
diff --git a/telephony/java/com/google/android/mms/pdu/ReadOrigInd.java b/telephony/common/com/google/android/mms/pdu/ReadOrigInd.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/ReadOrigInd.java
rename to telephony/common/com/google/android/mms/pdu/ReadOrigInd.java
diff --git a/telephony/java/com/google/android/mms/pdu/ReadRecInd.java b/telephony/common/com/google/android/mms/pdu/ReadRecInd.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/ReadRecInd.java
rename to telephony/common/com/google/android/mms/pdu/ReadRecInd.java
diff --git a/telephony/java/com/google/android/mms/pdu/RetrieveConf.java b/telephony/common/com/google/android/mms/pdu/RetrieveConf.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/RetrieveConf.java
rename to telephony/common/com/google/android/mms/pdu/RetrieveConf.java
diff --git a/telephony/java/com/google/android/mms/pdu/SendConf.java b/telephony/common/com/google/android/mms/pdu/SendConf.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/SendConf.java
rename to telephony/common/com/google/android/mms/pdu/SendConf.java
diff --git a/telephony/java/com/google/android/mms/pdu/SendReq.java b/telephony/common/com/google/android/mms/pdu/SendReq.java
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/SendReq.java
rename to telephony/common/com/google/android/mms/pdu/SendReq.java
diff --git a/telephony/java/com/google/android/mms/pdu/package.html b/telephony/common/com/google/android/mms/pdu/package.html
similarity index 100%
rename from telephony/java/com/google/android/mms/pdu/package.html
rename to telephony/common/com/google/android/mms/pdu/package.html
diff --git a/telephony/java/com/google/android/mms/util/AbstractCache.java b/telephony/common/com/google/android/mms/util/AbstractCache.java
similarity index 100%
rename from telephony/java/com/google/android/mms/util/AbstractCache.java
rename to telephony/common/com/google/android/mms/util/AbstractCache.java
diff --git a/telephony/java/com/google/android/mms/util/DownloadDrmHelper.java b/telephony/common/com/google/android/mms/util/DownloadDrmHelper.java
similarity index 100%
rename from telephony/java/com/google/android/mms/util/DownloadDrmHelper.java
rename to telephony/common/com/google/android/mms/util/DownloadDrmHelper.java
diff --git a/telephony/java/com/google/android/mms/util/DrmConvertSession.java b/telephony/common/com/google/android/mms/util/DrmConvertSession.java
similarity index 100%
rename from telephony/java/com/google/android/mms/util/DrmConvertSession.java
rename to telephony/common/com/google/android/mms/util/DrmConvertSession.java
diff --git a/telephony/java/com/google/android/mms/util/PduCache.java b/telephony/common/com/google/android/mms/util/PduCache.java
similarity index 100%
rename from telephony/java/com/google/android/mms/util/PduCache.java
rename to telephony/common/com/google/android/mms/util/PduCache.java
diff --git a/telephony/java/com/google/android/mms/util/PduCacheEntry.java b/telephony/common/com/google/android/mms/util/PduCacheEntry.java
similarity index 100%
rename from telephony/java/com/google/android/mms/util/PduCacheEntry.java
rename to telephony/common/com/google/android/mms/util/PduCacheEntry.java
diff --git a/telephony/java/com/google/android/mms/util/SqliteWrapper.java b/telephony/common/com/google/android/mms/util/SqliteWrapper.java
similarity index 100%
rename from telephony/java/com/google/android/mms/util/SqliteWrapper.java
rename to telephony/common/com/google/android/mms/util/SqliteWrapper.java
diff --git a/telephony/java/com/google/android/mms/util/package.html b/telephony/common/com/google/android/mms/util/package.html
similarity index 100%
rename from telephony/java/com/google/android/mms/util/package.html
rename to telephony/common/com/google/android/mms/util/package.html
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
new file mode 100644
index 0000000..72f758e
--- /dev/null
+++ b/telephony/java/android/telephony/Annotation.java
@@ -0,0 +1,512 @@
+package android.telephony;
+
+import android.annotation.IntDef;
+import android.telephony.data.ApnSetting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Telephony Annotations.
+ * Telephony sdk is a mainline module and others cannot reference hidden @IntDef. Moving some
+ * telephony annotations to a separate class to allow others statically link to it.
+ *
+ * @hide
+ */
+public class Annotation {
+ @IntDef(prefix = {"DATA_"}, value = {
+ TelephonyManager.DATA_ACTIVITY_NONE,
+ TelephonyManager.DATA_ACTIVITY_IN,
+ TelephonyManager.DATA_ACTIVITY_OUT,
+ TelephonyManager.DATA_ACTIVITY_INOUT,
+ TelephonyManager.DATA_ACTIVITY_DORMANT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DataActivityType {
+ }
+
+ @IntDef(prefix = {"DATA_"}, value = {
+ TelephonyManager.DATA_UNKNOWN,
+ TelephonyManager.DATA_DISCONNECTED,
+ TelephonyManager.DATA_CONNECTING,
+ TelephonyManager.DATA_CONNECTED,
+ TelephonyManager.DATA_SUSPENDED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DataState {
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"RADIO_POWER_"},
+ value = {
+ TelephonyManager.RADIO_POWER_OFF,
+ TelephonyManager.RADIO_POWER_ON,
+ TelephonyManager.RADIO_POWER_UNAVAILABLE,
+ })
+ public @interface RadioPowerState {
+ }
+
+ @IntDef({
+ TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN,
+ TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATING,
+ TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATED,
+ TelephonyManager.SIM_ACTIVATION_STATE_DEACTIVATED,
+ TelephonyManager.SIM_ACTIVATION_STATE_RESTRICTED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SimActivationState {
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"SRVCC_STATE_"},
+ value = {
+ TelephonyManager.SRVCC_STATE_HANDOVER_NONE,
+ TelephonyManager.SRVCC_STATE_HANDOVER_STARTED,
+ TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED,
+ TelephonyManager.SRVCC_STATE_HANDOVER_FAILED,
+ TelephonyManager.SRVCC_STATE_HANDOVER_CANCELED})
+ public @interface SrvccState {
+ }
+
+ @IntDef(prefix = {"CALL_STATE_"}, value = {
+ TelephonyManager.CALL_STATE_IDLE,
+ TelephonyManager.CALL_STATE_RINGING,
+ TelephonyManager.CALL_STATE_OFFHOOK
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CallState {
+ }
+
+ @IntDef({
+ TelephonyManager.NETWORK_TYPE_UNKNOWN,
+ TelephonyManager.NETWORK_TYPE_GPRS,
+ TelephonyManager.NETWORK_TYPE_EDGE,
+ TelephonyManager.NETWORK_TYPE_UMTS,
+ TelephonyManager.NETWORK_TYPE_CDMA,
+ TelephonyManager.NETWORK_TYPE_EVDO_0,
+ TelephonyManager.NETWORK_TYPE_EVDO_A,
+ TelephonyManager.NETWORK_TYPE_1xRTT,
+ TelephonyManager.NETWORK_TYPE_HSDPA,
+ TelephonyManager.NETWORK_TYPE_HSUPA,
+ TelephonyManager.NETWORK_TYPE_HSPA,
+ TelephonyManager.NETWORK_TYPE_IDEN,
+ TelephonyManager.NETWORK_TYPE_EVDO_B,
+ TelephonyManager.NETWORK_TYPE_LTE,
+ TelephonyManager.NETWORK_TYPE_EHRPD,
+ TelephonyManager.NETWORK_TYPE_HSPAP,
+ TelephonyManager.NETWORK_TYPE_GSM,
+ TelephonyManager.NETWORK_TYPE_TD_SCDMA,
+ TelephonyManager.NETWORK_TYPE_IWLAN,
+ TelephonyManager.NETWORK_TYPE_LTE_CA,
+ TelephonyManager.NETWORK_TYPE_NR,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface NetworkType {
+ }
+
+ @IntDef(flag = true, prefix = {"TYPE_"}, value = {
+ ApnSetting.TYPE_DEFAULT,
+ ApnSetting.TYPE_MMS,
+ ApnSetting.TYPE_SUPL,
+ ApnSetting.TYPE_DUN,
+ ApnSetting.TYPE_HIPRI,
+ ApnSetting.TYPE_FOTA,
+ ApnSetting.TYPE_IMS,
+ ApnSetting.TYPE_CBS,
+ ApnSetting.TYPE_IA,
+ ApnSetting.TYPE_EMERGENCY,
+ ApnSetting.TYPE_MCX
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ApnType {
+ }
+
+ @IntDef(value = {
+ DataFailCause.NONE,
+ DataFailCause.OPERATOR_BARRED,
+ DataFailCause.NAS_SIGNALLING,
+ DataFailCause.LLC_SNDCP,
+ DataFailCause.INSUFFICIENT_RESOURCES,
+ DataFailCause.MISSING_UNKNOWN_APN,
+ DataFailCause.UNKNOWN_PDP_ADDRESS_TYPE,
+ DataFailCause.USER_AUTHENTICATION,
+ DataFailCause.ACTIVATION_REJECT_GGSN,
+ DataFailCause.ACTIVATION_REJECT_UNSPECIFIED,
+ DataFailCause.SERVICE_OPTION_NOT_SUPPORTED,
+ DataFailCause.SERVICE_OPTION_NOT_SUBSCRIBED,
+ DataFailCause.SERVICE_OPTION_OUT_OF_ORDER,
+ DataFailCause.NSAPI_IN_USE,
+ DataFailCause.REGULAR_DEACTIVATION,
+ DataFailCause.QOS_NOT_ACCEPTED,
+ DataFailCause.NETWORK_FAILURE,
+ DataFailCause.UMTS_REACTIVATION_REQ,
+ DataFailCause.FEATURE_NOT_SUPP,
+ DataFailCause.TFT_SEMANTIC_ERROR,
+ DataFailCause.TFT_SYTAX_ERROR,
+ DataFailCause.UNKNOWN_PDP_CONTEXT,
+ DataFailCause.FILTER_SEMANTIC_ERROR,
+ DataFailCause.FILTER_SYTAX_ERROR,
+ DataFailCause.PDP_WITHOUT_ACTIVE_TFT,
+ DataFailCause.ACTIVATION_REJECTED_BCM_VIOLATION,
+ DataFailCause.ONLY_IPV4_ALLOWED,
+ DataFailCause.ONLY_IPV6_ALLOWED,
+ DataFailCause.ONLY_SINGLE_BEARER_ALLOWED,
+ DataFailCause.ESM_INFO_NOT_RECEIVED,
+ DataFailCause.PDN_CONN_DOES_NOT_EXIST,
+ DataFailCause.MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED,
+ DataFailCause.COLLISION_WITH_NETWORK_INITIATED_REQUEST,
+ DataFailCause.ONLY_IPV4V6_ALLOWED,
+ DataFailCause.ONLY_NON_IP_ALLOWED,
+ DataFailCause.UNSUPPORTED_QCI_VALUE,
+ DataFailCause.BEARER_HANDLING_NOT_SUPPORTED,
+ DataFailCause.ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED,
+ DataFailCause.UNSUPPORTED_APN_IN_CURRENT_PLMN,
+ DataFailCause.INVALID_TRANSACTION_ID,
+ DataFailCause.MESSAGE_INCORRECT_SEMANTIC,
+ DataFailCause.INVALID_MANDATORY_INFO,
+ DataFailCause.MESSAGE_TYPE_UNSUPPORTED,
+ DataFailCause.MSG_TYPE_NONCOMPATIBLE_STATE,
+ DataFailCause.UNKNOWN_INFO_ELEMENT,
+ DataFailCause.CONDITIONAL_IE_ERROR,
+ DataFailCause.MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE,
+ DataFailCause.PROTOCOL_ERRORS,
+ DataFailCause.APN_TYPE_CONFLICT,
+ DataFailCause.INVALID_PCSCF_ADDR,
+ DataFailCause.INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN,
+ DataFailCause.EMM_ACCESS_BARRED,
+ DataFailCause.EMERGENCY_IFACE_ONLY,
+ DataFailCause.IFACE_MISMATCH,
+ DataFailCause.COMPANION_IFACE_IN_USE,
+ DataFailCause.IP_ADDRESS_MISMATCH,
+ DataFailCause.IFACE_AND_POL_FAMILY_MISMATCH,
+ DataFailCause.EMM_ACCESS_BARRED_INFINITE_RETRY,
+ DataFailCause.AUTH_FAILURE_ON_EMERGENCY_CALL,
+ DataFailCause.INVALID_DNS_ADDR,
+ DataFailCause.INVALID_PCSCF_OR_DNS_ADDRESS,
+ DataFailCause.CALL_PREEMPT_BY_EMERGENCY_APN,
+ DataFailCause.UE_INITIATED_DETACH_OR_DISCONNECT,
+ DataFailCause.MIP_FA_REASON_UNSPECIFIED,
+ DataFailCause.MIP_FA_ADMIN_PROHIBITED,
+ DataFailCause.MIP_FA_INSUFFICIENT_RESOURCES,
+ DataFailCause.MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE,
+ DataFailCause.MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE,
+ DataFailCause.MIP_FA_REQUESTED_LIFETIME_TOO_LONG,
+ DataFailCause.MIP_FA_MALFORMED_REQUEST,
+ DataFailCause.MIP_FA_MALFORMED_REPLY,
+ DataFailCause.MIP_FA_ENCAPSULATION_UNAVAILABLE,
+ DataFailCause.MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE,
+ DataFailCause.MIP_FA_REVERSE_TUNNEL_UNAVAILABLE,
+ DataFailCause.MIP_FA_REVERSE_TUNNEL_IS_MANDATORY,
+ DataFailCause.MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED,
+ DataFailCause.MIP_FA_MISSING_NAI,
+ DataFailCause.MIP_FA_MISSING_HOME_AGENT,
+ DataFailCause.MIP_FA_MISSING_HOME_ADDRESS,
+ DataFailCause.MIP_FA_UNKNOWN_CHALLENGE,
+ DataFailCause.MIP_FA_MISSING_CHALLENGE,
+ DataFailCause.MIP_FA_STALE_CHALLENGE,
+ DataFailCause.MIP_HA_REASON_UNSPECIFIED,
+ DataFailCause.MIP_HA_ADMIN_PROHIBITED,
+ DataFailCause.MIP_HA_INSUFFICIENT_RESOURCES,
+ DataFailCause.MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE,
+ DataFailCause.MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE,
+ DataFailCause.MIP_HA_REGISTRATION_ID_MISMATCH,
+ DataFailCause.MIP_HA_MALFORMED_REQUEST,
+ DataFailCause.MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS,
+ DataFailCause.MIP_HA_REVERSE_TUNNEL_UNAVAILABLE,
+ DataFailCause.MIP_HA_REVERSE_TUNNEL_IS_MANDATORY,
+ DataFailCause.MIP_HA_ENCAPSULATION_UNAVAILABLE,
+ DataFailCause.CLOSE_IN_PROGRESS,
+ DataFailCause.NETWORK_INITIATED_TERMINATION,
+ DataFailCause.MODEM_APP_PREEMPTED,
+ DataFailCause.PDN_IPV4_CALL_DISALLOWED,
+ DataFailCause.PDN_IPV4_CALL_THROTTLED,
+ DataFailCause.PDN_IPV6_CALL_DISALLOWED,
+ DataFailCause.PDN_IPV6_CALL_THROTTLED,
+ DataFailCause.MODEM_RESTART,
+ DataFailCause.PDP_PPP_NOT_SUPPORTED,
+ DataFailCause.UNPREFERRED_RAT,
+ DataFailCause.PHYSICAL_LINK_CLOSE_IN_PROGRESS,
+ DataFailCause.APN_PENDING_HANDOVER,
+ DataFailCause.PROFILE_BEARER_INCOMPATIBLE,
+ DataFailCause.SIM_CARD_CHANGED,
+ DataFailCause.LOW_POWER_MODE_OR_POWERING_DOWN,
+ DataFailCause.APN_DISABLED,
+ DataFailCause.MAX_PPP_INACTIVITY_TIMER_EXPIRED,
+ DataFailCause.IPV6_ADDRESS_TRANSFER_FAILED,
+ DataFailCause.TRAT_SWAP_FAILED,
+ DataFailCause.EHRPD_TO_HRPD_FALLBACK,
+ DataFailCause.MIP_CONFIG_FAILURE,
+ DataFailCause.PDN_INACTIVITY_TIMER_EXPIRED,
+ DataFailCause.MAX_IPV4_CONNECTIONS,
+ DataFailCause.MAX_IPV6_CONNECTIONS,
+ DataFailCause.APN_MISMATCH,
+ DataFailCause.IP_VERSION_MISMATCH,
+ DataFailCause.DUN_CALL_DISALLOWED,
+ DataFailCause.INTERNAL_EPC_NONEPC_TRANSITION,
+ DataFailCause.INTERFACE_IN_USE,
+ DataFailCause.APN_DISALLOWED_ON_ROAMING,
+ DataFailCause.APN_PARAMETERS_CHANGED,
+ DataFailCause.NULL_APN_DISALLOWED,
+ DataFailCause.THERMAL_MITIGATION,
+ DataFailCause.DATA_SETTINGS_DISABLED,
+ DataFailCause.DATA_ROAMING_SETTINGS_DISABLED,
+ DataFailCause.DDS_SWITCHED,
+ DataFailCause.FORBIDDEN_APN_NAME,
+ DataFailCause.DDS_SWITCH_IN_PROGRESS,
+ DataFailCause.CALL_DISALLOWED_IN_ROAMING,
+ DataFailCause.NON_IP_NOT_SUPPORTED,
+ DataFailCause.PDN_NON_IP_CALL_THROTTLED,
+ DataFailCause.PDN_NON_IP_CALL_DISALLOWED,
+ DataFailCause.CDMA_LOCK,
+ DataFailCause.CDMA_INTERCEPT,
+ DataFailCause.CDMA_REORDER,
+ DataFailCause.CDMA_RELEASE_DUE_TO_SO_REJECTION,
+ DataFailCause.CDMA_INCOMING_CALL,
+ DataFailCause.CDMA_ALERT_STOP,
+ DataFailCause.CHANNEL_ACQUISITION_FAILURE,
+ DataFailCause.MAX_ACCESS_PROBE,
+ DataFailCause.CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION,
+ DataFailCause.NO_RESPONSE_FROM_BASE_STATION,
+ DataFailCause.REJECTED_BY_BASE_STATION,
+ DataFailCause.CONCURRENT_SERVICES_INCOMPATIBLE,
+ DataFailCause.NO_CDMA_SERVICE,
+ DataFailCause.RUIM_NOT_PRESENT,
+ DataFailCause.CDMA_RETRY_ORDER,
+ DataFailCause.ACCESS_BLOCK,
+ DataFailCause.ACCESS_BLOCK_ALL,
+ DataFailCause.IS707B_MAX_ACCESS_PROBES,
+ DataFailCause.THERMAL_EMERGENCY,
+ DataFailCause.CONCURRENT_SERVICES_NOT_ALLOWED,
+ DataFailCause.INCOMING_CALL_REJECTED,
+ DataFailCause.NO_SERVICE_ON_GATEWAY,
+ DataFailCause.NO_GPRS_CONTEXT,
+ DataFailCause.ILLEGAL_MS,
+ DataFailCause.ILLEGAL_ME,
+ DataFailCause.GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED,
+ DataFailCause.GPRS_SERVICES_NOT_ALLOWED,
+ DataFailCause.MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
+ DataFailCause.IMPLICITLY_DETACHED,
+ DataFailCause.PLMN_NOT_ALLOWED,
+ DataFailCause.LOCATION_AREA_NOT_ALLOWED,
+ DataFailCause.GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
+ DataFailCause.PDP_DUPLICATE,
+ DataFailCause.UE_RAT_CHANGE,
+ DataFailCause.CONGESTION,
+ DataFailCause.NO_PDP_CONTEXT_ACTIVATED,
+ DataFailCause.ACCESS_CLASS_DSAC_REJECTION,
+ DataFailCause.PDP_ACTIVATE_MAX_RETRY_FAILED,
+ DataFailCause.RADIO_ACCESS_BEARER_FAILURE,
+ DataFailCause.ESM_UNKNOWN_EPS_BEARER_CONTEXT,
+ DataFailCause.DRB_RELEASED_BY_RRC,
+ DataFailCause.CONNECTION_RELEASED,
+ DataFailCause.EMM_DETACHED,
+ DataFailCause.EMM_ATTACH_FAILED,
+ DataFailCause.EMM_ATTACH_STARTED,
+ DataFailCause.LTE_NAS_SERVICE_REQUEST_FAILED,
+ DataFailCause.DUPLICATE_BEARER_ID,
+ DataFailCause.ESM_COLLISION_SCENARIOS,
+ DataFailCause.ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK,
+ DataFailCause.ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER,
+ DataFailCause.ESM_BAD_OTA_MESSAGE,
+ DataFailCause.ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL,
+ DataFailCause.ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT,
+ DataFailCause.DS_EXPLICIT_DEACTIVATION,
+ DataFailCause.ESM_LOCAL_CAUSE_NONE,
+ DataFailCause.LTE_THROTTLING_NOT_REQUIRED,
+ DataFailCause.ACCESS_CONTROL_LIST_CHECK_FAILURE,
+ DataFailCause.SERVICE_NOT_ALLOWED_ON_PLMN,
+ DataFailCause.EMM_T3417_EXPIRED,
+ DataFailCause.EMM_T3417_EXT_EXPIRED,
+ DataFailCause.RRC_UPLINK_DATA_TRANSMISSION_FAILURE,
+ DataFailCause.RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER,
+ DataFailCause.RRC_UPLINK_CONNECTION_RELEASE,
+ DataFailCause.RRC_UPLINK_RADIO_LINK_FAILURE,
+ DataFailCause.RRC_UPLINK_ERROR_REQUEST_FROM_NAS,
+ DataFailCause.RRC_CONNECTION_ACCESS_STRATUM_FAILURE,
+ DataFailCause.RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS,
+ DataFailCause.RRC_CONNECTION_ACCESS_BARRED,
+ DataFailCause.RRC_CONNECTION_CELL_RESELECTION,
+ DataFailCause.RRC_CONNECTION_CONFIG_FAILURE,
+ DataFailCause.RRC_CONNECTION_TIMER_EXPIRED,
+ DataFailCause.RRC_CONNECTION_LINK_FAILURE,
+ DataFailCause.RRC_CONNECTION_CELL_NOT_CAMPED,
+ DataFailCause.RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE,
+ DataFailCause.RRC_CONNECTION_REJECT_BY_NETWORK,
+ DataFailCause.RRC_CONNECTION_NORMAL_RELEASE,
+ DataFailCause.RRC_CONNECTION_RADIO_LINK_FAILURE,
+ DataFailCause.RRC_CONNECTION_REESTABLISHMENT_FAILURE,
+ DataFailCause.RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER,
+ DataFailCause.RRC_CONNECTION_ABORT_REQUEST,
+ DataFailCause.RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR,
+ DataFailCause.NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH,
+ DataFailCause.NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH,
+ DataFailCause.ESM_PROCEDURE_TIME_OUT,
+ DataFailCause.INVALID_CONNECTION_ID,
+ DataFailCause.MAXIMIUM_NSAPIS_EXCEEDED,
+ DataFailCause.INVALID_PRIMARY_NSAPI,
+ DataFailCause.CANNOT_ENCODE_OTA_MESSAGE,
+ DataFailCause.RADIO_ACCESS_BEARER_SETUP_FAILURE,
+ DataFailCause.PDP_ESTABLISH_TIMEOUT_EXPIRED,
+ DataFailCause.PDP_MODIFY_TIMEOUT_EXPIRED,
+ DataFailCause.PDP_INACTIVE_TIMEOUT_EXPIRED,
+ DataFailCause.PDP_LOWERLAYER_ERROR,
+ DataFailCause.PDP_MODIFY_COLLISION,
+ DataFailCause.MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED,
+ DataFailCause.NAS_REQUEST_REJECTED_BY_NETWORK,
+ DataFailCause.RRC_CONNECTION_INVALID_REQUEST,
+ DataFailCause.RRC_CONNECTION_TRACKING_AREA_ID_CHANGED,
+ DataFailCause.RRC_CONNECTION_RF_UNAVAILABLE,
+ DataFailCause.RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE,
+ DataFailCause.RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE,
+ DataFailCause.RRC_CONNECTION_ABORTED_AFTER_HANDOVER,
+ DataFailCause.RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE,
+ DataFailCause.RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE,
+ DataFailCause.IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER,
+ DataFailCause.IMEI_NOT_ACCEPTED,
+ DataFailCause.EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
+ DataFailCause.EPS_SERVICES_NOT_ALLOWED_IN_PLMN,
+ DataFailCause.MSC_TEMPORARILY_NOT_REACHABLE,
+ DataFailCause.CS_DOMAIN_NOT_AVAILABLE,
+ DataFailCause.ESM_FAILURE,
+ DataFailCause.MAC_FAILURE,
+ DataFailCause.SYNCHRONIZATION_FAILURE,
+ DataFailCause.UE_SECURITY_CAPABILITIES_MISMATCH,
+ DataFailCause.SECURITY_MODE_REJECTED,
+ DataFailCause.UNACCEPTABLE_NON_EPS_AUTHENTICATION,
+ DataFailCause.CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED,
+ DataFailCause.NO_EPS_BEARER_CONTEXT_ACTIVATED,
+ DataFailCause.INVALID_EMM_STATE,
+ DataFailCause.NAS_LAYER_FAILURE,
+ DataFailCause.MULTIPLE_PDP_CALL_NOT_ALLOWED,
+ DataFailCause.EMBMS_NOT_ENABLED,
+ DataFailCause.IRAT_HANDOVER_FAILED,
+ DataFailCause.EMBMS_REGULAR_DEACTIVATION,
+ DataFailCause.TEST_LOOPBACK_REGULAR_DEACTIVATION,
+ DataFailCause.LOWER_LAYER_REGISTRATION_FAILURE,
+ DataFailCause.DATA_PLAN_EXPIRED,
+ DataFailCause.UMTS_HANDOVER_TO_IWLAN,
+ DataFailCause.EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY,
+ DataFailCause.EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE,
+ DataFailCause.EVDO_HDR_CHANGED,
+ DataFailCause.EVDO_HDR_EXITED,
+ DataFailCause.EVDO_HDR_NO_SESSION,
+ DataFailCause.EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL,
+ DataFailCause.EVDO_HDR_CONNECTION_SETUP_TIMEOUT,
+ DataFailCause.FAILED_TO_ACQUIRE_COLOCATED_HDR,
+ DataFailCause.OTASP_COMMIT_IN_PROGRESS,
+ DataFailCause.NO_HYBRID_HDR_SERVICE,
+ DataFailCause.HDR_NO_LOCK_GRANTED,
+ DataFailCause.DBM_OR_SMS_IN_PROGRESS,
+ DataFailCause.HDR_FADE,
+ DataFailCause.HDR_ACCESS_FAILURE,
+ DataFailCause.UNSUPPORTED_1X_PREV,
+ DataFailCause.LOCAL_END,
+ DataFailCause.NO_SERVICE,
+ DataFailCause.FADE,
+ DataFailCause.NORMAL_RELEASE,
+ DataFailCause.ACCESS_ATTEMPT_ALREADY_IN_PROGRESS,
+ DataFailCause.REDIRECTION_OR_HANDOFF_IN_PROGRESS,
+ DataFailCause.EMERGENCY_MODE,
+ DataFailCause.PHONE_IN_USE,
+ DataFailCause.INVALID_MODE,
+ DataFailCause.INVALID_SIM_STATE,
+ DataFailCause.NO_COLLOCATED_HDR,
+ DataFailCause.UE_IS_ENTERING_POWERSAVE_MODE,
+ DataFailCause.DUAL_SWITCH,
+ DataFailCause.PPP_TIMEOUT,
+ DataFailCause.PPP_AUTH_FAILURE,
+ DataFailCause.PPP_OPTION_MISMATCH,
+ DataFailCause.PPP_PAP_FAILURE,
+ DataFailCause.PPP_CHAP_FAILURE,
+ DataFailCause.PPP_CLOSE_IN_PROGRESS,
+ DataFailCause.LIMITED_TO_IPV4,
+ DataFailCause.LIMITED_TO_IPV6,
+ DataFailCause.VSNCP_TIMEOUT,
+ DataFailCause.VSNCP_GEN_ERROR,
+ DataFailCause.VSNCP_APN_UNATHORIZED,
+ DataFailCause.VSNCP_PDN_LIMIT_EXCEEDED,
+ DataFailCause.VSNCP_NO_PDN_GATEWAY_ADDRESS,
+ DataFailCause.VSNCP_PDN_GATEWAY_UNREACHABLE,
+ DataFailCause.VSNCP_PDN_GATEWAY_REJECT,
+ DataFailCause.VSNCP_INSUFFICIENT_PARAMETERS,
+ DataFailCause.VSNCP_RESOURCE_UNAVAILABLE,
+ DataFailCause.VSNCP_ADMINISTRATIVELY_PROHIBITED,
+ DataFailCause.VSNCP_PDN_ID_IN_USE,
+ DataFailCause.VSNCP_SUBSCRIBER_LIMITATION,
+ DataFailCause.VSNCP_PDN_EXISTS_FOR_THIS_APN,
+ DataFailCause.VSNCP_RECONNECT_NOT_ALLOWED,
+ DataFailCause.IPV6_PREFIX_UNAVAILABLE,
+ DataFailCause.HANDOFF_PREFERENCE_CHANGED,
+ DataFailCause.OEM_DCFAILCAUSE_1,
+ DataFailCause.OEM_DCFAILCAUSE_2,
+ DataFailCause.OEM_DCFAILCAUSE_3,
+ DataFailCause.OEM_DCFAILCAUSE_4,
+ DataFailCause.OEM_DCFAILCAUSE_5,
+ DataFailCause.OEM_DCFAILCAUSE_6,
+ DataFailCause.OEM_DCFAILCAUSE_7,
+ DataFailCause.OEM_DCFAILCAUSE_8,
+ DataFailCause.OEM_DCFAILCAUSE_9,
+ DataFailCause.OEM_DCFAILCAUSE_10,
+ DataFailCause.OEM_DCFAILCAUSE_11,
+ DataFailCause.OEM_DCFAILCAUSE_12,
+ DataFailCause.OEM_DCFAILCAUSE_13,
+ DataFailCause.OEM_DCFAILCAUSE_14,
+ DataFailCause.OEM_DCFAILCAUSE_15,
+ DataFailCause.REGISTRATION_FAIL,
+ DataFailCause.GPRS_REGISTRATION_FAIL,
+ DataFailCause.SIGNAL_LOST,
+ DataFailCause.PREF_RADIO_TECH_CHANGED,
+ DataFailCause.RADIO_POWER_OFF,
+ DataFailCause.TETHERED_CALL_ACTIVE,
+ DataFailCause.ERROR_UNSPECIFIED,
+ DataFailCause.UNKNOWN,
+ DataFailCause.RADIO_NOT_AVAILABLE,
+ DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER,
+ DataFailCause.CONNECTION_TO_DATACONNECTIONAC_BROKEN,
+ DataFailCause.LOST_CONNECTION,
+ DataFailCause.RESET_BY_FRAMEWORK
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DataFailureCause {
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"PRECISE_CALL_STATE_"},
+ value = {
+ PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+ PreciseCallState.PRECISE_CALL_STATE_IDLE,
+ PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
+ PreciseCallState.PRECISE_CALL_STATE_HOLDING,
+ PreciseCallState.PRECISE_CALL_STATE_DIALING,
+ PreciseCallState.PRECISE_CALL_STATE_ALERTING,
+ PreciseCallState. PRECISE_CALL_STATE_INCOMING,
+ PreciseCallState.PRECISE_CALL_STATE_WAITING,
+ PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED,
+ PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING})
+ public @interface PreciseCallStates {}
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"RIL_RADIO_TECHNOLOGY_" }, value = {
+ ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN,
+ ServiceState.RIL_RADIO_TECHNOLOGY_GPRS,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EDGE,
+ ServiceState.RIL_RADIO_TECHNOLOGY_UMTS,
+ ServiceState.RIL_RADIO_TECHNOLOGY_IS95A,
+ ServiceState.RIL_RADIO_TECHNOLOGY_IS95B,
+ ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSPA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B,
+ ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD,
+ ServiceState.RIL_RADIO_TECHNOLOGY_LTE,
+ ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP,
+ ServiceState.RIL_RADIO_TECHNOLOGY_GSM,
+ ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN,
+ ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA,
+ ServiceState.RIL_RADIO_TECHNOLOGY_NR})
+ public @interface RilRadioTechnology {}
+}
diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java
index 1c03d80..cd830ad 100644
--- a/telephony/java/android/telephony/CallAttributes.java
+++ b/telephony/java/android/telephony/CallAttributes.java
@@ -21,8 +21,8 @@
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import android.telephony.TelephonyManager.NetworkType;
+import android.telephony.Annotation.NetworkType;
import java.util.Objects;
/**
diff --git a/telephony/java/android/telephony/CellBroadcastService.java b/telephony/java/android/telephony/CellBroadcastService.java
new file mode 100644
index 0000000..d5e447e
--- /dev/null
+++ b/telephony/java/android/telephony/CellBroadcastService.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2019 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 android.telephony;
+
+import android.annotation.CallSuper;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * A service which exposes the cell broadcast handling module to the system.
+ * <p>
+ * To extend this class, you must declare the service in your manifest file to require the
+ * {@link android.Manifest.permission#BIND_CELL_BROADCAST_SERVICE} permission and include an intent
+ * filter with the {@link #CELL_BROADCAST_SERVICE_INTERFACE}.
+ * Implementations of this service should run in the phone process and with its UID.
+ * <p>
+ * For example:
+ * <pre>{@code
+ * <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ * android:sharedUserId="android.uid.phone">
+ * <service android:name=".MyCellBroadcastService"
+ * android:label="@string/service_name"
+ * android:process="com.android.phone"
+ * android:exported="true"
+ * android:permission="android.permission.BIND_CELL_BROADCAST_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.telephony.CellBroadcastService" />
+ * </intent-filter>
+ * </service>
+ * </manifest>
+ * }</pre>
+ * @hide
+ */
+@SystemApi
+public abstract class CellBroadcastService extends Service {
+
+ public static final String CELL_BROADCAST_SERVICE_INTERFACE =
+ "android.telephony.CellBroadcastService";
+
+ private final ICellBroadcastService.Stub mStubWrapper;
+
+ public CellBroadcastService() {
+ mStubWrapper = new ICellBroadcastServiceWrapper();
+ }
+
+ /**
+ * Handle a GSM cell broadcast SMS message forwarded from the system.
+ * @param slotIndex the index of the slot which received the message
+ * @param message the SMS PDU
+ */
+ public abstract void onGsmCellBroadcastSms(int slotIndex, byte[] message);
+
+ /**
+ * Handle a CDMA cell broadcast SMS message forwarded from the system.
+ * @param slotIndex the index of the slot which received the message
+ * @param message the SMS PDU
+ */
+ public abstract void onCdmaCellBroadcastSms(int slotIndex, byte[] message);
+
+ /**
+ * If overriding this method, call through to the super method for any unknown actions.
+ * {@inheritDoc}
+ */
+ @Override
+ @CallSuper
+ public IBinder onBind(Intent intent) {
+ return mStubWrapper;
+ }
+
+ /**
+ * A wrapper around ICellBroadcastService that forwards calls to implementations of
+ * {@link CellBroadcastService}.
+ * @hide
+ */
+ public class ICellBroadcastServiceWrapper extends ICellBroadcastService.Stub {
+ /**
+ * Handle a GSM cell broadcast SMS.
+ * @param slotIndex the index of the slot which received the broadcast
+ * @param message the SMS message PDU
+ */
+ @Override
+ public void handleGsmCellBroadcastSms(int slotIndex, byte[] message) {
+ CellBroadcastService.this.onGsmCellBroadcastSms(slotIndex, message);
+ }
+
+ /**
+ * Handle a CDMA cell broadcast SMS.
+ * @param slotIndex the index of the slot which received the broadcast
+ * @param message the SMS message PDU
+ */
+ @Override
+ public void handleCdmaCellBroadcastSms(int slotIndex, byte[] message) {
+ CellBroadcastService.this.onCdmaCellBroadcastSms(slotIndex, message);
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index ca264f7..246bec7 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.os.PersistableBundle;
+import android.telephony.Annotation.DataFailureCause;
import com.android.internal.util.ArrayUtils;
import java.lang.annotation.Retention;
@@ -968,355 +969,6 @@
*/
public static final int HANDOVER_FAILED = 0x10006;
- /** @hide */
- @IntDef(value = {
- NONE,
- OPERATOR_BARRED,
- NAS_SIGNALLING,
- LLC_SNDCP,
- INSUFFICIENT_RESOURCES,
- MISSING_UNKNOWN_APN,
- UNKNOWN_PDP_ADDRESS_TYPE,
- USER_AUTHENTICATION,
- ACTIVATION_REJECT_GGSN,
- ACTIVATION_REJECT_UNSPECIFIED,
- SERVICE_OPTION_NOT_SUPPORTED,
- SERVICE_OPTION_NOT_SUBSCRIBED,
- SERVICE_OPTION_OUT_OF_ORDER,
- NSAPI_IN_USE,
- REGULAR_DEACTIVATION,
- QOS_NOT_ACCEPTED,
- NETWORK_FAILURE,
- UMTS_REACTIVATION_REQ,
- FEATURE_NOT_SUPP,
- TFT_SEMANTIC_ERROR,
- TFT_SYTAX_ERROR,
- UNKNOWN_PDP_CONTEXT,
- FILTER_SEMANTIC_ERROR,
- FILTER_SYTAX_ERROR,
- PDP_WITHOUT_ACTIVE_TFT,
- ACTIVATION_REJECTED_BCM_VIOLATION,
- ONLY_IPV4_ALLOWED,
- ONLY_IPV6_ALLOWED,
- ONLY_SINGLE_BEARER_ALLOWED,
- ESM_INFO_NOT_RECEIVED,
- PDN_CONN_DOES_NOT_EXIST,
- MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED,
- COLLISION_WITH_NETWORK_INITIATED_REQUEST,
- ONLY_IPV4V6_ALLOWED,
- ONLY_NON_IP_ALLOWED,
- UNSUPPORTED_QCI_VALUE,
- BEARER_HANDLING_NOT_SUPPORTED,
- ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED,
- UNSUPPORTED_APN_IN_CURRENT_PLMN,
- INVALID_TRANSACTION_ID,
- MESSAGE_INCORRECT_SEMANTIC,
- INVALID_MANDATORY_INFO,
- MESSAGE_TYPE_UNSUPPORTED,
- MSG_TYPE_NONCOMPATIBLE_STATE,
- UNKNOWN_INFO_ELEMENT,
- CONDITIONAL_IE_ERROR,
- MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE,
- PROTOCOL_ERRORS,
- APN_TYPE_CONFLICT,
- INVALID_PCSCF_ADDR,
- INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN,
- EMM_ACCESS_BARRED,
- EMERGENCY_IFACE_ONLY,
- IFACE_MISMATCH,
- COMPANION_IFACE_IN_USE,
- IP_ADDRESS_MISMATCH,
- IFACE_AND_POL_FAMILY_MISMATCH,
- EMM_ACCESS_BARRED_INFINITE_RETRY,
- AUTH_FAILURE_ON_EMERGENCY_CALL,
- INVALID_DNS_ADDR,
- INVALID_PCSCF_OR_DNS_ADDRESS,
- CALL_PREEMPT_BY_EMERGENCY_APN,
- UE_INITIATED_DETACH_OR_DISCONNECT,
- MIP_FA_REASON_UNSPECIFIED,
- MIP_FA_ADMIN_PROHIBITED,
- MIP_FA_INSUFFICIENT_RESOURCES,
- MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE,
- MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE,
- MIP_FA_REQUESTED_LIFETIME_TOO_LONG,
- MIP_FA_MALFORMED_REQUEST,
- MIP_FA_MALFORMED_REPLY,
- MIP_FA_ENCAPSULATION_UNAVAILABLE,
- MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE,
- MIP_FA_REVERSE_TUNNEL_UNAVAILABLE,
- MIP_FA_REVERSE_TUNNEL_IS_MANDATORY,
- MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED,
- MIP_FA_MISSING_NAI,
- MIP_FA_MISSING_HOME_AGENT,
- MIP_FA_MISSING_HOME_ADDRESS,
- MIP_FA_UNKNOWN_CHALLENGE,
- MIP_FA_MISSING_CHALLENGE,
- MIP_FA_STALE_CHALLENGE,
- MIP_HA_REASON_UNSPECIFIED,
- MIP_HA_ADMIN_PROHIBITED,
- MIP_HA_INSUFFICIENT_RESOURCES,
- MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE,
- MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE,
- MIP_HA_REGISTRATION_ID_MISMATCH,
- MIP_HA_MALFORMED_REQUEST,
- MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS,
- MIP_HA_REVERSE_TUNNEL_UNAVAILABLE,
- MIP_HA_REVERSE_TUNNEL_IS_MANDATORY,
- MIP_HA_ENCAPSULATION_UNAVAILABLE,
- CLOSE_IN_PROGRESS,
- NETWORK_INITIATED_TERMINATION,
- MODEM_APP_PREEMPTED,
- PDN_IPV4_CALL_DISALLOWED,
- PDN_IPV4_CALL_THROTTLED,
- PDN_IPV6_CALL_DISALLOWED,
- PDN_IPV6_CALL_THROTTLED,
- MODEM_RESTART,
- PDP_PPP_NOT_SUPPORTED,
- UNPREFERRED_RAT,
- PHYSICAL_LINK_CLOSE_IN_PROGRESS,
- APN_PENDING_HANDOVER,
- PROFILE_BEARER_INCOMPATIBLE,
- SIM_CARD_CHANGED,
- LOW_POWER_MODE_OR_POWERING_DOWN,
- APN_DISABLED,
- MAX_PPP_INACTIVITY_TIMER_EXPIRED,
- IPV6_ADDRESS_TRANSFER_FAILED,
- TRAT_SWAP_FAILED,
- EHRPD_TO_HRPD_FALLBACK,
- MIP_CONFIG_FAILURE,
- PDN_INACTIVITY_TIMER_EXPIRED,
- MAX_IPV4_CONNECTIONS,
- MAX_IPV6_CONNECTIONS,
- APN_MISMATCH,
- IP_VERSION_MISMATCH,
- DUN_CALL_DISALLOWED,
- INTERNAL_EPC_NONEPC_TRANSITION,
- INTERFACE_IN_USE,
- APN_DISALLOWED_ON_ROAMING,
- APN_PARAMETERS_CHANGED,
- NULL_APN_DISALLOWED,
- THERMAL_MITIGATION,
- DATA_SETTINGS_DISABLED,
- DATA_ROAMING_SETTINGS_DISABLED,
- DDS_SWITCHED,
- FORBIDDEN_APN_NAME,
- DDS_SWITCH_IN_PROGRESS,
- CALL_DISALLOWED_IN_ROAMING,
- NON_IP_NOT_SUPPORTED,
- PDN_NON_IP_CALL_THROTTLED,
- PDN_NON_IP_CALL_DISALLOWED,
- CDMA_LOCK,
- CDMA_INTERCEPT,
- CDMA_REORDER,
- CDMA_RELEASE_DUE_TO_SO_REJECTION,
- CDMA_INCOMING_CALL,
- CDMA_ALERT_STOP,
- CHANNEL_ACQUISITION_FAILURE,
- MAX_ACCESS_PROBE,
- CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION,
- NO_RESPONSE_FROM_BASE_STATION,
- REJECTED_BY_BASE_STATION,
- CONCURRENT_SERVICES_INCOMPATIBLE,
- NO_CDMA_SERVICE,
- RUIM_NOT_PRESENT,
- CDMA_RETRY_ORDER,
- ACCESS_BLOCK,
- ACCESS_BLOCK_ALL,
- IS707B_MAX_ACCESS_PROBES,
- THERMAL_EMERGENCY,
- CONCURRENT_SERVICES_NOT_ALLOWED,
- INCOMING_CALL_REJECTED,
- NO_SERVICE_ON_GATEWAY,
- NO_GPRS_CONTEXT,
- ILLEGAL_MS,
- ILLEGAL_ME,
- GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED,
- GPRS_SERVICES_NOT_ALLOWED,
- MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
- IMPLICITLY_DETACHED,
- PLMN_NOT_ALLOWED,
- LOCATION_AREA_NOT_ALLOWED,
- GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN,
- PDP_DUPLICATE,
- UE_RAT_CHANGE,
- CONGESTION,
- NO_PDP_CONTEXT_ACTIVATED,
- ACCESS_CLASS_DSAC_REJECTION,
- PDP_ACTIVATE_MAX_RETRY_FAILED,
- RADIO_ACCESS_BEARER_FAILURE,
- ESM_UNKNOWN_EPS_BEARER_CONTEXT,
- DRB_RELEASED_BY_RRC,
- CONNECTION_RELEASED,
- EMM_DETACHED,
- EMM_ATTACH_FAILED,
- EMM_ATTACH_STARTED,
- LTE_NAS_SERVICE_REQUEST_FAILED,
- DUPLICATE_BEARER_ID,
- ESM_COLLISION_SCENARIOS,
- ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK,
- ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER,
- ESM_BAD_OTA_MESSAGE,
- ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL,
- ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT,
- DS_EXPLICIT_DEACTIVATION,
- ESM_LOCAL_CAUSE_NONE,
- LTE_THROTTLING_NOT_REQUIRED,
- ACCESS_CONTROL_LIST_CHECK_FAILURE,
- SERVICE_NOT_ALLOWED_ON_PLMN,
- EMM_T3417_EXPIRED,
- EMM_T3417_EXT_EXPIRED,
- RRC_UPLINK_DATA_TRANSMISSION_FAILURE,
- RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER,
- RRC_UPLINK_CONNECTION_RELEASE,
- RRC_UPLINK_RADIO_LINK_FAILURE,
- RRC_UPLINK_ERROR_REQUEST_FROM_NAS,
- RRC_CONNECTION_ACCESS_STRATUM_FAILURE,
- RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS,
- RRC_CONNECTION_ACCESS_BARRED,
- RRC_CONNECTION_CELL_RESELECTION,
- RRC_CONNECTION_CONFIG_FAILURE,
- RRC_CONNECTION_TIMER_EXPIRED,
- RRC_CONNECTION_LINK_FAILURE,
- RRC_CONNECTION_CELL_NOT_CAMPED,
- RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE,
- RRC_CONNECTION_REJECT_BY_NETWORK,
- RRC_CONNECTION_NORMAL_RELEASE,
- RRC_CONNECTION_RADIO_LINK_FAILURE,
- RRC_CONNECTION_REESTABLISHMENT_FAILURE,
- RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER,
- RRC_CONNECTION_ABORT_REQUEST,
- RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR,
- NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH,
- NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH,
- ESM_PROCEDURE_TIME_OUT,
- INVALID_CONNECTION_ID,
- MAXIMIUM_NSAPIS_EXCEEDED,
- INVALID_PRIMARY_NSAPI,
- CANNOT_ENCODE_OTA_MESSAGE,
- RADIO_ACCESS_BEARER_SETUP_FAILURE,
- PDP_ESTABLISH_TIMEOUT_EXPIRED,
- PDP_MODIFY_TIMEOUT_EXPIRED,
- PDP_INACTIVE_TIMEOUT_EXPIRED,
- PDP_LOWERLAYER_ERROR,
- PDP_MODIFY_COLLISION,
- MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED,
- NAS_REQUEST_REJECTED_BY_NETWORK,
- RRC_CONNECTION_INVALID_REQUEST,
- RRC_CONNECTION_TRACKING_AREA_ID_CHANGED,
- RRC_CONNECTION_RF_UNAVAILABLE,
- RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE,
- RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE,
- RRC_CONNECTION_ABORTED_AFTER_HANDOVER,
- RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE,
- RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE,
- IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER,
- IMEI_NOT_ACCEPTED,
- EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
- EPS_SERVICES_NOT_ALLOWED_IN_PLMN,
- MSC_TEMPORARILY_NOT_REACHABLE,
- CS_DOMAIN_NOT_AVAILABLE,
- ESM_FAILURE,
- MAC_FAILURE,
- SYNCHRONIZATION_FAILURE,
- UE_SECURITY_CAPABILITIES_MISMATCH,
- SECURITY_MODE_REJECTED,
- UNACCEPTABLE_NON_EPS_AUTHENTICATION,
- CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED,
- NO_EPS_BEARER_CONTEXT_ACTIVATED,
- INVALID_EMM_STATE,
- NAS_LAYER_FAILURE,
- MULTIPLE_PDP_CALL_NOT_ALLOWED,
- EMBMS_NOT_ENABLED,
- IRAT_HANDOVER_FAILED,
- EMBMS_REGULAR_DEACTIVATION,
- TEST_LOOPBACK_REGULAR_DEACTIVATION,
- LOWER_LAYER_REGISTRATION_FAILURE,
- DATA_PLAN_EXPIRED,
- UMTS_HANDOVER_TO_IWLAN,
- EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY,
- EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE,
- EVDO_HDR_CHANGED,
- EVDO_HDR_EXITED,
- EVDO_HDR_NO_SESSION,
- EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL,
- EVDO_HDR_CONNECTION_SETUP_TIMEOUT,
- FAILED_TO_ACQUIRE_COLOCATED_HDR,
- OTASP_COMMIT_IN_PROGRESS,
- NO_HYBRID_HDR_SERVICE,
- HDR_NO_LOCK_GRANTED,
- DBM_OR_SMS_IN_PROGRESS,
- HDR_FADE,
- HDR_ACCESS_FAILURE,
- UNSUPPORTED_1X_PREV,
- LOCAL_END,
- NO_SERVICE,
- FADE,
- NORMAL_RELEASE,
- ACCESS_ATTEMPT_ALREADY_IN_PROGRESS,
- REDIRECTION_OR_HANDOFF_IN_PROGRESS,
- EMERGENCY_MODE,
- PHONE_IN_USE,
- INVALID_MODE,
- INVALID_SIM_STATE,
- NO_COLLOCATED_HDR,
- UE_IS_ENTERING_POWERSAVE_MODE,
- DUAL_SWITCH,
- PPP_TIMEOUT,
- PPP_AUTH_FAILURE,
- PPP_OPTION_MISMATCH,
- PPP_PAP_FAILURE,
- PPP_CHAP_FAILURE,
- PPP_CLOSE_IN_PROGRESS,
- LIMITED_TO_IPV4,
- LIMITED_TO_IPV6,
- VSNCP_TIMEOUT,
- VSNCP_GEN_ERROR,
- VSNCP_APN_UNATHORIZED,
- VSNCP_PDN_LIMIT_EXCEEDED,
- VSNCP_NO_PDN_GATEWAY_ADDRESS,
- VSNCP_PDN_GATEWAY_UNREACHABLE,
- VSNCP_PDN_GATEWAY_REJECT,
- VSNCP_INSUFFICIENT_PARAMETERS,
- VSNCP_RESOURCE_UNAVAILABLE,
- VSNCP_ADMINISTRATIVELY_PROHIBITED,
- VSNCP_PDN_ID_IN_USE,
- VSNCP_SUBSCRIBER_LIMITATION,
- VSNCP_PDN_EXISTS_FOR_THIS_APN,
- VSNCP_RECONNECT_NOT_ALLOWED,
- IPV6_PREFIX_UNAVAILABLE,
- HANDOFF_PREFERENCE_CHANGED,
- OEM_DCFAILCAUSE_1,
- OEM_DCFAILCAUSE_2,
- OEM_DCFAILCAUSE_3,
- OEM_DCFAILCAUSE_4,
- OEM_DCFAILCAUSE_5,
- OEM_DCFAILCAUSE_6,
- OEM_DCFAILCAUSE_7,
- OEM_DCFAILCAUSE_8,
- OEM_DCFAILCAUSE_9,
- OEM_DCFAILCAUSE_10,
- OEM_DCFAILCAUSE_11,
- OEM_DCFAILCAUSE_12,
- OEM_DCFAILCAUSE_13,
- OEM_DCFAILCAUSE_14,
- OEM_DCFAILCAUSE_15,
- REGISTRATION_FAIL,
- GPRS_REGISTRATION_FAIL,
- SIGNAL_LOST,
- PREF_RADIO_TECH_CHANGED,
- RADIO_POWER_OFF,
- TETHERED_CALL_ACTIVE,
- ERROR_UNSPECIFIED,
- UNKNOWN,
- RADIO_NOT_AVAILABLE,
- UNACCEPTABLE_NETWORK_PARAMETER,
- CONNECTION_TO_DATACONNECTIONAC_BROKEN,
- LOST_CONNECTION,
- RESET_BY_FRAMEWORK
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface FailCause{}
-
private static final Map<Integer, String> sFailCauseMap;
static {
sFailCauseMap = new HashMap<>();
@@ -1737,7 +1389,8 @@
*
* @hide
*/
- public static boolean isRadioRestartFailure(@NonNull Context context, @FailCause int cause,
+ public static boolean isRadioRestartFailure(@NonNull Context context,
+ @DataFailureCause int cause,
int subId) {
CarrierConfigManager configManager = (CarrierConfigManager)
context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -1765,7 +1418,8 @@
}
/** @hide */
- public static boolean isPermanentFailure(@NonNull Context context, @FailCause int failCause,
+ public static boolean isPermanentFailure(@NonNull Context context,
+ @DataFailureCause int failCause,
int subId) {
synchronized (sPermanentFailureCache) {
@@ -1825,7 +1479,7 @@
}
/** @hide */
- public static boolean isEventLoggable(@FailCause int dataFailCause) {
+ public static boolean isEventLoggable(@DataFailureCause int dataFailCause) {
return (dataFailCause == OPERATOR_BARRED) || (dataFailCause == INSUFFICIENT_RESOURCES)
|| (dataFailCause == UNKNOWN_PDP_ADDRESS_TYPE)
|| (dataFailCause == USER_AUTHENTICATION)
@@ -1845,13 +1499,13 @@
}
/** @hide */
- public static String toString(@FailCause int dataFailCause) {
+ public static String toString(@DataFailureCause int dataFailCause) {
int cause = getFailCause(dataFailCause);
return (cause == UNKNOWN) ? "UNKNOWN(" + dataFailCause + ")" : sFailCauseMap.get(cause);
}
/** @hide */
- public static int getFailCause(@FailCause int failCause) {
+ public static int getFailCause(@DataFailureCause int failCause) {
if (sFailCauseMap.containsKey(failCause)) {
return failCause;
} else {
diff --git a/telephony/java/android/telephony/ICellBroadcastService.aidl b/telephony/java/android/telephony/ICellBroadcastService.aidl
new file mode 100644
index 0000000..eff64a2
--- /dev/null
+++ b/telephony/java/android/telephony/ICellBroadcastService.aidl
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2019, 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 android.telephony;
+
+/**
+ * Service bound to by the system to allow custom handling of cell broadcast messages.
+ * <p>
+ * @see android.telephony.CellBroadcastService
+ * @hide
+ */
+interface ICellBroadcastService {
+
+ /** @see android.telephony.CellBroadcastService#onGsmCellBroadcastSms */
+ oneway void handleGsmCellBroadcastSms(int slotId, in byte[] message);
+
+ /** @see android.telephony.CellBroadcastService#onCdmaCellBroadcastSms */
+ oneway void handleCdmaCellBroadcastSms(int slotId, in byte[] message);
+}
diff --git a/telephony/java/android/telephony/IFinancialSmsCallback.aidl b/telephony/java/android/telephony/IFinancialSmsCallback.aidl
deleted file mode 100644
index aa88615..0000000
--- a/telephony/java/android/telephony/IFinancialSmsCallback.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-** Copyright 2019, 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 android.telephony;
-
-import android.app.PendingIntent;
-import android.database.CursorWindow;
-import android.net.Uri;
-import android.os.Bundle;
-import com.android.internal.telephony.SmsRawData;
-
-/** Interface for returning back the financial sms messages asynchrously.
- * @hide
- */
-interface IFinancialSmsCallback {
- /**
- * Return sms messages back to calling financial app.
- *
- * @param messages the sms messages returned for cinancial app.
- */
- oneway void onGetSmsMessagesForFinancialApp(in CursorWindow messages);
-}
diff --git a/telephony/java/android/telephony/MbmsDownloadSession.java b/telephony/java/android/telephony/MbmsDownloadSession.java
index da4da79..45deea2 100644
--- a/telephony/java/android/telephony/MbmsDownloadSession.java
+++ b/telephony/java/android/telephony/MbmsDownloadSession.java
@@ -243,6 +243,7 @@
};
private AtomicReference<IMbmsDownloadService> mService = new AtomicReference<>(null);
+ private ServiceConnection mServiceConnection;
private final InternalDownloadSessionCallback mInternalCallback;
private final Map<DownloadStatusListener, InternalDownloadStatusListener>
mInternalDownloadStatusListeners = new HashMap<>();
@@ -318,56 +319,66 @@
}
private int bindAndInitialize() {
- return MbmsUtils.startBinding(mContext, MBMS_DOWNLOAD_SERVICE_ACTION,
- new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- IMbmsDownloadService downloadService =
- IMbmsDownloadService.Stub.asInterface(service);
- int result;
- try {
- result = downloadService.initialize(mSubscriptionId, mInternalCallback);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Service died before initialization");
- sIsInitialized.set(false);
- return;
- } catch (RuntimeException e) {
- Log.e(LOG_TAG, "Runtime exception during initialization");
- sendErrorToApp(
- MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
- e.toString());
- sIsInitialized.set(false);
- return;
- }
- if (result == MbmsErrors.UNKNOWN) {
- // Unbind and throw an obvious error
- close();
- throw new IllegalStateException("Middleware must not return an"
- + " unknown error code");
- }
- if (result != MbmsErrors.SUCCESS) {
- sendErrorToApp(result, "Error returned during initialization");
- sIsInitialized.set(false);
- return;
- }
- try {
- downloadService.asBinder().linkToDeath(mDeathRecipient, 0);
- } catch (RemoteException e) {
- sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST,
- "Middleware lost during initialization");
- sIsInitialized.set(false);
- return;
- }
- mService.set(downloadService);
- }
+ mServiceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ IMbmsDownloadService downloadService =
+ IMbmsDownloadService.Stub.asInterface(service);
+ int result;
+ try {
+ result = downloadService.initialize(mSubscriptionId, mInternalCallback);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Service died before initialization");
+ sIsInitialized.set(false);
+ return;
+ } catch (RuntimeException e) {
+ Log.e(LOG_TAG, "Runtime exception during initialization");
+ sendErrorToApp(
+ MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+ e.toString());
+ sIsInitialized.set(false);
+ return;
+ }
+ if (result == MbmsErrors.UNKNOWN) {
+ // Unbind and throw an obvious error
+ close();
+ throw new IllegalStateException("Middleware must not return an"
+ + " unknown error code");
+ }
+ if (result != MbmsErrors.SUCCESS) {
+ sendErrorToApp(result, "Error returned during initialization");
+ sIsInitialized.set(false);
+ return;
+ }
+ try {
+ downloadService.asBinder().linkToDeath(mDeathRecipient, 0);
+ } catch (RemoteException e) {
+ sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+ "Middleware lost during initialization");
+ sIsInitialized.set(false);
+ return;
+ }
+ mService.set(downloadService);
+ }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- Log.w(LOG_TAG, "bindAndInitialize: Remote service disconnected");
- sIsInitialized.set(false);
- mService.set(null);
- }
- });
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.w(LOG_TAG, "bindAndInitialize: Remote service disconnected");
+ sIsInitialized.set(false);
+ mService.set(null);
+ }
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ Log.w(LOG_TAG, "bindAndInitialize: Remote service returned null");
+ sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+ "Middleware service binding returned null");
+ sIsInitialized.set(false);
+ mService.set(null);
+ mContext.unbindService(this);
+ }
+ };
+ return MbmsUtils.startBinding(mContext, MBMS_DOWNLOAD_SERVICE_ACTION, mServiceConnection);
}
/**
@@ -965,17 +976,19 @@
public void close() {
try {
IMbmsDownloadService downloadService = mService.get();
- if (downloadService == null) {
+ if (downloadService == null || mServiceConnection == null) {
Log.i(LOG_TAG, "Service already dead");
return;
}
downloadService.dispose(mSubscriptionId);
+ mContext.unbindService(mServiceConnection);
} catch (RemoteException e) {
// Ignore
Log.i(LOG_TAG, "Remote exception while disposing of service");
} finally {
mService.set(null);
sIsInitialized.set(false);
+ mServiceConnection = null;
mInternalCallback.stop();
}
}
diff --git a/telephony/java/android/telephony/MbmsGroupCallSession.java b/telephony/java/android/telephony/MbmsGroupCallSession.java
index f1be31f..d54071f 100644
--- a/telephony/java/android/telephony/MbmsGroupCallSession.java
+++ b/telephony/java/android/telephony/MbmsGroupCallSession.java
@@ -80,6 +80,7 @@
};
private InternalGroupCallSessionCallback mInternalCallback;
+ private ServiceConnection mServiceConnection;
private Set<GroupCall> mKnownActiveGroupCalls = new ArraySet<>();
private final Context mContext;
@@ -163,7 +164,7 @@
public void close() {
try {
IMbmsGroupCallService groupCallService = mService.get();
- if (groupCallService == null) {
+ if (groupCallService == null || mServiceConnection == null) {
// Ignore and return, assume already disposed.
return;
}
@@ -172,11 +173,13 @@
s.getCallback().stop();
}
mKnownActiveGroupCalls.clear();
+ mContext.unbindService(mServiceConnection);
} catch (RemoteException e) {
// Ignore for now
} finally {
mService.set(null);
sIsInitialized.set(false);
+ mServiceConnection = null;
mInternalCallback.stop();
}
}
@@ -244,59 +247,69 @@
}
private int bindAndInitialize() {
- return MbmsUtils.startBinding(mContext, MBMS_GROUP_CALL_SERVICE_ACTION,
- new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- IMbmsGroupCallService groupCallService =
- IMbmsGroupCallService.Stub.asInterface(service);
- int result;
- try {
- result = groupCallService.initialize(mInternalCallback,
- mSubscriptionId);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Service died before initialization");
- mInternalCallback.onError(
- MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
- e.toString());
- sIsInitialized.set(false);
- return;
- } catch (RuntimeException e) {
- Log.e(LOG_TAG, "Runtime exception during initialization");
- mInternalCallback.onError(
- MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
- e.toString());
- sIsInitialized.set(false);
- return;
- }
- if (result == MbmsErrors.UNKNOWN) {
- // Unbind and throw an obvious error
- close();
- throw new IllegalStateException("Middleware must not return"
- + " an unknown error code");
- }
- if (result != MbmsErrors.SUCCESS) {
- mInternalCallback.onError(result,
- "Error returned during initialization");
- sIsInitialized.set(false);
- return;
- }
- try {
- groupCallService.asBinder().linkToDeath(mDeathRecipient, 0);
- } catch (RemoteException e) {
- mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST,
- "Middleware lost during initialization");
- sIsInitialized.set(false);
- return;
- }
- mService.set(groupCallService);
- }
+ mServiceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ IMbmsGroupCallService groupCallService =
+ IMbmsGroupCallService.Stub.asInterface(service);
+ int result;
+ try {
+ result = groupCallService.initialize(mInternalCallback,
+ mSubscriptionId);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Service died before initialization");
+ mInternalCallback.onError(
+ MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+ e.toString());
+ sIsInitialized.set(false);
+ return;
+ } catch (RuntimeException e) {
+ Log.e(LOG_TAG, "Runtime exception during initialization");
+ mInternalCallback.onError(
+ MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+ e.toString());
+ sIsInitialized.set(false);
+ return;
+ }
+ if (result == MbmsErrors.UNKNOWN) {
+ // Unbind and throw an obvious error
+ close();
+ throw new IllegalStateException("Middleware must not return"
+ + " an unknown error code");
+ }
+ if (result != MbmsErrors.SUCCESS) {
+ mInternalCallback.onError(result,
+ "Error returned during initialization");
+ sIsInitialized.set(false);
+ return;
+ }
+ try {
+ groupCallService.asBinder().linkToDeath(mDeathRecipient, 0);
+ } catch (RemoteException e) {
+ mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+ "Middleware lost during initialization");
+ sIsInitialized.set(false);
+ return;
+ }
+ mService.set(groupCallService);
+ }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- sIsInitialized.set(false);
- mService.set(null);
- }
- });
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ sIsInitialized.set(false);
+ mService.set(null);
+ }
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ Log.w(LOG_TAG, "bindAndInitialize: Remote service returned null");
+ mInternalCallback.onError(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+ "Middleware service binding returned null");
+ sIsInitialized.set(false);
+ mService.set(null);
+ mContext.unbindService(this);
+ }
+ };
+ return MbmsUtils.startBinding(mContext, MBMS_GROUP_CALL_SERVICE_ACTION, mServiceConnection);
}
}
diff --git a/telephony/java/android/telephony/MbmsStreamingSession.java b/telephony/java/android/telephony/MbmsStreamingSession.java
index cd465d2..3fbbc03 100644
--- a/telephony/java/android/telephony/MbmsStreamingSession.java
+++ b/telephony/java/android/telephony/MbmsStreamingSession.java
@@ -82,6 +82,7 @@
};
private InternalStreamingSessionCallback mInternalCallback;
+ private ServiceConnection mServiceConnection;
private Set<StreamingService> mKnownActiveStreamingServices = new ArraySet<>();
private final Context mContext;
@@ -168,7 +169,7 @@
public void close() {
try {
IMbmsStreamingService streamingService = mService.get();
- if (streamingService == null) {
+ if (streamingService == null || mServiceConnection == null) {
// Ignore and return, assume already disposed.
return;
}
@@ -177,11 +178,13 @@
s.getCallback().stop();
}
mKnownActiveStreamingServices.clear();
+ mContext.unbindService(mServiceConnection);
} catch (RemoteException e) {
// Ignore for now
} finally {
mService.set(null);
sIsInitialized.set(false);
+ mServiceConnection = null;
mInternalCallback.stop();
}
}
@@ -286,59 +289,69 @@
}
private int bindAndInitialize() {
- return MbmsUtils.startBinding(mContext, MBMS_STREAMING_SERVICE_ACTION,
- new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- IMbmsStreamingService streamingService =
- IMbmsStreamingService.Stub.asInterface(service);
- int result;
- try {
- result = streamingService.initialize(mInternalCallback,
- mSubscriptionId);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Service died before initialization");
- sendErrorToApp(
- MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
- e.toString());
- sIsInitialized.set(false);
- return;
- } catch (RuntimeException e) {
- Log.e(LOG_TAG, "Runtime exception during initialization");
- sendErrorToApp(
- MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
- e.toString());
- sIsInitialized.set(false);
- return;
- }
- if (result == MbmsErrors.UNKNOWN) {
- // Unbind and throw an obvious error
- close();
- throw new IllegalStateException("Middleware must not return"
- + " an unknown error code");
- }
- if (result != MbmsErrors.SUCCESS) {
- sendErrorToApp(result, "Error returned during initialization");
- sIsInitialized.set(false);
- return;
- }
- try {
- streamingService.asBinder().linkToDeath(mDeathRecipient, 0);
- } catch (RemoteException e) {
- sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST,
- "Middleware lost during initialization");
- sIsInitialized.set(false);
- return;
- }
- mService.set(streamingService);
- }
+ mServiceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ IMbmsStreamingService streamingService =
+ IMbmsStreamingService.Stub.asInterface(service);
+ int result;
+ try {
+ result = streamingService.initialize(mInternalCallback,
+ mSubscriptionId);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Service died before initialization");
+ sendErrorToApp(
+ MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+ e.toString());
+ sIsInitialized.set(false);
+ return;
+ } catch (RuntimeException e) {
+ Log.e(LOG_TAG, "Runtime exception during initialization");
+ sendErrorToApp(
+ MbmsErrors.InitializationErrors.ERROR_UNABLE_TO_INITIALIZE,
+ e.toString());
+ sIsInitialized.set(false);
+ return;
+ }
+ if (result == MbmsErrors.UNKNOWN) {
+ // Unbind and throw an obvious error
+ close();
+ throw new IllegalStateException("Middleware must not return"
+ + " an unknown error code");
+ }
+ if (result != MbmsErrors.SUCCESS) {
+ sendErrorToApp(result, "Error returned during initialization");
+ sIsInitialized.set(false);
+ return;
+ }
+ try {
+ streamingService.asBinder().linkToDeath(mDeathRecipient, 0);
+ } catch (RemoteException e) {
+ sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+ "Middleware lost during initialization");
+ sIsInitialized.set(false);
+ return;
+ }
+ mService.set(streamingService);
+ }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- sIsInitialized.set(false);
- mService.set(null);
- }
- });
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ sIsInitialized.set(false);
+ mService.set(null);
+ }
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ Log.w(LOG_TAG, "bindAndInitialize: Remote service returned null");
+ sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST,
+ "Middleware service binding returned null");
+ sIsInitialized.set(false);
+ mService.set(null);
+ mContext.unbindService(this);
+ }
+ };
+ return MbmsUtils.startBinding(mContext, MBMS_STREAMING_SERVICE_ACTION, mServiceConnection);
}
private void sendErrorToApp(int errorCode, String message) {
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index a76b8da..3e02871 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -24,8 +24,8 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.TelephonyManager.NetworkType;
+import android.telephony.Annotation.NetworkType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 1e1e3da..1ba0a41 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -28,6 +28,10 @@
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
+import android.telephony.Annotation.CallState;
+import android.telephony.Annotation.RadioPowerState;
+import android.telephony.Annotation.SimActivationState;
+import android.telephony.Annotation.SrvccState;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
@@ -180,7 +184,8 @@
public static final int LISTEN_CELL_INFO = 0x00000400;
/**
- * Listen for {@link PreciseCallState.State} of ringing, background and foreground calls.
+ * Listen for {@link android.telephony.Annotation.PreciseCallStates} of ringing,
+ * background and foreground calls.
*
* @hide
*/
@@ -369,7 +374,7 @@
@SystemApi
@TestApi
@RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
- public static final int LISTEN_OUTGOING_CALL_EMERGENCY_NUMBER = 0x10000000;
+ public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 0x10000000;
/**
* Listen for the emergency number placed from an outgoing SMS.
@@ -382,7 +387,7 @@
@SystemApi
@TestApi
@RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
- public static final int LISTEN_OUTGOING_SMS_EMERGENCY_NUMBER = 0x20000000;
+ public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 0x20000000;
/*
* Subscription used to listen to the phone state changes
@@ -567,7 +572,7 @@
* privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be
* passed as an argument.
*/
- public void onCallStateChanged(@TelephonyManager.CallState int state, String phoneNumber) {
+ public void onCallStateChanged(@CallState int state, String phoneNumber) {
// default implementation empty
}
@@ -773,7 +778,7 @@
* @hide
*/
@SystemApi
- public void onSrvccStateChanged(@TelephonyManager.SrvccState int srvccState) {
+ public void onSrvccStateChanged(@SrvccState int srvccState) {
}
@@ -791,7 +796,7 @@
* @hide
*/
@SystemApi
- public void onVoiceActivationStateChanged(@TelephonyManager.SimActivationState int state) {
+ public void onVoiceActivationStateChanged(@SimActivationState int state) {
}
/**
@@ -807,7 +812,7 @@
* @param state is the current SIM data activation state
* @hide
*/
- public void onDataActivationStateChanged(@TelephonyManager.SimActivationState int state) {
+ public void onDataActivationStateChanged(@SimActivationState int state) {
}
/**
@@ -873,6 +878,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) {
// default implementation empty
}
@@ -884,6 +890,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) {
// default implementation empty
}
@@ -964,7 +971,7 @@
* @hide
*/
@SystemApi
- public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) {
+ public void onRadioPowerStateChanged(@RadioPowerState int state) {
// default implementation empty
}
@@ -1231,7 +1238,7 @@
() -> mExecutor.execute(() -> psl.onPhoneCapabilityChanged(capability)));
}
- public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) {
+ public void onRadioPowerStateChanged(@RadioPowerState int state) {
PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
if (psl == null) return;
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index e1763ab..4273f5a 100644
--- a/telephony/java/android/telephony/PhysicalChannelConfig.java
+++ b/telephony/java/android/telephony/PhysicalChannelConfig.java
@@ -19,8 +19,8 @@
import android.annotation.IntDef;
import android.os.Parcel;
import android.os.Parcelable;
-import android.telephony.TelephonyManager.NetworkType;
+import android.telephony.Annotation.NetworkType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index 701a375..9f75332 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -23,6 +23,7 @@
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.Annotation.PreciseCallStates;
import android.telephony.DisconnectCause;
import android.telephony.PreciseDisconnectCause;
@@ -41,29 +42,13 @@
* <li>Precise background call state.
* </ul>
*
- * @see android.telephony.TelephonyManager.CallState which contains generic call states.
+ * @see android.telephony.Annotation.CallState which contains generic call states.
*
* @hide
*/
@SystemApi
public final class PreciseCallState implements Parcelable {
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"PRECISE_CALL_STATE_"},
- value = {
- PRECISE_CALL_STATE_NOT_VALID,
- PRECISE_CALL_STATE_IDLE,
- PRECISE_CALL_STATE_ACTIVE,
- PRECISE_CALL_STATE_HOLDING,
- PRECISE_CALL_STATE_DIALING,
- PRECISE_CALL_STATE_ALERTING,
- PRECISE_CALL_STATE_INCOMING,
- PRECISE_CALL_STATE_WAITING,
- PRECISE_CALL_STATE_DISCONNECTED,
- PRECISE_CALL_STATE_DISCONNECTING})
- public @interface State {}
-
/** Call state is not valid (Not received a call state). */
public static final int PRECISE_CALL_STATE_NOT_VALID = -1;
/** Call state: No activity. */
@@ -85,9 +70,9 @@
/** Call state: Disconnecting. */
public static final int PRECISE_CALL_STATE_DISCONNECTING = 8;
- private @State int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
- private @State int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
- private @State int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @PreciseCallStates int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @PreciseCallStates int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @PreciseCallStates int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
private int mDisconnectCause = DisconnectCause.NOT_VALID;
private int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
@@ -97,8 +82,9 @@
* @hide
*/
@UnsupportedAppUsage
- public PreciseCallState(@State int ringingCall, @State int foregroundCall,
- @State int backgroundCall, int disconnectCause,
+ public PreciseCallState(@PreciseCallStates int ringingCall,
+ @PreciseCallStates int foregroundCall,
+ @PreciseCallStates int backgroundCall, int disconnectCause,
int preciseDisconnectCause) {
mRingingCallState = ringingCall;
mForegroundCallState = foregroundCall;
@@ -131,21 +117,21 @@
/**
* Returns the precise ringing call state.
*/
- public @State int getRingingCallState() {
+ public @PreciseCallStates int getRingingCallState() {
return mRingingCallState;
}
/**
* Returns the precise foreground call state.
*/
- public @State int getForegroundCallState() {
+ public @PreciseCallStates int getForegroundCallState() {
return mForegroundCallState;
}
/**
* Returns the precise background call state.
*/
- public @State int getBackgroundCallState() {
+ public @PreciseCallStates int getBackgroundCallState() {
return mBackgroundCallState;
}
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index 90d443a..257d634 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -23,6 +23,10 @@
import android.net.LinkProperties;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.Annotation.ApnType;
+import android.telephony.Annotation.DataFailureCause;
+import android.telephony.Annotation.DataState;
+import android.telephony.Annotation.NetworkType;
import android.telephony.data.ApnSetting;
import java.util.Objects;
@@ -47,10 +51,10 @@
@SystemApi
public final class PreciseDataConnectionState implements Parcelable {
- private @TelephonyManager.DataState int mState = TelephonyManager.DATA_UNKNOWN;
- private @TelephonyManager.NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
- private @DataFailCause.FailCause int mFailCause = DataFailCause.NONE;
- private @ApnSetting.ApnType int mAPNTypes = ApnSetting.TYPE_NONE;
+ private @DataState int mState = TelephonyManager.DATA_UNKNOWN;
+ private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+ private @DataFailureCause int mFailCause = DataFailCause.NONE;
+ private @ApnType int mAPNTypes = ApnSetting.TYPE_NONE;
private String mAPN = "";
private LinkProperties mLinkProperties = null;
@@ -60,11 +64,11 @@
* @hide
*/
@UnsupportedAppUsage
- public PreciseDataConnectionState(@TelephonyManager.DataState int state,
- @TelephonyManager.NetworkType int networkType,
- @ApnSetting.ApnType int apnTypes, String apn,
+ public PreciseDataConnectionState(@DataState int state,
+ @NetworkType int networkType,
+ @ApnType int apnTypes, String apn,
LinkProperties linkProperties,
- @DataFailCause.FailCause int failCause) {
+ @DataFailureCause int failCause) {
mState = state;
mNetworkType = networkType;
mAPNTypes = apnTypes;
@@ -99,7 +103,7 @@
* Returns the state of data connection that supported the apn types returned by
* {@link #getDataConnectionApnTypeBitMask()}
*/
- public @TelephonyManager.DataState int getDataConnectionState() {
+ public @DataState int getDataConnectionState() {
return mState;
}
@@ -107,7 +111,7 @@
* Returns the network type associated with this data connection.
* @hide
*/
- public @TelephonyManager.NetworkType int getDataConnectionNetworkType() {
+ public @NetworkType int getDataConnectionNetworkType() {
return mNetworkType;
}
@@ -115,7 +119,7 @@
* Returns the data connection APN types supported by this connection and triggers
* {@link PreciseDataConnectionState} change.
*/
- public @ApnSetting.ApnType int getDataConnectionApnTypeBitMask() {
+ public @ApnType int getDataConnectionApnTypeBitMask() {
return mAPNTypes;
}
@@ -139,7 +143,7 @@
/**
* Returns data connection fail cause, in case there was a failure.
*/
- public @DataFailCause.FailCause int getDataConnectionFailCause() {
+ public @Annotation.DataFailureCause int getDataConnectionFailCause() {
return mFailCause;
}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index a985a6b..1d00b4f 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -29,6 +29,8 @@
import android.os.Parcelable;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.RilRadioTechnology;
import android.telephony.NetworkRegistrationInfo.Domain;
import android.telephony.NetworkRegistrationInfo.NRState;
import android.text.TextUtils;
@@ -154,32 +156,6 @@
*/
public static final int DUPLEX_MODE_TDD = 2;
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = { "RIL_RADIO_TECHNOLOGY_" },
- value = {
- RIL_RADIO_TECHNOLOGY_UNKNOWN,
- RIL_RADIO_TECHNOLOGY_GPRS,
- RIL_RADIO_TECHNOLOGY_EDGE,
- RIL_RADIO_TECHNOLOGY_UMTS,
- RIL_RADIO_TECHNOLOGY_IS95A,
- RIL_RADIO_TECHNOLOGY_IS95B,
- RIL_RADIO_TECHNOLOGY_1xRTT,
- RIL_RADIO_TECHNOLOGY_EVDO_0,
- RIL_RADIO_TECHNOLOGY_EVDO_A,
- RIL_RADIO_TECHNOLOGY_HSDPA,
- RIL_RADIO_TECHNOLOGY_HSUPA,
- RIL_RADIO_TECHNOLOGY_HSPA,
- RIL_RADIO_TECHNOLOGY_EVDO_B,
- RIL_RADIO_TECHNOLOGY_EHRPD,
- RIL_RADIO_TECHNOLOGY_LTE,
- RIL_RADIO_TECHNOLOGY_HSPAP,
- RIL_RADIO_TECHNOLOGY_GSM,
- RIL_RADIO_TECHNOLOGY_TD_SCDMA,
- RIL_RADIO_TECHNOLOGY_IWLAN,
- RIL_RADIO_TECHNOLOGY_LTE_CA,
- RIL_RADIO_TECHNOLOGY_NR})
- public @interface RilRadioTechnology {}
/**
* Available radio technologies for GSM, UMTS and CDMA.
* Duplicates the constants from hardware/radio/include/ril.h
@@ -987,6 +963,9 @@
case RIL_RADIO_TECHNOLOGY_LTE_CA:
rtString = "LTE_CA";
break;
+ case RIL_RADIO_TECHNOLOGY_NR:
+ rtString = "LTE_NR";
+ break;
default:
rtString = "Unexpected";
Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
@@ -1553,6 +1532,7 @@
return AccessNetworkType.CDMA2000;
case RIL_RADIO_TECHNOLOGY_LTE:
case RIL_RADIO_TECHNOLOGY_LTE_CA:
+ case RIL_RADIO_TECHNOLOGY_NR:
return AccessNetworkType.EUTRAN;
case RIL_RADIO_TECHNOLOGY_IWLAN:
return AccessNetworkType.IWLAN;
@@ -1601,6 +1581,8 @@
return ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN;
case TelephonyManager.NETWORK_TYPE_LTE_CA:
return ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA;
+ case TelephonyManager.NETWORK_TYPE_NR:
+ return ServiceState.RIL_RADIO_TECHNOLOGY_NR;
default:
return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
}
@@ -1617,7 +1599,7 @@
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public @TelephonyManager.NetworkType int getDataNetworkType() {
+ public @NetworkType int getDataNetworkType() {
final NetworkRegistrationInfo iwlanRegInfo = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
final NetworkRegistrationInfo wwanRegInfo = getNetworkRegistrationInfo(
@@ -1644,7 +1626,7 @@
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
- public @TelephonyManager.NetworkType int getVoiceNetworkType() {
+ public @NetworkType int getVoiceNetworkType() {
final NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
if (regState != null) {
@@ -1691,7 +1673,8 @@
|| radioTechnology == RIL_RADIO_TECHNOLOGY_GSM
|| radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA
|| radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN
- || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA;
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_NR;
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 5c39da7..f4330fa 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -32,8 +32,8 @@
import android.content.pm.PackageManager;
import android.database.CursorWindow;
import android.net.Uri;
-import android.os.BaseBundle;
import android.os.Binder;
+import android.os.BaseBundle;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
@@ -2081,7 +2081,9 @@
}
}
- /** callback for providing asynchronous sms messages for financial app. */
+ /**
+ * callback for providing asynchronous sms messages for financial app.
+ */
public abstract static class FinancialSmsCallback {
/**
* Callback to send sms messages back to financial app asynchronously.
@@ -2107,24 +2109,14 @@
* @param params the parameters to filter SMS messages returned.
* @param executor the executor on which callback will be invoked.
* @param callback a callback to receive CursorWindow with SMS messages.
+ *
*/
@RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS)
public void getSmsMessagesForFinancialApp(
Bundle params,
@NonNull @CallbackExecutor Executor executor,
@NonNull FinancialSmsCallback callback) {
- try {
- ISms iccSms = getISmsServiceOrThrow();
- iccSms.getSmsMessagesForFinancialApp(
- getSubscriptionId(), ActivityThread.currentPackageName(), params,
- new IFinancialSmsCallback.Stub() {
- public void onGetSmsMessagesForFinancialApp(CursorWindow msgs) {
- Binder.withCleanCallingIdentity(() -> executor.execute(
- () -> callback.onFinancialSmsMessages(msgs)));
- }});
- } catch (RemoteException ex) {
- ex.rethrowFromSystemServer();
- }
+ // This API is not functional and thus removed to avoid future confusion.
}
/**
@@ -2209,74 +2201,6 @@
}
}
- /**
- * Filters a bundle to only contain MMS config variables.
- *
- * This is for use with bundles returned by {@link CarrierConfigManager} which contain MMS
- * config and unrelated config. It is assumed that all MMS_CONFIG_* keys are present in the
- * supplied bundle.
- *
- * @param config a Bundle that contains MMS config variables and possibly more.
- * @return a new Bundle that only contains the MMS_CONFIG_* keys defined above.
- * @hide
- */
- public static Bundle getMmsConfig(BaseBundle config) {
- Bundle filtered = new Bundle();
- filtered.putBoolean(MMS_CONFIG_APPEND_TRANSACTION_ID,
- config.getBoolean(MMS_CONFIG_APPEND_TRANSACTION_ID));
- filtered.putBoolean(MMS_CONFIG_MMS_ENABLED, config.getBoolean(MMS_CONFIG_MMS_ENABLED));
- filtered.putBoolean(MMS_CONFIG_GROUP_MMS_ENABLED,
- config.getBoolean(MMS_CONFIG_GROUP_MMS_ENABLED));
- filtered.putBoolean(MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED,
- config.getBoolean(MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED));
- filtered.putBoolean(MMS_CONFIG_ALIAS_ENABLED, config.getBoolean(MMS_CONFIG_ALIAS_ENABLED));
- filtered.putBoolean(MMS_CONFIG_ALLOW_ATTACH_AUDIO,
- config.getBoolean(MMS_CONFIG_ALLOW_ATTACH_AUDIO));
- filtered.putBoolean(MMS_CONFIG_MULTIPART_SMS_ENABLED,
- config.getBoolean(MMS_CONFIG_MULTIPART_SMS_ENABLED));
- filtered.putBoolean(MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED,
- config.getBoolean(MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED));
- filtered.putBoolean(MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION,
- config.getBoolean(MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION));
- filtered.putBoolean(MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES,
- config.getBoolean(MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES));
- filtered.putBoolean(MMS_CONFIG_MMS_READ_REPORT_ENABLED,
- config.getBoolean(MMS_CONFIG_MMS_READ_REPORT_ENABLED));
- filtered.putBoolean(MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED,
- config.getBoolean(MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED));
- filtered.putBoolean(MMS_CONFIG_CLOSE_CONNECTION,
- config.getBoolean(MMS_CONFIG_CLOSE_CONNECTION));
- filtered.putInt(MMS_CONFIG_MAX_MESSAGE_SIZE, config.getInt(MMS_CONFIG_MAX_MESSAGE_SIZE));
- filtered.putInt(MMS_CONFIG_MAX_IMAGE_WIDTH, config.getInt(MMS_CONFIG_MAX_IMAGE_WIDTH));
- filtered.putInt(MMS_CONFIG_MAX_IMAGE_HEIGHT, config.getInt(MMS_CONFIG_MAX_IMAGE_HEIGHT));
- filtered.putInt(MMS_CONFIG_RECIPIENT_LIMIT, config.getInt(MMS_CONFIG_RECIPIENT_LIMIT));
- filtered.putInt(MMS_CONFIG_ALIAS_MIN_CHARS, config.getInt(MMS_CONFIG_ALIAS_MIN_CHARS));
- filtered.putInt(MMS_CONFIG_ALIAS_MAX_CHARS, config.getInt(MMS_CONFIG_ALIAS_MAX_CHARS));
- filtered.putInt(MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD,
- config.getInt(MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD));
- filtered.putInt(MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD,
- config.getInt(MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD));
- filtered.putInt(MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE,
- config.getInt(MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE));
- filtered.putInt(MMS_CONFIG_SUBJECT_MAX_LENGTH,
- config.getInt(MMS_CONFIG_SUBJECT_MAX_LENGTH));
- filtered.putInt(MMS_CONFIG_HTTP_SOCKET_TIMEOUT,
- config.getInt(MMS_CONFIG_HTTP_SOCKET_TIMEOUT));
- filtered.putString(MMS_CONFIG_UA_PROF_TAG_NAME,
- config.getString(MMS_CONFIG_UA_PROF_TAG_NAME));
- filtered.putString(MMS_CONFIG_USER_AGENT, config.getString(MMS_CONFIG_USER_AGENT));
- filtered.putString(MMS_CONFIG_UA_PROF_URL, config.getString(MMS_CONFIG_UA_PROF_URL));
- filtered.putString(MMS_CONFIG_HTTP_PARAMS, config.getString(MMS_CONFIG_HTTP_PARAMS));
- filtered.putString(MMS_CONFIG_EMAIL_GATEWAY_NUMBER,
- config.getString(MMS_CONFIG_EMAIL_GATEWAY_NUMBER));
- filtered.putString(MMS_CONFIG_NAI_SUFFIX, config.getString(MMS_CONFIG_NAI_SUFFIX));
- filtered.putBoolean(MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS,
- config.getBoolean(MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS));
- filtered.putBoolean(MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER,
- config.getBoolean(MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER));
- return filtered;
- }
-
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"SMS_CATEGORY_"},
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index dcd35fd..1b87657 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -53,7 +53,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.telephony.TelephonyManager.NetworkType;
+import android.telephony.Annotation.NetworkType;
import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsMmTelManager;
import android.util.DisplayMetrics;
@@ -2101,13 +2101,13 @@
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public static boolean isValidSlotIndex(int slotIndex) {
- return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getSimCount();
+ return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getMaxPhoneCount();
}
/** @hide */
@UnsupportedAppUsage
public static boolean isValidPhoneId(int phoneId) {
- return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount();
+ return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getMaxPhoneCount();
}
/** @hide */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 4f276bc..b584e9d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -63,8 +63,13 @@
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
+import android.telephony.Annotation.ApnType;
+import android.telephony.Annotation.CallState;
+import android.telephony.Annotation.DataState;
+import android.telephony.Annotation.NetworkType;
+import android.telephony.Annotation.RadioPowerState;
+import android.telephony.Annotation.SimActivationState;
import android.telephony.VisualVoicemailService.VisualVoicemailTask;
-import android.telephony.data.ApnSetting;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
import android.telephony.ims.ImsMmTelManager;
@@ -254,17 +259,6 @@
*/
public static final int UNINITIALIZED_CARD_ID = -2;
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"SRVCC_STATE_"},
- value = {
- SRVCC_STATE_HANDOVER_NONE,
- SRVCC_STATE_HANDOVER_STARTED,
- SRVCC_STATE_HANDOVER_COMPLETED,
- SRVCC_STATE_HANDOVER_FAILED,
- SRVCC_STATE_HANDOVER_CANCELED})
- public @interface SrvccState {}
-
private final Context mContext;
private final int mSubId;
@UnsupportedAppUsage
@@ -404,7 +398,7 @@
* TODO: b/139642279 publicize and rename.
* @hide
*/
- public static int getMaxPhoneCount() {
+ public int getMaxPhoneCount() {
// TODO: b/139642279 when turning on this feature, remove dependency of
// PROPERTY_REBOOT_REQUIRED_ON_MODEM_CHANGE and always return result based on
// PROPERTY_MAX_ACTIVE_MODEMS.
@@ -413,9 +407,9 @@
if (rebootRequired.equals("false")) {
// If no reboot is required, return max possible active modems.
return SystemProperties.getInt(
- TelephonyProperties.PROPERTY_MAX_ACTIVE_MODEMS, getDefault().getPhoneCount());
+ TelephonyProperties.PROPERTY_MAX_ACTIVE_MODEMS, getPhoneCount());
} else {
- return getDefault().getPhoneCount();
+ return getPhoneCount();
}
}
@@ -1177,6 +1171,35 @@
"android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
/**
+ * Broadcast intent that indicates multi-SIM configuration is changed. For example, it changed
+ * from single SIM capable to dual-SIM capable (DSDS or DSDA) or triple-SIM mode.
+ *
+ * It doesn't indicate how many subscriptions are actually active, or which states SIMs are,
+ * or that all steps during multi-SIM change are done. To know those information you still need
+ * to listen to SIM_STATE changes or active subscription changes.
+ *
+ * See extra of {@link #EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED} for updated value.
+ */
+ public static final String ACTION_MULTI_SIM_CONFIG_CHANGED =
+ "android.telephony.action.MULTI_SIM_CONFIG_CHANGED";
+
+
+ /**
+ * The number of active SIM supported by current multi-SIM config. It's not related to how many
+ * SIM/subscriptions are currently active.
+ *
+ * For single SIM mode, it's 1.
+ * For DSDS or DSDA mode, it's 2.
+ * For triple-SIM mode, it's 3.
+ *
+ * Extra of {@link #ACTION_MULTI_SIM_CONFIG_CHANGED}.
+ *
+ * type: integer
+ */
+ public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED =
+ "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED";
+
+ /**
* @hide
*/
public static final String USSD_RESPONSE = "USSD_RESPONSE";
@@ -2449,7 +2472,14 @@
* @return the lowercase 2 character ISO-3166 country code, or empty string if not available.
*/
public String getNetworkCountryIso() {
- return getNetworkCountryIso(getPhoneId());
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) return "";
+ return telephony.getNetworkCountryIsoForPhone(getPhoneId(),
+ null /* no permission check */);
+ } catch (RemoteException ex) {
+ return "";
+ }
}
/**
@@ -2475,11 +2505,12 @@
@SystemApi
@TestApi
@NonNull
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getNetworkCountryIso(int slotIndex) {
try {
ITelephony telephony = getITelephony();
if (telephony == null) return "";
- return telephony.getNetworkCountryIsoForPhone(slotIndex);
+ return telephony.getNetworkCountryIsoForPhone(slotIndex, getOpPackageName());
} catch (RemoteException ex) {
return "";
}
@@ -2538,33 +2569,6 @@
/** Max network type number. Update as new types are added. Don't add negative types. {@hide} */
public static final int MAX_NETWORK_TYPE = NETWORK_TYPE_NR;
- /** @hide */
- @IntDef({
- NETWORK_TYPE_UNKNOWN,
- NETWORK_TYPE_GPRS,
- NETWORK_TYPE_EDGE,
- NETWORK_TYPE_UMTS,
- NETWORK_TYPE_CDMA,
- NETWORK_TYPE_EVDO_0,
- NETWORK_TYPE_EVDO_A,
- NETWORK_TYPE_1xRTT,
- NETWORK_TYPE_HSDPA,
- NETWORK_TYPE_HSUPA,
- NETWORK_TYPE_HSPA,
- NETWORK_TYPE_IDEN,
- NETWORK_TYPE_EVDO_B,
- NETWORK_TYPE_LTE,
- NETWORK_TYPE_EHRPD,
- NETWORK_TYPE_HSPAP,
- NETWORK_TYPE_GSM,
- NETWORK_TYPE_TD_SCDMA,
- NETWORK_TYPE_IWLAN,
- NETWORK_TYPE_LTE_CA,
- NETWORK_TYPE_NR,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface NetworkType{}
-
/**
* Return the current data network type.
*
@@ -2741,6 +2745,8 @@
/** Class of broadly defined "4G" networks. {@hide} */
@UnsupportedAppUsage
public static final int NETWORK_CLASS_4_G = 3;
+ /** Class of broadly defined "5G" networks. {@hide} */
+ public static final int NETWORK_CLASS_5_G = 4;
/**
* Return general class of network type, such as "3G" or "4G". In cases
@@ -2773,6 +2779,8 @@
case NETWORK_TYPE_IWLAN:
case NETWORK_TYPE_LTE_CA:
return NETWORK_CLASS_4_G;
+ case NETWORK_TYPE_NR:
+ return NETWORK_CLASS_5_G;
default:
return NETWORK_CLASS_UNKNOWN;
}
@@ -4611,17 +4619,6 @@
@SystemApi
public static final int SIM_ACTIVATION_STATE_RESTRICTED = 4;
- /** @hide */
- @IntDef({
- SIM_ACTIVATION_STATE_UNKNOWN,
- SIM_ACTIVATION_STATE_ACTIVATING,
- SIM_ACTIVATION_STATE_ACTIVATED,
- SIM_ACTIVATION_STATE_DEACTIVATED,
- SIM_ACTIVATION_STATE_RESTRICTED
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SimActivationState{}
-
/**
* Sets the voice activation state
*
@@ -5006,15 +5003,6 @@
*/
public static final int CALL_STATE_OFFHOOK = 2;
- /** @hide */
- @IntDef(prefix = { "CALL_STATE_" }, value = {
- CALL_STATE_IDLE,
- CALL_STATE_RINGING,
- CALL_STATE_OFFHOOK
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface CallState{}
-
/**
* Returns the state of all calls on the device.
* <p>
@@ -5095,17 +5083,6 @@
*/
public static final int DATA_ACTIVITY_DORMANT = 0x00000004;
- /** @hide */
- @IntDef(prefix = {"DATA_"}, value = {
- DATA_ACTIVITY_NONE,
- DATA_ACTIVITY_IN,
- DATA_ACTIVITY_OUT,
- DATA_ACTIVITY_INOUT,
- DATA_ACTIVITY_DORMANT,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface DataActivityType{}
-
/**
* Returns a constant indicating the type of activity on a data connection
* (cellular).
@@ -8321,15 +8298,6 @@
return false;
}
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"RADIO_POWER_"},
- value = {RADIO_POWER_OFF,
- RADIO_POWER_ON,
- RADIO_POWER_UNAVAILABLE,
- })
- public @interface RadioPowerState {}
-
/**
* Radio explicitly powered off (e.g, airplane mode).
* @hide
@@ -11443,7 +11411,7 @@
*
* @hide
*/
- public boolean isDataEnabledForApn(@ApnSetting.ApnType int apnType) {
+ public boolean isDataEnabledForApn(@ApnType int apnType) {
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
try {
ITelephony service = getITelephony();
@@ -11464,7 +11432,7 @@
*
* @hide
*/
- public boolean isApnMetered(@ApnSetting.ApnType int apnType) {
+ public boolean isApnMetered(@ApnType int apnType) {
try {
ITelephony service = getITelephony();
if (service != null) {
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 116c051..2161dcb 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -26,6 +26,8 @@
import android.os.Parcelable;
import android.provider.Telephony;
import android.provider.Telephony.Carriers;
+import android.telephony.Annotation.ApnType;
+import android.telephony.Annotation.NetworkType;
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
@@ -109,23 +111,6 @@
/** APN type for MCX (Mission Critical Service) where X can be PTT/Video/Data */
public static final int TYPE_MCX = ApnTypes.MCX;
- /** @hide */
- @IntDef(flag = true, prefix = { "TYPE_" }, value = {
- TYPE_DEFAULT,
- TYPE_MMS,
- TYPE_SUPL,
- TYPE_DUN,
- TYPE_HIPRI,
- TYPE_FOTA,
- TYPE_IMS,
- TYPE_CBS,
- TYPE_IA,
- TYPE_EMERGENCY,
- TYPE_MCX
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ApnType {}
-
// Possible values for authentication types.
/** No authentication type. */
public static final int AUTH_TYPE_NONE = 0;
@@ -1425,7 +1410,7 @@
*
* @hide
*/
- public boolean canSupportNetworkType(@TelephonyManager.NetworkType int networkType) {
+ public boolean canSupportNetworkType(@NetworkType int networkType) {
// Do a special checking for GSM. In reality, GSM is a voice only network type and can never
// be used for data. We allow it here because in some DSDS corner cases, on the non-DDS
// sub, modem reports data rat unknown. In that case if voice is GSM and this APN supports
diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java
index 9170e88..49625bb 100644
--- a/telephony/java/android/telephony/data/DataCallResponse.java
+++ b/telephony/java/android/telephony/data/DataCallResponse.java
@@ -24,8 +24,8 @@
import android.net.LinkAddress;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.Annotation.DataFailureCause;
import android.telephony.DataFailCause;
-import android.telephony.DataFailCause.FailCause;
import android.telephony.data.ApnSetting.ProtocolType;
import com.android.internal.annotations.VisibleForTesting;
@@ -67,7 +67,7 @@
/** Indicates the data connection is active with physical link up. */
public static final int LINK_STATUS_ACTIVE = 2;
- private final @FailCause int mCause;
+ private final @DataFailureCause int mCause;
private final int mSuggestedRetryTime;
private final int mId;
private final @LinkStatus int mLinkStatus;
@@ -103,7 +103,7 @@
*
* @removed Use the {@link Builder()} instead.
*/
- public DataCallResponse(@FailCause int cause, int suggestedRetryTime, int id,
+ public DataCallResponse(@DataFailureCause int cause, int suggestedRetryTime, int id,
@LinkStatus int linkStatus,
@ProtocolType int protocolType, @Nullable String interfaceName,
@Nullable List<LinkAddress> addresses,
@@ -150,7 +150,7 @@
/**
* @return Data call fail cause. {@link DataFailCause#NONE} indicates no error.
*/
- @FailCause
+ @DataFailureCause
public int getCause() { return mCause; }
/**
@@ -314,7 +314,7 @@
* </code></pre>
*/
public static final class Builder {
- private @FailCause int mCause;
+ private @DataFailureCause int mCause;
private int mSuggestedRetryTime;
@@ -348,7 +348,7 @@
* @param cause Data call fail cause. {@link DataFailCause#NONE} indicates no error.
* @return The same instance of the builder.
*/
- public @NonNull Builder setCause(@FailCause int cause) {
+ public @NonNull Builder setCause(@DataFailureCause int cause) {
mCause = cause;
return this;
}
diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java
index 0d79ec9..30c209b 100644
--- a/telephony/java/android/telephony/data/DataProfile.java
+++ b/telephony/java/android/telephony/data/DataProfile.java
@@ -25,8 +25,8 @@
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.Annotation.ApnType;
import android.telephony.TelephonyManager.NetworkTypeBitMask;
-import android.telephony.data.ApnSetting.ApnType;
import android.telephony.data.ApnSetting.AuthType;
import android.text.TextUtils;
diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java
index 0e1751d..e793979 100644
--- a/telephony/java/android/telephony/data/QualifiedNetworksService.java
+++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java
@@ -27,8 +27,8 @@
import android.os.Message;
import android.os.RemoteException;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.Annotation.ApnType;
import android.telephony.Rlog;
-import android.telephony.data.ApnSetting.ApnType;
import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
@@ -133,7 +133,7 @@
* service.
*
* @param apnTypes APN types of the qualified networks. This must be a bitmask combination
- * of {@link ApnSetting.ApnType}.
+ * of {@link ApnType}.
* @param qualifiedNetworkTypes List of network types which are qualified for data
* connection setup for {@link @apnType} in the preferred order. Each element in the list
* is a {@link AccessNetworkType}. An empty list indicates no networks are qualified
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
index 19d0724..1666265 100644
--- a/telephony/java/android/telephony/emergency/EmergencyNumber.java
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.TestApi;
import android.hardware.radio.V1_4.EmergencyNumberSource;
import android.hardware.radio.V1_4.EmergencyServiceCategory;
import android.os.Parcel;
@@ -184,6 +185,7 @@
*
* @hide
*/
+ @TestApi
public static final int EMERGENCY_NUMBER_SOURCE_TEST = 1 << 5;
/** Bit-field which indicates the number is from the modem config. */
public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG =
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 7441c26..f3a335d 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -19,7 +19,6 @@
import android.app.PendingIntent;
import android.net.Uri;
import android.os.Bundle;
-import android.telephony.IFinancialSmsCallback;
import com.android.internal.telephony.SmsRawData;
/**
@@ -570,17 +569,6 @@
int subId, String callingPkg, String prefixes, in PendingIntent intent);
/**
- * Get sms inbox messages for the calling financial app.
- *
- * @param subId the SIM id.
- * @param callingPkg the package name of the calling app.
- * @param params parameters to filter the sms messages.
- * @param callback the callback interface to deliver the result.
- */
- void getSmsMessagesForFinancialApp(
- int subId, String callingPkg, in Bundle params, in IFinancialSmsCallback callback);
-
- /**
* Check if the destination is a possible premium short code.
*
* @param destAddress the destination address to test for possible short code
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index aa1f94f..2096325 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -19,7 +19,6 @@
import android.app.PendingIntent;
import android.net.Uri;
import android.os.Bundle;
-import android.telephony.IFinancialSmsCallback;
import java.util.List;
@@ -198,12 +197,6 @@
}
@Override
- public void getSmsMessagesForFinancialApp(
- int subId, String callingPkg, Bundle params, IFinancialSmsCallback callback) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public int checkSmsShortCodeDestination(
int subid, String callingApk, String destAddress, String countryIso) {
throw new UnsupportedOperationException();
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 866e936..4d90579 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -302,7 +302,7 @@
* operator's MCC (Mobile Country Code).
* @see android.telephony.TelephonyManager#getNetworkCountryIso
*/
- String getNetworkCountryIsoForPhone(int phoneId);
+ String getNetworkCountryIsoForPhone(int phoneId, String callingPkg);
/**
* Returns the neighboring cell information of the device.
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index 6eea118..c65c45f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -461,7 +461,11 @@
}
}
- static final class GeoFencingTriggerMessage {
+ /**
+ * Part of a GSM SMS cell broadcast message which may trigger geo-fencing logic.
+ * @hide
+ */
+ public static final class GeoFencingTriggerMessage {
/**
* Indicate the list of active alerts share their warning area coordinates which means the
* broadcast area is the union of the broadcast areas of the active alerts in this list.
@@ -476,6 +480,11 @@
this.cbIdentifiers = cbIdentifiers;
}
+ /**
+ * Whether the trigger message indicates that the broadcast areas are shared between all
+ * active alerts.
+ * @return true if broadcast areas are to be shared
+ */
boolean shouldShareBroadcastArea() {
return type == TYPE_ACTIVE_ALERT_SHARE_WAC;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
index 6bbff4b..cbe5211 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
@@ -74,22 +74,22 @@
/**
* Length of SMS-CB header
*/
- static final int PDU_HEADER_LENGTH = 6;
+ public static final int PDU_HEADER_LENGTH = 6;
/**
* GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1
*/
- static final int FORMAT_GSM = 1;
+ public static final int FORMAT_GSM = 1;
/**
* UMTS pdu format, as defined in 3gpp TS 23.041, section 9.4.2
*/
- static final int FORMAT_UMTS = 2;
+ public static final int FORMAT_UMTS = 2;
/**
- * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3
+ * ETWS pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3
*/
- static final int FORMAT_ETWS_PRIMARY = 3;
+ public static final int FORMAT_ETWS_PRIMARY = 3;
/**
* Message type value as defined in 3gpp TS 25.324, section 11.1.
@@ -230,43 +230,43 @@
}
@UnsupportedAppUsage
- int getGeographicalScope() {
+ public int getGeographicalScope() {
return mGeographicalScope;
}
@UnsupportedAppUsage
- int getSerialNumber() {
+ public int getSerialNumber() {
return mSerialNumber;
}
@UnsupportedAppUsage
- int getServiceCategory() {
+ public int getServiceCategory() {
return mMessageIdentifier;
}
- int getDataCodingScheme() {
+ public int getDataCodingScheme() {
return mDataCodingScheme;
}
- DataCodingScheme getDataCodingSchemeStructedData() {
+ public DataCodingScheme getDataCodingSchemeStructedData() {
return mDataCodingSchemeStructedData;
}
@UnsupportedAppUsage
- int getPageIndex() {
+ public int getPageIndex() {
return mPageIndex;
}
@UnsupportedAppUsage
- int getNumberOfPages() {
+ public int getNumberOfPages() {
return mNrOfPages;
}
- SmsCbEtwsInfo getEtwsInfo() {
+ public SmsCbEtwsInfo getEtwsInfo() {
return mEtwsInfo;
}
- SmsCbCmasInfo getCmasInfo() {
+ public SmsCbCmasInfo getCmasInfo() {
return mCmasInfo;
}
@@ -274,7 +274,7 @@
* Return whether this broadcast is an emergency (PWS) message type.
* @return true if this message is emergency type; false otherwise
*/
- boolean isEmergencyMessage() {
+ public boolean isEmergencyMessage() {
return mMessageIdentifier >= SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER
&& mMessageIdentifier <= SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER;
}
@@ -292,7 +292,7 @@
* Return whether this broadcast is an ETWS primary notification.
* @return true if this message is an ETWS primary notification; false otherwise
*/
- boolean isEtwsPrimaryNotification() {
+ public boolean isEtwsPrimaryNotification() {
return mFormat == FORMAT_ETWS_PRIMARY;
}
@@ -300,7 +300,7 @@
* Return whether this broadcast is in UMTS format.
* @return true if this message is in UMTS format; false otherwise
*/
- boolean isUmtsFormat() {
+ public boolean isUmtsFormat() {
return mFormat == FORMAT_UMTS;
}
diff --git a/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java b/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java
index 730b210..fe1d9d2 100644
--- a/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java
+++ b/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java
@@ -92,5 +92,18 @@
}
assertTrue("Did not see framework.jar in " + res, sawFramework);
assertTrue("Did not see services.jar in " + res, sawServices);
+
+
+ // Test the profile contents contain common methods for core-oj that would normally be AOT
+ // compiled.
+ res = mTestDevice.executeShellCommand("profman --dump-classes-and-methods --profile-file="
+ + SYSTEM_SERVER_PROFILE + " --apk=/apex/com.android.art/javalib/core-oj.jar");
+ boolean sawObjectInit = false;
+ for (String line : res.split("\n")) {
+ if (line.contains("Ljava/lang/Object;-><init>()V")) {
+ sawObjectInit = true;
+ }
+ }
+ assertTrue("Did not see Object.<init> in " + res, sawObjectInit);
}
}
diff --git a/tests/Codegen/runTest.sh b/tests/Codegen/runTest.sh
index 614cbb7..82e9f03 100755
--- a/tests/Codegen/runTest.sh
+++ b/tests/Codegen/runTest.sh
@@ -13,9 +13,12 @@
header_and_eval m -j16 codegen_cli && \
header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java && \
header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java && \
+ header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java && \
+ header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java && \
+ header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java && \
cd $ANDROID_BUILD_TOP &&
header_and_eval mmma -j16 frameworks/base/tests/Codegen && \
- header_and_eval adb install -r -t $ANDROID_PRODUCT_OUT/testcases/CodegenTests/arm64/CodegenTests.apk && \
+ header_and_eval adb install -r -t "$(find $ANDROID_TARGET_OUT_TESTCASES -name 'CodegenTests.apk')" && \
# header_and_eval adb shell am set-debug-app -w com.android.codegentest && \
header_and_eval adb shell am instrument -w -e package com.android.codegentest com.android.codegentest/androidx.test.runner.AndroidJUnitRunner
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.aidl
similarity index 68%
copy from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
copy to tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.aidl
index 8b35852..ab62c83 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.aidl
@@ -14,13 +14,6 @@
* limitations under the License.
*/
-package android.hardware.biometrics;
+package com.android.codegentest;
-/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
- * @hide
- */
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+parcelable HierrarchicalDataClassBase;
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
new file mode 100644
index 0000000..9e9ddae
--- /dev/null
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2019 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.codegentest;
+
+import android.os.Parcelable;
+
+import com.android.internal.util.DataClass;
+
+/**
+ * @see HierrarchicalDataClassChild
+ */
+@DataClass(
+ genConstructor = false,
+ genSetters = true)
+public class HierrarchicalDataClassBase implements Parcelable {
+
+ private int mBaseData;
+
+
+
+ // Code below generated by codegen v1.0.5.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java
+
+
+ @DataClass.Generated.Member
+ public int getBaseData() {
+ return mBaseData;
+ }
+
+ @DataClass.Generated.Member
+ public HierrarchicalDataClassBase setBaseData(int value) {
+ mBaseData = value;
+ return this;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public void writeToParcel(android.os.Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ dest.writeInt(mBaseData);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ protected HierrarchicalDataClassBase(android.os.Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ int baseData = in.readInt();
+
+ this.mBaseData = baseData;
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @android.annotation.NonNull Parcelable.Creator<HierrarchicalDataClassBase> CREATOR
+ = new Parcelable.Creator<HierrarchicalDataClassBase>() {
+ @Override
+ public HierrarchicalDataClassBase[] newArray(int size) {
+ return new HierrarchicalDataClassBase[size];
+ }
+
+ @Override
+ public HierrarchicalDataClassBase createFromParcel(android.os.Parcel in) {
+ return new HierrarchicalDataClassBase(in);
+ }
+ };
+
+ @DataClass.Generated(
+ time = 1570231100269L,
+ codegenVersion = "1.0.5",
+ sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassBase.java",
+ inputSignatures = "private int mBaseData\nclass HierrarchicalDataClassBase extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genSetters=true)")
+ @Deprecated
+ private void __metadata() {}
+
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.aidl
similarity index 68%
copy from core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
copy to tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.aidl
index 8b35852..a099722 100644
--- a/core/java/android/hardware/biometrics/IBiometricConfirmDeviceCredentialCallback.aidl
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.aidl
@@ -14,13 +14,6 @@
* limitations under the License.
*/
-package android.hardware.biometrics;
+package com.android.codegentest;
-/**
- * Communication channel between ConfirmDeviceCredential / ConfirmLock* and BiometricService.
- * @hide
- */
-interface IBiometricConfirmDeviceCredentialCallback {
- // Invoked when authentication should be canceled.
- oneway void cancel();
-}
\ No newline at end of file
+parcelable HierrarchicalDataClassChild;
diff --git a/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
new file mode 100644
index 0000000..27a6933
--- /dev/null
+++ b/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2019 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.codegentest;
+
+import android.annotation.NonNull;
+import android.os.Parcelable;
+
+import com.android.internal.util.DataClass;
+
+/**
+ * An example of data classes that extend one another.
+ *
+ * Note that some features like constructor generation might not work well due to lack of
+ * information about the superclass when generating code for subclass.
+ *
+ * It is recommended to avoid inheritance in favor of composition for new data classes,
+ * particularly parcelable ones.
+ *
+ * However for legacy classes or where inheritance is desired for allocation efficiency,
+ * you can either use a technique from this example, opting for mutability/setters, or just write
+ * constructors by hand.
+ *
+ * @see HierrarchicalDataClassBase
+ */
+@DataClass(
+ genParcelable = true,
+ genConstructor = false,
+ genSetters = true)
+public class HierrarchicalDataClassChild extends HierrarchicalDataClassBase {
+
+ private @NonNull String mChildData;
+
+
+
+ // Code below generated by codegen v1.0.5.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java
+
+
+ @DataClass.Generated.Member
+ public @NonNull String getChildData() {
+ return mChildData;
+ }
+
+ @DataClass.Generated.Member
+ public HierrarchicalDataClassChild setChildData(@NonNull String value) {
+ mChildData = value;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mChildData);
+ return this;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public void writeToParcel(android.os.Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ super.writeToParcel(dest, flags);
+
+ dest.writeString(mChildData);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ protected HierrarchicalDataClassChild(android.os.Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ super(in);
+
+ String childData = in.readString();
+
+ this.mChildData = childData;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mChildData);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<HierrarchicalDataClassChild> CREATOR
+ = new Parcelable.Creator<HierrarchicalDataClassChild>() {
+ @Override
+ public HierrarchicalDataClassChild[] newArray(int size) {
+ return new HierrarchicalDataClassChild[size];
+ }
+
+ @Override
+ public HierrarchicalDataClassChild createFromParcel(android.os.Parcel in) {
+ return new HierrarchicalDataClassChild(in);
+ }
+ };
+
+ @DataClass.Generated(
+ time = 1570231101208L,
+ codegenVersion = "1.0.5",
+ sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/HierrarchicalDataClassChild.java",
+ inputSignatures = "private @android.annotation.NonNull java.lang.String mChildData\nclass HierrarchicalDataClassChild extends com.android.codegentest.HierrarchicalDataClassBase implements []\n@com.android.internal.util.DataClass(genParcelable=true, genConstructor=false, genSetters=true)")
+ @Deprecated
+ private void __metadata() {}
+
+}
diff --git a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
new file mode 100644
index 0000000..dafece1
--- /dev/null
+++ b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2019 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.codegentest;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+
+import com.android.internal.util.AnnotationValidations;
+import com.android.internal.util.DataClass;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Additional test for various parcelling corner-cases.
+ */
+@DataClass(
+ genBuilder = true,
+ genAidl = false,
+ genToString = true)
+public class ParcelAllTheThingsDataClass implements Parcelable {
+
+ @NonNull String[] mStringArray = null;
+ @NonNull int[] mIntArray = null;
+ @NonNull List<String> mStringList = null;
+
+ @NonNull Map<String, SampleWithCustomBuilder> mMap = null;
+ @NonNull Map<String, String> mStringMap = null;
+
+ @NonNull SparseArray<SampleWithCustomBuilder> mSparseArray = null;
+ @NonNull SparseIntArray mSparseIntArray = null;
+
+
+
+ // Code below generated by codegen v1.0.5.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
+
+
+ @DataClass.Generated.Member
+ /* package-private */ ParcelAllTheThingsDataClass(
+ @NonNull String[] stringArray,
+ @NonNull int[] intArray,
+ @NonNull List<String> stringList,
+ @NonNull Map<String,SampleWithCustomBuilder> map,
+ @NonNull Map<String,String> stringMap,
+ @NonNull SparseArray<SampleWithCustomBuilder> sparseArray,
+ @NonNull SparseIntArray sparseIntArray) {
+ this.mStringArray = stringArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mStringArray);
+ this.mIntArray = intArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mIntArray);
+ this.mStringList = stringList;
+ AnnotationValidations.validate(
+ NonNull.class, null, mStringList);
+ this.mMap = map;
+ AnnotationValidations.validate(
+ NonNull.class, null, mMap);
+ this.mStringMap = stringMap;
+ AnnotationValidations.validate(
+ NonNull.class, null, mStringMap);
+ this.mSparseArray = sparseArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mSparseArray);
+ this.mSparseIntArray = sparseIntArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mSparseIntArray);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull String[] getStringArray() {
+ return mStringArray;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull int[] getIntArray() {
+ return mIntArray;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull List<String> getStringList() {
+ return mStringList;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Map<String,SampleWithCustomBuilder> getMap() {
+ return mMap;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Map<String,String> getStringMap() {
+ return mStringMap;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull SparseArray<SampleWithCustomBuilder> getSparseArray() {
+ return mSparseArray;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull SparseIntArray getSparseIntArray() {
+ return mSparseIntArray;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "ParcelAllTheThingsDataClass { " +
+ "stringArray = " + java.util.Arrays.toString(mStringArray) + ", " +
+ "intArray = " + java.util.Arrays.toString(mIntArray) + ", " +
+ "stringList = " + mStringList + ", " +
+ "map = " + mMap + ", " +
+ "stringMap = " + mStringMap + ", " +
+ "sparseArray = " + mSparseArray + ", " +
+ "sparseIntArray = " + mSparseIntArray +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public void writeToParcel(Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ dest.writeStringArray(mStringArray);
+ dest.writeIntArray(mIntArray);
+ dest.writeStringList(mStringList);
+ dest.writeMap(mMap);
+ dest.writeMap(mStringMap);
+ dest.writeSparseArray(mSparseArray);
+ dest.writeSparseIntArray(mSparseIntArray);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ protected ParcelAllTheThingsDataClass(Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ String[] stringArray = in.createStringArray();
+ int[] intArray = in.createIntArray();
+ List<String> stringList = new java.util.ArrayList<>();
+ in.readStringList(stringList);
+ Map<String,SampleWithCustomBuilder> map = new java.util.LinkedHashMap<>();
+ in.readMap(map, SampleWithCustomBuilder.class.getClassLoader());
+ Map<String,String> stringMap = new java.util.LinkedHashMap<>();
+ in.readMap(stringMap, String.class.getClassLoader());
+ SparseArray<SampleWithCustomBuilder> sparseArray = (SparseArray) in.readSparseArray(SampleWithCustomBuilder.class.getClassLoader());
+ SparseIntArray sparseIntArray = (SparseIntArray) in.readSparseIntArray();
+
+ this.mStringArray = stringArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mStringArray);
+ this.mIntArray = intArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mIntArray);
+ this.mStringList = stringList;
+ AnnotationValidations.validate(
+ NonNull.class, null, mStringList);
+ this.mMap = map;
+ AnnotationValidations.validate(
+ NonNull.class, null, mMap);
+ this.mStringMap = stringMap;
+ AnnotationValidations.validate(
+ NonNull.class, null, mStringMap);
+ this.mSparseArray = sparseArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mSparseArray);
+ this.mSparseIntArray = sparseIntArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mSparseIntArray);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<ParcelAllTheThingsDataClass> CREATOR
+ = new Parcelable.Creator<ParcelAllTheThingsDataClass>() {
+ @Override
+ public ParcelAllTheThingsDataClass[] newArray(int size) {
+ return new ParcelAllTheThingsDataClass[size];
+ }
+
+ @Override
+ public ParcelAllTheThingsDataClass createFromParcel(Parcel in) {
+ return new ParcelAllTheThingsDataClass(in);
+ }
+ };
+
+ /**
+ * A builder for {@link ParcelAllTheThingsDataClass}
+ */
+ @SuppressWarnings("WeakerAccess")
+ @DataClass.Generated.Member
+ public static class Builder {
+
+ private @NonNull String[] mStringArray;
+ private @NonNull int[] mIntArray;
+ private @NonNull List<String> mStringList;
+ private @NonNull Map<String,SampleWithCustomBuilder> mMap;
+ private @NonNull Map<String,String> mStringMap;
+ private @NonNull SparseArray<SampleWithCustomBuilder> mSparseArray;
+ private @NonNull SparseIntArray mSparseIntArray;
+
+ private long mBuilderFieldsSet = 0L;
+
+ public Builder() {
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setStringArray(@NonNull String... value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x1;
+ mStringArray = value;
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setIntArray(@NonNull int... value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x2;
+ mIntArray = value;
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setStringList(@NonNull List<String> value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x4;
+ mStringList = value;
+ return this;
+ }
+
+ /** @see #setStringList */
+ @DataClass.Generated.Member
+ public @NonNull Builder addStringList(String value) {
+ // You can refine this method's name by providing item's singular name, e.g.:
+ // @DataClass.PluralOf("item")) mItems = ...
+
+ if (mStringList == null) setStringList(new java.util.ArrayList<>());
+ mStringList.add(value);
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setMap(@NonNull Map<String,SampleWithCustomBuilder> value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x8;
+ mMap = value;
+ return this;
+ }
+
+ /** @see #setMap */
+ @DataClass.Generated.Member
+ public @NonNull Builder addMap(String key, SampleWithCustomBuilder value) {
+ // You can refine this method's name by providing item's singular name, e.g.:
+ // @DataClass.PluralOf("item")) mItems = ...
+
+ if (mMap == null) setMap(new java.util.LinkedHashMap());
+ mMap.put(key, value);
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setStringMap(@NonNull Map<String,String> value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x10;
+ mStringMap = value;
+ return this;
+ }
+
+ /** @see #setStringMap */
+ @DataClass.Generated.Member
+ public @NonNull Builder addStringMap(String key, String value) {
+ // You can refine this method's name by providing item's singular name, e.g.:
+ // @DataClass.PluralOf("item")) mItems = ...
+
+ if (mStringMap == null) setStringMap(new java.util.LinkedHashMap());
+ mStringMap.put(key, value);
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setSparseArray(@NonNull SparseArray<SampleWithCustomBuilder> value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x20;
+ mSparseArray = value;
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setSparseIntArray(@NonNull SparseIntArray value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x40;
+ mSparseIntArray = value;
+ return this;
+ }
+
+ /** Builds the instance. This builder should not be touched after calling this! */
+ public ParcelAllTheThingsDataClass build() {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x80; // Mark builder used
+
+ if ((mBuilderFieldsSet & 0x1) == 0) {
+ mStringArray = null;
+ }
+ if ((mBuilderFieldsSet & 0x2) == 0) {
+ mIntArray = null;
+ }
+ if ((mBuilderFieldsSet & 0x4) == 0) {
+ mStringList = null;
+ }
+ if ((mBuilderFieldsSet & 0x8) == 0) {
+ mMap = null;
+ }
+ if ((mBuilderFieldsSet & 0x10) == 0) {
+ mStringMap = null;
+ }
+ if ((mBuilderFieldsSet & 0x20) == 0) {
+ mSparseArray = null;
+ }
+ if ((mBuilderFieldsSet & 0x40) == 0) {
+ mSparseIntArray = null;
+ }
+ ParcelAllTheThingsDataClass o = new ParcelAllTheThingsDataClass(
+ mStringArray,
+ mIntArray,
+ mStringList,
+ mMap,
+ mStringMap,
+ mSparseArray,
+ mSparseIntArray);
+ return o;
+ }
+
+ private void checkNotUsed() {
+ if ((mBuilderFieldsSet & 0x80) != 0) {
+ throw new IllegalStateException(
+ "This Builder should not be reused. Use a new Builder instance instead");
+ }
+ }
+ }
+
+ @DataClass.Generated(
+ time = 1570231099316L,
+ codegenVersion = "1.0.5",
+ sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java",
+ inputSignatures = " @android.annotation.NonNull java.lang.String[] mStringArray\n @android.annotation.NonNull int[] mIntArray\n @android.annotation.NonNull java.util.List<java.lang.String> mStringList\n @android.annotation.NonNull java.util.Map<java.lang.String,com.android.codegentest.SampleWithCustomBuilder> mMap\n @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.String> mStringMap\n @android.annotation.NonNull android.util.SparseArray<com.android.codegentest.SampleWithCustomBuilder> mSparseArray\n @android.annotation.NonNull android.util.SparseIntArray mSparseIntArray\nclass ParcelAllTheThingsDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)")
+ @Deprecated
+ private void __metadata() {}
+
+}
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
index f0c5baa..1d73736 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
@@ -342,14 +342,14 @@
- // Code below generated by codegen v1.0.1.
+ // Code below generated by codegen v1.0.5.
//
// DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
//
// To regenerate run:
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
- //
- // CHECKSTYLE:OFF Generated code
+
@IntDef(prefix = "STATE_", value = {
STATE_UNDEFINED,
@@ -1290,6 +1290,123 @@
@DataClass.Generated.Member
public int describeContents() { return 0; }
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ /* package-private */ SampleDataClass(Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ long flg = in.readLong();
+ int num = in.readInt();
+ int num2 = in.readInt();
+ int num4 = in.readInt();
+ String name = (flg & 0x8) == 0 ? null : in.readString();
+ String name2 = in.readString();
+ String name4 = in.readString();
+ AccessibilityNodeInfo otherParcelable = (flg & 0x40) == 0 ? null : (AccessibilityNodeInfo) in.readTypedObject(AccessibilityNodeInfo.CREATOR);
+ Date date = sParcellingForDate.unparcel(in);
+ Pattern pattern = sParcellingForPattern.unparcel(in);
+ List<LinkAddress> linkAddresses2 = new ArrayList<>();
+ in.readParcelableList(linkAddresses2, LinkAddress.class.getClassLoader());
+ ArrayList<LinkAddress> linkAddresses = new ArrayList<>();
+ in.readParcelableList(linkAddresses, LinkAddress.class.getClassLoader());
+ LinkAddress[] linkAddresses4 = (flg & 0x800) == 0 ? null : (LinkAddress[]) in.createTypedArray(LinkAddress.CREATOR);
+ String stateName = in.readString();
+ int flags = in.readInt();
+ int state = in.readInt();
+ CharSequence _charSeq = (CharSequence) in.readCharSequence();
+ LinkAddress[] linkAddresses5 = (flg & 0x10000) == 0 ? null : (LinkAddress[]) in.createTypedArray(LinkAddress.CREATOR);
+ int stringRes = in.readInt();
+ int dayOfWeek = in.readInt();
+ float[] coords = in.createFloatArray();
+
+ this.mNum = num;
+ this.mNum2 = num2;
+ this.mNum4 = num4;
+ this.mName = name;
+ this.mName2 = name2;
+ AnnotationValidations.validate(
+ NonNull.class, null, mName2);
+ this.mName4 = name4;
+ AnnotationValidations.validate(
+ NonNull.class, null, mName4);
+ this.mOtherParcelable = otherParcelable;
+ this.mDate = date;
+ AnnotationValidations.validate(
+ NonNull.class, null, mDate);
+ this.mPattern = pattern;
+ AnnotationValidations.validate(
+ NonNull.class, null, mPattern);
+ this.mLinkAddresses2 = linkAddresses2;
+ AnnotationValidations.validate(
+ NonNull.class, null, mLinkAddresses2);
+ this.mLinkAddresses = linkAddresses;
+ AnnotationValidations.validate(
+ NonNull.class, null, mLinkAddresses);
+ this.mLinkAddresses4 = linkAddresses4;
+ this.mStateName = stateName;
+
+ if (!(Objects.equals(mStateName, STATE_NAME_UNDEFINED))
+ && !(Objects.equals(mStateName, STATE_NAME_ON))
+ && !(Objects.equals(mStateName, STATE_NAME_OFF))) {
+ throw new java.lang.IllegalArgumentException(
+ "stateName was " + mStateName + " but must be one of: "
+ + "STATE_NAME_UNDEFINED(" + STATE_NAME_UNDEFINED + "), "
+ + "STATE_NAME_ON(" + STATE_NAME_ON + "), "
+ + "STATE_NAME_OFF(" + STATE_NAME_OFF + ")");
+ }
+
+ AnnotationValidations.validate(
+ NonNull.class, null, mStateName);
+ this.mFlags = flags;
+
+ Preconditions.checkFlagsArgument(
+ mFlags,
+ FLAG_MANUAL_REQUEST
+ | FLAG_COMPATIBILITY_MODE_REQUEST
+ | FLAG_AUGMENTED_REQUEST);
+ this.mState = state;
+
+ if (!(mState == STATE_UNDEFINED)
+ && !(mState == STATE_ON)
+ && !(mState == STATE_OFF)) {
+ throw new java.lang.IllegalArgumentException(
+ "state was " + mState + " but must be one of: "
+ + "STATE_UNDEFINED(" + STATE_UNDEFINED + "), "
+ + "STATE_ON(" + STATE_ON + "), "
+ + "STATE_OFF(" + STATE_OFF + ")");
+ }
+
+ this.charSeq = _charSeq;
+ AnnotationValidations.validate(
+ NonNull.class, null, charSeq);
+ this.mLinkAddresses5 = linkAddresses5;
+ this.mStringRes = stringRes;
+ AnnotationValidations.validate(
+ StringRes.class, null, mStringRes);
+ this.mDayOfWeek = dayOfWeek;
+ AnnotationValidations.validate(
+ android.annotation.IntRange.class, null, mDayOfWeek,
+ "from", 0,
+ "to", 6);
+ this.mCoords = coords;
+ AnnotationValidations.validate(
+ Size.class, null, mCoords.length,
+ "value", 2);
+ AnnotationValidations.validate(
+ NonNull.class, null, mCoords);
+ int coordsSize = mCoords.length;
+ for (int i = 0; i < coordsSize; i++) {
+ AnnotationValidations.validate(
+ FloatRange.class, null, mCoords[i],
+ "from", 0f);
+ }
+
+
+ onConstructed();
+ }
+
@DataClass.Generated.Member
public static final @NonNull Parcelable.Creator<SampleDataClass> CREATOR
= new Parcelable.Creator<SampleDataClass>() {
@@ -1299,55 +1416,8 @@
}
@Override
- @SuppressWarnings({"unchecked", "RedundantCast"})
public SampleDataClass createFromParcel(Parcel in) {
- // You can override field unparcelling by defining methods like:
- // static FieldType unparcelFieldName(Parcel in) { ... }
-
- long flg = in.readLong();
- int num = in.readInt();
- int num2 = in.readInt();
- int num4 = in.readInt();
- String name = (flg & 0x8) == 0 ? null : in.readString();
- String name2 = in.readString();
- String name4 = in.readString();
- AccessibilityNodeInfo otherParcelable = (flg & 0x40) == 0 ? null : (AccessibilityNodeInfo) in.readTypedObject(AccessibilityNodeInfo.CREATOR);
- Date date = sParcellingForDate.unparcel(in);
- Pattern pattern = sParcellingForPattern.unparcel(in);
- List<LinkAddress> linkAddresses2 = new ArrayList<>();
- in.readParcelableList(linkAddresses2, LinkAddress.class.getClassLoader());
- ArrayList<LinkAddress> linkAddresses = new ArrayList<>();
- in.readParcelableList(linkAddresses, LinkAddress.class.getClassLoader());
- LinkAddress[] linkAddresses4 = (flg & 0x800) == 0 ? null : (LinkAddress[]) in.createTypedArray(LinkAddress.CREATOR);
- String stateName = in.readString();
- int flags = in.readInt();
- int state = in.readInt();
- CharSequence _charSeq = (CharSequence) in.readCharSequence();
- LinkAddress[] linkAddresses5 = (flg & 0x10000) == 0 ? null : (LinkAddress[]) in.createTypedArray(LinkAddress.CREATOR);
- int stringRes = in.readInt();
- int dayOfWeek = in.readInt();
- float[] coords = in.createFloatArray();
- return new SampleDataClass(
- num,
- num2,
- num4,
- name,
- name2,
- name4,
- otherParcelable,
- date,
- pattern,
- linkAddresses2,
- linkAddresses,
- linkAddresses4,
- stateName,
- flags,
- state,
- _charSeq,
- linkAddresses5,
- stringRes,
- dayOfWeek,
- coords);
+ return new SampleDataClass(in);
}
};
@@ -1798,8 +1868,8 @@
}
@DataClass.Generated(
- time = 1568235365376L,
- codegenVersion = "1.0.1",
+ time = 1570231097226L,
+ codegenVersion = "1.0.5",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java",
inputSignatures = "public static final java.lang.String STATE_NAME_UNDEFINED\npublic static final java.lang.String STATE_NAME_ON\npublic static final java.lang.String STATE_NAME_OFF\npublic static final int STATE_UNDEFINED\npublic static final int STATE_ON\npublic static final int STATE_OFF\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate int mNum\nprivate int mNum2\nprivate int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient android.net.LinkAddress[] mLinkAddresses6\ntransient int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=6L) int mDayOfWeek\nprivate @android.annotation.Size(2L) @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate static java.lang.String defaultName4()\nprivate int[] lazyInitTmpStorage()\npublic android.net.LinkAddress[] getLinkAddresses4()\nprivate boolean patternEquals(java.util.regex.Pattern)\nprivate int patternHashCode()\nprivate void onConstructed()\npublic void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java b/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java
index 6636207..c7a7735 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java
@@ -25,9 +25,14 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
import android.net.LinkAddress;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
import androidx.test.runner.AndroidJUnit4;
@@ -36,6 +41,9 @@
import java.util.Arrays;
import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -209,6 +217,32 @@
newBuilder().setDayOfWeek(42).build();
}
+ @Test
+ public void testDataStructures_parcelCorrectly() {
+ SampleWithCustomBuilder otherParcelable = new SampleWithCustomBuilder.Builder().setDelay(3, SECONDS).build();
+
+ ParcelAllTheThingsDataClass instance = new ParcelAllTheThingsDataClass.Builder()
+ .setIntArray(40, 41)
+ .addMap("foo", otherParcelable)
+ .setSparseArray(new SparseArray<SampleWithCustomBuilder>() {{
+ put(45, otherParcelable);
+ }})
+ .setSparseIntArray(new SparseIntArray() {{
+ put(48, 49);
+ }})
+ .addStringMap("foo2", "fooValue")
+ .setStringArray("foo", "bar")
+ .addStringList("foo")
+ .build();
+
+ ParcelAllTheThingsDataClass unparceledInstance =
+ parcelAndUnparcel(instance, ParcelAllTheThingsDataClass.CREATOR);
+
+ // SparseArray and friends don't implement equals
+ // so just compare string representations instead
+ assertEquals(instance.toString(), unparceledInstance.toString());
+ }
+
private static <T extends Parcelable> T parcelAndUnparcel(
T original, Parcelable.Creator<T> creator) {
Parcel p = Parcel.obtain();
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
index 86f37fe..2efa193 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
@@ -17,14 +17,16 @@
package com.android.codegentest;
import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.SystemClock;
import com.android.internal.util.DataClass;
import java.util.concurrent.TimeUnit;
-@DataClass(genBuilder = true)
-public class SampleWithCustomBuilder {
+@DataClass(genBuilder = true, genAidl = false, genToString = true)
+public class SampleWithCustomBuilder implements Parcelable {
long delayAmount = 0;
@NonNull
@@ -73,15 +75,24 @@
}
+ private static TimeUnit unparcelDelayUnit(Parcel p) {
+ return TimeUnit.values()[p.readInt()];
+ }
- // Code below generated by codegen v1.0.1.
+ private void parcelDelayUnit(Parcel p, int flags) {
+ p.writeInt(delayUnit.ordinal());
+ }
+
+
+
+ // Code below generated by codegen v1.0.5.
//
// DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
//
// To regenerate run:
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
- //
- // CHECKSTYLE:OFF Generated code
+
@DataClass.Generated.Member
/* package-private */ SampleWithCustomBuilder(
@@ -112,6 +123,68 @@
return creationTimestamp;
}
+ @Override
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "SampleWithCustomBuilder { " +
+ "delayAmount = " + delayAmount + ", " +
+ "delayUnit = " + delayUnit + ", " +
+ "creationTimestamp = " + creationTimestamp +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public void writeToParcel(Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ dest.writeLong(delayAmount);
+ parcelDelayUnit(dest, flags);
+ dest.writeLong(creationTimestamp);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ protected SampleWithCustomBuilder(Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ long _delayAmount = in.readLong();
+ TimeUnit _delayUnit = unparcelDelayUnit(in);
+ long _creationTimestamp = in.readLong();
+
+ this.delayAmount = _delayAmount;
+ this.delayUnit = _delayUnit;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, delayUnit);
+ this.creationTimestamp = _creationTimestamp;
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<SampleWithCustomBuilder> CREATOR
+ = new Parcelable.Creator<SampleWithCustomBuilder>() {
+ @Override
+ public SampleWithCustomBuilder[] newArray(int size) {
+ return new SampleWithCustomBuilder[size];
+ }
+
+ @Override
+ public SampleWithCustomBuilder createFromParcel(Parcel in) {
+ return new SampleWithCustomBuilder(in);
+ }
+ };
+
/**
* A builder for {@link SampleWithCustomBuilder}
*/
@@ -176,10 +249,10 @@
}
@DataClass.Generated(
- time = 1568235366386L,
- codegenVersion = "1.0.1",
+ time = 1570231098303L,
+ codegenVersion = "1.0.5",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java",
- inputSignatures = " long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n long creationTimestamp\nclass SampleWithCustomBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true)\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []")
+ inputSignatures = " long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n long creationTimestamp\nprivate static java.util.concurrent.TimeUnit unparcelDelayUnit(android.os.Parcel)\nprivate void parcelDelayUnit(android.os.Parcel,int)\nclass SampleWithCustomBuilder extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []")
@Deprecated
private void __metadata() {}
diff --git a/tests/MirrorSurfaceTest/Android.bp b/tests/MirrorSurfaceTest/Android.bp
new file mode 100644
index 0000000..e359c64
--- /dev/null
+++ b/tests/MirrorSurfaceTest/Android.bp
@@ -0,0 +1,6 @@
+android_test {
+ name: "MirrorSurfaceTest",
+ srcs: ["src/**/*.java"],
+ platform_apis: true,
+ certificate: "platform",
+}
diff --git a/tests/MirrorSurfaceTest/AndroidManifest.xml b/tests/MirrorSurfaceTest/AndroidManifest.xml
new file mode 100644
index 0000000..123cd0f
--- /dev/null
+++ b/tests/MirrorSurfaceTest/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.google.android.test.mirrorsurface">
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER"/>
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+ <application android:label="MirrorSurfaceTest">
+ <activity android:name=".MirrorSurfaceActivity"
+ android:label="Mirror Surface"
+ android:configChanges="orientation|screenSize">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/MirrorSurfaceTest/res/layout/activity_mirror_surface.xml b/tests/MirrorSurfaceTest/res/layout/activity_mirror_surface.xml
new file mode 100644
index 0000000..73b509f
--- /dev/null
+++ b/tests/MirrorSurfaceTest/res/layout/activity_mirror_surface.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="20dp"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/mirror_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="20dp"
+ android:text="Mirror"
+ android:textSize="20dp" />
+
+ <Button
+ android:id="@+id/remove_mirror_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="20dp"
+ android:text="Remove Mirror"
+ android:textSize="20dp" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="40dp"
+ android:layout_marginRight="40dp"
+ android:layout_marginTop="10dp"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="20dp"
+ android:text="SCALE: " />
+
+ <EditText
+ android:hint="0.5"
+ android:id="@+id/scale"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="numberDecimal" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="40dp"
+ android:layout_marginRight="40dp"
+ android:layout_marginTop="10dp"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="20dp"
+ android:text="DISPLAY FRAME: " />
+
+ <EditText
+ android:hint="0, 0, 20, 20"
+ android:id="@+id/displayFrame"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="numberDecimal|text"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="40dp"
+ android:layout_marginRight="40dp"
+ android:layout_marginTop="10dp"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="20dp"
+ android:text="SOURCE POSITION: " />
+
+ <TextView
+ android:id="@+id/sourcePosition"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="numberDecimal|text"/>
+ </LinearLayout>
+</LinearLayout>
diff --git a/tests/MirrorSurfaceTest/res/layout/move_view.xml b/tests/MirrorSurfaceTest/res/layout/move_view.xml
new file mode 100644
index 0000000..5707700
--- /dev/null
+++ b/tests/MirrorSurfaceTest/res/layout/move_view.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="20dp"
+ android:gravity="center">
+
+ <RelativeLayout
+ android:id="@+id/arrows"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageButton
+ android:id="@+id/up_arrow"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toEndOf="@+id/right_arrow"
+ android:background="@android:color/holo_green_light"
+ android:padding="10dp"
+ android:src="@android:drawable/arrow_up_float" />
+
+ <ImageButton
+ android:id="@+id/down_arrow"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/up_arrow"
+ android:layout_marginTop="80dp"
+ android:layout_toEndOf="@+id/right_arrow"
+ android:background="@android:color/holo_green_light"
+ android:padding="10dp"
+ android:src="@android:drawable/arrow_down_float" />
+
+ <ImageButton
+ android:id="@+id/right_arrow"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignTop="@+id/up_arrow"
+ android:layout_alignBottom="@+id/down_arrow"
+ android:layout_marginTop="55dp"
+ android:layout_marginEnd="15dp"
+ android:layout_marginBottom="55dp"
+ android:background="@android:color/holo_green_light"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ android:rotation="90"
+ android:src="@android:drawable/arrow_down_float" />
+
+ <ImageButton
+ android:id="@+id/left_arrow"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignTop="@+id/up_arrow"
+ android:layout_alignBottom="@+id/down_arrow"
+ android:layout_marginStart="15dp"
+ android:layout_marginTop="55dp"
+ android:layout_marginBottom="55dp"
+ android:layout_toEndOf="@+id/down_arrow"
+ android:background="@android:color/holo_green_light"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp"
+ android:rotation="-90"
+ android:src="@android:drawable/arrow_down_float" />
+ </RelativeLayout>
+
+ <RelativeLayout
+
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:id="@+id/zoom_in_button"
+ android:layout_width="40dp"
+ android:layout_marginBottom="-8dp"
+ android:layout_height="40dp"
+ android:text="+" />
+
+ <Button
+ android:layout_below="@+id/zoom_in_button"
+ android:id="@+id/zoom_out_button"
+ android:layout_width="40dp"
+ android:layout_height="40dp"
+ android:text="-" />
+ </RelativeLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java b/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java
new file mode 100644
index 0000000..b863713
--- /dev/null
+++ b/tests/MirrorSurfaceTest/src/com/google/android/test/mirrorsurface/MirrorSurfaceActivity.java
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2019 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.google.android.test.mirrorsurface;
+
+
+import android.app.Activity;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.IWindowManager;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class MirrorSurfaceActivity extends Activity implements View.OnClickListener,
+ View.OnLongClickListener, View.OnTouchListener {
+ private static final int BORDER_SIZE = 10;
+ private static final int DEFAULT_SCALE = 2;
+ private static final int DEFAULT_BORDER_COLOR = Color.argb(255, 255, 153, 0);
+ private static final int MOVE_FRAME_AMOUNT = 20;
+
+ private IWindowManager mIWm;
+ private WindowManager mWm;
+
+ private SurfaceControl mSurfaceControl = new SurfaceControl();
+ private SurfaceControl mBorderSc;
+
+ private SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
+ private View mOverlayView;
+ private View mArrowOverlay;
+
+ private Rect mDisplayBounds = new Rect();
+
+ private EditText mScaleText;
+ private EditText mDisplayFrameText;
+ private TextView mSourcePositionText;
+
+ private Rect mTmpRect = new Rect();
+ private final Surface mTmpSurface = new Surface();
+
+ private boolean mHasMirror;
+
+ private Rect mCurrFrame = new Rect();
+ private float mCurrScale = DEFAULT_SCALE;
+
+ private final Handler mHandler = new Handler();
+
+ private MoveMirrorRunnable mMoveMirrorRunnable = new MoveMirrorRunnable();
+ private boolean mIsPressedDown = false;
+
+ private int mDisplayId;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_mirror_surface);
+ mWm = (WindowManager) getSystemService(WINDOW_SERVICE);
+ mIWm = WindowManagerGlobal.getWindowManagerService();
+
+ DisplayMetrics displayMetrics = new DisplayMetrics();
+ getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
+ mDisplayBounds.set(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
+
+ mScaleText = findViewById(R.id.scale);
+ mDisplayFrameText = findViewById(R.id.displayFrame);
+ mSourcePositionText = findViewById(R.id.sourcePosition);
+
+ mCurrFrame.set(0, 0, mDisplayBounds.width() / 2, mDisplayBounds.height() / 2);
+ mCurrScale = DEFAULT_SCALE;
+
+ mDisplayId = getWindowManager().getDefaultDisplay().getDisplayId();
+ updateEditTexts();
+
+ findViewById(R.id.mirror_button).setOnClickListener(view -> {
+ if (mArrowOverlay == null) {
+ createArrowOverlay();
+ }
+ createOrUpdateMirror();
+ });
+
+ findViewById(R.id.remove_mirror_button).setOnClickListener(v -> {
+ removeMirror();
+ removeArrowOverlay();
+ });
+
+ createMirrorOverlay();
+ }
+
+ private void updateEditTexts() {
+ mDisplayFrameText.setText(
+ String.format("%s, %s, %s, %s", mCurrFrame.left, mCurrFrame.top, mCurrFrame.right,
+ mCurrFrame.bottom));
+ mScaleText.setText(String.valueOf(mCurrScale));
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (mOverlayView != null) {
+ removeMirror();
+ mWm.removeView(mOverlayView);
+ mOverlayView = null;
+ }
+ removeArrowOverlay();
+ }
+
+ private void createArrowOverlay() {
+ mArrowOverlay = getLayoutInflater().inflate(R.layout.move_view, null);
+ WindowManager.LayoutParams arrowParams = new WindowManager.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,
+ WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+ WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ PixelFormat.RGBA_8888);
+ arrowParams.gravity = Gravity.RIGHT | Gravity.BOTTOM;
+ mWm.addView(mArrowOverlay, arrowParams);
+
+ View leftArrow = mArrowOverlay.findViewById(R.id.left_arrow);
+ View topArrow = mArrowOverlay.findViewById(R.id.up_arrow);
+ View rightArrow = mArrowOverlay.findViewById(R.id.right_arrow);
+ View bottomArrow = mArrowOverlay.findViewById(R.id.down_arrow);
+
+ leftArrow.setOnClickListener(this);
+ topArrow.setOnClickListener(this);
+ rightArrow.setOnClickListener(this);
+ bottomArrow.setOnClickListener(this);
+
+ leftArrow.setOnLongClickListener(this);
+ topArrow.setOnLongClickListener(this);
+ rightArrow.setOnLongClickListener(this);
+ bottomArrow.setOnLongClickListener(this);
+
+ leftArrow.setOnTouchListener(this);
+ topArrow.setOnTouchListener(this);
+ rightArrow.setOnTouchListener(this);
+ bottomArrow.setOnTouchListener(this);
+
+ mArrowOverlay.findViewById(R.id.zoom_in_button).setOnClickListener(v -> {
+ if (mCurrScale <= 1) {
+ mCurrScale *= 2;
+ } else {
+ mCurrScale += 0.5;
+ }
+
+ updateMirror(mCurrFrame, mCurrScale);
+ });
+ mArrowOverlay.findViewById(R.id.zoom_out_button).setOnClickListener(v -> {
+ if (mCurrScale <= 1) {
+ mCurrScale /= 2;
+ } else {
+ mCurrScale -= 0.5;
+ }
+
+ updateMirror(mCurrFrame, mCurrScale);
+ });
+ }
+
+ private void removeArrowOverlay() {
+ if (mArrowOverlay != null) {
+ mWm.removeView(mArrowOverlay);
+ mArrowOverlay = null;
+ }
+ }
+
+ private void createMirrorOverlay() {
+ mOverlayView = new LinearLayout(this);
+ WindowManager.LayoutParams params = new WindowManager.LayoutParams(mDisplayBounds.width(),
+ mDisplayBounds.height(),
+ WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+ WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ PixelFormat.RGBA_8888);
+ params.gravity = Gravity.LEFT | Gravity.TOP;
+ params.setTitle("Mirror Overlay");
+ mOverlayView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
+
+ mWm.addView(mOverlayView, params);
+
+ }
+
+ private void removeMirror() {
+ if (mSurfaceControl.isValid()) {
+ mTransaction.remove(mSurfaceControl).apply();
+ }
+ mHasMirror = false;
+ }
+
+ private void createOrUpdateMirror() {
+ if (mHasMirror) {
+ updateMirror(getDisplayFrame(), getScale());
+ } else {
+ createMirror(getDisplayFrame(), getScale());
+ }
+
+ }
+
+ private Rect getDisplayFrame() {
+ mTmpRect.setEmpty();
+ String[] frameVals = mDisplayFrameText.getText().toString().split("\\s*,\\s*");
+ if (frameVals.length != 4) {
+ return mTmpRect;
+ }
+
+ try {
+ mTmpRect.set(Integer.parseInt(frameVals[0]), Integer.parseInt(frameVals[1]),
+ Integer.parseInt(frameVals[2]), Integer.parseInt(frameVals[3]));
+ } catch (Exception e) {
+ mTmpRect.setEmpty();
+ }
+
+ return mTmpRect;
+ }
+
+ private float getScale() {
+ try {
+ return Float.parseFloat(mScaleText.getText().toString());
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ private void createMirror(Rect displayFrame, float scale) {
+ boolean success = false;
+ try {
+ success = mIWm.mirrorDisplay(mDisplayId, mSurfaceControl);
+ } catch (RemoteException e) {
+ }
+
+ if (!success) {
+ return;
+ }
+
+ if (!mSurfaceControl.isValid()) {
+ return;
+ }
+
+ mHasMirror = true;
+
+ mBorderSc = new SurfaceControl.Builder()
+ .setName("Mirror Border")
+ .setBufferSize(1, 1)
+ .setFormat(PixelFormat.TRANSLUCENT)
+ .build();
+
+ updateMirror(displayFrame, scale);
+
+ mTransaction
+ .show(mSurfaceControl)
+ .reparent(mSurfaceControl, mOverlayView.getViewRootImpl().getSurfaceControl())
+ .setLayer(mBorderSc, 1)
+ .show(mBorderSc)
+ .reparent(mBorderSc, mSurfaceControl)
+ .apply();
+ }
+
+ private void updateMirror(Rect displayFrame, float scale) {
+ if (displayFrame.isEmpty()) {
+ Rect bounds = mDisplayBounds;
+ int defaultCropW = Math.round(bounds.width() / 2);
+ int defaultCropH = Math.round(bounds.height() / 2);
+ displayFrame.set(0, 0, defaultCropW, defaultCropH);
+ }
+
+ if (scale <= 0) {
+ scale = DEFAULT_SCALE;
+ }
+
+ mCurrFrame.set(displayFrame);
+ mCurrScale = scale;
+
+ int width = (int) Math.ceil(displayFrame.width() / scale);
+ int height = (int) Math.ceil(displayFrame.height() / scale);
+
+ Rect sourceBounds = getSourceBounds(displayFrame, scale);
+
+ mTransaction.setGeometry(mSurfaceControl, sourceBounds, displayFrame, Surface.ROTATION_0)
+ .setPosition(mBorderSc, sourceBounds.left, sourceBounds.top)
+ .setBufferSize(mBorderSc, width, height)
+ .apply();
+
+ drawBorder(mBorderSc, width, height, (int) Math.ceil(BORDER_SIZE / scale));
+
+ mSourcePositionText.setText(sourceBounds.left + ", " + sourceBounds.top);
+ mDisplayFrameText.setText(
+ String.format("%s, %s, %s, %s", mCurrFrame.left, mCurrFrame.top, mCurrFrame.right,
+ mCurrFrame.bottom));
+ mScaleText.setText(String.valueOf(mCurrScale));
+ }
+
+ private void drawBorder(SurfaceControl borderSc, int width, int height, int borderSize) {
+ mTmpSurface.copyFrom(borderSc);
+
+ Canvas c = null;
+ try {
+ c = mTmpSurface.lockCanvas(null);
+ } catch (IllegalArgumentException | Surface.OutOfResourcesException e) {
+ }
+ if (c == null) {
+ return;
+ }
+
+ // Top
+ c.save();
+ c.clipRect(new Rect(0, 0, width, borderSize));
+ c.drawColor(DEFAULT_BORDER_COLOR);
+ c.restore();
+ // Left
+ c.save();
+ c.clipRect(new Rect(0, 0, borderSize, height));
+ c.drawColor(DEFAULT_BORDER_COLOR);
+ c.restore();
+ // Right
+ c.save();
+ c.clipRect(new Rect(width - borderSize, 0, width, height));
+ c.drawColor(DEFAULT_BORDER_COLOR);
+ c.restore();
+ // Bottom
+ c.save();
+ c.clipRect(new Rect(0, height - borderSize, width, height));
+ c.drawColor(DEFAULT_BORDER_COLOR);
+ c.restore();
+
+ mTmpSurface.unlockCanvasAndPost(c);
+ }
+
+ @Override
+ public void onClick(View v) {
+ Point offset = findOffset(v);
+ moveMirrorForArrows(offset.x, offset.y);
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ mIsPressedDown = true;
+ Point point = findOffset(v);
+ mMoveMirrorRunnable.mXOffset = point.x;
+ mMoveMirrorRunnable.mYOffset = point.y;
+ mHandler.post(mMoveMirrorRunnable);
+ return false;
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mIsPressedDown = false;
+ break;
+ }
+ return false;
+ }
+
+ private Point findOffset(View v) {
+ Point offset = new Point(0, 0);
+
+ switch (v.getId()) {
+ case R.id.up_arrow:
+ offset.y = -MOVE_FRAME_AMOUNT;
+ break;
+ case R.id.down_arrow:
+ offset.y = MOVE_FRAME_AMOUNT;
+ break;
+ case R.id.right_arrow:
+ offset.x = -MOVE_FRAME_AMOUNT;
+ break;
+ case R.id.left_arrow:
+ offset.x = MOVE_FRAME_AMOUNT;
+ break;
+ }
+
+ return offset;
+ }
+
+ private void moveMirrorForArrows(int xOffset, int yOffset) {
+ mCurrFrame.offset(xOffset, yOffset);
+
+ updateMirror(mCurrFrame, mCurrScale);
+ }
+
+ /**
+ * Calculates the desired source bounds. This will be the area under from the center of the
+ * displayFrame, factoring in scale.
+ */
+ private Rect getSourceBounds(Rect displayFrame, float scale) {
+ int halfWidth = displayFrame.width() / 2;
+ int halfHeight = displayFrame.height() / 2;
+ int left = displayFrame.left + (halfWidth - (int) (halfWidth / scale));
+ int right = displayFrame.right - (halfWidth - (int) (halfWidth / scale));
+ int top = displayFrame.top + (halfHeight - (int) (halfHeight / scale));
+ int bottom = displayFrame.bottom - (halfHeight - (int) (halfHeight / scale));
+ return new Rect(left, top, right, bottom);
+ }
+
+ class MoveMirrorRunnable implements Runnable {
+ int mXOffset = 0;
+ int mYOffset = 0;
+
+ @Override
+ public void run() {
+ if (mIsPressedDown) {
+ moveMirrorForArrows(mXOffset, mYOffset);
+ mHandler.postDelayed(mMoveMirrorRunnable, 150);
+ }
+ }
+ }
+}
diff --git a/tests/net/java/android/net/netlink/InetDiagSocketTest.java b/tests/net/java/android/net/netlink/InetDiagSocketTest.java
index b4f6e99..46e27c1 100644
--- a/tests/net/java/android/net/netlink/InetDiagSocketTest.java
+++ b/tests/net/java/android/net/netlink/InetDiagSocketTest.java
@@ -45,6 +45,7 @@
import libcore.util.HexEncoding;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -200,6 +201,7 @@
checkGetConnectionOwnerUid("::1", "::1");
}
+ @Ignore("Times out on Marlin/Sailfish")
/* Verify fix for b/141603906 */
@Test
public void testB141603906() throws Exception {
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 9e21db7..41440ab 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -207,7 +207,7 @@
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.testutils.ExceptionUtils;
import com.android.testutils.HandlerUtilsKt;
-import com.android.testutils.RecorderCallback.CallbackRecord;
+import com.android.testutils.RecorderCallback.CallbackEntry;
import com.android.testutils.TestableNetworkCallback;
import org.junit.After;
@@ -258,13 +258,13 @@
private static final String TAG = "ConnectivityServiceTest";
private static final int TIMEOUT_MS = 500;
- private static final int TEST_LINGER_DELAY_MS = 250;
+ private static final int TEST_LINGER_DELAY_MS = 300;
// Chosen to be less than the linger timeout. This ensures that we can distinguish between a
// LOST callback that arrives immediately and a LOST callback that arrives after the linger
// timeout. For this, our assertions should run fast enough to leave less than
// (mService.mLingerDelayMs - TEST_CALLBACK_TIMEOUT_MS) between the time callbacks are
// supposedly fired, and the time we call expectCallback.
- private static final int TEST_CALLBACK_TIMEOUT_MS = 200;
+ private static final int TEST_CALLBACK_TIMEOUT_MS = 250;
// Chosen to be less than TEST_CALLBACK_TIMEOUT_MS. This ensures that requests have time to
// complete before callbacks are verified.
private static final int TEST_REQUEST_TIMEOUT_MS = 150;
@@ -1466,6 +1466,10 @@
* received. assertNoCallback may be called at any time.
*/
private class TestNetworkCallback extends TestableNetworkCallback {
+ TestNetworkCallback() {
+ super(TEST_CALLBACK_TIMEOUT_MS);
+ }
+
@Override
public void assertNoCallback() {
// TODO: better support this use case in TestableNetworkCallback
@@ -1474,12 +1478,12 @@
}
@Override
- public <T extends CallbackRecord> T expectCallback(final KClass<T> type, final HasNetwork n,
+ public <T extends CallbackEntry> T expectCallback(final KClass<T> type, final HasNetwork n,
final long timeoutMs) {
final T callback = super.expectCallback(type, n, timeoutMs);
- if (callback instanceof CallbackRecord.Losing) {
+ if (callback instanceof CallbackEntry.Losing) {
// TODO : move this to the specific test(s) needing this rather than here.
- final CallbackRecord.Losing losing = (CallbackRecord.Losing) callback;
+ final CallbackEntry.Losing losing = (CallbackEntry.Losing) callback;
final int maxMsToLive = losing.getMaxMsToLive();
String msg = String.format(
"Invalid linger time value %d, must be between %d and %d",
@@ -1540,16 +1544,16 @@
cv = waitForConnectivityBroadcasts(2);
mWiFiNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- wifiNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
cellNetworkCallback.assertNoCallback();
waitFor(cv);
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
cv = waitForConnectivityBroadcasts(1);
mCellNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
waitFor(cv);
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
@@ -1570,21 +1574,21 @@
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(true);
genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- genericNetworkCallback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ genericNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
genericNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
wifiNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
mWiFiNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- wifiNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
mCellNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
}
@@ -1624,7 +1628,7 @@
// We then get LOSING when wifi validates and cell is outscored.
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
// TODO: Investigate sending validated before losing.
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
@@ -1633,15 +1637,15 @@
mEthernetNetworkAgent.connect(true);
callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent);
// TODO: Investigate sending validated before losing.
- callback.expectCallback(CallbackRecord.LOSING, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
mEthernetNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
- defaultCallback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -1657,7 +1661,7 @@
newNetwork = mWiFiNetworkAgent;
}
- callback.expectCallback(CallbackRecord.LOSING, oldNetwork);
+ callback.expectCallback(CallbackEntry.LOSING, oldNetwork);
// TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no
// longer lingering?
defaultCallback.expectAvailableCallbacksValidated(newNetwork);
@@ -1671,7 +1675,7 @@
// We expect a notification about the capabilities change, and nothing else.
defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mWiFiNetworkAgent);
defaultCallback.assertNoCallback();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
// Wifi no longer satisfies our listen, which is for an unmetered network.
@@ -1680,11 +1684,11 @@
// Disconnect our test networks.
mWiFiNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
mCellNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
waitForIdle();
assertEquals(null, mCm.getActiveNetwork());
@@ -1715,8 +1719,8 @@
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -1727,15 +1731,15 @@
mWiFiNetworkAgent.adjustScore(50);
mWiFiNetworkAgent.connect(false); // Score: 70
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
// Tear down wifi.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -1746,19 +1750,19 @@
mWiFiNetworkAgent.connect(true);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
// TODO: Investigate sending validated before losing.
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
mCellNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
- defaultCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
waitForIdle();
assertEquals(null, mCm.getActiveNetwork());
@@ -1773,7 +1777,7 @@
defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
// TODO: Investigate sending validated before losing.
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -1784,13 +1788,13 @@
// TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer
// lingering?
mCm.unregisterNetworkCallback(noopCallback);
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
// Similar to the above: lingering can start even after the lingered request is removed.
// Disconnect wifi and switch to cell.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -1809,12 +1813,12 @@
callback.assertNoCallback();
// Now unregister cellRequest and expect cell to start lingering.
mCm.unregisterNetworkCallback(noopCallback);
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
// Let linger run its course.
callback.assertNoCallback();
final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4;
- callback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent, lingerTimeoutMs);
+ callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, lingerTimeoutMs);
// Register a TRACK_DEFAULT request and check that it does not affect lingering.
TestNetworkCallback trackDefaultCallback = new TestNetworkCallback();
@@ -1823,20 +1827,20 @@
mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET);
mEthernetNetworkAgent.connect(true);
callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent);
- callback.expectCallback(CallbackRecord.LOSING, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
// Let linger run its course.
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent, lingerTimeoutMs);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent, lingerTimeoutMs);
// Clean up.
mEthernetNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
- defaultCallback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
- trackDefaultCallback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+ trackDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
mCm.unregisterNetworkCallback(callback);
mCm.unregisterNetworkCallback(defaultCallback);
@@ -1866,7 +1870,7 @@
mWiFiNetworkAgent.connect(true);
defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
// File a request for cellular, then release it.
@@ -1875,7 +1879,7 @@
NetworkCallback noopCallback = new NetworkCallback();
mCm.requestNetwork(cellRequest, noopCallback);
mCm.unregisterNetworkCallback(noopCallback);
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
// Let linger run its course.
callback.assertNoCallback();
@@ -1919,12 +1923,12 @@
// If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to
// wifi even though it's unvalidated.
mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), true, false);
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
// Disconnect wifi, and then reconnect, again with explicitlySelected=true.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.explicitlySelected(true, false);
mWiFiNetworkAgent.connect(false);
@@ -1933,14 +1937,14 @@
// If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the
// network to disconnect.
mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), false, false);
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
// Reconnect, again with explicitlySelected=true, but this time validate.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.explicitlySelected(true, false);
mWiFiNetworkAgent.connect(true);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
@@ -1956,20 +1960,20 @@
// (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to
// wifi immediately.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.explicitlySelected(true, true);
mWiFiNetworkAgent.connect(false);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackRecord.LOSING, mEthernetNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mEthernetNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
mEthernetNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
// Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true.
// Check that the network is not scored specially and that the device prefers cell data.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.explicitlySelected(false, true);
mWiFiNetworkAgent.connect(false);
@@ -1980,8 +1984,8 @@
mWiFiNetworkAgent.disconnect();
mCellNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- callback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
}
private int[] makeIntArray(final int size, final int value) {
@@ -2228,7 +2232,7 @@
// Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
// validated.
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
NetworkCapabilities nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED,
mWiFiNetworkAgent);
assertTrue(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY));
@@ -2236,7 +2240,7 @@
// Disconnect and reconnect wifi with partial connectivity again.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connectWithPartialConnectivity();
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
@@ -2248,7 +2252,7 @@
// If the user chooses no, disconnect wifi immediately.
mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), false/* accept */,
false /* always */);
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
// If user accepted partial connectivity before, and device reconnects to that network
// again, but now the network has full connectivity. The network shouldn't contain
@@ -2264,14 +2268,14 @@
// ConnectivityService#updateNetworkInfo().
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY));
// Wifi should be the default network.
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
// The user accepted partial connectivity and selected "don't ask again". Now the user
// reconnects to the partial connectivity network. Switch to wifi as soon as partial
@@ -2285,7 +2289,7 @@
// ConnectivityService#updateNetworkInfo().
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent);
mWiFiNetworkAgent.setNetworkValid();
@@ -2295,7 +2299,7 @@
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
// If the user accepted partial connectivity, and the device auto-reconnects to the partial
// connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED.
@@ -2309,11 +2313,11 @@
mWiFiNetworkAgent.connectWithPartialValidConnectivity();
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
callback.expectCapabilitiesWith(
NET_CAPABILITY_PARTIAL_CONNECTIVITY | NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
}
@Test
@@ -2355,7 +2359,7 @@
false /* always */);
waitForIdle();
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
- captivePortalCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
NetworkCapabilities nc =
validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
@@ -2388,7 +2392,7 @@
// Take down network.
// Expect onLost callback.
mWiFiNetworkAgent.disconnect();
- captivePortalCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
// Bring up a network with a captive portal.
// Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
@@ -2402,7 +2406,7 @@
// Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
mWiFiNetworkAgent.setNetworkValid();
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
- captivePortalCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
// Expect NET_CAPABILITY_VALIDATED onAvailable callback.
validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
@@ -2414,7 +2418,7 @@
// Expect NET_CAPABILITY_VALIDATED onLost callback.
mWiFiNetworkAgent.setNetworkInvalid();
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
- validatedCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
}
@Test
@@ -2446,7 +2450,7 @@
mWiFiNetworkAgent.setNetworkPortal("http://example.com");
mCm.reportNetworkConnectivity(wifiNetwork, false);
captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- validatedCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
// Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
mCm.startCaptivePortalApp(wifiNetwork);
@@ -2467,7 +2471,7 @@
mWiFiNetworkAgent.setNetworkValid();
mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
- captivePortalCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
verify(mNotificationManager, times(1)).notifyAsUser(anyString(),
eq(NotificationType.LOGGED_IN.eventId), any(), eq(UserHandle.ALL));
@@ -2615,7 +2619,7 @@
cFoo.assertNoCallback();
mWiFiNetworkAgent.setNetworkSpecifier(nsBar);
- cFoo.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ cFoo.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
cBar.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
for (TestNetworkCallback c: emptyCallbacks) {
c.expectCapabilitiesThat(mWiFiNetworkAgent,
@@ -2643,10 +2647,10 @@
cBar.assertNoCallback();
mWiFiNetworkAgent.setNetworkSpecifier(null);
- cFoo.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- cBar.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ cFoo.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ cBar.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
for (TestNetworkCallback c: emptyCallbacks) {
- c.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, mWiFiNetworkAgent);
+ c.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mWiFiNetworkAgent);
}
assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar);
@@ -2789,7 +2793,7 @@
// Bring down cell. Expect no default network callback, since it wasn't the default.
mCellNetworkAgent.disconnect();
- cellNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
defaultNetworkCallback.assertNoCallback();
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -2804,11 +2808,11 @@
// followed by AVAILABLE cell.
mWiFiNetworkAgent.disconnect();
cellNetworkCallback.assertNoCallback();
- defaultNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
mCellNetworkAgent.disconnect();
- cellNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
- defaultNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
waitForIdle();
assertEquals(null, mCm.getActiveNetwork());
@@ -2825,7 +2829,7 @@
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
vpnNetworkAgent.disconnect();
- defaultNetworkCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
+ defaultNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent);
waitForIdle();
assertEquals(null, mCm.getActiveNetwork());
}
@@ -2853,7 +2857,7 @@
lp.setInterfaceName("foonet_data0");
mCellNetworkAgent.sendLinkProperties(lp);
// We should get onLinkPropertiesChanged().
- cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
+ cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
@@ -2861,7 +2865,7 @@
mCellNetworkAgent.suspend();
cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_SUSPENDED,
mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackRecord.SUSPENDED, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
// Register a garden variety default network request.
@@ -2876,7 +2880,7 @@
mCellNetworkAgent.resume();
cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_SUSPENDED,
mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackRecord.RESUMED, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.RESUMED, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
dfltNetworkCallback = new TestNetworkCallback();
@@ -2939,10 +2943,10 @@
// When wifi connects, cell lingers.
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
fgCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- fgCallback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ fgCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
fgCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
assertTrue(isForegroundNetwork(mCellNetworkAgent));
assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
@@ -2950,7 +2954,7 @@
// When lingering is complete, cell is still there but is now in the background.
waitForIdle();
int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4;
- fgCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent, timeoutMs);
+ fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, timeoutMs);
// Expect a network capabilities update sans FOREGROUND.
callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
assertFalse(isForegroundNetwork(mCellNetworkAgent));
@@ -2976,7 +2980,7 @@
// Release the request. The network immediately goes into the background, since it was not
// lingering.
mCm.unregisterNetworkCallback(cellCallback);
- fgCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
// Expect a network capabilities update sans FOREGROUND.
callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
assertFalse(isForegroundNetwork(mCellNetworkAgent));
@@ -2984,8 +2988,8 @@
// Disconnect wifi and check that cell is foreground again.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- fgCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ fgCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertTrue(isForegroundNetwork(mCellNetworkAgent));
@@ -3122,7 +3126,7 @@
testFactory.waitForNetworkRequests(1);
// ... and cell data to be torn down.
- cellNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
assertLength(1, mCm.getAllNetworks());
testFactory.unregister();
@@ -3211,7 +3215,7 @@
mWiFiNetworkAgent.setNetworkInvalid();
mCm.reportNetworkConnectivity(wifiNetwork, false);
defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
- validatedWifiCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
// Because avoid bad wifi is off, we don't switch to cellular.
defaultCallback.assertNoCallback();
@@ -3255,7 +3259,7 @@
mWiFiNetworkAgent.setNetworkInvalid();
mCm.reportNetworkConnectivity(wifiNetwork, false);
defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
- validatedWifiCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
// Simulate the user selecting "switch" and checking the don't ask again checkbox.
Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
@@ -3282,7 +3286,7 @@
// If cell goes down, we switch to wifi.
mCellNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
validatedWifiCallback.assertNoCallback();
@@ -3346,7 +3350,7 @@
networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false,
TEST_CALLBACK_TIMEOUT_MS);
mWiFiNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
// Validate that UNAVAILABLE is not called
networkCallback.assertNoCallback();
@@ -3366,7 +3370,7 @@
mCm.requestNetwork(nr, networkCallback, timeoutMs);
// pass timeout and validate that UNAVAILABLE is called
- networkCallback.expectCallback(CallbackRecord.UNAVAILABLE, null);
+ networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, null);
// create a network satisfying request - validate that request not triggered
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
@@ -3457,7 +3461,7 @@
// Simulate the factory releasing the request as unfulfillable and expect onUnavailable!
testFactory.triggerUnfulfillable(requests.get(newRequestId));
- networkCallback.expectCallback(CallbackRecord.UNAVAILABLE, null);
+ networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, null);
testFactory.waitForRequests();
// unregister network callback - a no-op (since already freed by the
@@ -4299,7 +4303,7 @@
// Disconnect wifi aware network.
wifiAware.disconnect();
- callback.expectCallbackThat(TIMEOUT_MS, (info) -> info instanceof CallbackRecord.Lost);
+ callback.expectCallbackThat(TIMEOUT_MS, (info) -> info instanceof CallbackEntry.Lost);
mCm.unregisterNetworkCallback(callback);
verifyNoNetwork();
@@ -4348,12 +4352,12 @@
// ConnectivityService.
TestNetworkAgentWrapper networkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp);
networkAgent.connect(true);
- networkCallback.expectCallback(CallbackRecord.AVAILABLE, networkAgent);
- networkCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, networkAgent);
- CallbackRecord.LinkPropertiesChanged cbi =
- networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
+ networkCallback.expectCallback(CallbackEntry.AVAILABLE, networkAgent);
+ networkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, networkAgent);
+ CallbackEntry.LinkPropertiesChanged cbi =
+ networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
networkAgent);
- networkCallback.expectCallback(CallbackRecord.BLOCKED_STATUS, networkAgent);
+ networkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, networkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent);
networkCallback.assertNoCallback();
checkDirectlyConnectedRoutes(cbi.getLp(), Arrays.asList(myIpv4Address),
@@ -4368,7 +4372,7 @@
newLp.addLinkAddress(myIpv6Address1);
newLp.addLinkAddress(myIpv6Address2);
networkAgent.sendLinkProperties(newLp);
- cbi = networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, networkAgent);
+ cbi = networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, networkAgent);
networkCallback.assertNoCallback();
checkDirectlyConnectedRoutes(cbi.getLp(),
Arrays.asList(myIpv4Address, myIpv6Address1, myIpv6Address2),
@@ -4574,12 +4578,12 @@
assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
new String[] { "2001:db8::1", "192.0.2.1" }));
reset(mMockDnsResolver);
- cellNetworkCallback.expectCallback(CallbackRecord.AVAILABLE, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED,
+ cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED,
mCellNetworkAgent);
- CallbackRecord.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback(
- CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackRecord.BLOCKED_STATUS, mCellNetworkAgent);
+ CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback(
+ CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertFalse(cbi.getLp().isPrivateDnsActive());
assertNull(cbi.getLp().getPrivateDnsServerName());
@@ -4610,7 +4614,7 @@
setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com");
// Can't test dns configuration for strict mode without properly mocking
// out the DNS lookups, but can test that LinkProperties is updated.
- cbi = cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
+ cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertTrue(cbi.getLp().isPrivateDnsActive());
@@ -4633,12 +4637,12 @@
mCellNetworkAgent.sendLinkProperties(lp);
mCellNetworkAgent.connect(false);
waitForIdle();
- cellNetworkCallback.expectCallback(CallbackRecord.AVAILABLE, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED,
+ cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED,
mCellNetworkAgent);
- CallbackRecord.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback(
- CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackRecord.BLOCKED_STATUS, mCellNetworkAgent);
+ CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback(
+ CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertFalse(cbi.getLp().isPrivateDnsActive());
assertNull(cbi.getLp().getPrivateDnsServerName());
@@ -4655,7 +4659,7 @@
LinkProperties lp2 = new LinkProperties(lp);
lp2.addDnsServer(InetAddress.getByName("145.100.185.16"));
mCellNetworkAgent.sendLinkProperties(lp2);
- cbi = cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
+ cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertFalse(cbi.getLp().isPrivateDnsActive());
@@ -4679,7 +4683,7 @@
// private dns fields should be sent.
mService.mNetdEventCallback.onPrivateDnsValidationEvent(
mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", true);
- cbi = cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
+ cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertTrue(cbi.getLp().isPrivateDnsActive());
@@ -4691,7 +4695,7 @@
LinkProperties lp3 = new LinkProperties(lp2);
lp3.setMtu(1300);
mCellNetworkAgent.sendLinkProperties(lp3);
- cbi = cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
+ cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertTrue(cbi.getLp().isPrivateDnsActive());
@@ -4704,7 +4708,7 @@
LinkProperties lp4 = new LinkProperties(lp3);
lp4.removeDnsServer(InetAddress.getByName("145.100.185.16"));
mCellNetworkAgent.sendLinkProperties(lp4);
- cbi = cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
+ cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertFalse(cbi.getLp().isPrivateDnsActive());
@@ -4795,19 +4799,19 @@
defaultCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
- genericNetworkCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
+ genericNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
genericNotVpnNetworkCallback.assertNoCallback();
vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, nc -> null == nc.getUids());
- defaultCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
ranges.clear();
vpnNetworkAgent.setUids(ranges);
- genericNetworkCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
+ genericNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent);
genericNotVpnNetworkCallback.assertNoCallback();
wifiNetworkCallback.assertNoCallback();
- vpnNetworkCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
+ vpnNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent);
// TODO : The default network callback should actually get a LOST call here (also see the
// comment below for AVAILABLE). This is because ConnectivityService does not look at UID
@@ -4815,7 +4819,7 @@
// can't currently update their UIDs without disconnecting, so this does not matter too
// much, but that is the reason the test here has to check for an update to the
// capabilities instead of the expected LOST then AVAILABLE.
- defaultCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
ranges.add(new UidRange(uid, uid));
mMockVpn.setUids(ranges);
@@ -4827,23 +4831,23 @@
vpnNetworkCallback.expectAvailableCallbacksValidated(vpnNetworkAgent);
// TODO : Here like above, AVAILABLE would be correct, but because this can't actually
// happen outside of the test, ConnectivityService does not rematch callbacks.
- defaultCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
mWiFiNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- genericNotVpnNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
- wifiNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ genericNotVpnNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
vpnNetworkCallback.assertNoCallback();
defaultCallback.assertNoCallback();
vpnNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
+ genericNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent);
genericNotVpnNetworkCallback.assertNoCallback();
wifiNetworkCallback.assertNoCallback();
- vpnNetworkCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
- defaultCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
+ vpnNetworkCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent);
assertEquals(null, mCm.getActiveNetwork());
mCm.unregisterNetworkCallback(genericNetworkCallback);
@@ -4909,7 +4913,7 @@
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
vpnNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent);
defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
mCm.unregisterNetworkCallback(defaultCallback);
@@ -4940,7 +4944,7 @@
// Even though the VPN is unvalidated, it becomes the default network for our app.
callback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
// TODO: this looks like a spurious callback.
- callback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
+ callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
callback.assertNoCallback();
assertTrue(vpnNetworkAgent.getScore() > mEthernetNetworkAgent.getScore());
@@ -4965,7 +4969,7 @@
callback.assertNoCallback();
vpnNetworkAgent.disconnect();
- callback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
+ callback.expectCallback(CallbackEntry.LOST, vpnNetworkAgent);
callback.expectAvailableCallbacksValidated(mEthernetNetworkAgent);
}
@@ -5407,7 +5411,7 @@
// Switch to METERED network. Restrict the use of the network.
mWiFiNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellNetworkAgent);
// Network becomes NOT_METERED.
@@ -5421,7 +5425,7 @@
defaultCallback.assertNoCallback();
mCellNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
defaultCallback.assertNoCallback();
mCm.unregisterNetworkCallback(defaultCallback);
@@ -5497,7 +5501,7 @@
// the NAT64 prefix was removed because one was never discovered.
cellLp.addLinkAddress(myIpv4);
mCellNetworkAgent.sendLinkProperties(cellLp);
- networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any());
@@ -5510,7 +5514,7 @@
cellLp.removeLinkAddress(myIpv4);
cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
mCellNetworkAgent.sendLinkProperties(cellLp);
- networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
// When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started.
@@ -5519,14 +5523,14 @@
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
kNat64PrefixString, 96);
LinkProperties lpBeforeClat = networkCallback.expectCallback(
- CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp();
+ CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp();
assertEquals(0, lpBeforeClat.getStackedLinks().size());
assertEquals(kNat64Prefix, lpBeforeClat.getNat64Prefix());
verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString());
// Clat iface comes up. Expect stacked link to be added.
clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true);
- networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellNetworkAgent.getNetwork())
.getStackedLinks();
assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0));
@@ -5534,7 +5538,7 @@
// Change trivial linkproperties and see if stacked link is preserved.
cellLp.addDnsServer(InetAddress.getByName("8.8.8.8"));
mCellNetworkAgent.sendLinkProperties(cellLp);
- networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
List<LinkProperties> stackedLpsAfterChange =
mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getStackedLinks();
@@ -5552,12 +5556,12 @@
cellLp.addLinkAddress(myIpv4);
cellLp.addRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
mCellNetworkAgent.sendLinkProperties(cellLp);
- networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
// As soon as stop is called, the linkproperties lose the stacked interface.
- networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork());
LinkProperties expected = new LinkProperties(cellLp);
expected.setNat64Prefix(kNat64Prefix);
@@ -5584,11 +5588,11 @@
cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8"));
mCellNetworkAgent.sendLinkProperties(cellLp);
- networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
kNat64PrefixString, 96);
- networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString());
@@ -5608,7 +5612,7 @@
// Clean up.
mCellNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
networkCallback.assertNoCallback();
mCm.unregisterNetworkCallback(networkCallback);
}
@@ -5640,7 +5644,7 @@
reset(mNetworkManagementService);
mWiFiNetworkAgent.connect(true);
networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- networkCallback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(),
eq(ConnectivityManager.TYPE_WIFI));
@@ -5649,7 +5653,7 @@
// Disconnect wifi and switch back to cell
reset(mNetworkManagementService);
mWiFiNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
assertNoCallbacks(networkCallback);
verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
@@ -5661,14 +5665,14 @@
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
mWiFiNetworkAgent.connect(true);
networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- networkCallback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
// Disconnect cell
reset(mNetworkManagementService);
reset(mMockNetd);
mCellNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
// LOST callback is triggered earlier than removing idle timer. Broadcast should also be
// sent as network being switched. Ensure rule removal for cell will not be triggered
// unexpectedly before network being removed.
@@ -5719,12 +5723,12 @@
LinkProperties lp = new LinkProperties();
lp.setTcpBufferSizes(testTcpBufferSizes);
mCellNetworkAgent.sendLinkProperties(lp);
- networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verifyTcpBufferSizeChange(testTcpBufferSizes);
// Clean up.
mCellNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+ networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
networkCallback.assertNoCallback();
mCm.unregisterNetworkCallback(networkCallback);
}
diff --git a/tools/codegen/src/com/android/codegen/ClassInfo.kt b/tools/codegen/src/com/android/codegen/ClassInfo.kt
index 5061be2..92da9da 100644
--- a/tools/codegen/src/com/android/codegen/ClassInfo.kt
+++ b/tools/codegen/src/com/android/codegen/ClassInfo.kt
@@ -38,6 +38,11 @@
val superInterfaces = (fileAst.types[0] as ClassOrInterfaceDeclaration)
.implementedTypes.map { it.asString() }
+ val superClass = run {
+ val superClasses = (fileAst.types[0] as ClassOrInterfaceDeclaration).extendedTypes
+ if (superClasses.isNonEmpty) superClasses[0] else null
+ }
+
val ClassName = classAst.nameAsString
private val genericArgsAst = classAst.typeParameters
val genericArgs = if (genericArgsAst.isEmpty()) "" else {
diff --git a/tools/codegen/src/com/android/codegen/ClassPrinter.kt b/tools/codegen/src/com/android/codegen/ClassPrinter.kt
index 1f0d4b8..bd72d9e 100644
--- a/tools/codegen/src/com/android/codegen/ClassPrinter.kt
+++ b/tools/codegen/src/com/android/codegen/ClassPrinter.kt
@@ -1,6 +1,7 @@
package com.android.codegen
import com.github.javaparser.ast.Modifier
+import com.github.javaparser.ast.body.CallableDeclaration
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
import com.github.javaparser.ast.body.TypeDeclaration
import com.github.javaparser.ast.expr.*
@@ -37,6 +38,7 @@
val GeneratedMember by lazy { classRef("com.android.internal.util.DataClass.Generated.Member") }
val Parcelling by lazy { classRef("com.android.internal.util.Parcelling") }
val Parcelable by lazy { classRef("android.os.Parcelable") }
+ val Parcel by lazy { classRef("android.os.Parcel") }
val UnsupportedAppUsage by lazy { classRef("android.annotation.UnsupportedAppUsage") }
init {
@@ -354,7 +356,9 @@
}
fun hasMethod(name: String, vararg argTypes: String): Boolean {
- return classAst.methods.any {
+ val members: List<CallableDeclaration<*>> =
+ if (name == ClassName) classAst.constructors else classAst.methods
+ return members.any {
it.name.asString() == name &&
it.parameters.map { it.type.asString() } == argTypes.toList()
}
@@ -365,6 +369,10 @@
.mapIndexed { i, node -> FieldInfo(index = i, fieldAst = node, classInfo = this) }
.filter { hasMethod("lazyInit${it.NameUpperCamel}") }
+ val extendsParcelableClass by lazy {
+ Parcelable !in superInterfaces && superClass != null
+ }
+
init {
val builderFactoryOverride = classAst.methods.find {
it.isStatic && it.nameAsString == "builder"
diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt
index 914e475..5a95676 100644
--- a/tools/codegen/src/com/android/codegen/Generators.kt
+++ b/tools/codegen/src/com/android/codegen/Generators.kt
@@ -341,7 +341,7 @@
}
}
- if (Type.contains("Map<")) {
+ if (FieldClass.endsWith("Map") && FieldInnerType != null) {
generateBuilderMethod(
name = adderName,
defVisibility = visibility,
@@ -422,6 +422,10 @@
+"// void parcelFieldName(Parcel dest, int flags) { ... }"
+""
+ if (extendsParcelableClass) {
+ +"super.writeToParcel(dest, flags);\n"
+ }
+
if (booleanFields.isNotEmpty() || nullableFields.isNotEmpty()) {
+"$flagStorageType flg = 0;"
booleanFields.forEachApply {
@@ -463,6 +467,123 @@
+""
}
+ if (!hasMethod(ClassName, Parcel)) {
+ val visibility = if (classAst.isFinal) "/* package-private */" else "protected"
+
+ +"/** @hide */"
+ +"@SuppressWarnings({\"unchecked\", \"RedundantCast\"})"
+ +GENERATED_MEMBER_HEADER
+ "$visibility $ClassName($Parcel in) {" {
+ +"// You can override field unparcelling by defining methods like:"
+ +"// static FieldType unparcelFieldName(Parcel in) { ... }"
+ +""
+
+ if (extendsParcelableClass) {
+ +"super(in);\n"
+ }
+
+ if (booleanFields.isNotEmpty() || nullableFields.isNotEmpty()) {
+ +"$flagStorageType flg = in.read$FlagStorageType();"
+ }
+ booleanFields.forEachApply {
+ +"$Type $_name = (flg & $fieldBit) != 0;"
+ }
+ nonBooleanFields.forEachApply {
+
+ // Handle customized parceling
+ val customParcellingMethod = "unparcel$NameUpperCamel"
+ if (hasMethod(customParcellingMethod, Parcel)) {
+ +"$Type $_name = $customParcellingMethod(in);"
+ } else if (customParcellingClass != null) {
+ +"$Type $_name = $sParcelling.unparcel(in);"
+ } else if (hasAnnotation("@$DataClassEnum")) {
+ val ordinal = "${_name}Ordinal"
+ +"int $ordinal = in.readInt();"
+ +"$Type $_name = $ordinal < 0 ? null : $FieldClass.values()[$ordinal];"
+ } else {
+ val methodArgs = mutableListOf<String>()
+
+ // Create container if any
+ val containerInitExpr = when {
+ FieldClass.endsWith("Map") -> "new $LinkedHashMap<>()"
+ FieldClass == "List" || FieldClass == "ArrayList" ->
+ "new ${classRef("java.util.ArrayList")}<>()"
+ else -> ""
+ }
+ val passContainer = containerInitExpr.isNotEmpty()
+
+ // nullcheck +
+ // "FieldType fieldName = (FieldType)"
+ if (passContainer) {
+ methodArgs.add(_name)
+ !"$Type $_name = "
+ if (mayBeNull) {
+ +"null;"
+ !"if ((flg & $fieldBit) != 0) {"
+ pushIndent()
+ +""
+ !"$_name = "
+ }
+ +"$containerInitExpr;"
+ } else {
+ !"$Type $_name = "
+ if (mayBeNull) !"(flg & $fieldBit) == 0 ? null : "
+ if (ParcelMethodsSuffix == "StrongInterface") {
+ !"$FieldClass.Stub.asInterface("
+ } else if (Type !in PRIMITIVE_TYPES + "String" + "Bundle" &&
+ (!isArray || FieldInnerType !in PRIMITIVE_TYPES + "String") &&
+ ParcelMethodsSuffix != "Parcelable") {
+ !"($FieldClass) "
+ }
+ }
+
+ // Determine method args
+ when {
+ ParcelMethodsSuffix == "Parcelable" ->
+ methodArgs += "$FieldClass.class.getClassLoader()"
+ ParcelMethodsSuffix == "SparseArray" ->
+ methodArgs += "$FieldInnerClass.class.getClassLoader()"
+ ParcelMethodsSuffix == "TypedObject" ->
+ methodArgs += "$FieldClass.CREATOR"
+ ParcelMethodsSuffix == "TypedArray" ->
+ methodArgs += "$FieldInnerClass.CREATOR"
+ ParcelMethodsSuffix == "Map" ->
+ methodArgs += "${fieldTypeGenegicArgs[1].substringBefore("<")}.class.getClassLoader()"
+ ParcelMethodsSuffix.startsWith("Parcelable")
+ || (isList || isArray)
+ && FieldInnerType !in PRIMITIVE_TYPES + "String" ->
+ methodArgs += "$FieldInnerClass.class.getClassLoader()"
+ }
+
+ // ...in.readFieldType(args...);
+ when {
+ ParcelMethodsSuffix == "StrongInterface" -> !"in.readStrongBinder"
+ isArray -> !"in.create$ParcelMethodsSuffix"
+ else -> !"in.read$ParcelMethodsSuffix"
+ }
+ !"(${methodArgs.joinToString(", ")})"
+ if (ParcelMethodsSuffix == "StrongInterface") !")"
+ +";"
+
+ // Cleanup if passContainer
+ if (passContainer && mayBeNull) {
+ popIndent()
+ rmEmptyLine()
+ +"\n}"
+ }
+ }
+ }
+
+ +""
+ fields.forEachApply {
+ !"this."
+ generateSetFrom(_name)
+ }
+
+ generateOnConstructedCallback()
+ }
+ }
+
if (classAst.fields.none { it.variables[0].nameAsString == "CREATOR" }) {
val Creator = classRef("android.os.Parcelable.Creator")
@@ -477,104 +598,8 @@
}
+"@Override"
- +"@SuppressWarnings({\"unchecked\", \"RedundantCast\"})"
"public $ClassName createFromParcel($Parcel in)" {
- +"// You can override field unparcelling by defining methods like:"
- +"// static FieldType unparcelFieldName(Parcel in) { ... }"
- +""
- if (booleanFields.isNotEmpty() || nullableFields.isNotEmpty()) {
- +"$flagStorageType flg = in.read$FlagStorageType();"
- }
- booleanFields.forEachApply {
- +"$Type $_name = (flg & $fieldBit) != 0;"
- }
- nonBooleanFields.forEachApply {
-
- // Handle customized parceling
- val customParcellingMethod = "unparcel$NameUpperCamel"
- if (hasMethod(customParcellingMethod, Parcel)) {
- +"$Type $_name = $customParcellingMethod(in);"
- } else if (customParcellingClass != null) {
- +"$Type $_name = $sParcelling.unparcel(in);"
- } else if (hasAnnotation("@$DataClassEnum")) {
- val ordinal = "${_name}Ordinal"
- +"int $ordinal = in.readInt();"
- +"$Type $_name = $ordinal < 0 ? null : $FieldClass.values()[$ordinal];"
- } else {
- val methodArgs = mutableListOf<String>()
-
- // Create container if any
- val containerInitExpr = when {
- FieldClass.endsWith("Map") -> "new $LinkedHashMap<>()"
- FieldClass == "List" || FieldClass == "ArrayList" ->
- "new ${classRef("java.util.ArrayList")}<>()"
- else -> ""
- }
- val passContainer = containerInitExpr.isNotEmpty()
-
- // nullcheck +
- // "FieldType fieldName = (FieldType)"
- if (passContainer) {
- methodArgs.add(_name)
- !"$Type $_name = "
- if (mayBeNull) {
- +"null;"
- !"if ((flg & $fieldBit) != 0) {"
- pushIndent()
- +""
- !"$_name = "
- }
- +"$containerInitExpr;"
- } else {
- !"$Type $_name = "
- if (mayBeNull) !"(flg & $fieldBit) == 0 ? null : "
- if (ParcelMethodsSuffix == "StrongInterface") {
- !"$FieldClass.Stub.asInterface("
- } else if (Type !in PRIMITIVE_TYPES + "String" + "Bundle" &&
- (!isArray || FieldInnerType !in PRIMITIVE_TYPES + "String") &&
- ParcelMethodsSuffix != "Parcelable") {
- !"($Type) "
- }
- }
-
- // Determine method args
- when {
- ParcelMethodsSuffix == "Parcelable" ->
- methodArgs += "$FieldClass.class.getClassLoader()"
- ParcelMethodsSuffix == "TypedObject" ->
- methodArgs += "$FieldClass.CREATOR"
- ParcelMethodsSuffix == "TypedArray" ->
- methodArgs += "$FieldInnerClass.CREATOR"
- ParcelMethodsSuffix.startsWith("Parcelable")
- || FieldClass == "Map"
- || (isList || isArray)
- && FieldInnerType !in PRIMITIVE_TYPES + "String" ->
- methodArgs += "$FieldInnerClass.class.getClassLoader()"
- }
-
- // ...in.readFieldType(args...);
- when {
- ParcelMethodsSuffix == "StrongInterface" -> !"in.readStrongBinder"
- isArray -> !"in.create$ParcelMethodsSuffix"
- else -> !"in.read$ParcelMethodsSuffix"
- }
- !"(${methodArgs.joinToString(", ")})"
- if (ParcelMethodsSuffix == "StrongInterface") !")"
- +";"
-
- // Cleanup if passContainer
- if (passContainer && mayBeNull) {
- popIndent()
- rmEmptyLine()
- +"\n}"
- }
- }
- }
- "return new $ClassType(" {
- fields.forEachTrimmingTrailingComma {
- +"$_name,"
- }
- } + ";"
+ +"return new $ClassName(in);"
}
rmEmptyLine()
} + ";"
diff --git a/tools/codegen/src/com/android/codegen/Main.kt b/tools/codegen/src/com/android/codegen/Main.kt
index ad5bb9e..039f7b2 100755
--- a/tools/codegen/src/com/android/codegen/Main.kt
+++ b/tools/codegen/src/com/android/codegen/Main.kt
@@ -95,7 +95,13 @@
you can use with final fields.
Version: $CODEGEN_VERSION
-Questions? Feedback? Contact: eugenesusla@
+
+Questions? Feedback?
+Contact: eugenesusla@
+Bug/feature request: http://go/codegen-bug
+
+Slides: http://go/android-codegen
+In-depth example: http://go/SampleDataClass
"""
fun main(args: Array<String>) {
@@ -136,7 +142,7 @@
//
// To regenerate run:
// $ $cliExecutable ${cliArgs.dropLast(1).joinToString("") { "$it " }}$fileEscaped
- /
+
"""
if (FeatureFlag.CONST_DEFS()) generateConstDefs()
@@ -146,8 +152,7 @@
generateConstructor("public")
} else if (FeatureFlag.BUILDER()
|| FeatureFlag.COPY_CONSTRUCTOR()
- || FeatureFlag.WITHERS()
- || FeatureFlag.PARCELABLE()) {
+ || FeatureFlag.WITHERS()) {
generateConstructor("/* package-private */")
}
if (FeatureFlag.COPY_CONSTRUCTOR()) generateCopyConstructor()
diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt
index b2cc813..a36f2c8 100644
--- a/tools/codegen/src/com/android/codegen/SharedConstants.kt
+++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt
@@ -1,7 +1,7 @@
package com.android.codegen
const val CODEGEN_NAME = "codegen"
-const val CODEGEN_VERSION = "1.0.1"
+const val CODEGEN_VERSION = "1.0.5"
const val CANONICAL_BUILDER_CLASS = "Builder"
const val BASE_BUILDER_CLASS = "BaseBuilder"
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 97f3de2..70ac0be 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -50,14 +50,19 @@
command.javaSourceArgs.forEach { path ->
val file = File(path)
val text = file.readText()
- val code = tryParse(text, path)
- val pack = if (code.packageDeclaration.isPresent) code.packageDeclaration
- .get().nameAsString else ""
- val newPath = pack.replace('.', '/') + '/' + file.name
- val outSrc = when {
- containsProtoLogText(text, command.protoLogClassNameArg) ->
+ val newPath = path
+ val outSrc = try {
+ val code = tryParse(text, path)
+ if (containsProtoLogText(text, command.protoLogClassNameArg)) {
transformer.processClass(text, newPath, code)
- else -> text
+ } else {
+ text
+ }
+ } catch (ex: ParsingException) {
+ // If we cannot parse this file, skip it (and log why). Compilation will fail
+ // in a subsequent build step.
+ println("\n${ex.message}\n")
+ text
}
outJar.putNextEntry(ZipEntry(newPath))
outJar.write(outSrc.toByteArray())
@@ -91,11 +96,17 @@
val file = File(path)
val text = file.readText()
if (containsProtoLogText(text, command.protoLogClassNameArg)) {
- val code = tryParse(text, path)
- val pack = if (code.packageDeclaration.isPresent) code.packageDeclaration
- .get().nameAsString else ""
- val newPath = pack.replace('.', '/') + '/' + file.name
- builder.processClass(code, newPath)
+ try {
+ val code = tryParse(text, path)
+ val pack = if (code.packageDeclaration.isPresent) code.packageDeclaration
+ .get().nameAsString else ""
+ val newPath = pack.replace('.', '/') + '/' + file.name
+ builder.processClass(code, newPath)
+ } catch (ex: ParsingException) {
+ // If we cannot parse this file, skip it (and log why). Compilation will fail
+ // in a subsequent build step.
+ println("\n${ex.message}\n")
+ }
}
}
val out = FileOutputStream(command.viewerConfigJsonArg)
diff --git a/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
new file mode 100644
index 0000000..b83b594
--- /dev/null
+++ b/wifi/java/android/net/wifi/ILocalOnlyHotspotCallback.aidl
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2019, 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 android.net.wifi;
+
+import android.net.wifi.WifiConfiguration;
+
+/**
+ * Communicates LOHS status back to the application process.
+ *
+ * @hide
+ */
+oneway interface ILocalOnlyHotspotCallback {
+ void onHotspotStarted(in WifiConfiguration config);
+ void onHotspotStopped();
+ void onHotspotFailed(int reason);
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index a97a5a5..b7e1094 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -26,6 +26,7 @@
import android.net.Network;
import android.net.wifi.IActionListener;
import android.net.wifi.IDppCallback;
+import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.ISoftApCallback;
import android.net.wifi.ITrafficStateCallback;
@@ -138,11 +139,11 @@
boolean stopSoftAp();
- int startLocalOnlyHotspot(in Messenger messenger, in IBinder binder, String packageName);
+ int startLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback, String packageName);
void stopLocalOnlyHotspot();
- void startWatchLocalOnlyHotspot(in Messenger messenger, in IBinder binder);
+ void startWatchLocalOnlyHotspot(in ILocalOnlyHotspotCallback callback);
void stopWatchLocalOnlyHotspot();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 00895e8..5782f5b 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -45,10 +45,9 @@
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.WorkSource;
@@ -1127,16 +1126,6 @@
private Looper mLooper;
private boolean mVerboseLoggingEnabled = false;
- /* LocalOnlyHotspot callback message types */
- /** @hide */
- public static final int HOTSPOT_STARTED = 0;
- /** @hide */
- public static final int HOTSPOT_STOPPED = 1;
- /** @hide */
- public static final int HOTSPOT_FAILED = 2;
- /** @hide */
- public static final int HOTSPOT_OBSERVER_REGISTERED = 3;
-
private final Object mLock = new Object(); // lock guarding access to the following vars
@GuardedBy("mLock")
private LocalOnlyHotspotCallbackProxy mLOHSCallbackProxy;
@@ -2730,6 +2719,13 @@
}
}
+ private Executor executorForHandler(@Nullable Handler handler) {
+ if (handler == null) {
+ return mContext.getMainExecutor();
+ }
+ return new HandlerExecutor(handler);
+ }
+
/**
* Request a local only hotspot that an application can use to communicate between co-located
* devices connected to the created WiFi hotspot. The network created by this method will not
@@ -2787,21 +2783,20 @@
*/
public void startLocalOnlyHotspot(LocalOnlyHotspotCallback callback,
@Nullable Handler handler) {
+ Executor executor = executorForHandler(handler);
synchronized (mLock) {
- Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
LocalOnlyHotspotCallbackProxy proxy =
- new LocalOnlyHotspotCallbackProxy(this, looper, callback);
+ new LocalOnlyHotspotCallbackProxy(this, executor, callback);
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
throw new RemoteException("Wifi service is not running");
}
String packageName = mContext.getOpPackageName();
- int returnCode = iWifiManager.startLocalOnlyHotspot(
- proxy.getMessenger(), new Binder(), packageName);
+ int returnCode = iWifiManager.startLocalOnlyHotspot(proxy, packageName);
if (returnCode != LocalOnlyHotspotCallback.REQUEST_REGISTERED) {
// Send message to the proxy to make sure we call back on the correct thread
- proxy.notifyFailed(returnCode);
+ proxy.onHotspotFailed(returnCode);
return;
}
mLOHSCallbackProxy = proxy;
@@ -2879,16 +2874,16 @@
*/
public void watchLocalOnlyHotspot(LocalOnlyHotspotObserver observer,
@Nullable Handler handler) {
+ Executor executor = executorForHandler(handler);
synchronized (mLock) {
- Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
- mLOHSObserverProxy = new LocalOnlyHotspotObserverProxy(this, looper, observer);
+ mLOHSObserverProxy =
+ new LocalOnlyHotspotObserverProxy(this, executor, observer);
try {
IWifiManager iWifiManager = getIWifiManager();
if (iWifiManager == null) {
throw new RemoteException("Wifi service is not running");
}
- iWifiManager.startWatchLocalOnlyHotspot(
- mLOHSObserverProxy.getMessenger(), new Binder());
+ iWifiManager.startWatchLocalOnlyHotspot(mLOHSObserverProxy);
mLOHSObserverProxy.registered();
} catch (RemoteException e) {
mLOHSObserverProxy = null;
@@ -3446,82 +3441,58 @@
/**
* Callback proxy for LocalOnlyHotspotCallback objects.
*/
- private static class LocalOnlyHotspotCallbackProxy {
- private final Handler mHandler;
+ private static class LocalOnlyHotspotCallbackProxy extends ILocalOnlyHotspotCallback.Stub {
private final WeakReference<WifiManager> mWifiManager;
- private final Looper mLooper;
- private final Messenger mMessenger;
+ private final Executor mExecutor;
+ private final LocalOnlyHotspotCallback mCallback;
/**
- * Constructs a {@link LocalOnlyHotspotCallback} using the specified looper. All callbacks
- * will be delivered on the thread of the specified looper.
+ * Constructs a {@link LocalOnlyHotspotCallbackProxy} using the specified executor. All
+ * callbacks will run using the given executor.
*
* @param manager WifiManager
- * @param looper Looper for delivering callbacks
+ * @param executor Executor for delivering callbacks.
* @param callback LocalOnlyHotspotCallback to notify the calling application.
*/
- LocalOnlyHotspotCallbackProxy(WifiManager manager, Looper looper,
- final LocalOnlyHotspotCallback callback) {
+ LocalOnlyHotspotCallbackProxy(WifiManager manager, Executor executor,
+ LocalOnlyHotspotCallback callback) {
mWifiManager = new WeakReference<>(manager);
- mLooper = looper;
-
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- Log.d(TAG, "LocalOnlyHotspotCallbackProxy: handle message what: "
- + msg.what + " msg: " + msg);
-
- WifiManager manager = mWifiManager.get();
- if (manager == null) {
- Log.w(TAG, "LocalOnlyHotspotCallbackProxy: handle message post GC");
- return;
- }
-
- switch (msg.what) {
- case HOTSPOT_STARTED:
- WifiConfiguration config = (WifiConfiguration) msg.obj;
- if (config == null) {
- Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null.");
- callback.onFailed(LocalOnlyHotspotCallback.ERROR_GENERIC);
- return;
- }
- callback.onStarted(manager.new LocalOnlyHotspotReservation(config));
- break;
- case HOTSPOT_STOPPED:
- Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped");
- callback.onStopped();
- break;
- case HOTSPOT_FAILED:
- int reasonCode = msg.arg1;
- Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: "
- + reasonCode);
- callback.onFailed(reasonCode);
- Log.w(TAG, "done with the callback...");
- break;
- default:
- Log.e(TAG, "LocalOnlyHotspotCallbackProxy unhandled message. type: "
- + msg.what);
- }
- }
- };
- mMessenger = new Messenger(mHandler);
+ mExecutor = executor;
+ mCallback = callback;
}
- public Messenger getMessenger() {
- return mMessenger;
+ @Override
+ public void onHotspotStarted(WifiConfiguration config) {
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ if (config == null) {
+ Log.e(TAG, "LocalOnlyHotspotCallbackProxy: config cannot be null.");
+ onHotspotFailed(LocalOnlyHotspotCallback.ERROR_GENERIC);
+ return;
+ }
+ final LocalOnlyHotspotReservation reservation =
+ manager.new LocalOnlyHotspotReservation(config);
+ mExecutor.execute(() -> mCallback.onStarted(reservation));
}
- /**
- * Helper method allowing the the incoming application call to move the onFailed callback
- * over to the desired callback thread.
- *
- * @param reason int representing the error type
- */
- public void notifyFailed(int reason) throws RemoteException {
- Message msg = Message.obtain();
- msg.what = HOTSPOT_FAILED;
- msg.arg1 = reason;
- mMessenger.send(msg);
+ @Override
+ public void onHotspotStopped() {
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ Log.w(TAG, "LocalOnlyHotspotCallbackProxy: hotspot stopped");
+ mExecutor.execute(() -> mCallback.onStopped());
+ }
+
+ @Override
+ public void onHotspotFailed(int reason) {
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ Log.w(TAG, "LocalOnlyHotspotCallbackProxy: failed to start. reason: "
+ + reason);
+ mExecutor.execute(() -> mCallback.onFailed(reason));
}
}
@@ -3589,69 +3560,57 @@
/**
* Callback proxy for LocalOnlyHotspotObserver objects.
*/
- private static class LocalOnlyHotspotObserverProxy {
- private final Handler mHandler;
+ private static class LocalOnlyHotspotObserverProxy extends ILocalOnlyHotspotCallback.Stub {
private final WeakReference<WifiManager> mWifiManager;
- private final Looper mLooper;
- private final Messenger mMessenger;
+ private final Executor mExecutor;
+ private final LocalOnlyHotspotObserver mObserver;
/**
* Constructs a {@link LocalOnlyHotspotObserverProxy} using the specified looper.
* All callbacks will be delivered on the thread of the specified looper.
*
* @param manager WifiManager
- * @param looper Looper for delivering callbacks
+ * @param executor Executor for delivering callbacks
* @param observer LocalOnlyHotspotObserver to notify the calling application.
*/
- LocalOnlyHotspotObserverProxy(WifiManager manager, Looper looper,
+ LocalOnlyHotspotObserverProxy(WifiManager manager, Executor executor,
final LocalOnlyHotspotObserver observer) {
mWifiManager = new WeakReference<>(manager);
- mLooper = looper;
-
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- Log.d(TAG, "LocalOnlyHotspotObserverProxy: handle message what: "
- + msg.what + " msg: " + msg);
-
- WifiManager manager = mWifiManager.get();
- if (manager == null) {
- Log.w(TAG, "LocalOnlyHotspotObserverProxy: handle message post GC");
- return;
- }
-
- switch (msg.what) {
- case HOTSPOT_OBSERVER_REGISTERED:
- observer.onRegistered(manager.new LocalOnlyHotspotSubscription());
- break;
- case HOTSPOT_STARTED:
- WifiConfiguration config = (WifiConfiguration) msg.obj;
- if (config == null) {
- Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null.");
- return;
- }
- observer.onStarted(config);
- break;
- case HOTSPOT_STOPPED:
- observer.onStopped();
- break;
- default:
- Log.e(TAG, "LocalOnlyHotspotObserverProxy unhandled message. type: "
- + msg.what);
- }
- }
- };
- mMessenger = new Messenger(mHandler);
- }
-
- public Messenger getMessenger() {
- return mMessenger;
+ mExecutor = executor;
+ mObserver = observer;
}
public void registered() throws RemoteException {
- Message msg = Message.obtain();
- msg.what = HOTSPOT_OBSERVER_REGISTERED;
- mMessenger.send(msg);
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ mExecutor.execute(() ->
+ mObserver.onRegistered(manager.new LocalOnlyHotspotSubscription()));
+ }
+
+ @Override
+ public void onHotspotStarted(WifiConfiguration config) {
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ if (config == null) {
+ Log.e(TAG, "LocalOnlyHotspotObserverProxy: config cannot be null.");
+ return;
+ }
+ mExecutor.execute(() -> mObserver.onStarted(config));
+ }
+
+ @Override
+ public void onHotspotStopped() {
+ WifiManager manager = mWifiManager.get();
+ if (manager == null) return;
+
+ mExecutor.execute(() -> mObserver.onStopped());
+ }
+
+ @Override
+ public void onHotspotFailed(int reason) {
+ // do nothing
}
}
diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
index e595164..8f3635f 100644
--- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
+++ b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
@@ -20,8 +20,8 @@
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import android.telephony.TelephonyManager.NetworkType;
+import android.telephony.Annotation.NetworkType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java
index 2e82f4e..4ca2a16 100644
--- a/wifi/java/com/android/server/wifi/BaseWifiService.java
+++ b/wifi/java/com/android/server/wifi/BaseWifiService.java
@@ -23,6 +23,7 @@
import android.net.Network;
import android.net.wifi.IActionListener;
import android.net.wifi.IDppCallback;
+import android.net.wifi.ILocalOnlyHotspotCallback;
import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.IOnWifiUsabilityStatsListener;
import android.net.wifi.ISoftApCallback;
@@ -205,11 +206,6 @@
throw new UnsupportedOperationException();
}
- /** @removed */
- public void setCountryCode(String country) {
- throw new UnsupportedOperationException();
- }
-
@Override
public String getCountryCode() {
throw new UnsupportedOperationException();
@@ -285,22 +281,34 @@
throw new UnsupportedOperationException();
}
- @Override
+ /** @deprecated replaced by {@link #startLocalOnlyHotspot(ILocalOnlyHotspotCallback, String)} */
+ @Deprecated
public int startLocalOnlyHotspot(Messenger messenger, IBinder binder, String packageName) {
throw new UnsupportedOperationException();
}
@Override
+ public int startLocalOnlyHotspot(ILocalOnlyHotspotCallback callback, String packageName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public void stopLocalOnlyHotspot() {
throw new UnsupportedOperationException();
}
- @Override
+ /** @deprecated replaced by {@link #startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback)} */
+ @Deprecated
public void startWatchLocalOnlyHotspot(Messenger messenger, IBinder binder) {
throw new UnsupportedOperationException();
}
@Override
+ public void startWatchLocalOnlyHotspot(ILocalOnlyHotspotCallback callback) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public void stopWatchLocalOnlyHotspot() {
throw new UnsupportedOperationException();
}
@@ -325,11 +333,6 @@
throw new UnsupportedOperationException();
}
- /** @removed */
- public Messenger getWifiServiceMessenger(String packageName) {
- throw new UnsupportedOperationException();
- }
-
@Override
public void enableTdls(String remoteIPAddress, boolean enable) {
throw new UnsupportedOperationException();
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 7e7f002..885139b 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -16,9 +16,6 @@
package android.net.wifi;
-import static android.net.wifi.WifiManager.HOTSPOT_FAILED;
-import static android.net.wifi.WifiManager.HOTSPOT_STARTED;
-import static android.net.wifi.WifiManager.HOTSPOT_STOPPED;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
@@ -68,8 +65,6 @@
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
import android.os.RemoteException;
import android.os.test.TestLooper;
@@ -117,8 +112,6 @@
private Handler mHandler;
private TestLooper mLooper;
private WifiManager mWifiManager;
- private Messenger mWifiServiceMessenger;
- final ArgumentCaptor<Messenger> mMessengerCaptor = ArgumentCaptor.forClass(Messenger.class);
@Before public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -128,7 +121,6 @@
when(mContext.getApplicationInfo()).thenReturn(mApplicationInfo);
when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
- mWifiServiceMessenger = new Messenger(mHandler);
mWifiManager = new WifiManager(mContext, mWifiService, mLooper.getLooper());
verify(mWifiService).getVerboseLoggingLevel();
}
@@ -178,7 +170,7 @@
@Test
public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
@@ -196,7 +188,7 @@
public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
@@ -357,7 +349,7 @@
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
verify(mWifiService)
- .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
+ .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString());
}
/**
@@ -368,7 +360,7 @@
public void testStartLocalOnlyHotspotThrowsSecurityException() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
doThrow(new SecurityException()).when(mWifiService)
- .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
+ .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString());
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
}
@@ -380,7 +372,7 @@
public void testStartLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
doThrow(new IllegalStateException()).when(mWifiService)
- .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
+ .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString());
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
}
@@ -390,12 +382,13 @@
@Test
public void testCorrectLooperIsUsedForHandler() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
verify(mContext, never()).getMainLooper();
+ verify(mContext, never()).getMainExecutor();
}
/**
@@ -406,15 +399,15 @@
public void testMainLooperIsUsedWhenHandlerNotProvided() throws Exception {
// record thread from looper.getThread and check ids.
TestLooper altLooper = new TestLooper();
- when(mContext.getMainLooper()).thenReturn(altLooper.getLooper());
+ when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor());
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
mWifiManager.startLocalOnlyHotspot(callback, null);
altLooper.dispatchAll();
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
- verify(mContext).getMainLooper();
+ verify(mContext).getMainExecutor();
}
/**
@@ -426,18 +419,17 @@
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
TestLooper callbackLooper = new TestLooper();
Handler callbackHandler = new Handler(callbackLooper.getLooper());
- when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
+ ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
+ ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
+ when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString()))
+ .thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
callbackLooper.dispatchAll();
mLooper.dispatchAll();
assertFalse(callback.mOnStartedCalled);
assertEquals(null, callback.mRes);
// now trigger the callback
- Message msg = new Message();
- msg.what = HOTSPOT_STARTED;
- msg.obj = mApConfig;
- mMessengerCaptor.getValue().send(msg);
+ internalCallback.getValue().onHotspotStarted(mApConfig);
mLooper.dispatchAll();
callbackLooper.dispatchAll();
assertTrue(callback.mOnStartedCalled);
@@ -453,17 +445,17 @@
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
TestLooper callbackLooper = new TestLooper();
Handler callbackHandler = new Handler(callbackLooper.getLooper());
- when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
+ ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
+ ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
+ when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString()))
+ .thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
callbackLooper.dispatchAll();
mLooper.dispatchAll();
assertFalse(callback.mOnStartedCalled);
assertEquals(null, callback.mRes);
// now trigger the callback
- Message msg = new Message();
- msg.what = HOTSPOT_STARTED;
- mMessengerCaptor.getValue().send(msg);
+ internalCallback.getValue().onHotspotStarted(null);
mLooper.dispatchAll();
callbackLooper.dispatchAll();
assertFalse(callback.mOnStartedCalled);
@@ -478,16 +470,16 @@
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
TestLooper callbackLooper = new TestLooper();
Handler callbackHandler = new Handler(callbackLooper.getLooper());
- when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
+ ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
+ ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
+ when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString()))
+ .thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
callbackLooper.dispatchAll();
mLooper.dispatchAll();
assertFalse(callback.mOnStoppedCalled);
// now trigger the callback
- Message msg = new Message();
- msg.what = HOTSPOT_STOPPED;
- mMessengerCaptor.getValue().send(msg);
+ internalCallback.getValue().onHotspotStopped();
mLooper.dispatchAll();
callbackLooper.dispatchAll();
assertTrue(callback.mOnStoppedCalled);
@@ -501,17 +493,16 @@
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
TestLooper callbackLooper = new TestLooper();
Handler callbackHandler = new Handler(callbackLooper.getLooper());
- when(mWifiService.startLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class), anyString())).thenReturn(REQUEST_REGISTERED);
+ ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
+ ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
+ when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString()))
+ .thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
callbackLooper.dispatchAll();
mLooper.dispatchAll();
assertEquals(ERROR_NOT_SET, callback.mFailureReason);
// now trigger the callback
- Message msg = new Message();
- msg.what = HOTSPOT_FAILED;
- msg.arg1 = ERROR_NO_CHANNEL;
- mMessengerCaptor.getValue().send(msg);
+ internalCallback.getValue().onHotspotFailed(ERROR_NO_CHANNEL);
mLooper.dispatchAll();
callbackLooper.dispatchAll();
assertEquals(ERROR_NO_CHANNEL, callback.mFailureReason);
@@ -523,7 +514,7 @@
@Test
public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
@@ -539,7 +530,7 @@
@Test
public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
anyString())).thenReturn(ERROR_TETHERING_DISALLOWED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
@@ -557,7 +548,7 @@
public void testLocalOnlyHotspotCallbackFullOnSecurityException() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
doThrow(new SecurityException()).when(mWifiService)
- .startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class), anyString());
+ .startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString());
try {
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
} catch (SecurityException e) {
@@ -577,7 +568,7 @@
@Test
public void testLocalOnlyHotspotCallbackFullOnNoChannelError() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
@@ -593,7 +584,7 @@
@Test
public void testCancelLocalOnlyHotspotRequestCallsStopOnWifiService() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mWifiManager.cancelLocalOnlyHotspotRequest();
@@ -615,7 +606,7 @@
@Test
public void testCallbackAfterLocalOnlyHotspotWasCancelled() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
anyString())).thenReturn(REQUEST_REGISTERED);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mWifiManager.cancelLocalOnlyHotspotRequest();
@@ -634,7 +625,7 @@
@Test
public void testCancelAfterLocalOnlyHotspotCallbackTriggered() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
- when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class),
+ when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class),
anyString())).thenReturn(ERROR_INCOMPATIBLE_MODE);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
@@ -654,7 +645,7 @@
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
- verify(mWifiService).startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+ verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
}
/**
@@ -665,7 +656,7 @@
public void testStartWatchLocalOnlyHotspotThrowsSecurityException() throws Exception {
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
doThrow(new SecurityException()).when(mWifiService)
- .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+ .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
}
@@ -677,7 +668,7 @@
public void testStartWatchLocalOnlyHotspotThrowsIllegalStateException() throws Exception {
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
doThrow(new IllegalStateException()).when(mWifiService)
- .startWatchLocalOnlyHotspot(any(Messenger.class), any(IBinder.class));
+ .startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
}
@@ -822,6 +813,7 @@
verify(mWifiService).registerSoftApCallback(any(IBinder.class),
any(ISoftApCallback.Stub.class), anyInt());
verify(mContext, never()).getMainLooper();
+ verify(mContext, never()).getMainExecutor();
}
/**
@@ -834,6 +826,7 @@
mLooper.dispatchAll();
assertTrue(observer.mOnRegistered);
verify(mContext, never()).getMainLooper();
+ verify(mContext, never()).getMainExecutor();
}
/**
@@ -844,13 +837,13 @@
public void testMainLooperIsUsedWhenHandlerNotProvidedForObserver() throws Exception {
// record thread from looper.getThread and check ids.
TestLooper altLooper = new TestLooper();
- when(mContext.getMainLooper()).thenReturn(altLooper.getLooper());
+ when(mContext.getMainExecutor()).thenReturn(altLooper.getNewExecutor());
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
mWifiManager.watchLocalOnlyHotspot(observer, null);
altLooper.dispatchAll();
assertTrue(observer.mOnRegistered);
assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
- verify(mContext).getMainLooper();
+ verify(mContext).getMainExecutor();
}
/**
@@ -865,8 +858,7 @@
assertFalse(observer.mOnRegistered);
assertEquals(null, observer.mSub);
mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
- verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class));
+ verify(mWifiService).startWatchLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class));
// now trigger the callback
observerLooper.dispatchAll();
mLooper.dispatchAll();
@@ -884,16 +876,14 @@
TestLooper observerLooper = new TestLooper();
Handler observerHandler = new Handler(observerLooper.getLooper());
mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
- verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class));
+ ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
+ ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
+ verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
observerLooper.dispatchAll();
mLooper.dispatchAll();
assertFalse(observer.mOnStartedCalled);
// now trigger the callback
- Message msg = new Message();
- msg.what = HOTSPOT_STARTED;
- msg.obj = mApConfig;
- mMessengerCaptor.getValue().send(msg);
+ internalCallback.getValue().onHotspotStarted(mApConfig);
mLooper.dispatchAll();
observerLooper.dispatchAll();
assertTrue(observer.mOnStartedCalled);
@@ -910,15 +900,14 @@
TestLooper observerLooper = new TestLooper();
Handler observerHandler = new Handler(observerLooper.getLooper());
mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
- verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class));
+ ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
+ ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
+ verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
observerLooper.dispatchAll();
mLooper.dispatchAll();
assertFalse(observer.mOnStartedCalled);
// now trigger the callback
- Message msg = new Message();
- msg.what = HOTSPOT_STARTED;
- mMessengerCaptor.getValue().send(msg);
+ internalCallback.getValue().onHotspotStarted(null);
mLooper.dispatchAll();
observerLooper.dispatchAll();
assertFalse(observer.mOnStartedCalled);
@@ -936,15 +925,14 @@
TestLooper observerLooper = new TestLooper();
Handler observerHandler = new Handler(observerLooper.getLooper());
mWifiManager.watchLocalOnlyHotspot(observer, observerHandler);
- verify(mWifiService).startWatchLocalOnlyHotspot(mMessengerCaptor.capture(),
- any(IBinder.class));
+ ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
+ ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
+ verify(mWifiService).startWatchLocalOnlyHotspot(internalCallback.capture());
observerLooper.dispatchAll();
mLooper.dispatchAll();
assertFalse(observer.mOnStoppedCalled);
// now trigger the callback
- Message msg = new Message();
- msg.what = HOTSPOT_STOPPED;
- mMessengerCaptor.getValue().send(msg);
+ internalCallback.getValue().onHotspotStopped();
mLooper.dispatchAll();
observerLooper.dispatchAll();
assertTrue(observer.mOnStoppedCalled);
@@ -1173,6 +1161,7 @@
Handler altHandler = new Handler(altLooper.getLooper());
mWifiManager.registerTrafficStateCallback(mTrafficStateCallback, altHandler);
verify(mContext, never()).getMainLooper();
+ verify(mContext, never()).getMainExecutor();
verify(mWifiService).registerTrafficStateCallback(
any(IBinder.class), callbackCaptor.capture(), anyInt());