diff options
210 files changed, 3681 insertions, 1412 deletions
diff --git a/Android.bp b/Android.bp index a3132c5eb31b..f60cbda91f38 100644 --- a/Android.bp +++ b/Android.bp @@ -772,7 +772,7 @@ cc_library { filegroup { name: "incremental_aidl", srcs: [ - "core/java/android/os/incremental/IIncrementalService.aidl", + "core/java/android/os/incremental/IIncrementalManager.aidl", "core/java/android/os/incremental/IIncrementalServiceProxy.aidl", "core/java/android/os/incremental/IncrementalDataLoaderParamsParcel.aidl", "core/java/android/os/incremental/IncrementalFileSystemControlParcel.aidl", @@ -1034,7 +1034,7 @@ stubs_defaults { "sdk-dir", "api-versions-jars-dir", ], - previous_api: ":last-released-public-api-for-metalava-annotations", + previous_api: ":last-released-public-api", merge_annotations_dirs: [ "metalava-manual", ], @@ -1091,7 +1091,7 @@ stubs_defaults { libs: ["framework-internal-utils"], installable: false, annotations_enabled: true, - previous_api: ":last-released-public-api-for-metalava-annotations", + previous_api: ":last-released-public-api", merge_annotations_dirs: [ "metalava-manual", ], @@ -1427,7 +1427,7 @@ droidstubs { installable: false, sdk_version: "core_platform", annotations_enabled: true, - previous_api: ":last-released-public-api-for-metalava-annotations", + previous_api: ":last-released-public-api", merge_annotations_dirs: [ "metalava-manual", ], @@ -1613,7 +1613,6 @@ filegroup { "core/java/android/util/LocalLog.java", "core/java/android/util/TimeUtils.java", "core/java/com/android/internal/os/SomeArgs.java", - "core/java/com/android/internal/util/DumpUtils.java", "core/java/com/android/internal/util/FastXmlSerializer.java", "core/java/com/android/internal/util/HexDump.java", "core/java/com/android/internal/util/IndentingPrintWriter.java", @@ -1630,8 +1629,10 @@ filegroup { filegroup { name: "framework-cellbroadcast-shared-srcs", srcs: [ + "core/java/android/os/HandlerExecutor.java", "core/java/android/util/LocalLog.java", - "core/java/android/util/Slog.java", + "core/java/com/android/internal/util/IState.java", + "core/java/com/android/internal/util/Preconditions.java", "core/java/com/android/internal/util/State.java", "core/java/com/android/internal/util/StateMachine.java", ], diff --git a/apex/appsearch/Android.bp b/apex/appsearch/Android.bp new file mode 100644 index 000000000000..bcdcc7da8070 --- /dev/null +++ b/apex/appsearch/Android.bp @@ -0,0 +1,35 @@ +// 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. + +apex { + name: "com.android.appsearch", + + manifest: "apex_manifest.json", + + key: "com.android.appsearch.key", + certificate: ":com.android.appsearch.certificate", +} + +apex_key { + name: "com.android.appsearch.key", + public_key: "com.android.appsearch.avbpubkey", + private_key: "com.android.appsearch.pem", +} + +android_app_certificate { + name: "com.android.appsearch.certificate", + // This will use com.android.appsearch.x509.pem (the cert) and + // com.android.appsearch.pk8 (the private key) + certificate: "com.android.appsearch", +} diff --git a/apex/appsearch/apex_manifest.json b/apex/appsearch/apex_manifest.json new file mode 100644 index 000000000000..273b867e8f98 --- /dev/null +++ b/apex/appsearch/apex_manifest.json @@ -0,0 +1,4 @@ +{ + "name": "com.android.appsearch", + "version": 1 +} diff --git a/apex/appsearch/com.android.appsearch.avbpubkey b/apex/appsearch/com.android.appsearch.avbpubkey Binary files differnew file mode 100644 index 000000000000..4e5acae9c1e4 --- /dev/null +++ b/apex/appsearch/com.android.appsearch.avbpubkey diff --git a/apex/appsearch/com.android.appsearch.pem b/apex/appsearch/com.android.appsearch.pem new file mode 100644 index 000000000000..4ed5945acc86 --- /dev/null +++ b/apex/appsearch/com.android.appsearch.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKQIBAAKCAgEAro9f/jvoIsj6ywuRmuUQS8UtprhohJitrovDMfm/T2R/WQvy +AvUxgetyF4XvBPCDRqCsGxXCJMQOn1furrAeTmWbGHPhA0PI1Ys/qtfNMbh9THyn +70I2c4X70CUQ+8/Y8BJ8CAB4iER/s9QtD28QLvM2BBUzRoKUSBGUYNMlYobjgRdK +57V7yg48LkvUIg1fzIW3M5gCgOXa0u1xOadKX3m7tzCboHcXp5anfWX5PH1+okRu +jzdI8OjtUq23qhoRw5Skz0Vbf4a+8t3kT3slF/Q7O8LoRPwpZsvIcvTyCGAqlra7 +2L2LN4H1p+u2ko3r/QmRbJn2eXW07elkyrggXMyn2rTxibQgk53wYfSavMyNd/E7 ++de/uJ60l2aPa+5KUaR8eYwchXEELdqQ+zRgSZ2711xCaY4glEj7DT6VlEEdr26x +akX0ra7e2sVGv1um/dvSyVO5aFKKjVvo4LqhWKWO8yvDMxmDDTNatvWhY2Bhd3RA +0hilYpWQFb9Tv5f4E0tZmfvlddgux7sw++Y/RIimBFoSyf5AezAUIFYYoYvEzytB +muq1/ecNHr+Z2tZMxN88sJVhzRzD9tKUyXhvxOV2Lg9TIeVTWGwQqgSnHWtIe+1p +cw8inPfYEhP4Q+3W/RlPvNdu75x8Nj2aG7bxZnhoQDRDw5ddgma27I+a8esCAwEA +AQKCAgBsNh9I6HRAVBz8kCBkSEnw3rwtFTZdtJQ+lw+bRHpvShqT5g7R/JQDOSTS +JkoE4uBOgT4P0E45Inz6FLW2/yDacqxR3UwJDRVMI/WFACCJCRhLuR8V+BLvTIjN +AJ1lrPSL5rmS8E/IEcakgQyp+6ypnkXHBCl0NXCcuKEl4N7VFE+mb/0UZPHnUSnH +fWR085uGmwH17u7mXxdnGKDPH8DALSPMLUrcj9dPIdqUpwl5kUZWa1uqVphWF98/ +GMe5oE2Q0+3TO+i7xplKz3lAOFPHZLTvmCUK1tMHkZ6ifOwpewwLwB30/5N1BpB1 +126nrWk0xKCtFUixBOHzdnLwJHKSbi7chQU5q39oAJoTfxdmAJlaG0zQHUQZ44MQ +gemzSA7uJbtoAOAZVF1K14xbIpnfidqTB7N3RCmiJE+/Hpkq6PxgPfu5rqocPbPC +t0FgJ4NXNmKOAuJllSlrrHATcUOhF4g5pX7tvOc8X4y7bvfwOmtw5ez3INKMF0q6 +/y0vVCi6N1Z7CTa9eY8feZ1PImk/Fkq4NInSPyx7ZE3pLYmsvuJjliFrWo9TRVae +Dt5vvBKBOpAfhDiHkeXbX7Raj2B6c6adF4no/3SAVlAjIq1iBVjfQWyHAGUoEW1O +u3LdHTIb6gSTLJ4AfryEKrOE+1VMlYt92GwX692KKXMaJjytSQKCAQEA3pYbl8HD +Y++UyEN5VzWAQedT3//GDwpDfgdERe2E4smYrkVNJ2WAG2SqY1A35DIl8be3eHvl +soaL38j48ailfDYY9tI+IlapNh+VOLej+HiOytaPlLhcv2FpSC2qZT4EiU6IBXLo ++l6FrmD/VQXTjvoktzsDB/n1t4Dfa3Ogf+lLf1Jxr94YpEnDh18V5ofj78SplVLm +NrzsHxAafE4Ni2a7dyWjcDYIuL7FTShT+0K4W45tRr+CGxThxu7LEe7zw4Z1IagU +jJNtXjvDD/Zw4UTqI6RwWGZsu6UjPS6LHhOqnWqflWmFRIfMbDkuWvnGZTM9DkVg +kk1+BNi1PECZXwKCAQEAyMOjbVo6XV3lFN0X8TpHyg/z9ar00/SE7WEJHqPSuzYT +rSfU4vDDlaPAwkYvGi9ZKi9VM+R3CyBNxnK9Yq6NurHhhrYcAwdS/hGLT1K2o0Y8 +Pgv7gZCFb+SIwLBhlUG9otGULcBzLneqgVUqyMG6IoCjuC2LRyB71Xc2UMyg6n/f +XpV2RTMb8f+26cgm6nj0SDAfgpr8HV6uNV80c6l1A8gq86nUWwiVAEUdmExSDe7J +shsfWAj8RSErqDXf1BtEdPLJUSIPX5VXkzAXOXIkengwVno0vv0dBN8uraS8iQSG +0JsJLLcw9b5kvnh6FEbE7POsIqKyCZV9VADwO6YW9QKCAQBYQsdwNqoGv6KMgozj +8tgHyfWtVduwbQ50M+dznwpZbzz2pY5Bd/MDabhSpyVyfBwlrAa5ZM+hKc7fDu7/ +zDLKfR0LCjUPIrP4PS/LjK4dQZjFf6zxeOV2EedQcqMlgCEGXTh8iKMvXDm/+sBk +c2n/QNs8OM8r44b2m8h78B6NefGw6/0ekn/M7V72F9M0VWAh3Cauim+09tbePmFy +NvUR+MuPJEKZpSNyNltADCS49izqSSC1tAygNniMjHXDh6/rMS7TCLYVRARTIHlp +o/wAp3X8aiEOPJcTFRlTElihtYSq5POgqHXqxbpek5H5CyALUvT76rCvcsDspQ3A +dZEbAoIBAQCoLEmP5o8Rev/UdEgECB/uwWJIngYsLp3TAv/SrMRvkiL1X3JTD/+m +L9/eXVBDjPoR/khPCcg2h77ex2qhaTrL8wnKAG6CkvYQYb3impTnPIRmLT9nDxrX +2gY78wQrNUCXTRvlH1rcx90KLb+DH9S95ig+tdf/otRYwl27XU5GYQtJfcXuvZth +IiWku8btjpiCh909WHpsV81yY+faI08j9d8U8WQzRYMbEMpzsyrhBO/rxBCDfDNl +7R1W8JooYRb9KAs/bVqXZNBROW2a72RjOp6zMfdRLVHLrPC7AE32MNaFk/khfesD +T5OwgdcxeP6oxo2hDcw5fwHXBlo2fTCpAoIBAQChgjv5AfQ50spqvHy6MNem4tV0 +L0IsxmNLsi8X2a6s4kStwUzOxDA8c/e54XabxQNZ0ERU1q+bgbG7PWC4twDMPR8i +2DO6rgqSK4MjGOTgAoeDuy3mElFQmCLRs04Wf4jh8kPi217WFlYBynh2HmBKbh42 +JmIrLetbKEK13FXRvMkgZcX4OIDrT5TOvev4VZArU8PTRlWv3sqsKAVXjX0clGHf +I0/2kSsr2qq1UY7JrYWZsZ9uqz2ZH0pF19a6O/Cq4uqTYoL+sYzFTSeFmChRjV1g +ancTvTn9lcBqECDMgq5DE/p96Oxg/t8elalR6WDUlysafphVz3nTuyMTh7ka +-----END RSA PRIVATE KEY----- diff --git a/apex/appsearch/com.android.appsearch.pk8 b/apex/appsearch/com.android.appsearch.pk8 Binary files differnew file mode 100644 index 000000000000..77e98b20877b --- /dev/null +++ b/apex/appsearch/com.android.appsearch.pk8 diff --git a/apex/appsearch/com.android.appsearch.x509.pem b/apex/appsearch/com.android.appsearch.x509.pem new file mode 100644 index 000000000000..e37c4b9fcead --- /dev/null +++ b/apex/appsearch/com.android.appsearch.x509.pem @@ -0,0 +1,35 @@ +-----BEGIN CERTIFICATE----- +MIIGETCCA/mgAwIBAgIUGl+MIvpEi0+TWzj0ieh6WtjXmP8wDQYJKoZIhvcNAQEL +BQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH +DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy +b2lkMRIwEAYDVQQDDAlhcHBzZWFyY2gxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRA +YW5kcm9pZC5jb20wIBcNMTkxMTIwMjMxNTM1WhgPNDc1NzEwMTYyMzE1MzVaMIGW +MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91 +bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDES +MBAGA1UEAwwJYXBwc2VhcmNoMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJv +aWQuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsyPlp3q3P9Xg +W1WhIwQiF9em9oqaGQ/3dbIxickAy591qcRbpHb4lDTZusRECfqlV215mV+lv5x4 +EhOnId3uPKBAJ/YDtL7zUW6TWL7to7zEnUqSIKTcoQzNF2EiCeGuRhrtgYvAD3HQ +dwr4xrbSADbDArF04A49voLpsmq1fyNgl86VISiMRqoSLJnA6eghlduuOt+nf252 +6WgxDs/JrO/eK70q0+RwmWzVJ/tVr+36a65N4EHhfL4t2hdV0k0XFob7hBn7XWzC +QrSR3jCvE3yAfAr3tq5c19/WWBA7V45nEHzXyAvBUHWubYvDi+vm/yzqU2rQwScC +bzp4zK4CnhBHqb4gHoy0+kfFIwJ1A3GT2pl3ba/NsIYgliMtPQfkDV5PE5RTNcwH +21ewH7vm2+spQv5Z/2TEV2lEHlp2vuAliyn2AT4u1ginr6vtBRFLmpPeziFcfB0y +7h04GctZpX8odz+XI7aMDe47RNu9XyJX0vulntxmlDF76k8Z9DIXg02hY+yc/i7+ +2ztnj1eXL51p+HyhK5VbvJWbKkVaMQijlbuIMYNzMA6L0WHWRc2Cux9UDODMGoiC +w09JpqudCS/95I/F1xaWJ/Kh3vKeQshHAz0hrL7v7wpjmfeXf6NGsWJGy+giCwZj +ABtn9nFQoesgi7M1LeazD5Q/4v4AMaUCAwEAAaNTMFEwHQYDVR0OBBYEFJpHCy2Y +3qaL6cLpE9fe53L61KEEMB8GA1UdIwQYMBaAFJpHCy2Y3qaL6cLpE9fe53L61KEE +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAGDYAcOhbOYcDB2K +WDZka+FCORFFvz4nLQGE7Z9TAn1g7XusM2KbXlb2drIN6CWOFlnKQrUsNsAHrc+s +tl+A1vC3/NfYKKBVuizPx/kHUgz3k/UIJzbzEu/uCJd86idcJoUTqC/qEJAeeQqM +XpsNP1Yg7oyzZT8sFlUAKeDeXJ7fIDXR6nduUQ6uJXkee/5JF3VedHdgHAUsC19/ +KHhyVU3MLDUNBdAmM79+DsdVYi2Pw31jojMu95Zz1MYTRBcgQAiEw5nncr38k6ac +Gy+JffgJR68FzI4QLBSxnDRFD2zXJ09lpP6Sjb1FVcDzk7Bi/EQDLBkrkbeLsk5F +a0xz9VoJ3kM7Cc4R9MXN4ZWuePjdJwgasnHmllsXn45R9odgJgmfzuUwtgNw/XKQ +QcQl7Q9QUrBCqIoHijxscUZCBSmIHVNBBDckRAmSXHeWMRlO3uBR4IA/Jfrt//4f +uc7CNUp+LQ6EzBXJOVFrXRtau6Oj+jM1+fzxKo1uV2+T+GdVEE5jeF/6nB3qna6h +2NmyLqbqeqp2QxgzBWSGy8Ugs6zg4wItJBqOoRLKKFxTJu5OAzJ4fUA+g7WFXNhR +kG56SJ863LZoORKHWE72oXYeIW98Tq0qKLH3NzH5L4tfX8DeBTq+APezHetH1ljA +D0avPy62g0i643bbpwZgezBgRIKL +-----END CERTIFICATE----- diff --git a/apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java b/apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java new file mode 100644 index 000000000000..e611033ea3a7 --- /dev/null +++ b/apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java @@ -0,0 +1,144 @@ +/* + * 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.appsearch.impl; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.util.ArrayMap; +import android.util.ArraySet; +import android.util.Pair; +import android.util.SparseArray; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Fake in-memory implementation of the Icing key-value store and reverse index. + * <p> + * Currently, only queries by single exact term are supported. There is no support for persistence, + * namespaces, i18n tokenization, or schema. + * + * @hide + */ +public class FakeIcing { + private final AtomicInteger mNextDocId = new AtomicInteger(); + private final Map<String, Integer> mUriToDocIdMap = new ArrayMap<>(); + /** Array of Documents (pair of uri and content) where index into the array is the docId. */ + private final SparseArray<Pair<String, String>> mDocStore = new SparseArray<>(); + /** Map of term to posting-list (the set of DocIds containing that term). */ + private final Map<String, Set<Integer>> mIndex = new ArrayMap<>(); + + /** + * Inserts a document into the index. + * + * @param uri The globally unique identifier of the document. + * @param doc The contents of the document. + */ + public void put(@NonNull String uri, @NonNull String doc) { + // Update mDocIdMap + Integer docId = mUriToDocIdMap.get(uri); + if (docId != null) { + // Delete the old doc + mDocStore.remove(docId); + } + + // Allocate a new docId + docId = mNextDocId.getAndIncrement(); + mUriToDocIdMap.put(uri, docId); + + // Update mDocStore + mDocStore.put(docId, Pair.create(uri, doc)); + + // Update mIndex + String[] words = normalizeString(doc).split("\\s+"); + for (String word : words) { + Set<Integer> postingList = mIndex.get(word); + if (postingList == null) { + postingList = new ArraySet<>(); + mIndex.put(word, postingList); + } + postingList.add(docId); + } + } + + /** + * Retrieves a document from the index. + * + * @param uri The URI of the document to retrieve. + * @return The body of the document, or {@code null} if no such document exists. + */ + @Nullable + public String get(@NonNull String uri) { + Integer docId = mUriToDocIdMap.get(uri); + if (docId == null) { + return null; + } + Pair<String, String> record = mDocStore.get(docId); + if (record == null) { + return null; + } + return record.second; + } + + /** + * Returns documents containing the given term. + * + * @param term A single exact term to look up in the index. + * @return The URIs of the matching documents, or an empty {@code List} if no documents match. + */ + @NonNull + public List<String> query(@NonNull String term) { + String normTerm = normalizeString(term); + Set<Integer> docIds = mIndex.get(normTerm); + if (docIds == null || docIds.isEmpty()) { + return Collections.emptyList(); + } + List<String> uris = new ArrayList<>(docIds.size()); + for (int docId : docIds) { + Pair<String, String> record = mDocStore.get(docId); + if (record != null) { + uris.add(record.first); + } + } + return uris; + } + + /** + * Deletes a document by its URI. + * + * @param uri The URI of the document to be deleted. + */ + public void delete(@NonNull String uri) { + // Update mDocIdMap + Integer docId = mUriToDocIdMap.get(uri); + if (docId != null) { + // Delete the old doc + mDocStore.remove(docId); + mUriToDocIdMap.remove(uri); + } + } + + /** Strips out punctuation and converts to lowercase. */ + private static String normalizeString(String input) { + return input.replaceAll("\\p{P}", "").toLowerCase(Locale.getDefault()); + } +} 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 f2de2001bcbe..62c77ef20871 100644 --- a/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java +++ b/apex/statsd/service/java/com/android/server/stats/StatsCompanionService.java @@ -18,6 +18,7 @@ package com.android.server.stats; import static android.app.AppOpsManager.OP_FLAGS_ALL_TRUSTED; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS; +import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import static android.os.Process.getUidForPid; import static android.os.storage.VolumeInfo.TYPE_PRIVATE; import static android.os.storage.VolumeInfo.TYPE_PUBLIC; @@ -115,7 +116,6 @@ import android.util.proto.ProtoStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.procstats.IProcessStats; import com.android.internal.app.procstats.ProcessStats; -import com.android.internal.os.BackgroundThread; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.internal.os.BinderCallsStats.ExportedCallStat; @@ -535,7 +535,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { // Assumes that sStatsdLock is held. @GuardedBy("sStatsdLock") - private final void informAllUidsLocked(Context context) throws RemoteException { + private void informAllUidsLocked(Context context) throws RemoteException { UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); PackageManager pm = context.getPackageManager(); final List<UserInfo> users = um.getUsers(true); @@ -557,7 +557,11 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { Slog.e(TAG, "Failed to close the read side of the pipe.", e); } final ParcelFileDescriptor writeFd = fds[1]; - BackgroundThread.getHandler().post(() -> { + HandlerThread backgroundThread = new HandlerThread( + "statsCompanionService.bg", THREAD_PRIORITY_BACKGROUND); + backgroundThread.start(); + Handler handler = new Handler(backgroundThread.getLooper()); + handler.post(() -> { FileOutputStream fout = new ParcelFileDescriptor.AutoCloseOutputStream(writeFd); try { ProtoOutputStream output = new ProtoOutputStream(fout); @@ -607,6 +611,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } finally { IoUtils.closeQuietly(fout); + backgroundThread.quit(); + backgroundThread.interrupt(); } }); } diff --git a/api/current.txt b/api/current.txt index f1c03a4e576d..aefe20979a1c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9899,6 +9899,7 @@ package android.content { method public abstract void sendOrderedBroadcast(@RequiresPermission android.content.Intent, @Nullable String); method public abstract void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); method public void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); + method public void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable String, @Nullable android.os.Bundle, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendOrderedBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); method @Deprecated @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY) public abstract void sendStickyBroadcast(@RequiresPermission android.content.Intent); method @Deprecated @RequiresPermission(allOf={"android.permission.INTERACT_ACROSS_USERS", android.Manifest.permission.BROADCAST_STICKY}) public abstract void sendStickyBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle); @@ -23063,6 +23064,7 @@ package android.location { public final class GnssStatus { method @FloatRange(from=0, to=360) public float getAzimuthDegrees(@IntRange(from=0) int); + method @FloatRange(from=0, to=63) public float getBasebandCn0DbHz(@IntRange(from=0) int); method @FloatRange(from=0) public float getCarrierFrequencyHz(@IntRange(from=0) int); method @FloatRange(from=0, to=63) public float getCn0DbHz(@IntRange(from=0) int); method public int getConstellationType(@IntRange(from=0) int); @@ -23070,6 +23072,7 @@ package android.location { method @IntRange(from=0) public int getSatelliteCount(); method @IntRange(from=1, to=200) public int getSvid(@IntRange(from=0) int); method public boolean hasAlmanacData(@IntRange(from=0) int); + method public boolean hasBasebandCn0DbHz(@IntRange(from=0) int); method public boolean hasCarrierFrequencyHz(@IntRange(from=0) int); method public boolean hasEphemerisData(@IntRange(from=0) int); method public boolean usedInFix(@IntRange(from=0) int); @@ -23085,7 +23088,7 @@ package android.location { public static final class GnssStatus.Builder { ctor public GnssStatus.Builder(); - method @NonNull public android.location.GnssStatus.Builder addSatellite(int, @IntRange(from=1, to=200) int, @FloatRange(from=0, to=63) float, @FloatRange(from=0xffffffa6, to=90) float, @FloatRange(from=0, to=360) float, boolean, boolean, boolean, boolean, @FloatRange(from=0) float); + method @NonNull public android.location.GnssStatus.Builder addSatellite(int, @IntRange(from=1, to=200) int, @FloatRange(from=0, to=63) float, @FloatRange(from=0xffffffa6, to=90) float, @FloatRange(from=0, to=360) float, boolean, boolean, boolean, boolean, @FloatRange(from=0) float, boolean, @FloatRange(from=0, to=63) float); method @NonNull public android.location.GnssStatus build(); method @NonNull public android.location.GnssStatus.Builder clearSatellites(); } @@ -29889,6 +29892,7 @@ package android.net.wifi { ctor @Deprecated public WifiConfiguration(); method public int describeContents(); method @Deprecated public android.net.ProxyInfo getHttpProxy(); + method @Deprecated @NonNull public String getKey(); method @Deprecated @NonNull public android.net.MacAddress getRandomizedMacAddress(); method @Deprecated public boolean isPasspoint(); method @Deprecated public void setHttpProxy(android.net.ProxyInfo); @@ -30243,6 +30247,7 @@ package android.net.wifi { method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsEnhancedOpen(boolean); method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsHiddenSsid(boolean); method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsMetered(boolean); + method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsUserAllowedToManuallyConnect(boolean); method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setIsUserInteractionRequired(boolean); method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPasspointConfig(@NonNull android.net.wifi.hotspot2.PasspointConfiguration); method @NonNull public android.net.wifi.WifiNetworkSuggestion.Builder setPriority(@IntRange(from=0) int); @@ -41525,6 +41530,7 @@ package android.service.autofill { field public static final int FLAG_DONT_SAVE_ON_FINISH = 2; // 0x2 field public static final int FLAG_SAVE_ON_ALL_VIEWS_INVISIBLE = 1; // 0x1 field public static final int NEGATIVE_BUTTON_STYLE_CANCEL = 0; // 0x0 + field public static final int NEGATIVE_BUTTON_STYLE_NEVER = 2; // 0x2 field public static final int NEGATIVE_BUTTON_STYLE_REJECT = 1; // 0x1 field public static final int POSITIVE_BUTTON_STYLE_CONTINUE = 1; // 0x1 field public static final int POSITIVE_BUTTON_STYLE_SAVE = 0; // 0x0 @@ -52497,6 +52503,9 @@ package android.view { package android.view.accessibility { public final class AccessibilityEvent extends android.view.accessibility.AccessibilityRecord implements android.os.Parcelable { + ctor public AccessibilityEvent(); + ctor public AccessibilityEvent(int); + ctor public AccessibilityEvent(@NonNull android.view.accessibility.AccessibilityEvent); method public void appendRecord(android.view.accessibility.AccessibilityRecord); method public int describeContents(); method public static String eventTypeToString(int); @@ -52607,6 +52616,10 @@ package android.view.accessibility { } public class AccessibilityNodeInfo implements android.os.Parcelable { + ctor public AccessibilityNodeInfo(); + ctor public AccessibilityNodeInfo(@NonNull android.view.View); + ctor public AccessibilityNodeInfo(@NonNull android.view.View, int); + ctor public AccessibilityNodeInfo(@NonNull android.view.accessibility.AccessibilityNodeInfo); method public void addAction(android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction); method @Deprecated public void addAction(int); method public void addChild(android.view.View); @@ -52840,6 +52853,8 @@ package android.view.accessibility { } public static final class AccessibilityNodeInfo.CollectionInfo { + ctor public AccessibilityNodeInfo.CollectionInfo(int, int, boolean); + ctor public AccessibilityNodeInfo.CollectionInfo(int, int, boolean, int); method public int getColumnCount(); method public int getRowCount(); method public int getSelectionMode(); @@ -52852,6 +52867,8 @@ package android.view.accessibility { } public static final class AccessibilityNodeInfo.CollectionItemInfo { + ctor public AccessibilityNodeInfo.CollectionItemInfo(int, int, int, int, boolean); + ctor public AccessibilityNodeInfo.CollectionItemInfo(int, int, int, int, boolean, boolean); method public int getColumnIndex(); method public int getColumnSpan(); method public int getRowIndex(); @@ -52863,6 +52880,7 @@ package android.view.accessibility { } public static final class AccessibilityNodeInfo.RangeInfo { + ctor public AccessibilityNodeInfo.RangeInfo(int, float, float, float); method public float getCurrent(); method public float getMax(); method public float getMin(); @@ -52894,6 +52912,8 @@ package android.view.accessibility { } public class AccessibilityRecord { + ctor public AccessibilityRecord(); + ctor public AccessibilityRecord(@NonNull android.view.accessibility.AccessibilityRecord); method public int getAddedCount(); method public CharSequence getBeforeText(); method public CharSequence getClassName(); @@ -52954,6 +52974,8 @@ package android.view.accessibility { } public final class AccessibilityWindowInfo implements android.os.Parcelable { + ctor public AccessibilityWindowInfo(); + ctor public AccessibilityWindowInfo(@NonNull android.view.accessibility.AccessibilityWindowInfo); method public int describeContents(); method public android.view.accessibility.AccessibilityNodeInfo getAnchor(); method public void getBoundsInScreen(android.graphics.Rect); diff --git a/api/system-current.txt b/api/system-current.txt index 90321d769960..1d5298df8547 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4378,6 +4378,7 @@ package android.net { public final class IpConfiguration implements android.os.Parcelable { ctor public IpConfiguration(); ctor public IpConfiguration(@NonNull android.net.IpConfiguration); + method public int describeContents(); method @Nullable public android.net.ProxyInfo getHttpProxy(); method @NonNull public android.net.IpConfiguration.IpAssignment getIpAssignment(); method @NonNull public android.net.IpConfiguration.ProxySettings getProxySettings(); @@ -4386,6 +4387,7 @@ package android.net { method public void setIpAssignment(@NonNull android.net.IpConfiguration.IpAssignment); method public void setProxySettings(@NonNull android.net.IpConfiguration.ProxySettings); method public void setStaticIpConfiguration(@Nullable android.net.StaticIpConfiguration); + method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.net.IpConfiguration> CREATOR; } @@ -9172,6 +9174,7 @@ package android.telephony { method @NonNull public android.content.ContentValues getContentValues(); method @Nullable public android.telephony.SmsCbEtwsInfo getEtwsWarningInfo(); method public int getGeographicalScope(); + method @NonNull public java.util.List<android.telephony.CbGeoUtils.Geometry> getGeometries(); method @Nullable public String getLanguageCode(); method @NonNull public android.telephony.SmsCbLocation getLocation(); method public int getMaximumWaitingDuration(); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 1c8f4948eb85..46f88d5c81e4 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1362,6 +1362,18 @@ class ContextImpl extends Context { } @Override + public void sendOrderedBroadcast(Intent intent, String receiverPermission, String receiverAppOp, + Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, + String initialData, @Nullable Bundle initialExtras) { + int intAppOp = AppOpsManager.OP_NONE; + if (!TextUtils.isEmpty(receiverAppOp)) { + intAppOp = AppOpsManager.strOpToOp(receiverAppOp); + } + sendOrderedBroadcastAsUser(intent, getUser(), receiverPermission, intAppOp, options, + resultReceiver, scheduler, initialCode, initialData, initialExtras); + } + + @Override @Deprecated public void sendStickyBroadcast(Intent intent) { warnIfCallingFromSystemProcess(); diff --git a/core/java/android/app/timedetector/ITimeDetectorService.aidl b/core/java/android/app/timedetector/ITimeDetectorService.aidl index ddc4932d6fec..9877fc741b7b 100644 --- a/core/java/android/app/timedetector/ITimeDetectorService.aidl +++ b/core/java/android/app/timedetector/ITimeDetectorService.aidl @@ -16,6 +16,7 @@ package android.app.timedetector; +import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; /** @@ -33,4 +34,5 @@ import android.app.timedetector.PhoneTimeSuggestion; */ interface ITimeDetectorService { void suggestPhoneTime(in PhoneTimeSuggestion timeSuggestion); + void suggestManualTime(in ManualTimeSuggestion timeSuggestion); } diff --git a/core/java/android/app/timedetector/ManualTimeSuggestion.aidl b/core/java/android/app/timedetector/ManualTimeSuggestion.aidl new file mode 100644 index 000000000000..213940493114 --- /dev/null +++ b/core/java/android/app/timedetector/ManualTimeSuggestion.aidl @@ -0,0 +1,19 @@ +/* + * 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.timedetector; + +parcelable ManualTimeSuggestion; diff --git a/core/java/android/app/timedetector/ManualTimeSuggestion.java b/core/java/android/app/timedetector/ManualTimeSuggestion.java new file mode 100644 index 000000000000..e7d619a27607 --- /dev/null +++ b/core/java/android/app/timedetector/ManualTimeSuggestion.java @@ -0,0 +1,127 @@ +/* + * 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.timedetector; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.TimestampedValue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +/** + * A time signal from a manual (user provided) source. The value consists of the number of + * milliseconds elapsed since 1/1/1970 00:00:00 UTC and the time according to the elapsed realtime + * clock when that number was established. The elapsed realtime clock is considered accurate but + * volatile, so time signals must not be persisted across device resets. + * + * @hide + */ +public final class ManualTimeSuggestion implements Parcelable { + + public static final @NonNull Creator<ManualTimeSuggestion> CREATOR = + new Creator<ManualTimeSuggestion>() { + public ManualTimeSuggestion createFromParcel(Parcel in) { + return ManualTimeSuggestion.createFromParcel(in); + } + + public ManualTimeSuggestion[] newArray(int size) { + return new ManualTimeSuggestion[size]; + } + }; + + @NonNull + private final TimestampedValue<Long> mUtcTime; + @Nullable + private ArrayList<String> mDebugInfo; + + public ManualTimeSuggestion(@NonNull TimestampedValue<Long> utcTime) { + mUtcTime = Objects.requireNonNull(utcTime); + } + + private static ManualTimeSuggestion createFromParcel(Parcel in) { + TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */); + ManualTimeSuggestion suggestion = new ManualTimeSuggestion(utcTime); + @SuppressWarnings("unchecked") + ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */); + suggestion.mDebugInfo = debugInfo; + return suggestion; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeParcelable(mUtcTime, 0); + dest.writeList(mDebugInfo); + } + + @NonNull + public TimestampedValue<Long> getUtcTime() { + return mUtcTime; + } + + @NonNull + public List<String> getDebugInfo() { + return Collections.unmodifiableList(mDebugInfo); + } + + /** + * Associates information with the instance that can be useful for debugging / logging. The + * information is present in {@link #toString()} but is not considered for + * {@link #equals(Object)} and {@link #hashCode()}. + */ + public void addDebugInfo(String... debugInfos) { + if (mDebugInfo == null) { + mDebugInfo = new ArrayList<>(); + } + mDebugInfo.addAll(Arrays.asList(debugInfos)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ManualTimeSuggestion that = (ManualTimeSuggestion) o; + return Objects.equals(mUtcTime, that.mUtcTime); + } + + @Override + public int hashCode() { + return Objects.hash(mUtcTime); + } + + @Override + public String toString() { + return "ManualTimeSuggestion{" + + "mUtcTime=" + mUtcTime + + ", mDebugInfo=" + mDebugInfo + + '}'; + } +} diff --git a/core/java/android/app/timedetector/TimeDetector.java b/core/java/android/app/timedetector/TimeDetector.java index 334e9582a145..48d5cd2d65a5 100644 --- a/core/java/android/app/timedetector/TimeDetector.java +++ b/core/java/android/app/timedetector/TimeDetector.java @@ -17,19 +17,22 @@ package android.app.timedetector; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; +import android.os.SystemClock; import android.util.Log; +import android.util.TimestampedValue; /** * The interface through which system components can send signals to the TimeDetectorService. * @hide */ @SystemService(Context.TIME_DETECTOR_SERVICE) -public final class TimeDetector { +public class TimeDetector { private static final String TAG = "timedetector.TimeDetector"; private static final boolean DEBUG = false; @@ -41,10 +44,11 @@ public final class TimeDetector { } /** - * Suggests the current time to the detector. The detector may ignore the signal if better - * signals are available such as those that come from more reliable sources or were - * determined more recently. + * Suggests the current phone-signal derived time to the detector. The detector may ignore the + * signal if better signals are available such as those that come from more reliable sources or + * were determined more recently. */ + @RequiresPermission(android.Manifest.permission.SET_TIME) public void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion) { if (DEBUG) { Log.d(TAG, "suggestPhoneTime called: " + timeSuggestion); @@ -56,4 +60,29 @@ public final class TimeDetector { } } + /** + * Suggests the user's manually entered current time to the detector. + */ + @RequiresPermission(android.Manifest.permission.SET_TIME) + public void suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion) { + if (DEBUG) { + Log.d(TAG, "suggestManualTime called: " + timeSuggestion); + } + try { + mITimeDetectorService.suggestManualTime(timeSuggestion); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * A shared utility method to create a {@link ManualTimeSuggestion}. + */ + public static ManualTimeSuggestion createManualTimeSuggestion(long when, String why) { + TimestampedValue<Long> utcTime = + new TimestampedValue<>(SystemClock.elapsedRealtime(), when); + ManualTimeSuggestion manualTimeSuggestion = new ManualTimeSuggestion(utcTime); + manualTimeSuggestion.addDebugInfo(why); + return manualTimeSuggestion; + } } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index fba647b7620c..341b5206ba90 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2484,6 +2484,48 @@ public abstract class Context { } /** + * Version of + * {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, + * Bundle)} that allows you to specify the App Op to enforce restrictions on which receivers + * the broadcast will be sent to as well as supply an optional sending options + * + * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts. + * + * @param intent The Intent to broadcast; all receivers matching this + * Intent will receive the broadcast. + * @param receiverPermission String naming a permissions that + * a receiver must hold in order to receive your broadcast. + * If null, no permission is required. + * @param receiverAppOp The app op associated with the broadcast. If null, no appOp is + * required. If both receiverAppOp and receiverPermission are non-null, + * a receiver must have both of them to + * receive the broadcast + * @param options (optional) Additional sending options, generated from a + * {@link android.app.BroadcastOptions}. + * @param resultReceiver Your own BroadcastReceiver to treat as the final + * receiver of the broadcast. + * @param scheduler A custom Handler with which to schedule the + * resultReceiver callback; if null it will be + * scheduled in the Context's main thread. + * @param initialCode An initial value for the result code. Often + * Activity.RESULT_OK. + * @param initialData An initial value for the result data. Often + * null. + * @param initialExtras An initial value for the result extras. Often + * null. + * + * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) + * @see android.app.BroadcastOptions + */ + public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent, + @Nullable String receiverPermission, @Nullable String receiverAppOp, + @Nullable Bundle options, @Nullable BroadcastReceiver resultReceiver, + @Nullable Handler scheduler, int initialCode, @Nullable String initialData, + @Nullable Bundle initialExtras) { + throw new RuntimeException("Not implemented. Must override in a subclass."); + } + + /** * <p>Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the * Intent you are sending stays around after the broadcast is complete, * so that others can quickly retrieve that data through the return @@ -3385,6 +3427,7 @@ public abstract class Context { //@hide: TIME_DETECTOR_SERVICE, //@hide: TIME_ZONE_DETECTOR_SERVICE, PERMISSION_SERVICE, + INCREMENTAL_SERVICE, }) @Retention(RetentionPolicy.SOURCE) public @interface ServiceName {} @@ -4927,6 +4970,13 @@ public abstract class Context { public static final String APP_INTEGRITY_SERVICE = "app_integrity"; /** + * Use with {@link #getSystemService(String)} to retrieve an + * {@link android.os.incremental.IncrementalManager}. + * @hide + */ + public static final String INCREMENTAL_SERVICE = "incremental"; + + /** * Determine whether the given permission is allowed for a particular * process and user ID running in the system. * diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index e44d6ae40356..d6442e28439f 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -590,6 +590,16 @@ public class ContextWrapper extends Context { } @Override + public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent, + @Nullable String receiverPermission, @Nullable String receiverAppOp, + @Nullable Bundle options, @Nullable BroadcastReceiver resultReceiver, + @Nullable Handler scheduler, int initialCode, @Nullable String initialData, + @Nullable Bundle initialExtras) { + mBase.sendOrderedBroadcast(intent, receiverPermission, receiverAppOp, options, + resultReceiver, scheduler, initialCode, initialData, initialExtras); + } + + @Override @Deprecated public void sendStickyBroadcast(Intent intent) { mBase.sendStickyBroadcast(intent); diff --git a/core/java/android/net/IpConfiguration.java b/core/java/android/net/IpConfiguration.java index 143467b15fe8..dddb64d8cece 100644 --- a/core/java/android/net/IpConfiguration.java +++ b/core/java/android/net/IpConfiguration.java @@ -191,18 +191,12 @@ public final class IpConfiguration implements Parcelable { 83 * httpProxy.hashCode(); } - /** - * Implement the Parcelable interface - * @hide - */ + /** Implement the Parcelable interface */ public int describeContents() { return 0; } - /** - * Implement the Parcelable interface - * @hide - */ + /** Implement the Parcelable interface */ public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeString(ipAssignment.name()); dest.writeString(proxySettings.name()); diff --git a/core/java/android/os/incremental/IIncrementalService.aidl b/core/java/android/os/incremental/IIncrementalManager.aidl index 1c832ca9e6db..d6446d485af5 100644 --- a/core/java/android/os/incremental/IIncrementalService.aidl +++ b/core/java/android/os/incremental/IIncrementalManager.aidl @@ -19,7 +19,7 @@ package android.os.incremental; import android.os.incremental.IncrementalDataLoaderParamsParcel; /** @hide */ -interface IIncrementalService { +interface IIncrementalManager { /** * A set of flags for the |createMode| parameters when creating a new Incremental storage. */ @@ -53,6 +53,12 @@ interface IIncrementalService { int makeDirectory(int storageId, in @utf8InCpp String pathUnderStorage); /** + * Recursively creates a directory under a storage. The target directory is specified by its relative path under the storage. + * All the parent directories of the target directory will be created if they do not exist already. + */ + int makeDirectories(int storageId, in @utf8InCpp String pathUnderStorage); + + /** * Creates a file under a storage, specifying its name, size and metadata. */ int makeFile(int storageId, in @utf8InCpp String pathUnderStorage, long size, in byte[] metadata); @@ -64,10 +70,12 @@ interface IIncrementalService { int makeFileFromRange(int storageId, in @utf8InCpp String targetPathUnderStorage, in @utf8InCpp String sourcePathUnderStorage, long start, long end); /** - * Creates a hard link between two files in a storage. - * Both source and destination are specified by relative paths under storage. + * Creates a hard link between two files in two storage instances. + * Source and dest specified by parent storage IDs and their relative paths under the storage. + * The source and dest storage instances should be in the same fs mount. + * Note: destStorageId can be the same as sourceStorageId. */ - int makeLink(int storageId, in @utf8InCpp String sourcePathUnderStorage, in @utf8InCpp String destPathUnderStorage); + int makeLink(int sourceStorageId, in @utf8InCpp String sourcePathUnderStorage, int destStorageId, in @utf8InCpp String destPathUnderStorage); /** * Deletes a hard link in a storage, specified by the relative path of the link target under storage. @@ -85,12 +93,12 @@ interface IIncrementalService { byte[] getFileMetadata(int storageId, in @utf8InCpp String pathUnderStorage); /** - * Returns the list of file paths under a storage. + * Starts loading data for a storage. */ - @utf8InCpp String[] getFileList(int storageId); + boolean startLoading(int storageId); /** - * Starts loading data for a storage. + * Deletes a storage given its ID. Deletes its bind mounts and unmount it. Stop its data loader. */ - boolean startLoading(int storageId); + void deleteStorage(int storageId); } diff --git a/core/java/android/os/incremental/IncrementalDataLoaderParams.java b/core/java/android/os/incremental/IncrementalDataLoaderParams.java new file mode 100644 index 000000000000..701f1cc8de02 --- /dev/null +++ b/core/java/android/os/incremental/IncrementalDataLoaderParams.java @@ -0,0 +1,84 @@ +/* + * 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.os.incremental; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.ParcelFileDescriptor; + +import java.util.Arrays; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * This class represents the parameters used to configure an Incremental Data Loader. + * Hide for now. + * @hide + */ +public class IncrementalDataLoaderParams { + @NonNull private final IncrementalDataLoaderParamsParcel mData; + + public IncrementalDataLoaderParams(@NonNull String url, @NonNull String packageName, + @Nullable Map<String, ParcelFileDescriptor> namedFds) { + IncrementalDataLoaderParamsParcel data = new IncrementalDataLoaderParamsParcel(); + data.staticArgs = url; + data.packageName = packageName; + if (namedFds == null || namedFds.isEmpty()) { + data.dynamicArgs = new NamedParcelFileDescriptor[0]; + } else { + data.dynamicArgs = new NamedParcelFileDescriptor[namedFds.size()]; + int i = 0; + for (Map.Entry<String, ParcelFileDescriptor> namedFd : namedFds.entrySet()) { + data.dynamicArgs[i] = new NamedParcelFileDescriptor(); + data.dynamicArgs[i].name = namedFd.getKey(); + data.dynamicArgs[i].fd = namedFd.getValue(); + i += 1; + } + } + mData = data; + } + + public IncrementalDataLoaderParams(@NonNull IncrementalDataLoaderParamsParcel data) { + mData = data; + } + + /** + * @return static server's URL + */ + public final @NonNull String getStaticArgs() { + return mData.staticArgs; + } + + /** + * @return data loader's package name + */ + public final @NonNull String getPackageName() { + return mData.packageName; + } + + public final @NonNull IncrementalDataLoaderParamsParcel getData() { + return mData; + } + + /** + * @return data loader's dynamic arguments such as file descriptors + */ + public final @NonNull Map<String, ParcelFileDescriptor> getDynamicArgs() { + return Arrays.stream(mData.dynamicArgs).collect( + Collectors.toMap(p->p.name, p->p.fd)); + } +} diff --git a/core/java/android/os/incremental/IncrementalDataLoaderParamsParcel.aidl b/core/java/android/os/incremental/IncrementalDataLoaderParamsParcel.aidl index 50c28f0a4c17..cd988dcace5b 100644 --- a/core/java/android/os/incremental/IncrementalDataLoaderParamsParcel.aidl +++ b/core/java/android/os/incremental/IncrementalDataLoaderParamsParcel.aidl @@ -23,7 +23,7 @@ import android.os.incremental.NamedParcelFileDescriptor; * @hide */ parcelable IncrementalDataLoaderParamsParcel { - @utf8InCpp String staticUri; @utf8InCpp String packageName; + @utf8InCpp String staticArgs; NamedParcelFileDescriptor[] dynamicArgs; } diff --git a/core/java/android/os/incremental/IncrementalManager.java b/core/java/android/os/incremental/IncrementalManager.java new file mode 100644 index 000000000000..5aabf86e17e6 --- /dev/null +++ b/core/java/android/os/incremental/IncrementalManager.java @@ -0,0 +1,327 @@ +/* + * 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.os.incremental; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemService; +import android.content.Context; +import android.os.RemoteException; +import android.system.ErrnoException; +import android.system.Os; +import android.util.SparseArray; + +import com.android.internal.annotations.GuardedBy; + +import java.io.File; +import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Provides operations to open or create an IncrementalStorage, using IIncrementalManager service. + * Example Usage: + * + * <blockquote><pre> + * IncrementalManager manager = (IncrementalManager) getSystemService(Context.INCREMENTAL_MANAGER); + * IncrementalStorage storage = manager.openStorage("/path/to/incremental/dir"); + * </pre></blockquote> + * + * @hide + */ +@SystemService(Context.INCREMENTAL_SERVICE) +public class IncrementalManager { + private static final String TAG = "IncrementalManager"; + private final IIncrementalManager mService; + @GuardedBy("mStorages") + private final SparseArray<IncrementalStorage> mStorages = new SparseArray<>(); + + public static final int CREATE_MODE_TEMPORARY_BIND = + IIncrementalManager.CREATE_MODE_TEMPORARY_BIND; + public static final int CREATE_MODE_PERMANENT_BIND = + IIncrementalManager.CREATE_MODE_PERMANENT_BIND; + public static final int CREATE_MODE_CREATE = + IIncrementalManager.CREATE_MODE_CREATE; + public static final int CREATE_MODE_OPEN_EXISTING = + IIncrementalManager.CREATE_MODE_OPEN_EXISTING; + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"CREATE_MODE_"}, value = { + CREATE_MODE_TEMPORARY_BIND, + CREATE_MODE_PERMANENT_BIND, + CREATE_MODE_CREATE, + CREATE_MODE_OPEN_EXISTING, + }) + public @interface CreateMode { + } + + public IncrementalManager(@NonNull IIncrementalManager is) { + mService = is; + } + + /** + * Returns a storage object given a storage ID. + * + * @param storageId The storage ID to identify the storage object. + * @return IncrementalStorage object corresponding to storage ID. + */ + @Nullable + public IncrementalStorage getStorage(int storageId) { + synchronized (mStorages) { + return mStorages.get(storageId); + } + } + + /** + * Opens or create an Incremental File System mounted directory and returns an + * IncrementalStorage object. + * + * @param path Absolute path to mount Incremental File System on. + * @param params IncrementalDataLoaderParams object to configure data loading. + * @param createMode Mode for opening an old Incremental File System mount or + * creating a new mount. + * @param autoStartDataLoader Set true to immediately start data loader after creating storage. + * @return IncrementalStorage object corresponding to the mounted directory. + */ + @Nullable + public IncrementalStorage createStorage(@NonNull String path, + @NonNull IncrementalDataLoaderParams params, @CreateMode int createMode, + boolean autoStartDataLoader) { + try { + final int id = mService.createStorage(path, params.getData(), createMode); + if (id < 0) { + return null; + } + final IncrementalStorage storage = new IncrementalStorage(mService, id); + synchronized (mStorages) { + mStorages.put(id, storage); + } + if (autoStartDataLoader) { + storage.startLoading(); + } + return storage; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Opens an existing Incremental File System mounted directory and returns an + * IncrementalStorage object. + * + * @param path Absolute target path that Incremental File System has been mounted on. + * @return IncrementalStorage object corresponding to the mounted directory. + */ + @Nullable + public IncrementalStorage openStorage(@NonNull String path) { + try { + final int id = mService.openStorage(path); + if (id < 0) { + return null; + } + final IncrementalStorage storage = new IncrementalStorage(mService, id); + synchronized (mStorages) { + mStorages.put(id, storage); + } + return storage; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Opens or creates an IncrementalStorage that is linked to another IncrementalStorage. + * + * @return IncrementalStorage object corresponding to the linked storage. + */ + @Nullable + public IncrementalStorage createStorage(@NonNull String path, + @NonNull IncrementalStorage linkedStorage, @CreateMode int createMode) { + try { + final int id = mService.createLinkedStorage(path, linkedStorage.getId(), createMode); + if (id < 0) { + return null; + } + final IncrementalStorage storage = new IncrementalStorage(mService, id); + synchronized (mStorages) { + mStorages.put(id, storage); + } + return storage; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Iterates through path parents to find the base dir of an Incremental Storage. + * + * @param file Target file to search storage for. + * @return Absolute path which is a bind-mount point of Incremental File System. + */ + private Path getStoragePathForFile(File file) { + File currentPath = new File(file.getParent()); + while (currentPath.getParent() != null) { + IncrementalStorage storage = openStorage(currentPath.getAbsolutePath()); + if (storage != null) { + return currentPath.toPath(); + } + currentPath = new File(currentPath.getParent()); + } + return null; + } + + /** + * Renames an Incremental path to a new path. If source path is a file, make a link from the old + * Incremental file to the new one. If source path is a dir, unbind old dir from Incremental + * Storage and bind the new one. + * <ol> + * <li> For renaming a dir, dest dir will be created if not exists, and does not need to + * be on the same Incremental storage as the source. </li> + * <li> For renaming a file, dest file must be on the same Incremental storage as source. + * </li> + * </ol> + * + * @param sourcePath Absolute path to the source. Should be the same type as the destPath + * (file or dir). Expected to already exist and is an Incremental path. + * @param destPath Absolute path to the destination. + * @throws IllegalArgumentException when 1) source does not exist, + * or 2) source and dest type mismatch (one is file and the other is dir), + * or 3) source path is not on Incremental File System, + * @throws IOException when 1) cannot find the root path of the Incremental storage of source, + * or 2) cannot retrieve the Incremental storage instance of the source, + * or 3) renaming a file, but dest is not on the same Incremental Storage, + * or 4) renaming a dir, dest dir does not exist but fails to be created. + * + * TODO(b/136132412): add unit tests + */ + public void rename(@NonNull String sourcePath, @NonNull String destPath) throws IOException { + final File source = new File(sourcePath); + final File dest = new File(destPath); + if (!source.exists()) { + throw new IllegalArgumentException("Path not exist: " + sourcePath); + } + if (dest.exists()) { + throw new IllegalArgumentException("Target path already exists: " + destPath); + } + if (source.isDirectory() && dest.exists() && dest.isFile()) { + throw new IllegalArgumentException( + "Trying to rename a dir but destination is a file: " + destPath); + } + if (source.isFile() && dest.exists() && dest.isDirectory()) { + throw new IllegalArgumentException( + "Trying to rename a file but destination is a dir: " + destPath); + } + if (!isIncrementalPath(sourcePath)) { + throw new IllegalArgumentException("Not an Incremental path: " + sourcePath); + } + + Path storagePath = Paths.get(sourcePath); + if (source.isFile()) { + storagePath = getStoragePathForFile(source); + } + if (storagePath == null || storagePath.toAbsolutePath() == null) { + throw new IOException("Invalid source storage path for: " + sourcePath); + } + final IncrementalStorage storage = openStorage(storagePath.toAbsolutePath().toString()); + if (storage == null) { + throw new IOException("Failed to retrieve storage from Incremental Service."); + } + if (source.isFile()) { + renameFile(storage, storagePath, source, dest); + } else { + renameDir(storage, storagePath, source, dest); + } + } + + private void renameFile(IncrementalStorage storage, Path storagePath, + File source, File dest) throws IOException { + Path sourcePath = source.toPath(); + Path destPath = dest.toPath(); + if (!sourcePath.startsWith(storagePath)) { + throw new IOException("Path: " + source.getAbsolutePath() + " is not on storage at: " + + storagePath.toString()); + } + if (!destPath.startsWith(storagePath)) { + throw new IOException("Path: " + dest.getAbsolutePath() + " is not on storage at: " + + storagePath.toString()); + } + final Path sourceRelativePath = storagePath.relativize(sourcePath); + final Path destRelativePath = storagePath.relativize(destPath); + storage.moveFile(sourceRelativePath.toString(), destRelativePath.toString()); + + } + + private void renameDir(IncrementalStorage storage, Path storagePath, + File source, File dest) throws IOException { + Path destPath = dest.toPath(); + boolean usedMkdir = false; + try { + Os.mkdir(dest.getAbsolutePath(), 0755); + usedMkdir = true; + } catch (ErrnoException e) { + // Traditional mkdir fails but maybe we can create it on Incremental File System if + // the dest path is on the same Incremental storage as the source. + if (destPath.startsWith(storagePath)) { + storage.makeDirectories(storagePath.relativize(destPath).toString()); + } else { + throw new IOException("Failed to create directory: " + dest.getAbsolutePath(), e); + } + } + try { + storage.moveDir(source.getAbsolutePath(), dest.getAbsolutePath()); + } catch (Exception ex) { + if (usedMkdir) { + try { + Os.remove(dest.getAbsolutePath()); + } catch (ErrnoException ignored) { + } + } + throw new IOException( + "Failed to move " + source.getAbsolutePath() + " to " + dest.getAbsolutePath()); + } + } + + /** + * Closes a storage specified by the absolute path. If the path is not Incremental, do nothing. + * Unbinds the target dir and deletes the corresponding storage instance. + */ + public void closeStorage(@NonNull String path) { + try { + final int id = mService.openStorage(path); + if (id < 0) { + return; + } + mService.deleteStorage(id); + synchronized (mStorages) { + mStorages.remove(id); + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Checks if path is mounted on Incremental File System. + */ + public static boolean isIncrementalPath(@NonNull String path) { + // TODO(b/136132412): implement native method + return false; + } +} diff --git a/core/java/android/os/incremental/IncrementalStorage.java b/core/java/android/os/incremental/IncrementalStorage.java new file mode 100644 index 000000000000..2bf89ed7f7e8 --- /dev/null +++ b/core/java/android/os/incremental/IncrementalStorage.java @@ -0,0 +1,346 @@ +/* + * 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.os.incremental; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.RemoteException; + +import java.io.File; +import java.io.IOException; + +/** + * Provides operations on an Incremental File System directory, using IncrementalService. Example + * usage: + * + * <blockquote><pre> + * IncrementalManager manager = (IncrementalManager) getSystemService(Context.INCREMENTAL_MANAGER); + * IncrementalStorage storage = manager.openStorage("/path/to/incremental/dir"); + * storage.makeDirectory("subdir"); + * </pre></blockquote> + * + * @hide + */ +public final class IncrementalStorage { + private static final String TAG = "IncrementalStorage"; + private final int mId; + private final IIncrementalManager mService; + + + public IncrementalStorage(@NonNull IIncrementalManager is, int id) { + mService = is; + mId = id; + } + + public int getId() { + return mId; + } + + /** + * Temporarily bind-mounts the current storage directory to a target directory. The bind-mount + * will NOT be preserved between device reboots. + * + * @param targetPath Absolute path to the target directory. + */ + public void bind(@NonNull String targetPath) throws IOException { + bind("", targetPath); + } + + /** + * Temporarily bind-mounts a subdir under the current storage directory to a target directory. + * The bind-mount will NOT be preserved between device reboots. + * + * @param sourcePathUnderStorage Source path as a relative path under current storage + * directory. + * @param targetPath Absolute path to the target directory. + */ + public void bind(@NonNull String sourcePathUnderStorage, @NonNull String targetPath) + throws IOException { + try { + int res = mService.makeBindMount(mId, sourcePathUnderStorage, targetPath, + IIncrementalManager.BIND_TEMPORARY); + if (res < 0) { + throw new IOException("bind() failed with errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + + /** + * Permanently bind-mounts the current storage directory to a target directory. The bind-mount + * WILL be preserved between device reboots. + * + * @param targetPath Absolute path to the target directory. + */ + public void bindPermanent(@NonNull String targetPath) throws IOException { + bindPermanent("", targetPath); + } + + /** + * Permanently bind-mounts a subdir under the current storage directory to a target directory. + * The bind-mount WILL be preserved between device reboots. + * + * @param sourcePathUnderStorage Relative path under the current storage directory. + * @param targetPath Absolute path to the target directory. + */ + public void bindPermanent(@NonNull String sourcePathUnderStorage, @NonNull String targetPath) + throws IOException { + try { + int res = mService.makeBindMount(mId, sourcePathUnderStorage, targetPath, + IIncrementalManager.BIND_PERMANENT); + if (res < 0) { + throw new IOException("bind() permanent failed with errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Unbinds a bind mount. + * + * @param targetPath Absolute path to the target directory. + */ + public void unBind(@NonNull String targetPath) throws IOException { + try { + int res = mService.deleteBindMount(mId, targetPath); + if (res < 0) { + throw new IOException("unbind() failed with errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Creates a sub-directory under the current storage directory. + * + * @param pathUnderStorage Relative path of the sub-directory, e.g., "subdir" + */ + public void makeDirectory(@NonNull String pathUnderStorage) throws IOException { + try { + int res = mService.makeDirectory(mId, pathUnderStorage); + if (res < 0) { + throw new IOException("makeDirectory() failed with errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Creates a sub-directory under the current storage directory. If its parent dirs do not exist, + * create the parent dirs as well. + * + * @param pathUnderStorage Relative path of the sub-directory, e.g., "subdir/subsubdir" + */ + public void makeDirectories(@NonNull String pathUnderStorage) throws IOException { + try { + int res = mService.makeDirectories(mId, pathUnderStorage); + if (res < 0) { + throw new IOException("makeDirectory() failed with errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Creates a file under the current storage directory. + * + * @param pathUnderStorage Relative path of the new file. + * @param size Size of the new file in bytes. + * @param metadata Metadata bytes. + */ + public void makeFile(@NonNull String pathUnderStorage, long size, + @Nullable byte[] metadata) throws IOException { + try { + int res = mService.makeFile(mId, pathUnderStorage, size, metadata); + if (res < 0) { + throw new IOException("makeFile() failed with errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Creates a file in Incremental storage. The content of the file is mapped from a range inside + * a source file in the same storage. + * + * @param destRelativePath Target relative path under storage. + * @param sourceRelativePath Source relative path under storage. + * @param rangeStart Starting offset (in bytes) in the source file. + * @param rangeEnd Ending offset (in bytes) in the source file. + */ + public void makeFileFromRange(@NonNull String destRelativePath, + @NonNull String sourceRelativePath, long rangeStart, long rangeEnd) throws IOException { + try { + int res = mService.makeFileFromRange(mId, destRelativePath, sourceRelativePath, + rangeStart, rangeEnd); + if (res < 0) { + throw new IOException("makeFileFromRange() failed, errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Creates a hard-link between two paths, which can be under different storages but in the same + * Incremental File System. + * + * @param sourcePathUnderStorage The relative path of the source. + * @param destStorage The target storage of the link target. + * @param destPathUnderStorage The relative path of the target. + */ + public void makeLink(@NonNull String sourcePathUnderStorage, IncrementalStorage destStorage, + @NonNull String destPathUnderStorage) throws IOException { + try { + int res = mService.makeLink(mId, sourcePathUnderStorage, destStorage.getId(), + destPathUnderStorage); + if (res < 0) { + throw new IOException("makeLink() failed with errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Deletes a hard-link under the current storage directory. + * + * @param pathUnderStorage The relative path of the target. + */ + public void unlink(@NonNull String pathUnderStorage) throws IOException { + try { + int res = mService.unlink(mId, pathUnderStorage); + if (res < 0) { + throw new IOException("unlink() failed with errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Rename an old file name to a new file name under the current storage directory. + * + * @param sourcePathUnderStorage Old file path as a relative path to the storage directory. + * @param destPathUnderStorage New file path as a relative path to the storage directory. + */ + public void moveFile(@NonNull String sourcePathUnderStorage, + @NonNull String destPathUnderStorage) throws IOException { + try { + int res = mService.makeLink(mId, sourcePathUnderStorage, mId, destPathUnderStorage); + if (res < 0) { + throw new IOException("moveFile() failed at makeLink(), errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + try { + mService.unlink(mId, sourcePathUnderStorage); + } catch (RemoteException ignored) { + } + } + + /** + * Move a directory, which is bind-mounted to a given storage, to a new location. The bind mount + * will be persistent between reboots. + * + * @param sourcePath The old path of the directory as an absolute path. + * @param destPath The new path of the directory as an absolute path, expected to already + * exist. + */ + public void moveDir(@NonNull String sourcePath, @NonNull String destPath) throws IOException { + if (!new File(destPath).exists()) { + throw new IOException("moveDir() requires that destination dir already exists."); + } + try { + int res = mService.makeBindMount(mId, "", destPath, IIncrementalManager.BIND_PERMANENT); + if (res < 0) { + throw new IOException("moveDir() failed at making bind mount, errno " + -res); + } + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + try { + mService.deleteBindMount(mId, sourcePath); + } catch (RemoteException ignored) { + } + } + + /** + * Checks whether a file under the current storage directory is fully loaded. + * + * @param pathUnderStorage The relative path of the file. + * @return True if the file is fully loaded. + */ + public boolean isFileFullyLoaded(@NonNull String pathUnderStorage) { + return isFileRangeLoaded(pathUnderStorage, 0, -1); + } + + /** + * Checks whether a range in a file if loaded. + * + * @param pathUnderStorage The relative path of the file. + * @param start The starting offset of the range. + * @param end The ending offset of the range. + * @return True if the file is fully loaded. + */ + public boolean isFileRangeLoaded(@NonNull String pathUnderStorage, long start, long end) { + try { + return mService.isFileRangeLoaded(mId, pathUnderStorage, start, end); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return false; + } + } + + /** + * Returns the metadata object of an IncFs File. + * + * @param pathUnderStorage The relative path of the file. + * @return Byte array that contains metadata bytes. + */ + @Nullable + public byte[] getFileMetadata(@NonNull String pathUnderStorage) { + try { + return mService.getFileMetadata(mId, pathUnderStorage); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return null; + } + } + + /** + * Informs the data loader service associated with the current storage to start data loader + * + * @return True if data loader is successfully started. + */ + public boolean startLoading() { + try { + return mService.startLoading(mId); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return false; + } + } +} diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 703b86d3f878..f627daa74da4 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -89,7 +89,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Set; @@ -10646,6 +10645,7 @@ public final class Settings { /** {@hide} */ public static final String BLUETOOTH_HEARING_AID_PRIORITY_PREFIX = "bluetooth_hearing_aid_priority_"; + /** * Enable/disable radio bug detection * @@ -11463,105 +11463,6 @@ public final class Settings { "adb_allowed_connection_time"; /** - * Get the key that retrieves a bluetooth headset's priority. - * @hide - */ - public static final String getBluetoothHeadsetPriorityKey(String address) { - return BLUETOOTH_HEADSET_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves a bluetooth a2dp sink's priority. - * @hide - */ - public static final String getBluetoothA2dpSinkPriorityKey(String address) { - return BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves a bluetooth a2dp src's priority. - * @hide - */ - public static final String getBluetoothA2dpSrcPriorityKey(String address) { - return BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves a bluetooth a2dp device's ability to support optional codecs. - * @hide - */ - public static final String getBluetoothA2dpSupportsOptionalCodecsKey(String address) { - return BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX + - address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves whether a bluetooth a2dp device should have optional codecs - * enabled. - * @hide - */ - public static final String getBluetoothA2dpOptionalCodecsEnabledKey(String address) { - return BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX + - address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves a bluetooth Input Device's priority. - * @hide - */ - public static final String getBluetoothHidHostPriorityKey(String address) { - return BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves a bluetooth pan client priority. - * @hide - */ - public static final String getBluetoothPanPriorityKey(String address) { - return BLUETOOTH_PAN_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves a bluetooth hearing aid priority. - * @hide - */ - public static final String getBluetoothHearingAidPriorityKey(String address) { - return BLUETOOTH_HEARING_AID_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves a bluetooth map priority. - * @hide - */ - public static final String getBluetoothMapPriorityKey(String address) { - return BLUETOOTH_MAP_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves a bluetooth map client priority. - * @hide - */ - public static final String getBluetoothMapClientPriorityKey(String address) { - return BLUETOOTH_MAP_CLIENT_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves a bluetooth pbap client priority. - * @hide - */ - public static final String getBluetoothPbapClientPriorityKey(String address) { - return BLUETOOTH_PBAP_CLIENT_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); - } - - /** - * Get the key that retrieves a bluetooth sap priority. - * @hide - */ - public static final String getBluetoothSapPriorityKey(String address) { - return BLUETOOTH_SAP_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT); - } - - /** * Scaling factor for normal window animations. Setting to 0 will * disable window animations. */ diff --git a/telephony/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index add03160bbe9..add03160bbe9 100644 --- a/telephony/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java index 48ba4295f3c8..4df43628b5d3 100644 --- a/core/java/android/service/autofill/SaveInfo.java +++ b/core/java/android/service/autofill/SaveInfo.java @@ -216,10 +216,21 @@ public final class SaveInfo implements Parcelable { */ public static final int NEGATIVE_BUTTON_STYLE_REJECT = 1; + /** + * Style for the negative button of the save UI to never do the + * save operation. This means that the user does not need to save + * any data on this activity or application. Once the user tapping + * the negative button, the service should never trigger the save + * UI again. In addition to this, must consider providing restore + * options for the user. + */ + public static final int NEGATIVE_BUTTON_STYLE_NEVER = 2; + /** @hide */ @IntDef(prefix = { "NEGATIVE_BUTTON_STYLE_" }, value = { NEGATIVE_BUTTON_STYLE_CANCEL, - NEGATIVE_BUTTON_STYLE_REJECT + NEGATIVE_BUTTON_STYLE_REJECT, + NEGATIVE_BUTTON_STYLE_NEVER }) @Retention(RetentionPolicy.SOURCE) @interface NegativeButtonStyle{} @@ -571,6 +582,7 @@ public final class SaveInfo implements Parcelable { * * @see #NEGATIVE_BUTTON_STYLE_CANCEL * @see #NEGATIVE_BUTTON_STYLE_REJECT + * @see #NEGATIVE_BUTTON_STYLE_NEVER * * @throws IllegalArgumentException If the style is invalid */ @@ -578,11 +590,7 @@ public final class SaveInfo implements Parcelable { @Nullable IntentSender listener) { throwIfDestroyed(); Preconditions.checkArgumentInRange(style, NEGATIVE_BUTTON_STYLE_CANCEL, - NEGATIVE_BUTTON_STYLE_REJECT, "style"); - if (style != NEGATIVE_BUTTON_STYLE_CANCEL - && style != NEGATIVE_BUTTON_STYLE_REJECT) { - throw new IllegalArgumentException("Invalid style: " + style); - } + NEGATIVE_BUTTON_STYLE_NEVER, "style"); mNegativeButtonStyle = style; mNegativeActionListener = listener; return this; diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 32b0f413321a..34654edd00e8 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -17,6 +17,7 @@ package android.view.accessibility; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; @@ -796,10 +797,32 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par private ArrayList<AccessibilityRecord> mRecords; - /* - * Hide constructor from clients. + /** + * Creates a new {@link AccessibilityEvent}. */ - private AccessibilityEvent() { + public AccessibilityEvent() { + if (DEBUG_ORIGIN) originStackTrace = Thread.currentThread().getStackTrace(); + } + + + /** + * Creates a new {@link AccessibilityEvent} with the given <code>eventType</code>. + * + * @param eventType The event type. + */ + public AccessibilityEvent(int eventType) { + mEventType = eventType; + if (DEBUG_ORIGIN) originStackTrace = Thread.currentThread().getStackTrace(); + } + + /** + * Copy constructor. Creates a new {@link AccessibilityEvent}, and this instance is initialized + * from the given <code>event</code>. + * + * @param event The other event. + */ + public AccessibilityEvent(@NonNull AccessibilityEvent event) { + init(event); } /** @@ -816,6 +839,15 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par mWindowChangeTypes = event.mWindowChangeTypes; mEventTime = event.mEventTime; mPackageName = event.mPackageName; + if (event.mRecords != null) { + final int recordCount = event.mRecords.size(); + mRecords = new ArrayList<>(recordCount); + for (int i = 0; i < recordCount; i++) { + final AccessibilityRecord record = event.mRecords.get(i); + final AccessibilityRecord recordClone = new AccessibilityRecord(record); + mRecords.add(recordClone); + } + } if (DEBUG_ORIGIN) originStackTrace = event.originStackTrace; } @@ -1109,6 +1141,9 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * Returns a cached instance if such is available or a new one is * instantiated with its type property set. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityEvent(int)} instead. + * * @param eventType The event type. * @return An instance. */ @@ -1123,23 +1158,15 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * created. The returned instance is initialized from the given * <code>event</code>. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityEvent(AccessibilityEvent)} instead. + * * @param event The other event. * @return An instance. */ public static AccessibilityEvent obtain(AccessibilityEvent event) { AccessibilityEvent eventClone = AccessibilityEvent.obtain(); eventClone.init(event); - - if (event.mRecords != null) { - final int recordCount = event.mRecords.size(); - eventClone.mRecords = new ArrayList<AccessibilityRecord>(recordCount); - for (int i = 0; i < recordCount; i++) { - final AccessibilityRecord record = event.mRecords.get(i); - final AccessibilityRecord recordClone = AccessibilityRecord.obtain(record); - eventClone.mRecords.add(recordClone); - } - } - return eventClone; } @@ -1147,6 +1174,9 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * Returns a cached instance if such is available or a new one is * instantiated. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityEvent()} instead. + * * @return An instance. */ public static AccessibilityEvent obtain() { @@ -1162,6 +1192,8 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * <b>Note: You must not touch the object after calling this function.</b> * </p> * + * <p>In most situations object pooling is not beneficial, and recycling is not necessary. + * * @throws IllegalStateException If the event is already recycled. */ @Override diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index a38955540927..66bf982894aa 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -775,15 +775,38 @@ public class AccessibilityNodeInfo implements Parcelable { private TouchDelegateInfo mTouchDelegateInfo; /** - * Hide constructor from clients. + * Creates a new {@link AccessibilityNodeInfo}. */ - private AccessibilityNodeInfo() { - /* do nothing */ + public AccessibilityNodeInfo() { } - /** @hide */ - AccessibilityNodeInfo(AccessibilityNodeInfo info) { - init(info); + /** + * Creates a new {@link AccessibilityNodeInfo} with the given <code>source</code>. + * + * @param source The source view. + */ + public AccessibilityNodeInfo(@NonNull View source) { + setSource(source); + } + + /** + * Creates a new {@link AccessibilityNodeInfo} with the given <code>source</code>. + * + * @param root The root of the virtual subtree. + * @param virtualDescendantId The id of the virtual descendant. + */ + public AccessibilityNodeInfo(@NonNull View root, int virtualDescendantId) { + setSource(root, virtualDescendantId); + } + + /** + * Copy constructor. Creates a new {@link AccessibilityNodeInfo}, and this new instance is + * initialized from the given <code>info</code>. + * + * @param info The other info. + */ + public AccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) { + init(info, false /* usePoolingInfo */); } /** @@ -911,7 +934,7 @@ public class AccessibilityNodeInfo implements Parcelable { // when it is obtained. Enforce sealing again before we init to fail when a node has been // recycled during a refresh to catch such errors earlier. enforceSealed(); - init(refreshedInfo); + init(refreshedInfo, true /* usePoolingInfo */); refreshedInfo.recycle(); return true; } @@ -3299,6 +3322,9 @@ public class AccessibilityNodeInfo implements Parcelable { * Returns a cached instance if such is available otherwise a new one * and sets the source. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityNodeInfo(View)} instead. + * * @param source The source view. * @return An instance. * @@ -3314,6 +3340,9 @@ public class AccessibilityNodeInfo implements Parcelable { * Returns a cached instance if such is available otherwise a new one * and sets the source. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityNodeInfo(View, int)} instead. + * * @param root The root of the virtual subtree. * @param virtualDescendantId The id of the virtual descendant. * @return An instance. @@ -3329,6 +3358,9 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Returns a cached instance if such is available otherwise a new one. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityNodeInfo()} instead. + * * @return An instance. */ public static AccessibilityNodeInfo obtain() { @@ -3344,12 +3376,15 @@ public class AccessibilityNodeInfo implements Parcelable { * create. The returned instance is initialized from the given * <code>info</code>. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityNodeInfo(AccessibilityNodeInfo)} instead. + * * @param info The other info. * @return An instance. */ public static AccessibilityNodeInfo obtain(AccessibilityNodeInfo info) { AccessibilityNodeInfo infoClone = AccessibilityNodeInfo.obtain(); - infoClone.init(info); + infoClone.init(info, true /* usePoolingInfo */); return infoClone; } @@ -3358,6 +3393,8 @@ public class AccessibilityNodeInfo implements Parcelable { * <p> * <strong>Note:</strong> You must not touch the object after calling this function. * + * <p>In most situations object pooling is not beneficial, and recycling is not necessary. + * * @throws IllegalStateException If the info is already recycled. */ public void recycle() { @@ -3647,8 +3684,9 @@ public class AccessibilityNodeInfo implements Parcelable { * Initializes this instance from another one. * * @param other The other instance. + * @param usePoolingInfos whether using pooled object internally or not */ - private void init(AccessibilityNodeInfo other) { + private void init(AccessibilityNodeInfo other, boolean usePoolingInfos) { mSealed = other.mSealed; mSourceNodeId = other.mSourceNodeId; mParentNodeId = other.mParentNodeId; @@ -3707,6 +3745,18 @@ public class AccessibilityNodeInfo implements Parcelable { mExtras = other.mExtras != null ? new Bundle(other.mExtras) : null; + if (usePoolingInfos) { + initPoolingInfos(other); + } else { + initCopyInfos(other); + } + + final TouchDelegateInfo otherInfo = other.mTouchDelegateInfo; + mTouchDelegateInfo = (otherInfo != null) + ? new TouchDelegateInfo(otherInfo.mTargetMap, true) : null; + } + + private void initPoolingInfos(AccessibilityNodeInfo other) { if (mRangeInfo != null) mRangeInfo.recycle(); mRangeInfo = (other.mRangeInfo != null) ? RangeInfo.obtain(other.mRangeInfo) : null; @@ -3716,10 +3766,20 @@ public class AccessibilityNodeInfo implements Parcelable { if (mCollectionItemInfo != null) mCollectionItemInfo.recycle(); mCollectionItemInfo = (other.mCollectionItemInfo != null) ? CollectionItemInfo.obtain(other.mCollectionItemInfo) : null; + } - final TouchDelegateInfo otherInfo = other.mTouchDelegateInfo; - mTouchDelegateInfo = (otherInfo != null) - ? new TouchDelegateInfo(otherInfo.mTargetMap, true) : null; + private void initCopyInfos(AccessibilityNodeInfo other) { + RangeInfo ri = other.mRangeInfo; + mRangeInfo = (ri == null) ? null + : new RangeInfo(ri.mType, ri.mMin, ri.mMax, ri.mCurrent); + CollectionInfo ci = other.mCollectionInfo; + mCollectionInfo = (ci == null) ? null + : new CollectionInfo(ci.mRowCount, ci.mColumnCount, + ci.mHierarchical, ci.mSelectionMode); + CollectionItemInfo cii = other.mCollectionItemInfo; + mCollectionItemInfo = (cii == null) ? null + : new CollectionItemInfo(cii.mRowIndex, cii.mRowSpan, cii.mColumnIndex, + cii.mColumnSpan, cii.mHeading, cii.mSelected); } /** @@ -3854,7 +3914,7 @@ public class AccessibilityNodeInfo implements Parcelable { * Clears the state of this instance. */ private void clear() { - init(DEFAULT); + init(DEFAULT, true /* usePoolingInfo */); } private static boolean isDefaultStandardAction(AccessibilityAction action) { @@ -4709,6 +4769,10 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Obtains a pooled instance that is a clone of another one. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link AccessibilityNodeInfo.RangeInfo#AccessibilityNodeInfo.RangeInfo(int, + * float, float, float)} instead. + * * @param other The instance to clone. * * @hide @@ -4720,6 +4784,10 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Obtains a pooled instance. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link AccessibilityNodeInfo.RangeInfo#AccessibilityNodeInfo.RangeInfo(int, + * float, float, float)} instead. + * * @param type The type of the range. * @param min The minimum value. Use {@code Float.NEGATIVE_INFINITY} if the range has no * minimum. @@ -4750,7 +4818,7 @@ public class AccessibilityNodeInfo implements Parcelable { * maximum. * @param current The current value. */ - private RangeInfo(int type, float min, float max, float current) { + public RangeInfo(int type, float min, float max, float current) { mType = type; mMin = min; mMax = max; @@ -4799,6 +4867,8 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Recycles this instance. + * + * <p>In most situations object pooling is not beneficial, and recycling is not necessary. */ void recycle() { clear(); @@ -4849,6 +4919,10 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Obtains a pooled instance that is a clone of another one. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link + * AccessibilityNodeInfo.CollectionInfo#AccessibilityNodeInfo.CollectionInfo} instead. + * * @param other The instance to clone. * @hide */ @@ -4860,6 +4934,11 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Obtains a pooled instance. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link + * AccessibilityNodeInfo.CollectionInfo#AccessibilityNodeInfo.CollectionInfo(int, int, + * boolean)} instead. + * * @param rowCount The number of rows, or -1 if count is unknown. * @param columnCount The number of columns, or -1 if count is unknown. * @param hierarchical Whether the collection is hierarchical. @@ -4872,6 +4951,11 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Obtains a pooled instance. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link + * AccessibilityNodeInfo.CollectionInfo#AccessibilityNodeInfo.CollectionInfo(int, int, + * boolean, int)} instead. + * * @param rowCount The number of rows. * @param columnCount The number of columns. * @param hierarchical Whether the collection is hierarchical. @@ -4902,9 +4986,20 @@ public class AccessibilityNodeInfo implements Parcelable { * @param rowCount The number of rows. * @param columnCount The number of columns. * @param hierarchical Whether the collection is hierarchical. + */ + public CollectionInfo(int rowCount, int columnCount, boolean hierarchical) { + this(rowCount, columnCount, hierarchical, SELECTION_MODE_NONE); + } + + /** + * Creates a new instance. + * + * @param rowCount The number of rows. + * @param columnCount The number of columns. + * @param hierarchical Whether the collection is hierarchical. * @param selectionMode The collection's selection mode. */ - private CollectionInfo(int rowCount, int columnCount, boolean hierarchical, + public CollectionInfo(int rowCount, int columnCount, boolean hierarchical, int selectionMode) { mRowCount = rowCount; mColumnCount = columnCount; @@ -4955,6 +5050,8 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Recycles this instance. + * + * <p>In most situations object pooling is not beneficial, and recycling is not necessary. */ void recycle() { clear(); @@ -4991,6 +5088,11 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Obtains a pooled instance that is a clone of another one. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link + * AccessibilityNodeInfo.CollectionItemInfo#AccessibilityNodeInfo.CollectionItemInfo} + * instead. + * * @param other The instance to clone. * @hide */ @@ -5002,6 +5104,11 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Obtains a pooled instance. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link + * AccessibilityNodeInfo.CollectionItemInfo#AccessibilityNodeInfo.CollectionItemInfo(int, + * int, int, int, boolean)} instead. + * * @param rowIndex The row index at which the item is located. * @param rowSpan The number of rows the item spans. * @param columnIndex The column index at which the item is located. @@ -5017,6 +5124,11 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Obtains a pooled instance. * + * <p>In most situations object pooling is not beneficial. Creates a new instance using the + * constructor {@link + * AccessibilityNodeInfo.CollectionItemInfo#AccessibilityNodeInfo.CollectionItemInfo(int, + * int, int, int, boolean, boolean)} instead. + * * @param rowIndex The row index at which the item is located. * @param rowSpan The number of rows the item spans. * @param columnIndex The column index at which the item is located. @@ -5058,7 +5170,22 @@ public class AccessibilityNodeInfo implements Parcelable { * @param columnSpan The number of columns the item spans. * @param heading Whether the item is a heading. */ - private CollectionItemInfo(int rowIndex, int rowSpan, int columnIndex, int columnSpan, + public CollectionItemInfo(int rowIndex, int rowSpan, int columnIndex, int columnSpan, + boolean heading) { + this(rowIndex, rowSpan, columnIndex, columnSpan, heading, false); + } + + /** + * Creates a new instance. + * + * @param rowIndex The row index at which the item is located. + * @param rowSpan The number of rows the item spans. + * @param columnIndex The column index at which the item is located. + * @param columnSpan The number of columns the item spans. + * @param heading Whether the item is a heading. + * @param selected Whether the item is selected. + */ + public CollectionItemInfo(int rowIndex, int rowSpan, int columnIndex, int columnSpan, boolean heading, boolean selected) { mRowIndex = rowIndex; mRowSpan = rowSpan; @@ -5126,6 +5253,8 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Recycles this instance. + * + * <p>In most situations object pooling is not beneficial, and recycling is not necessary. */ void recycle() { clear(); diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java index d7d7e210e5f4..4f6c9ef55220 100644 --- a/core/java/android/view/accessibility/AccessibilityRecord.java +++ b/core/java/android/view/accessibility/AccessibilityRecord.java @@ -18,6 +18,7 @@ package android.view.accessibility; import static com.android.internal.util.CollectionUtils.isEmpty; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; import android.os.Parcelable; @@ -113,10 +114,20 @@ public class AccessibilityRecord { int mConnectionId = UNDEFINED; - /* - * Hide constructor. + /** + * Creates a new {@link AccessibilityRecord}. */ - AccessibilityRecord() { + public AccessibilityRecord() { + } + + /** + * Copy constructor. Creates a new {@link AccessibilityRecord}, and this instance is initialized + * with data from the given <code>record</code>. + * + * @param record The other record. + */ + public AccessibilityRecord(@NonNull AccessibilityRecord record) { + init(record); } /** @@ -790,6 +801,9 @@ public class AccessibilityRecord { * instantiated. The instance is initialized with data from the * given record. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityRecord(AccessibilityRecord)} instead. + * * @return An instance. */ public static AccessibilityRecord obtain(AccessibilityRecord record) { @@ -802,6 +816,9 @@ public class AccessibilityRecord { * Returns a cached instance if such is available or a new one is * instantiated. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityRecord()} instead. + * * @return An instance. */ public static AccessibilityRecord obtain() { @@ -823,6 +840,8 @@ public class AccessibilityRecord { * <p> * <strong>Note:</strong> You must not touch the object after calling this function. * + * <p>In most situations object pooling is not beneficial, and recycling is not necessary. + * * @throws IllegalStateException If the record is already recycled. */ public void recycle() { diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java index 5fa8a6e0e06b..2cc6e9aebd74 100644 --- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java +++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java @@ -119,12 +119,19 @@ public final class AccessibilityWindowInfo implements Parcelable { private int mConnectionId = UNDEFINED_WINDOW_ID; - private AccessibilityWindowInfo() { - /* do nothing - hide constructor */ + /** + * Creates a new {@link AccessibilityWindowInfo}. + */ + public AccessibilityWindowInfo() { } - /** @hide */ - AccessibilityWindowInfo(AccessibilityWindowInfo info) { + /** + * Copy constructor. Creates a new {@link AccessibilityWindowInfo}, and this new instance is + * initialized from given <code>info</code>. + * + * @param info The other info. + */ + public AccessibilityWindowInfo(@NonNull AccessibilityWindowInfo info) { init(info); } @@ -469,6 +476,9 @@ public final class AccessibilityWindowInfo implements Parcelable { * Returns a cached instance if such is available or a new one is * created. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityWindowInfo()} instead. + * * @return An instance. */ public static AccessibilityWindowInfo obtain() { @@ -487,6 +497,9 @@ public final class AccessibilityWindowInfo implements Parcelable { * created. The returned instance is initialized from the given * <code>info</code>. * + * <p>In most situations object pooling is not beneficial. Create a new instance using the + * constructor {@link #AccessibilityWindowInfo(AccessibilityWindowInfo)} instead. + * * @param info The other info. * @return An instance. */ @@ -514,6 +527,8 @@ public final class AccessibilityWindowInfo implements Parcelable { * <strong>Note:</strong> You must not touch the object after calling this function. * </p> * + * <p>In most situations object pooling is not beneficial, and recycling is not necessary. + * * @throws IllegalStateException If the info is already recycled. */ public void recycle() { diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java index fee8345d1660..0847fbdd2291 100644 --- a/core/java/com/android/internal/content/NativeLibraryHelper.java +++ b/core/java/com/android/internal/content/NativeLibraryHelper.java @@ -33,7 +33,6 @@ import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; import android.os.Build; import android.os.SELinux; -import android.os.SystemProperties; import android.system.ErrnoException; import android.system.Os; import android.util.Slog; @@ -444,6 +443,24 @@ public class NativeLibraryHelper { return sum; } + /** + * Configure the native library files managed by Incremental Service. Makes sure Incremental + * Service will create native library directories and set up native library binary files in the + * same structure as they are in non-incremental installations. + * + * @param pkg The package to be installed, including all the APK files. + * @param handle The pointer to an zip archive. + * @param libraryRoot The root directory of the native library files, e.g., lib/ + * @param abiList The list of ABIs that are supported by the current device. + * @param useIsaSubdir Whether or not to set up a sub dir for the ISA. + * @return ABI code if installation succeeds or error code if installation fails. + */ + public static int configureNativeBinariesForSupportedAbi(Package pkg, Handle handle, + File libraryRoot, String[] abiList, boolean useIsaSubdir) { + // TODO(b/136132412): Implement this. + return -1; + } + // We don't care about the other return values for now. private static final int BITCODE_PRESENT = 1; diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 865ec27e00c4..9ee79eada626 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -254,18 +254,6 @@ public class ZygoteInit { InputStream is; try { - // If we are profiling the boot image, avoid preloading classes. - // Can't use device_config since we are the zygote. - String prop = SystemProperties.get( - "persist.device_config.runtime_native_boot.profilebootclasspath", ""); - // Might be empty if the property is unset since the default is "". - if (prop.length() == 0) { - prop = SystemProperties.get("dalvik.vm.profilebootclasspath", ""); - } - if ("true".equals(prop)) { - return; - } - is = new FileInputStream(PRELOADED_CLASSES); } catch (FileNotFoundException e) { Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + "."); @@ -345,6 +333,22 @@ public class ZygoteInit { runtime.preloadDexCaches(); Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + // If we are profiling the boot image, reset the Jit counters after preloading the + // classes. We want to preload for performance, and we can use method counters to + // infer what clases are used after calling resetJitCounters, for profile purposes. + // Can't use device_config since we are the zygote. + String prop = SystemProperties.get( + "persist.device_config.runtime_native_boot.profilebootclasspath", ""); + // Might be empty if the property is unset since the default is "". + if (prop.length() == 0) { + prop = SystemProperties.get("dalvik.vm.profilebootclasspath", ""); + } + if ("true".equals(prop)) { + Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ResetJitCounters"); + runtime.resetJitCounters(); + Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + } + // Bring back root. We'll need it later if we're in the zygote. if (droppedPriviliges) { try { diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java index b4bab809cc00..154ea52bf9ba 100644 --- a/core/java/com/android/internal/util/BitUtils.java +++ b/core/java/com/android/internal/util/BitUtils.java @@ -68,9 +68,9 @@ public final class BitUtils { int[] result = new int[size]; int index = 0; int bitPos = 0; - while (val > 0) { + while (val != 0) { if ((val & 1) == 1) result[index++] = bitPos; - val = val >> 1; + val = val >>> 1; bitPos++; } return result; @@ -79,7 +79,7 @@ public final class BitUtils { public static long packBits(int[] bits) { long packed = 0; for (int b : bits) { - packed |= (1 << b); + packed |= (1L << b); } return packed; } diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp index 0cfbec5c0934..1b2776525e47 100644 --- a/core/jni/android/graphics/Path.cpp +++ b/core/jni/android/graphics/Path.cpp @@ -419,7 +419,7 @@ public: float errorSquared = acceptableError * acceptableError; float errorConic = acceptableError / 2; // somewhat arbitrary - while ((verb = pathIter.next(points, false)) != SkPath::kDone_Verb) { + while ((verb = pathIter.next(points)) != SkPath::kDone_Verb) { createVerbSegments(pathIter, verb, points, segmentPoints, lengths, errorSquared, errorConic); } diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto index 0cfb36b3f4d3..d181436d18f3 100644 --- a/core/proto/android/app/settings_enums.proto +++ b/core/proto/android/app/settings_enums.proto @@ -2451,4 +2451,14 @@ enum PageId { // CATEGORY: SETTINGS // OS: R SETTINGS_PLATFORM_COMPAT_DASHBOARD = 1805; + + // OPEN: Settings > Location -> Work profile tab + // CATEGORY: SETTINGS + // OS: R + LOCATION_WORK = 1806; + + // OPEN: Settings > Account -> Work profile tab + // CATEGORY: SETTINGS + // OS: R + ACCOUNT_WORK = 1807; } diff --git a/core/res/res/layout/shutdown_dialog.xml b/core/res/res/layout/shutdown_dialog.xml index 2d214b32164b..ec67aa86bcc9 100644 --- a/core/res/res/layout/shutdown_dialog.xml +++ b/core/res/res/layout/shutdown_dialog.xml @@ -32,6 +32,19 @@ android:layout_height="32sp" android:text="@string/shutdown_progress" android:textDirection="locale" + android:textSize="18sp" + android:textAppearance="?attr/textAppearanceMedium" + android:gravity="center" + android:layout_marginBottom="24dp" + android:visibility="gone" + android:fontFamily="@string/config_headlineFontFamily"/> + + <TextView + android:id="@+id/text2" + android:layout_width="wrap_content" + android:layout_height="32sp" + android:text="@string/shutdown_progress" + android:textDirection="locale" android:textSize="24sp" android:textAppearance="?attr/textAppearanceLarge" android:gravity="center" diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index db5b2cbeef85..d095690588f5 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Die werkprofiel se administrasieprogram ontbreek of is korrup. Gevolglik is jou werkprofiel en verwante data uitgevee. Kontak jou administrateur vir bystand."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jou werkprofiel is nie meer op hierdie toestel beskikbaar nie"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Te veel wagwoordpogings"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Toestel word bestuur"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Jou organisasie bestuur hierdie toestel en kan netwerkverkeer monitor. Tik vir besonderhede."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Jou toestel sal uitgevee word"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Laai tans..."</string> <string name="capital_on" msgid="2770685323900821829">"AAN"</string> <string name="capital_off" msgid="7443704171014626777">"AF"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"gemerk"</string> + <string name="not_checked" msgid="7972320087569023342">"nie gemerk nie"</string> <string name="whichApplication" msgid="5432266899591255759">"Voltooi handeling met"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Voltooi handeling met gebruik van %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Voltooi handeling"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 4e84c66aabed..75444ea595c2 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"የሥራ መገለጫ አስተዳዳሪ መተግበሪያው ወይም ይጎድላል ወይም ተበላሽቷል። በዚህ ምክንያት የሥራ መገለጫዎ እና ተዛማጅ ውሂብ ተሰርዘዋል። እርዳታን ለማግኘት አስተዳዳሪዎን ያነጋግሩ።"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"የሥራ መገለጫዎ ከዚህ በኋላ በዚህ መሣሪያ ላይ አይገኝም"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"በጣም ብዙ የይለፍ ቃል ሙከራዎች"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"መሣሪያው የሚተዳደር ነው"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"የእርስዎ ድርጅት ይህን መሣሪያ ያስተዳድራል፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል። ዝርዝሮችን ለማግኘት መታ ያድርጉ።"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"የእርስዎ መሣሪያ ይደመሰሳል"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"በመጫን ላይ…"</string> <string name="capital_on" msgid="2770685323900821829">"በ"</string> <string name="capital_off" msgid="7443704171014626777">"ውጪ"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ምልክት ተደርጎበታል"</string> + <string name="not_checked" msgid="7972320087569023342">"ምልክት አልተደረገበትም"</string> <string name="whichApplication" msgid="5432266899591255759">"... በመጠቀም ድርጊቱን አጠናቅ"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$sን ተጠቅመው እርምጃ ያጠናቅቁ"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"እርምጃውን አጠናቅቅ"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"የተከፈለ ማያን ቀያይር"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"የማያ ገጽ ቁልፍ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ቅጽበታዊ ገጽ እይታ"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"የ<xliff:g id="APP_NAME">%1$s</xliff:g> መተግበሪያ በብቅ-ባይ መስኮት ውስጥ።"</string> </resources> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index bf9eeb2f78be..9928436b2a01 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -196,6 +196,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"تطبيق المشرف للملف الشخصي للعمل مفقود أو تالف لذا تم حذف الملف الشخصي للعمل والبيانات ذات الصلة. اتصل بالمشرف للحصول على المساعدة."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"لم يعد ملفك الشخصي للعمل متاحًا على هذا الجهاز"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"تم إجراء محاولات كثيرة جدًا لإدخال كلمة المرور"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"تتم إدارة الجهاز"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"تدير مؤسستك هذا الجهاز ويمكنها مراقبة حركة بيانات الشبكة. يمكنك النقر للحصول على تفاصيل."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"سيتم محو بيانات جهازك."</string> @@ -1196,10 +1198,8 @@ <string name="loading" msgid="3138021523725055037">"جارٍ التحميل…"</string> <string name="capital_on" msgid="2770685323900821829">"مفعّلة"</string> <string name="capital_off" msgid="7443704171014626777">"إيقاف"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"تم وضع علامة"</string> + <string name="not_checked" msgid="7972320087569023342">"لم يتم وضع علامة"</string> <string name="whichApplication" msgid="5432266899591255759">"إكمال الإجراء باستخدام"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"إكمال الإجراء باستخدام %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"إكمال الإجراء"</string> @@ -2140,6 +2140,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"تبديل \"تقسيم الشاشة\""</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"شاشة القفل"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"لقطة شاشة"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> في نافذة منبثقة"</string> </resources> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 7fa36deb967f..cfd62394fd79 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"কৰ্মস্থানৰ প্ৰ\'ফাইলৰ প্ৰশাসক এপ্ নাই বা ব্যৱহাৰযোগ্য হৈ থকা নাই। যাৰ ফলত আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইল আৰু ইয়াৰ লগত জড়িত অন্য ডেটাসমূহ মচা হৈছে। সহায়ৰ বাবে আপোনাৰ প্ৰশাসকৰ সৈতে সম্পর্ক কৰক।"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"আপোনাৰ কৰ্মস্থানৰ প্ৰ\'ফাইল এই ডিভাইচটোত আৰু উপলব্ধ নহয়"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"বহুতবাৰ ভুলকৈ পাছৱৰ্ড দিয়া হৈছে"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"পৰিচালিত ডিভাইচ"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"আপোনাৰ প্ৰতিষ্ঠানটোৱে এই ডিভাইচটো পৰিচালনা কৰে আৰু ই নেটৱৰ্কৰ ট্ৰেফিক পৰ্যবেক্ষণ কৰিব পাৰে। সবিশেষ জানিবলৈ টিপক।"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"আপোনাৰ ডিভাইচৰ ডেটা মচা হ\'ব"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"ল\'ড কৰি থকা হৈছে…"</string> <string name="capital_on" msgid="2770685323900821829">"অন কৰক"</string> <string name="capital_off" msgid="7443704171014626777">"অফ কৰক"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"টিক চিহ্ন দিয়া হৈছে"</string> + <string name="not_checked" msgid="7972320087569023342">"টিক চিহ্ন দিয়া হোৱা নাই"</string> <string name="whichApplication" msgid="5432266899591255759">"এয়া ব্যৱহাৰ কৰি কার্য সম্পূর্ণ কৰক"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ব্যৱহাৰ কৰি কাৰ্যটো সম্পূৰ্ণ কৰক"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"কাৰ্য সম্পূৰ্ণ কৰক"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"বিভাজিত স্ক্ৰীন ট’গল কৰক"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"লক স্ক্ৰীন"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"স্ক্ৰীণশ্বট"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"পপ আপ ৱিণ্ড’ত <xliff:g id="APP_NAME">%1$s</xliff:g> এপ্।"</string> </resources> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 85186faa8cf1..a26d49d79d28 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"İş profili admin tətbiqi ya yoxdur, ya da korlanıb. Nəticədə iş profili və onunla bağlı data silinib. Kömək üçün admin ilə əlaqə saxlayın."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"İş profili artıq bu cihazda əlçatan deyil"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Həddindən çox parol cəhdi"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Cihaz idarə olunur"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Təşkilat bu cihazı idarə edir və şəbəkənin ötürülməsinə nəzarət edə bilər. Detallar üçün klikləyin."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Cihazınız təmizlənəcəkdir"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Yüklənir…"</string> <string name="capital_on" msgid="2770685323900821829">"AÇIQ"</string> <string name="capital_off" msgid="7443704171014626777">"QAPALI"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"yoxlanılıb"</string> + <string name="not_checked" msgid="7972320087569023342">"yoxlanılmayıb"</string> <string name="whichApplication" msgid="5432266899591255759">"Əməliyyatı tamamlayın:"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s istifadə edərək əməliyyatı tamamlayın"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Əməliyyatı tamamlayın"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Bölünmüş Ekrana keçid"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Kilid Ekranı"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekran şəkli"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Açilən pəncərədə <xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi."</string> </resources> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index d576e8c7fc8d..6d0ae6bab591 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -190,6 +190,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikacija za administratore na profilu za Work nedostaje ili je oštećena. Zbog toga su profil za Work i povezani podaci izbrisani. Obratite se administratoru za pomoć."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profil za Work više nije dostupan na ovom uređaju"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše pokušaja unosa lozinke"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Uređajem se upravlja"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Organizacija upravlja ovim uređajem i može da nadgleda mrežni saobraćaj. Dodirnite za detalje."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti obrisan"</string> @@ -1136,10 +1138,8 @@ <string name="loading" msgid="3138021523725055037">"Učitava se…"</string> <string name="capital_on" msgid="2770685323900821829">"DA"</string> <string name="capital_off" msgid="7443704171014626777">"NE"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"označeno je"</string> + <string name="not_checked" msgid="7972320087569023342">"nije označeno"</string> <string name="whichApplication" msgid="5432266899591255759">"Dovršavanje radnje pomoću"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Završite radnju pomoću aplikacije %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Završi radnju"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index f2fb72ee485f..390e8b190d92 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -192,6 +192,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Праграма адміністратара для працоўнага профілю адсутнічае або пашкоджана. У выніку гэтага ваш працоўны профіль і звязаныя з ім даныя былі выдалены. Звярніцеся па дапамогу да адміністратара."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Ваш працоўны профіль больш не даступны на гэтай прыладзе"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Занадта шмат спроб уводу пароля"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Прылада знаходзіцца пад кіраваннем"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Ваша арганізацыя кіруе гэтай прыладай і можа сачыць за сеткавым трафікам. Дакраніцеся для атрымання дадатковай інфармацыі."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Даныя вашай прылады будуць сцерты"</string> @@ -1156,10 +1158,8 @@ <string name="loading" msgid="3138021523725055037">"Загрузка..."</string> <string name="capital_on" msgid="2770685323900821829">"Уключыць"</string> <string name="capital_off" msgid="7443704171014626777">"Выключана"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"пазначана"</string> + <string name="not_checked" msgid="7972320087569023342">"не пазначана"</string> <string name="whichApplication" msgid="5432266899591255759">"Завяршыць дзеянне з дапамогай"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Завяршыць дзеянне з дапамогай %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Завяршыць дзеянне"</string> @@ -2072,6 +2072,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Пераключальнік падзеленага экрана"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Экран блакіроўкі"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Здымак экрана"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" ва ўсплывальным акне."</string> </resources> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index f89b985989df..d47229df5d40 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Приложението за администриране на служебния потребителски профил липсва или е повредено. В резултат на това той и свързаните с него данни са изтрити. За съдействие се свържете с администратора си."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Служебният ви потребителски профил вече не е налице на това устройство"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Опитите за паролата са твърде много"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Устройството се управлява"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Организацията ви управлява това устройство и може да наблюдава мрежовия трафик. Докоснете за подробности."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Данните на устройството ви ще бъдат изтрити"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Зарежда се..."</string> <string name="capital_on" msgid="2770685323900821829">"ВКЛ"</string> <string name="capital_off" msgid="7443704171014626777">"ИЗКЛ"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"с отметка"</string> + <string name="not_checked" msgid="7972320087569023342">"без отметка"</string> <string name="whichApplication" msgid="5432266899591255759">"Изпълняване на действието чрез"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Завършване на действието посредством %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Изпълняване на действието"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Превключване на разделения екран"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заключен екран"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Екранна снимка"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Приложението <xliff:g id="APP_NAME">%1$s</xliff:g> в изскачащ прозорец."</string> </resources> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 2086da70e8f5..a767a71265da 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"কর্মস্থলের প্রোফাইলের প্রশাসক অ্যাপটি হয় নেই, অথবা সেটি ক্ষতিগ্রস্ত হয়েছে৷ এর ফলে আপনার কর্মস্থলের প্রোফাইল এবং সম্পর্কিত ডেটা মুছে ফেলা হয়েছে৷ সহায়তার জন্য আপনার প্রশাসকের সাথে যোগাযোগ করুন৷"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"আপনার কর্মস্থলের প্রোফাইলটি আর এই ডিভাইসে নেই"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"বহুবার ভুল পাসওয়ার্ড দিয়েছেন"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"ডিভাইসটি পরিচালনা করা হচ্ছে"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"আপনার প্রতিষ্ঠান এই ডিভাইসটি পরিচালনা করে এবং এটির নেটওয়ার্ক ট্রাফিকের উপরে নজর রাখতে পারে। বিশদ বিবরণের জন্য ট্যাপ করুন।,"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"আপনার ডিভাইসটি মুছে ফেলা হবে"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"লোড হচ্ছে..."</string> <string name="capital_on" msgid="2770685323900821829">"চালু"</string> <string name="capital_off" msgid="7443704171014626777">"বন্ধ আছে"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"টিকচিহ্ন দেওয়া আছে"</string> + <string name="not_checked" msgid="7972320087569023342">"টিকচিহ্ন দেওয়া নেই"</string> <string name="whichApplication" msgid="5432266899591255759">"এটি ব্যবহার করে ক্রিয়াকলাপ সম্পূর্ণ করুন"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ব্যবহার করে ক্রিয়াকলাপ সম্পূর্ণ করুন"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"ক্রিয়াকলাপ সম্পূর্ণ করুন"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"স্প্লিট স্ক্রিন টগল করুন"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"লক স্ক্রিন"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"স্ক্রিনশট"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"পপ-আপ উইন্ডোতে <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপ।"</string> </resources> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index b30ea42659c9..f1c15001e6ae 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -190,6 +190,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Nedostaje aplikacija administratora za radni profil ili je neispravna. Zbog toga su vaš radni profil i povezani podaci izbrisani. Obratite administratoru za pomoć."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Radni profil više nije dostupan na ovom uređaju"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše puta ste pokušali otključati uređaj"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Uređajem se upravlja."</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja ovim uređajem i može pratiti mrežni saobraćaj. Dodirnite za detalje."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će biti izbrisan"</string> @@ -1136,10 +1138,8 @@ <string name="loading" msgid="3138021523725055037">"Učitavanje..."</string> <string name="capital_on" msgid="2770685323900821829">"Uključeno"</string> <string name="capital_off" msgid="7443704171014626777">"Isključeno"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"označeno"</string> + <string name="not_checked" msgid="7972320087569023342">"nije označeno"</string> <string name="whichApplication" msgid="5432266899591255759">"Izvrši akciju koristeći"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Dovršite akciju koristeći %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Izvršiti akciju"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 560e49354b42..4b1940518584 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Falta l\'aplicació d\'administració del perfil professional o està malmesa. Com a conseqüència, s\'han suprimit el teu perfil professional i les dades relacionades. Contacta amb l\'administrador per obtenir ajuda."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"El teu perfil professional ja no està disponible en aquest dispositiu"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Has intentat introduir la contrasenya massa vegades"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"El dispositiu està gestionat"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"La teva organització gestiona aquest dispositiu i és possible que supervisi el trànsit de xarxa. Toca per obtenir més informació."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"El contingut del dispositiu s\'esborrarà"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"S\'està carregant…"</string> <string name="capital_on" msgid="2770685323900821829">"SÍ"</string> <string name="capital_off" msgid="7443704171014626777">"NO"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"seleccionat"</string> + <string name="not_checked" msgid="7972320087569023342">"no seleccionat"</string> <string name="whichApplication" msgid="5432266899591255759">"Completa l\'acció mitjançant"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Completa l\'acció amb %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Completa l\'acció"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Commuta Pantalla dividida"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Pantalla de bloqueig"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de pantalla"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplicació <xliff:g id="APP_NAME">%1$s</xliff:g> a la finestra emergent."</string> </resources> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 9527c150e5ec..22fd4c6464ef 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -192,6 +192,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikace pro správu pracovního profilu chybí nebo je poškozena. Váš pracovní profil a související data proto byla smazána. Požádejte o pomoc administrátora."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Váš pracovní profil v tomto zařízení již není k dispozici"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Příliš mnoho pokusů o zadání hesla"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Zařízení je spravováno"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Toto zařízení je spravováno vaší organizací, která může sledovat síťový provoz. Podrobnosti zobrazíte klepnutím."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Zařízení bude vymazáno"</string> @@ -1156,10 +1158,8 @@ <string name="loading" msgid="3138021523725055037">"Načítání..."</string> <string name="capital_on" msgid="2770685323900821829">"I"</string> <string name="capital_off" msgid="7443704171014626777">"O"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"vybráno"</string> + <string name="not_checked" msgid="7972320087569023342">"nevybráno"</string> <string name="whichApplication" msgid="5432266899591255759">"Dokončit akci pomocí aplikace"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Dokončit akci pomocí aplikace %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Dokončit akci"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 852256e9c79f..4475a1bd3e13 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Administrationsappen til arbejdsprofilen mangler eller er beskadiget. Derfor er din arbejdsprofil og dine relaterede data blevet slettet. Kontakt din administrator for at få hjælp."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Din arbejdsprofil er ikke længere tilgængelig på denne enhed"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"For mange mislykkede adgangskodeforsøg"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Dette er en administreret enhed"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Din organisation administrerer denne enhed og kan overvåge netværkstrafik. Tryk for at se info."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Enheden slettes"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Indlæser…"</string> <string name="capital_on" msgid="2770685323900821829">"TIL"</string> <string name="capital_off" msgid="7443704171014626777">"FRA"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"slået til"</string> + <string name="not_checked" msgid="7972320087569023342">"slået fra"</string> <string name="whichApplication" msgid="5432266899591255759">"Brug"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Gennemfør handling ved hjælp af %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Afslut handling"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 8d86317b8bd2..2489fca648a9 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Die Admin-App für das Arbeitsprofil fehlt oder ist beschädigt. Daher wurden dein Arbeitsprofil und alle zugehörigen Daten gelöscht. Bitte wende dich für weitere Hilfe an deinen Administrator."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Dein Arbeitsprofil ist auf diesem Gerät nicht mehr verfügbar"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Zu viele falsche Passworteingaben"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Dies ist ein verwaltetes Gerät"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Deine Organisation verwaltet dieses Gerät und überprüft unter Umständen den Netzwerkverkehr. Tippe hier, um weitere Informationen zu erhalten."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Die Daten auf deinem Gerät werden gelöscht."</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Wird geladen…"</string> <string name="capital_on" msgid="2770685323900821829">"AN"</string> <string name="capital_off" msgid="7443704171014626777">"AUS"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"aktiviert"</string> + <string name="not_checked" msgid="7972320087569023342">"deaktiviert"</string> <string name="whichApplication" msgid="5432266899591255759">"Aktion durchführen mit"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Aktion mit %1$s abschließen"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Abschließen"</string> @@ -1539,7 +1539,7 @@ <string name="launchBrowserDefault" msgid="6328349989932924119">"Browser starten?"</string> <string name="SetupCallDefault" msgid="5581740063237175247">"Anruf annehmen?"</string> <string name="activity_resolver_use_always" msgid="5575222334666843269">"Immer"</string> - <string name="activity_resolver_set_always" msgid="4142825808921411476">"Auf \"Immer öffnen\" festlegen"</string> + <string name="activity_resolver_set_always" msgid="4142825808921411476">"Immer damit öffnen"</string> <string name="activity_resolver_use_once" msgid="948462794469672658">"Nur diesmal"</string> <string name="activity_resolver_app_settings" msgid="6758823206817748026">"Einstellungen"</string> <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"Das Arbeitsprofil wird von %1$s nicht unterstützt."</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 890a54881dee..6c76a1f3d2ef 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Η εφαρμογή διαχείρισης προφίλ εργασίας είτε λείπει είτε είναι κατεστραμμένη. Ως αποτέλεσμα, διαγράφηκε το προφίλ εργασίας και τα σχετικά δεδομένα. Επικοινωνήστε με τον διαχειριστή σας για βοήθεια."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Το προφίλ εργασίας σας δεν είναι πια διαθέσιμο σε αυτήν τη συσκευή"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Πάρα πολλές προσπάθειες εισαγωγής κωδικού πρόσβασης"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Η συσκευή είναι διαχειριζόμενη"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Ο οργανισμός σας διαχειρίζεται αυτήν τη συσκευή και ενδέχεται να παρακολουθεί την επισκεψιμότητα δικτύου. Πατήστε για λεπτομέρειες."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Η συσκευή σας θα διαγραφεί"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Φόρτωση…"</string> <string name="capital_on" msgid="2770685323900821829">"Ενεργό"</string> <string name="capital_off" msgid="7443704171014626777">"Ανενεργό"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"επιλεγμένο"</string> + <string name="not_checked" msgid="7972320087569023342">"μη επιλεγμένο"</string> <string name="whichApplication" msgid="5432266899591255759">"Ολοκλήρωση ενέργειας με τη χρήση"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Ολοκληρωμένη ενέργεια με χρήση %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Ολοκλήρωση ενέργειας"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 468b9a3333db..e5f610b4629c 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Loading…"</string> <string name="capital_on" msgid="2770685323900821829">"ON"</string> <string name="capital_off" msgid="7443704171014626777">"OFF"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ticked"</string> + <string name="not_checked" msgid="7972320087569023342">"not ticked"</string> <string name="whichApplication" msgid="5432266899591255759">"Complete action using"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Complete action using %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Complete action"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 2c715772d0a0..2cff16f93942 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Loading…"</string> <string name="capital_on" msgid="2770685323900821829">"ON"</string> <string name="capital_off" msgid="7443704171014626777">"OFF"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ticked"</string> + <string name="not_checked" msgid="7972320087569023342">"not ticked"</string> <string name="whichApplication" msgid="5432266899591255759">"Complete action using"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Complete action using %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Complete action"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 468b9a3333db..e5f610b4629c 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Loading…"</string> <string name="capital_on" msgid="2770685323900821829">"ON"</string> <string name="capital_off" msgid="7443704171014626777">"OFF"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ticked"</string> + <string name="not_checked" msgid="7972320087569023342">"not ticked"</string> <string name="whichApplication" msgid="5432266899591255759">"Complete action using"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Complete action using %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Complete action"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 468b9a3333db..e5f610b4629c 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Your organisation manages this device and may monitor network traffic. Tap for details."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Loading…"</string> <string name="capital_on" msgid="2770685323900821829">"ON"</string> <string name="capital_off" msgid="7443704171014626777">"OFF"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ticked"</string> + <string name="not_checked" msgid="7972320087569023342">"not ticked"</string> <string name="whichApplication" msgid="5432266899591255759">"Complete action using"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Complete action using %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Complete action"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 03ed6a5c8de3..6d536e43a26c 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"The work profile admin app is either missing or corrupted. As a result, your work profile and related data have been deleted. Contact your admin for assistance."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Your work profile is no longer available on this device"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Too many password attempts"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Device is managed"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Your organization manages this device and may monitor network traffic. Tap for details."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Your device will be erased"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Loading…"</string> <string name="capital_on" msgid="2770685323900821829">"ON"</string> <string name="capital_off" msgid="7443704171014626777">"OFF"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"checked"</string> + <string name="not_checked" msgid="7972320087569023342">"not checked"</string> <string name="whichApplication" msgid="5432266899591255759">"Complete action using"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Complete action using %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Complete action"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 6d0caff65dbb..3b9c7ad74957 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"La app de administración de perfil de trabajo no se encuentra o está dañada. Por lo tanto, se borraron tu perfil de trabajo y los datos relacionados. Para obtener asistencia, comunícate con el administrador."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Tu perfil de trabajo ya no está disponible en este dispositivo"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Demasiados intentos para ingresar la contraseña"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Dispositivo administrado"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Tu organización administra este dispositivo y es posible que controle el tráfico de red. Presiona para obtener más información."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Se borrarán los datos del dispositivo"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Cargando…"</string> <string name="capital_on" msgid="2770685323900821829">"Sí"</string> <string name="capital_off" msgid="7443704171014626777">"No"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"activado"</string> + <string name="not_checked" msgid="7972320087569023342">"desactivado"</string> <string name="whichApplication" msgid="5432266899591255759">"Completar la acción mediante"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Completar acción con %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Completar acción"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index ca5097bf3356..2e749043299a 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Falta la aplicación de administración del perfil de trabajo o está dañada. Por ello, se han eliminado tu perfil de trabajo y los datos relacionados. Ponte en contacto con el administrador para obtener ayuda."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Tu perfil de trabajo ya no está disponible en este dispositivo"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Has fallado demasiadas veces al introducir la contraseña"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"El dispositivo está administrado"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Tu organización administra este dispositivo y puede supervisar el tráfico de red. Toca la notificación para obtener más información."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Tu dispositivo se borrará"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Cargando..."</string> <string name="capital_on" msgid="2770685323900821829">"ACTIVADO"</string> <string name="capital_off" msgid="7443704171014626777">"DESACTIVADO"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"seleccionado"</string> + <string name="not_checked" msgid="7972320087569023342">"no seleccionado"</string> <string name="whichApplication" msgid="5432266899591255759">"Completar acción utilizando"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Completar acción con %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Completar acción"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 6b01527df2c8..85612549de25 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Tööprofiili administraatori rakendus puudub või on rikutud. Seetõttu on teie tööprofiil ja seotud andmed kustutatud. Abi saamiseks võtke ühendust administraatoriga."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Teie tööprofiil pole selles seadmes enam saadaval"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Liiga palju paroolikatseid"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Seade on hallatud"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Teie organisatsioon haldab seda seadet ja võib jälgida võrguliiklust. Puudutage üksikasjade vaatamiseks."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Seade kustutatakse"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Laadimine ..."</string> <string name="capital_on" msgid="2770685323900821829">"SEES"</string> <string name="capital_off" msgid="7443704171014626777">"VÄLJAS"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"märgitud"</string> + <string name="not_checked" msgid="7972320087569023342">"märkimata"</string> <string name="whichApplication" msgid="5432266899591255759">"Lõpetage toiming rakendusega"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Toimingu lõpetamine, kasutades rakendust %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Vii toiming lõpule"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Vaheta jagatud ekraanikuva"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lukustuskuva"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekraanipilt"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> on hüpikaknas."</string> </resources> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 66672ddf6ab0..263b5ed7e232 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Laneko profila administratzeko aplikazioa falta da edo hondatuta dago. Ondorioz, ezabatu egin dira laneko profila bera eta harekin erlazionatutako datuak. Laguntza lortzeko, jarri administratzailearekin harremanetan."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Laneko profila ez dago erabilgarri gailu honetan"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Gehiegitan saiatu zara pasahitza idazten"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Jabeak kudeatzen du gailua"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Erakundeak kudeatzen du gailua eta baliteke sareko trafikoa gainbegiratzea. Sakatu hau xehetasunak ikusteko."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Gailuko datuak ezabatu egingo dira"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Kargatzen…"</string> <string name="capital_on" msgid="2770685323900821829">"AKTIBATUTA"</string> <string name="capital_off" msgid="7443704171014626777">"DESAKTIBATUTA"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"markatuta"</string> + <string name="not_checked" msgid="7972320087569023342">"markatu gabe"</string> <string name="whichApplication" msgid="5432266899591255759">"Gauzatu ekintza hau erabilita:"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Osatu ekintza %1$s erabiliz"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Osatu ekintza"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index c10dba53dd66..997b6aff7835 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"برنامه سرپرست نمایه کاری یا وجود ندارد یا خراب است. در نتیجه، نمایه کاری شما و دادههای مرتبط با آن حذف شده است. برای دریافت راهنمایی با سرپرست سیستم تماس بگیرید."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"نمایه کاری شما دیگر در این دستگاه دردسترس نیست"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"تلاشهای بسیار زیادی برای وارد کردن گذرواژه انجام شده است"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"دستگاه مدیریت میشود"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"سازمانتان این دستگاه را مدیریت میکند و ممکن است ترافیک شبکه را پایش کند. برای اطلاع از جزئیات، ضربه بزنید."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"دستگاهتان پاک خواهد شد"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"درحال بارکردن…"</string> <string name="capital_on" msgid="2770685323900821829">"روشن"</string> <string name="capital_off" msgid="7443704171014626777">"خاموش"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"علامتزدهشده"</string> + <string name="not_checked" msgid="7972320087569023342">"بدون علامت"</string> <string name="whichApplication" msgid="5432266899591255759">"تکمیل عملکرد با استفاده از"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"تکمیل عملکرد با استفاده از %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"تکمیل عملکرد"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"تغییر وضعیت صفحهٔ دونیمه"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"صفحه قفل"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"عکس صفحهنمایش"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"برنامه <xliff:g id="APP_NAME">%1$s</xliff:g> در پنجره بالاپر."</string> </resources> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 35addd127aad..86badf6dbf89 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Työprofiilin hallintasovellus puuttuu tai se on vioittunut. Tästä syystä työprofiilisi ja siihen liittyvät tiedot on poistettu. Pyydä ohjeita järjestelmänvalvojaltasi."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Työprofiilisi ei ole enää käytettävissä tällä laitteella."</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Liikaa salasanayrityksiä"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Hallinnoitu laite"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisaatiosi hallinnoi tätä laitetta ja voi tarkkailla verkkoliikennettä. Katso lisätietoja napauttamalla."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Laitteen tiedot poistetaan"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Ladataan…"</string> <string name="capital_on" msgid="2770685323900821829">"PÄÄLLÄ"</string> <string name="capital_off" msgid="7443704171014626777">"POIS"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"valittu"</string> + <string name="not_checked" msgid="7972320087569023342">"ei valittu"</string> <string name="whichApplication" msgid="5432266899591255759">"Tee toiminto käyttäen sovellusta"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Suorita sovelluksella %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Suorita toiminto"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 39dd90550956..2b890656d5dc 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Le profil professionnel de l\'application d\'administration est manquant ou corrompu. Votre profil professionnel et ses données connexes ont donc été supprimés. Communiquez avec votre administrateur pour obtenir de l\'assistance."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Votre profil professionnel n\'est plus accessible sur cet appareil"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Trop de tentatives d\'entrée du mot de passe"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"L\'appareil est géré"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Touchez ici pour obtenir plus d\'information."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Le contenu de votre appareil sera effacé"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Chargement en cours..."</string> <string name="capital_on" msgid="2770685323900821829">"OUI"</string> <string name="capital_off" msgid="7443704171014626777">"NON"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"coché"</string> + <string name="not_checked" msgid="7972320087569023342">"non coché"</string> <string name="whichApplication" msgid="5432266899591255759">"Continuer avec"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Continuer avec %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Terminer l\'action"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Basculer l\'écran partagé"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Écran de verrouillage"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Capture d\'écran"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Application <xliff:g id="APP_NAME">%1$s</xliff:g> dans une fenêtre contextuelle."</string> </resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index edc050c11cf9..7522b5aa26fb 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"L\'application d\'administration du profil professionnel est manquante ou endommagée. Par conséquent, votre profil professionnel et toutes les données associées ont été supprimés. Pour obtenir de l\'aide, contactez l\'administrateur."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Votre profil professionnel n\'est plus disponible sur cet appareil"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Trop de tentatives de saisie du mot de passe"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"L\'appareil est géré"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Appuyez ici pour obtenir plus d\'informations."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Les données de votre appareil vont être effacées"</string> @@ -1066,7 +1068,7 @@ <string name="selectAll" msgid="1532369154488982046">"Tout sélectionner"</string> <string name="cut" msgid="2561199725874745819">"Couper"</string> <string name="copy" msgid="5472512047143665218">"Copier"</string> - <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Échec de la copie dans le Presse-papiers"</string> + <string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"Échec de la copie dans le presse-papiers"</string> <string name="paste" msgid="461843306215520225">"Coller"</string> <string name="paste_as_plain_text" msgid="7664800665823182587">"Coller au format texte brut"</string> <string name="replace" msgid="7842675434546657444">"Remplacer..."</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Chargement…"</string> <string name="capital_on" msgid="2770685323900821829">"OUI"</string> <string name="capital_off" msgid="7443704171014626777">"NON"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"activé"</string> + <string name="not_checked" msgid="7972320087569023342">"désactivé"</string> <string name="whichApplication" msgid="5432266899591255759">"Continuer avec"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Terminer l\'action avec %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Terminer l\'action"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 583cadf3b8d5..4d40e214b1ba 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Falta a aplicación de administración do perfil de traballo ou ben está danada. Como resultado, eliminouse o teu perfil de traballo e os datos relacionados. Para obter asistencia, contacta co administrador."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"O teu perfil de traballo xa non está dispoñible neste dispositivo"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Demasiados intentos de introdución do contrasinal"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo está xestionado"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"A túa organización xestiona este dispositivo e pode controlar o tráfico de rede. Toca para obter máis detalles."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Borrarase o teu dispositivo"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Cargando..."</string> <string name="capital_on" msgid="2770685323900821829">"SI"</string> <string name="capital_off" msgid="7443704171014626777">"NON"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"seleccionado"</string> + <string name="not_checked" msgid="7972320087569023342">"non seleccionado"</string> <string name="whichApplication" msgid="5432266899591255759">"Completar a acción usando"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Completar a acción usando %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Completar acción"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activar/desactivar pantalla dividida"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Pantalla de bloqueo"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captura de pantalla"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> nunha ventá emerxente."</string> </resources> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index de315426c78c..ea3a573d7115 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"કાર્ય પ્રોફાઇલ વ્યવસ્થાપક ઍપ્લિકેશન ખૂટે છે અથવા તો દૂષિત છે. પરિણામે, તમારી કાર્યાલયની પ્રોફાઇલ અને તે સંબંધિત ડેટા કાઢી નાખવામાં આવ્યો છે. સહાયતા માટે તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"આ ઉપકરણ પર તમારી કાર્યાલયની પ્રોફાઇલ હવે ઉપલબ્ધ નથી"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"પાસવર્ડના ઘણા વધુ પ્રયત્નો"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"ઉપકરણ સંચાલિત છે"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"તમારી સંસ્થા આ ઉપકરણનું સંચાલન કરે છે અને નેટવર્ક ટ્રાફિફનું નિયમન કરી શકે છે. વિગતો માટે ટૅપ કરો."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"તમારું ઉપકરણ કાઢી નાખવામાં આવશે"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"લોડ કરી રહ્યું છે…"</string> <string name="capital_on" msgid="2770685323900821829">"ચાલુ"</string> <string name="capital_off" msgid="7443704171014626777">"બંધ"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ચેક કર્યું"</string> + <string name="not_checked" msgid="7972320087569023342">"ચેક કર્યું નથી"</string> <string name="whichApplication" msgid="5432266899591255759">"આના ઉપયોગથી ક્રિયા પૂર્ણ કરો"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ઉપયોગથી ક્રિયા પૂર્ણ કરો"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"ક્રિયા પૂર્ણ કરો"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"સ્ક્રીનને વિભાજિત કરવાની ક્રિયા ટૉગલ કરો"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"લૉક સ્ક્રીન"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"સ્ક્રીનશૉટ"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"પૉપ-અપ વિંડોમાં <xliff:g id="APP_NAME">%1$s</xliff:g> ઍપ."</string> </resources> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 5a422d8ad3af..e12fa08010b7 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"वर्क प्रोफ़ाइल व्यवस्थापक ऐप्लिकेशन या तो मौजूद नहीं है या वह खराब हो गया है. परिणामस्वरूप, आपकी वर्क प्रोफ़ाइल और उससे जुड़े डेटा को हटा दिया गया है. सहायता के लिए अपने व्यवस्थापक से संपर्क करें."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"आपकी वर्क प्रोफ़ाइल अब इस डिवाइस पर उपलब्ध नहीं है"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"कई बार गलत पासवर्ड डाला गया"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"डिवाइस प्रबंधित है"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"आपका संगठन इस डिवाइस का प्रबंधन करता है और वह नेटवर्क ट्रैफ़िक की निगरानी भी कर सकता है. विवरण के लिए टैप करें."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"आपके डिवाइस को मिटा दिया जाएगा"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"लोड हो रहे हैं..."</string> <string name="capital_on" msgid="2770685323900821829">"ऑन"</string> <string name="capital_off" msgid="7443704171014626777">"बंद"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"चालू है"</string> + <string name="not_checked" msgid="7972320087569023342">"बंद है"</string> <string name="whichApplication" msgid="5432266899591255759">"इसका इस्तेमाल करके कार्रवाई को पूरा करें"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s का उपयोग करके कार्रवाई पूरी करें"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"कार्रवाई पूरी करें"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"स्प्लिट स्क्रीन पर टॉगल करें"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"स्क्रीन लॉक करें"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"स्क्रीनशॉट लें"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"पॉप-अप विंडो में <xliff:g id="APP_NAME">%1$s</xliff:g> ऐप्लिकेशन."</string> </resources> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index ed7234bc49e0..0871d06bceff 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -190,6 +190,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Administratorska aplikacija radnog profila nedostaje ili je oštećena. Zbog toga su radni profil i povezani podaci izbrisani. Za pomoć se obratite svom administratoru."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Vaš radni profil više nije dostupan na ovom uređaju"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Previše pokušaja unosa zaporke"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Uređaj je upravljan"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja ovim uređajem i može nadzirati mrežni promet. Dodirnite za pojedinosti."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Uređaj će se izbrisati"</string> @@ -1136,10 +1138,8 @@ <string name="loading" msgid="3138021523725055037">"Učitavanje…"</string> <string name="capital_on" msgid="2770685323900821829">"Uklj."</string> <string name="capital_off" msgid="7443704171014626777">"Isklj."</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"potvrđeno"</string> + <string name="not_checked" msgid="7972320087569023342">"nije potvrđeno"</string> <string name="whichApplication" msgid="5432266899591255759">"Radnju dovrši pomoću stavke"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Dovršavanje radnje pomoću aplikacije %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Dovrši radnju"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index aab529824b1a..ce11fc628693 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"A munkaprofil rendszergazdai alkalmazása hiányzik vagy sérült. A rendszer ezért törölte a munkaprofilt, és az ahhoz kapcsolódó adatokat. Ha segítségre van szüksége, vegye fel a kapcsolatot rendszergazdájával."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Munkaprofilja már nem hozzáférhető ezen az eszközön."</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Túl sok jelszómegadási kísérlet"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Felügyelt eszköz"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Ezt az eszközt szervezete kezeli, és lehetséges, hogy a hálózati forgalmat is figyelik. További részletekért koppintson."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"A rendszer törölni fogja eszközét"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Betöltés..."</string> <string name="capital_on" msgid="2770685323900821829">"Be"</string> <string name="capital_off" msgid="7443704171014626777">"Ki"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"kiválasztva"</string> + <string name="not_checked" msgid="7972320087569023342">"nincs kiválasztva"</string> <string name="whichApplication" msgid="5432266899591255759">"Művelet végrehajtása a következővel:"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Művelet elvégzése a(z) %1$s segítségével"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Művelet végrehajtása"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index ee461f50a24a..629b225072e0 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Աշխատանքային պրոֆիլի ադմինիստրատորի հավելվածը բացակայում է կամ վնասված է: Արդյունքում ձեր աշխատանքային պրոֆիլը և առնչվող տվյալները ջնջվել են: Օգնության համար դիմեք ձեր ադմինիստրատորին:"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Ձեր աշխատանքային պրոֆիլն այս սարքում այլևս հասանելի չէ"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Գաղտնաբառը մուտքագրելու չափից շատ փորձեր են կատարվել"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Սարքը կառավարվում է"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Ձեր կազմակերպությունը կառավարում է այս սարքը և կարող է վերահսկել ցանցի թրաֆիկը: Հպեք՝ մանրամասները դիտելու համար:"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Ձեր սարքը ջնջվելու է"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Բեռնում..."</string> <string name="capital_on" msgid="2770685323900821829">"I"</string> <string name="capital_off" msgid="7443704171014626777">"O"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"նշված է"</string> + <string name="not_checked" msgid="7972320087569023342">"նշված չէ"</string> <string name="whichApplication" msgid="5432266899591255759">"Ավարտել գործողությունը` օգտագործելով"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Եզրափակել գործողությունը՝ օգտագործելով %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Ավարտել գործողությունը"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Միացնել/անջատել էկրանի տրոհումը"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Կողպէկրան"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Սքրինշոթ"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ելնող պատուհանում։"</string> </resources> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index ece3a6c260cc..f99c1076de17 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikasi admin profil kerja tidak ada atau rusak. Akibatnya, profil kerja dan data terkait telah dihapus. Hubungi admin untuk meminta bantuan."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profil kerja tidak tersedia lagi di perangkat ini"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Terlalu banyak percobaan memasukkan sandi"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Perangkat ini ada yang mengelola"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasi mengelola perangkat ini dan mungkin memantau traffic jaringan. Ketuk untuk melihat detailnya."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Perangkat akan dihapus"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Memuat..."</string> <string name="capital_on" msgid="2770685323900821829">"AKTIF"</string> <string name="capital_off" msgid="7443704171014626777">"MATI"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"dicentang"</string> + <string name="not_checked" msgid="7972320087569023342">"tidak dicentang"</string> <string name="whichApplication" msgid="5432266899591255759">"Tindakan lengkap menggunakan"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Selesaikan tindakan menggunakan %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Selesaikan tindakan"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 3bcdda63a404..0f4d6de4d399 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Stjórnunarforrit vinnusniðsins vantar eða er skemmt. Vinnusniðinu og gögnum því tengdu hefur því verið eytt. Hafðu samband við kerfisstjórann til að fá frekari aðstoð."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Vinnusniðið þitt er ekki lengur í boði á þessu tæki"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Of margar tilraunir til að slá inn aðgangsorð"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Tækinu er stjórnað"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Fyrirtækið þitt stjórnar þessu tæki og kann að fylgjast með netnotkun. Ýttu hér til að fá upplýsingar."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Tækið verður hreinsað"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Hleður…"</string> <string name="capital_on" msgid="2770685323900821829">"KVEIKT"</string> <string name="capital_off" msgid="7443704171014626777">"SLÖKKT"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"valið"</string> + <string name="not_checked" msgid="7972320087569023342">"ekki valið"</string> <string name="whichApplication" msgid="5432266899591255759">"Ljúka aðgerð með"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Ljúka aðgerð með %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Ljúka aðgerð"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Breyta skjáskiptingu"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lásskjár"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skjámynd"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Forritið <xliff:g id="APP_NAME">%1$s</xliff:g> í sprettiglugga."</string> </resources> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 01bb13665aee..f14e8582b374 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"L\'app di amministrazione dei profili di lavoro manca o è danneggiata. Di conseguenza, il tuo profilo di lavoro e i relativi dati sono stati eliminati. Contatta l\'amministratore per ricevere assistenza."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Il tuo profilo di lavoro non è più disponibile sul dispositivo"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Troppi tentativi di inserimento della password"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Il dispositivo è gestito"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Questo dispositivo è gestito dalla tua organizzazione, che potrebbe monitorare il traffico di rete. Tocca per i dettagli."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Il dispositivo verrà resettato"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Caricamento..."</string> <string name="capital_on" msgid="2770685323900821829">"ON"</string> <string name="capital_off" msgid="7443704171014626777">"OFF"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"selezionato"</string> + <string name="not_checked" msgid="7972320087569023342">"deselezionato"</string> <string name="whichApplication" msgid="5432266899591255759">"Completa l\'azione con"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Completamento azione con %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Completa azione"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index ed2e66a03f3b..375d7d110a6b 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -192,6 +192,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"אפליקציית הניהול של פרופיל העבודה חסרה או פגומה. כתוצאה מכך, פרופיל העבודה שלך נמחק, כולל כל הנתונים הקשורים אליו. לקבלת עזרה, פנה למנהל המערכת."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"פרופיל העבודה שלך אינו זמין עוד במכשיר הזה"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"בוצעו ניסיונות רבים מדי להזנת סיסמה"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"המכשיר מנוהל"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"הארגון שלך מנהל מכשיר זה ועשוי לנטר את התנועה ברשת. הקש לקבלת פרטים."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"תתבצע מחיקה של המכשיר"</string> @@ -1156,10 +1158,8 @@ <string name="loading" msgid="3138021523725055037">"טוען..."</string> <string name="capital_on" msgid="2770685323900821829">"מופעל"</string> <string name="capital_off" msgid="7443704171014626777">"כבוי"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"מסומן"</string> + <string name="not_checked" msgid="7972320087569023342">"לא מסומן"</string> <string name="whichApplication" msgid="5432266899591255759">"השלמת פעולה באמצעות"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"להשלמת הפעולה באמצעות %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"השלם פעולה"</string> @@ -2072,6 +2072,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"החלפת מצב של מסך מפוצל"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"מסך הנעילה"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"צילום מסך"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> בחלון קופץ."</string> </resources> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 7ad1bc2aad1c..eb990ec02f87 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"仕事用プロファイルの管理アプリがないか、破損しています。そのため仕事用プロファイルと関連データが削除されました。管理者にサポートをご依頼ください。"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"お使いの仕事用プロファイルはこのデバイスで使用できなくなりました"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"パスワード入力回数が上限を超えました"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"管理対象のデバイス"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"このデバイスは組織によって管理され、ネットワーク トラフィックが監視される場合があります。詳しくはタップしてください。"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"デバイスのデータが消去されます"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"読み込んでいます..."</string> <string name="capital_on" msgid="2770685323900821829">"ON"</string> <string name="capital_off" msgid="7443704171014626777">"OFF"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ON"</string> + <string name="not_checked" msgid="7972320087569023342">"OFF"</string> <string name="whichApplication" msgid="5432266899591255759">"アプリケーションを選択"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$sを使用してアクションを完了"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"アクションを実行"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"分割画面の切り替え"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ロック画面"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"スクリーンショット"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> アプリがポップアップ ウィンドウで開きます。"</string> </resources> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 7e4035d8d4b0..d2d1fed80059 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"სამსახურის პროფილის ადმინისტრატორის აპი მიუწვდომელია ან დაზიანებულია. ამის გამო, თქვენი სამსახურის პროფილი და დაკავშირებული მონაცემები წაიშალა. დახმარებისთვის დაუკავშირდით თქვენს ადმინისტრატორს."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"თქვენი სამსახურის პროფილი აღარ არის ხელმისაწვდომი ამ მოწყობილობაზე"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"დაფიქსირდა პაროლის შეყვანის ზედმეტად ბევრი მცდელობა"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"მოწყობილობა მართულია"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"ამ მოწყობილობას თქვენი ორგანიზაცია მართავს და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია. შეეხეთ დამატებითი დეტალებისთვის."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"თქვენი მოწყობილობა წაიშლება"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"ჩატვირთვა…"</string> <string name="capital_on" msgid="2770685323900821829">"ჩართ."</string> <string name="capital_off" msgid="7443704171014626777">"გამორთ."</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"მონიშნულია"</string> + <string name="not_checked" msgid="7972320087569023342">"არ არის მონიშნული"</string> <string name="whichApplication" msgid="5432266899591255759">"რა გამოვიყენოთ?"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"მოქმედების %1$s-ის გამოყენებით დასრულება"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"მოქმედების დასრულება"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"გაყოფილი ეკრანის გადართვა"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ჩაკეტილი ეკრანი"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ეკრანის ანაბეჭდი"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> აპი ამომხტარ ფანჯარაში."</string> </resources> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 661f7c1bce07..a1002f719a55 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Жұмыс профилінің әкімші қолданбасы жоқ немесе бүлінген. Нәтижесінде жұмыс профиліңіз және қатысты деректер жойылды. Көмек алу үшін әкімшіге хабарласыңыз."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Жұмыс профиліңіз осы құрылғыда енді қолжетімді емес"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Құпия сөз көп рет қате енгізілді"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Құрылғы басқарылады"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін. Мәліметтер алу үшін түртіңіз."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Құрылғыңыздағы деректер өшіріледі"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Жүктелуде…"</string> <string name="capital_on" msgid="2770685323900821829">"Қосулы"</string> <string name="capital_off" msgid="7443704171014626777">"Өшірулі"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"белгіленген"</string> + <string name="not_checked" msgid="7972320087569023342">"белгіленбеген"</string> <string name="whichApplication" msgid="5432266899591255759">"Әрекетті аяқтау"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Әрекетті %1$s қолданбасын пайдаланып аяқтау"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Әрекетті аяқтау"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Экранды бөлу мүмкіндігін қосу/өшіру"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Құлып экраны"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Скриншот"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Қалқымалы терезедегі <xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы"</string> </resources> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index ded29998917b..61a3ec6fb444 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"កម្មវិធីអ្នកគ្រប់គ្រងកម្រងព័ត៌មានការងារនេះអាចបាត់ ឬមានបញ្ហា។ ដូច្នេះហើយទើបកម្រងព័ត៌មានការងាររបស់អ្នក និងទិន្នន័យដែលពាក់ព័ន្ធត្រូវបានលុប។ សូមទាក់ទងទៅអ្នកគ្រប់គ្រងរបស់អ្នក ដើម្បីទទួលបានជំនួយ។"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"កម្រងព័ត៌មានការងាររបស់អ្នកលែងមាននៅលើឧបករណ៍នេះទៀតហើយ"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ការព្យាយាមបញ្ចូលពាក្យសម្ងាត់ច្រើនដងពេកហើយ"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"ឧបករណ៍ស្ថិតក្រោមការគ្រប់គ្រង"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"ស្ថាប័នរបស់អ្នកគ្រប់គ្រងឧបករណ៍នេះ ហើយអាចនឹងតាមដានចរាចរណ៍បណ្តាញ។ ចុចដើម្បីទទួលបានព័ត៌មានលម្អិត។"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"ឧបករណ៍របស់អ្នកនឹងត្រូវបានលុប"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"កំពុងផ្ទុក..."</string> <string name="capital_on" msgid="2770685323900821829">"បើក"</string> <string name="capital_off" msgid="7443704171014626777">"បិទ"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"បានធីក"</string> + <string name="not_checked" msgid="7972320087569023342">"មិនបានធីក"</string> <string name="whichApplication" msgid="5432266899591255759">"បញ្ចប់សកម្មភាពដោយប្រើ"</string> <!-- String.format failed for translation --> <!-- no translation found for whichApplicationNamed (6969946041713975681) --> @@ -2006,6 +2006,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"បិទ/បើកមុខងារបំបែកអេក្រង់"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"អេក្រង់ចាក់សោ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"រូបថតអេក្រង់"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"កម្មវិធី <xliff:g id="APP_NAME">%1$s</xliff:g> នៅក្នុងវិនដូលោតឡើង។"</string> </resources> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 10930af4069c..5524d400027f 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ನಿರ್ವಾಹಕ ಅಪ್ಲಿಕೇಶನ್ ಕಳೆದು ಹೋಗಿದೆ ಅಥವಾ ಹಾಳಾಗಿದೆ. ಇದರ ಪರಿಣಾಮವಾಗಿ ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಮತ್ತು ಅದಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗಿದೆ. ಸಹಾಯಕ್ಕಾಗಿ ನಿಮ್ಮ ನಿರ್ವಾಹಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ನಿಮ್ಮ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಈ ಸಾಧನದಲ್ಲಿ ಈಗ ಲಭ್ಯವಿಲ್ಲ"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ಹಲವಾರು ಪಾಸ್ವರ್ಡ್ ಪ್ರಯತ್ನಗಳು"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸಲಾಗುತ್ತಿದೆ"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನವನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅದು ನೆಟ್ವರ್ಕ್ ಟ್ರಾಫಿಕ್ ಮೇಲೆ ಗಮನವಿರಿಸಬಹುದು. ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string> <string name="capital_on" msgid="2770685323900821829">"ಆನ್ ಮಾಡಿ"</string> <string name="capital_off" msgid="7443704171014626777">"ಆಫ್ ಮಾಡು"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ಪರಿಶೀಲಿಸಲಾಗಿದೆ"</string> + <string name="not_checked" msgid="7972320087569023342">"ಪರಿಶೀಲಿಸಲಾಗಿಲ್ಲ"</string> <string name="whichApplication" msgid="5432266899591255759">"ಇದನ್ನು ಬಳಸಿಕೊಂಡು ಕ್ರಿಯೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿ"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ಬಳಸಿಕೊಂಡು ಕ್ರಿಯೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿ"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"ಕ್ರಿಯೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿ"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ಸ್ಪ್ಲಿಟ್-ಸ್ಕ್ರೀನ್ ಟಾಗಲ್ ಮಾಡಿ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ಲಾಕ್ ಸ್ಕ್ರೀನ್"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ಸ್ಕ್ರೀನ್ಶಾಟ್"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"ಪಾಪ್-ಅಪ್ ಸ್ಪೇಸ್ ವಿಂಡೋದಲ್ಲಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಆ್ಯಪ್."</string> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 431af176e0ac..423dbd6749cb 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"직장 프로필 관리 앱이 없거나 손상되어 직장 프로필 및 관련 데이터가 삭제되었습니다. 도움이 필요한 경우 관리자에게 문의하세요."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"직장 프로필을 이 기기에서 더 이상 사용할 수 없습니다."</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"비밀번호 입력을 너무 많이 시도함"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"관리되는 기기"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"조직에서 이 기기를 관리하며 네트워크 트래픽을 모니터링할 수도 있습니다. 자세한 내용을 보려면 탭하세요."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"기기가 삭제됩니다."</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"로드 중.."</string> <string name="capital_on" msgid="2770685323900821829">"ON"</string> <string name="capital_off" msgid="7443704171014626777">"OFF"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"선택함"</string> + <string name="not_checked" msgid="7972320087569023342">"선택 안함"</string> <string name="whichApplication" msgid="5432266899591255759">"작업을 수행할 때 사용하는 애플리케이션"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s을(를) 사용하여 작업 완료"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"작업 완료"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"화면 분할 모드 전환"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"잠금 화면"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"스크린샷"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"팝업 창의 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱"</string> </resources> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index c8116cc3ba25..d1d773c03d77 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Жумуш профилинин башкаруучу колдонмосу жок же бузулгандыктан, жумуш профилиңиз жана ага байланыштуу дайындар жок кылынды. Жардам алуу үчүн администраторуңузга кайрылыңыз."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Жумуш профилиңиз бул түзмөктөн жок кылынды"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Өтө көп жолу сырсөздү киргизүү аракети жасалды"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Түзмөктү ишкана башкарат"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Ишканаңыз бул түзмөктү башкарат жана тармак трафигин көзөмөлдөшү мүмкүн. Чоо-жайын көрүү үчүн таптап коюңуз."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Түзмөгүңүз тазаланат"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Жүктөлүүдө…"</string> <string name="capital_on" msgid="2770685323900821829">"ЖАНДЫРЫЛГАН"</string> <string name="capital_off" msgid="7443704171014626777">"ӨЧҮК"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"белгиленген"</string> + <string name="not_checked" msgid="7972320087569023342">"белгилене элек"</string> <string name="whichApplication" msgid="5432266899591255759">"Аракет колдонууну бүтүрүү"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s аркылуу аракетти аягына чейин чыгаруу"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Аракетти аягына чыгаруу"</string> @@ -1307,8 +1307,7 @@ <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Тиркелген түзмөк бул телефонго шайкеш келбейт. Көбүрөөк маалымат алуу үчүн таптап коюңуз."</string> <string name="adb_active_notification_title" msgid="408390247354560331">"Мүчүлүштүктөрдү USB аркылуу оңдоо иштеп жатат"</string> <string name="adb_active_notification_message" msgid="5617264033476778211">"Өчүрүү үчүн тийип коюңуз"</string> - <!-- no translation found for adb_active_notification_message (6624498401272780855) --> - <skip /> + <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB аркылуу мүчүлүштүктөрдү оңдоону өчүрүүнү тандаңыз."</string> <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Сыноо программасынын режими иштетилди"</string> <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Сыноо программасынын режимин өчүрүү үчүн, баштапкы жөндөөлөргө кайтарыңыз."</string> <string name="console_running_notification_title" msgid="6087888939261635904">"Сериялык консоль иштетилди"</string> @@ -2005,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Экранды бөлүүнү күйгүзүү же өчүрүү"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Кулпуланган экран"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Скриншот"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу Калкыма терезеде көрүндү."</string> </resources> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 9acb031172a1..ded2a4fbf8e2 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"ບໍ່ມີແອັບຜູ້ເບິ່ງແຍງລະບົບໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ ຫຼື ເສຍຫາຍ. ຜົນກໍຄື, ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ ແລະ ຂໍ້ມູນທີ່ກ່ຽວຂ້ອງຂອງທ່ານຖືກລຶບອອກແລ້ວ. ໃຫ້ຕິດຕໍ່ຜູ້ເບິ່ງແຍງລະບົບສຳລັບການຊ່ວຍເຫຼືອ."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານບໍ່ສາມາດໃຊ້ໄດ້ໃນອຸປະກອນນີ້ອີກຕໍ່ໄປ"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ລອງໃສ່ລະຫັດຜ່ານຫຼາຍເທື່ອເກີນໄປ"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"ອຸປະກອນມີການຈັດການ"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"ອົງກອນຂອງທ່ານຈັດການອຸປະກອນນີ້ ແລະ ອາດກວດສອບທຣາບຟິກເຄືອຂ່າຍນຳ. ແຕະເພື່ອເບິ່ງລາຍລະອຽດ."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"ອຸປະກອນຂອງທ່ານຈະຖືກລຶບ"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"ກຳລັງໂຫລດ..."</string> <string name="capital_on" msgid="2770685323900821829">"ເປີດ"</string> <string name="capital_off" msgid="7443704171014626777">"ປິດ"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ໝາຍຖືກແລ້ວ"</string> + <string name="not_checked" msgid="7972320087569023342">"ບໍ່ໄດ້ໝາຍຖືກ"</string> <string name="whichApplication" msgid="5432266899591255759">"ດຳເນີນການໂດຍໃຊ້"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"ສຳເລັດການດຳເນີນການໂດຍໃຊ້ %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"ສຳເລັດຄຳສັ່ງ"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ເປີດ/ປິດການແບ່ງໜ້າຈໍ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ໜ້າຈໍລັອກ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ຮູບໜ້າຈໍ"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"ແອັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ໃນໜ້າຈໍປັອບອັບ."</string> </resources> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 30b551e1d406..eac535c7b3c2 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -192,6 +192,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Trūksta darbo profilio administratoriaus programos arba ji sugadinta. Todėl darbo profilis ir susiję duomenys buvo ištrinti. Jei reikia pagalbos, susisiekite su administratoriumi."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Darbo profilis nebepasiekiamas šiame įrenginyje"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Per daug slaptažodžio bandymų"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Įrenginys yra tvarkomas"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Šį įrenginį tvarko organizacija ir gali stebėti tinklo srautą. Palieskite, kad gautumėte daugiau informacijos."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Įrenginys bus ištrintas"</string> @@ -1156,10 +1158,8 @@ <string name="loading" msgid="3138021523725055037">"Įkeliama..."</string> <string name="capital_on" msgid="2770685323900821829">"ĮJ."</string> <string name="capital_off" msgid="7443704171014626777">"IŠJ."</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"pažymėta"</string> + <string name="not_checked" msgid="7972320087569023342">"nepažymėta"</string> <string name="whichApplication" msgid="5432266899591255759">"Užbaigti veiksmą naudojant"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Užbaigti veiksmą naudojant %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Užbaigti veiksmą"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index ae1831b76e91..f586212653ad 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -190,6 +190,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Trūkst darba profila administratora lietotnes, vai šī lietotne ir bojāta. Šī iemesla dēļ jūsu darba profils un saistītie dati tika dzēsti. Lai saņemtu palīdzību, sazinieties ar administratoru."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jūsu darba profils šai ierīcē vairs nav pieejams."</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Veikts pārāk daudz paroles ievadīšanas mēģinājumu."</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Ierīce tiek pārvaldīta"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Jūsu organizācija pārvalda šo ierīci un var uzraudzīt tīkla datplūsmu. Pieskarieties, lai saņemtu detalizētu informāciju."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Jūsu ierīces dati tiks dzēsti"</string> @@ -1136,10 +1138,8 @@ <string name="loading" msgid="3138021523725055037">"Notiek ielāde..."</string> <string name="capital_on" msgid="2770685323900821829">"IESLĒGT"</string> <string name="capital_off" msgid="7443704171014626777">"IZSL."</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"atzīmēts"</string> + <string name="not_checked" msgid="7972320087569023342">"nav atzīmēts"</string> <string name="whichApplication" msgid="5432266899591255759">"Izvēlieties lietotni"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Pabeigt darbību, izmantojot %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Pabeigt darbību"</string> @@ -2038,6 +2038,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Pārslēgt ekrāna sadalīšanu"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Bloķēt ekrānu"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekrānuzņēmums"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> uznirstošajā logā."</string> </resources> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 480561ff31f5..0d308a1d9b8d 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Апликацијата на администраторот за работниот профил или исчезна или е оштетена. Како резултат на тоа, вашиот работен профил и поврзаните податоци ќе се избришат. За помош, контактирајте со администраторот."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Вашиот работен профил веќе не е достапен на уредов"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Премногу обиди за внесување лозинка"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Некој управува со уредот"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Вашата организација управува со уредов и можно е да го следи сообраќајот на мрежата. Допрете за детали."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Уредот ќе се избрише"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Се вчитува..."</string> <string name="capital_on" msgid="2770685323900821829">"ВКЛУЧЕНО"</string> <string name="capital_off" msgid="7443704171014626777">"ИСКЛУЧЕНО"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"штиклирано"</string> + <string name="not_checked" msgid="7972320087569023342">"не е штиклирано"</string> <string name="whichApplication" msgid="5432266899591255759">"Заврши дејство со"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Остварете го дејството со %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Заврши го дејството"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index d3b9123a581f..63a7194c114f 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"ഔദ്യോഗിക പ്രൊഫൈൽ അഡ്മിൻ ആപ്പ് വിട്ടുപോയിരിക്കുന്നു അല്ലെങ്കിൽ കേടായിരിക്കുന്നു. ഫലമായി, നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലും ബന്ധപ്പെട്ട വിവരങ്ങളും ഇല്ലാതാക്കിയിരിക്കുന്നു. സഹായത്തിന് അഡ്മിനെ ബന്ധപ്പെടുക."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ഈ ഉപകരണത്തിൽ തുടർന്നങ്ങോട്ട് നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈൽ ലഭ്യമല്ല"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"വളരെയധികം പാസ്വേഡ് ശ്രമങ്ങൾ"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"ഉപകരണം മാനേജുചെയ്യുന്നുണ്ട്"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"നിങ്ങളുടെ സ്ഥാപനമാണ് ഈ ഉപകരണം മാനേജുചെയ്യുന്നത്, നെറ്റ്വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിക്കുകയും ചെയ്തേക്കാം, വിശദാംശങ്ങൾ അറിയാൻ ടാപ്പുചെയ്യുക."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"നിങ്ങളുടെ ഉപകരണം മായ്ക്കും"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"ലോഡുചെയ്യുന്നു..."</string> <string name="capital_on" msgid="2770685323900821829">"ഓൺ"</string> <string name="capital_off" msgid="7443704171014626777">"ഓഫ്"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"പരിശോധിച്ചത്"</string> + <string name="not_checked" msgid="7972320087569023342">"പരിശോധിക്കാത്തത്"</string> <string name="whichApplication" msgid="5432266899591255759">"പൂർണ്ണമായ പ്രവർത്തനം ഉപയോഗിക്കുന്നു"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ഉപയോഗിച്ച് പ്രവർത്തനം പൂർത്തിയാക്കുക"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"പ്രവർത്തനം പൂർത്തിയാക്കുക"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"സ്ക്രീൻ വിഭജന മോഡ് മാറ്റുക"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ലോക്ക് സ്ക്രീൻ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"സ്ക്രീൻഷോട്ട്"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"പോപ്പ്-അപ്പ് വിൻഡോയിലെ <xliff:g id="APP_NAME">%1$s</xliff:g> ആപ്പ്."</string> </resources> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index e8f6a5028de4..b3cf5ce92aea 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Ажлын профайлын админ апп байхгүй эсвэл эвдэрсэн байна. Үүний улмаас таны ажлын профайл болон холбогдох мэдээллийг устгасан болно. Тусламж хэрэгтэй бол админтай холбогдоно уу."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Таны ажлын профайл энэ төхөөрөмжид боломжгүй байна"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Нууц үгийг хэт олон удаа буруу оруулсан байна"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Төхөөрөмжийг удирдсан"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Таны байгууллага энэ төхөөрөмжийг удирдаж, сүлжээний ачааллыг хянадаг. Дэлгэрэнгүй мэдээлэл авах бол товшино уу."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Таны төхөөрөмж устах болно."</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Ачааллаж байна..."</string> <string name="capital_on" msgid="2770685323900821829">"Идэвхтэй"</string> <string name="capital_off" msgid="7443704171014626777">"Идэвхгүй"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"тэмдэглэсэн"</string> + <string name="not_checked" msgid="7972320087569023342">"тэмдэглээгүй"</string> <string name="whichApplication" msgid="5432266899591255759">"Үйлдлийг дуусгах"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ашиглан үйлдлийг гүйцээх"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Үйлдлийг дуусгах"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Дэлгэц хуваахыг унтраах/асаах"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Дэлгэцийг түгжих"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Дэлгэцийн зураг дарах"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Үзэгдэх цонхонд байгаа <xliff:g id="APP_NAME">%1$s</xliff:g> апп."</string> </resources> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 18f091197986..22b1dcc4da9b 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"कार्य प्रोफाइल प्रशासक अॅप गहाळ आहे किंवा करप्ट आहे. परिणामी, तुमचे कार्य प्रोफाइल आणि संबंधित डेटा हटवले गेले आहेत. सहाय्यासाठी आपल्या प्रशासकाशी संपर्क साधा."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"तुमचे कार्य प्रोफाइल आता या डिव्हाइसवर उपलब्ध नाही"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"बर्याचदा पासवर्ड टाकण्याचा प्रयत्न केला"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"डिव्हाइस व्यवस्थापित केले आहे"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"तुमची संस्था हे डिव्हाइस व्यवस्थापित करते आणि नेटवर्क रहदारीचे निरीक्षण करू शकते. तपशीलांसाठी टॅप करा."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"तुमचे डिव्हाइस मिटविले जाईल"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"लोड करत आहे..."</string> <string name="capital_on" msgid="2770685323900821829">"सुरू"</string> <string name="capital_off" msgid="7443704171014626777">"बंद"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"तपासले"</string> + <string name="not_checked" msgid="7972320087569023342">"तपासले नाही"</string> <string name="whichApplication" msgid="5432266899591255759">"याचा वापर करून क्रिया पूर्ण करा"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s वापरून क्रिया पूर्ण करा"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"क्रिया पूर्ण झाली"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"विभाजित स्क्रीन टॉगल करा"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"स्क्रीन लॉक करा"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"स्क्रीनशॉट"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"पॉप-अप विंडोमध्ये <xliff:g id="APP_NAME">%1$s</xliff:g> ॲप."</string> </resources> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 0a404e7bdea8..88c12b64636a 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Apl pentadbir profil kerja tiada atau rosak. Akibatnya, profil kerja anda dan data yang berkaitan telah dipadamkan. Hubungi pentadbir anda untuk mendapatkan bantuan."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profil kerja anda tidak lagi tersedia pada peranti ini"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Terlalu banyak percubaan kata laluan"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Peranti ini diurus"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasi anda mengurus peranti ini dan mungkin memantau trafik rangkaian. Ketik untuk mendapatkan butiran."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Peranti anda akan dipadam"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Memuatkan…"</string> <string name="capital_on" msgid="2770685323900821829">"HIDUP"</string> <string name="capital_off" msgid="7443704171014626777">"MATIKAN"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ditandai"</string> + <string name="not_checked" msgid="7972320087569023342">"tidak ditandai"</string> <string name="whichApplication" msgid="5432266899591255759">"Selesaikan tindakan menggunakan"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Selesaikan tindakan menggunakan %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Selesaikan tindakan"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Togol Skrin Pisah"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Skrin Kunci"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Tangkapan skrin"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Apl <xliff:g id="APP_NAME">%1$s</xliff:g> dalam tetingkap Timbul."</string> </resources> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index e34190dddc2f..cdf68cd3d53c 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"အလုပ်ပရိုဖိုင် စီမံခန့်ခွဲရန်အက်ပ် မရှိပါ သို့မဟုတ် ပျက်စီးနေပါသည်။ ထို့ကြောင့် သင်၏ အလုပ်ပရိုဖိုင်နှင့် ဆက်စပ်နေသော ဒေတာများကို ဖျက်လိုက်ပါပြီ။ အကူအညီရယူရန် သင်၏စီမံခန့်ခွဲသူကို ဆက်သွယ်ပါ။"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ဤစက်ပစ္စည်းတွင် သင်၏ အလုပ်ပရိုဖိုင်မရှိတော့ပါ"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"စကားဝှက်ထည့်သွင်းရန် ကြိုးစားသည့် အကြိမ်အရေအတွက် အလွန်များသွား၍ ဖြစ်ပါသည်"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"စက်ပစ္စည်းကို စီမံခန့်ခွဲထားပါသည်"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"ဤစက်ပစ္စည်းကို သင်၏ အဖွဲ့အစည်းက စီမံပြီး ကွန်ရက်အသွားအလာကို စောင့်ကြည့်နိုင်ပါသည်။ ထပ်မံလေ့လာရန် တို့ပါ။"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"သင့်ကိရိယာအား ပယ်ဖျက်လိမ့်မည်"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"တင်နေ…"</string> <string name="capital_on" msgid="2770685323900821829">"ဖွင့်ရန်"</string> <string name="capital_off" msgid="7443704171014626777">"ပိတ်"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"အမှန်ခြစ်ပြီး"</string> + <string name="not_checked" msgid="7972320087569023342">"ခြစ် မထား"</string> <string name="whichApplication" msgid="5432266899591255759">"အသုံးပြု၍ ဆောင်ရွက်မှုအားပြီးဆုံးစေခြင်း"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ကို သုံးပြီး လုပ်ဆောင်ချက် ပြီးဆုံးပါစေ"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"လုပ်ဆောင်ချက်ကို အပြီးသတ်ပါ"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းကို နှိပ်ပါ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"လော့ခ်မျက်နှာပြင်"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ဖန်သားပြင်ဓာတ်ပုံ"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"ပေါ့ပ်အပ်ဝင်းဒိုးတွင်ရှိသော <xliff:g id="APP_NAME">%1$s</xliff:g>အက်ပ်။"</string> </resources> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 69ee0177a1bb..b129c3c01b00 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Administratorappen for jobbprofilen mangler eller er skadet. Dette har ført til at jobbprofilen og alle data knyttet til den, har blitt slettet. Ta kontakt med administratoren for å få hjelp."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jobbprofilen din er ikke lenger tilgjengelig på denne enheten"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"For mange passordforsøk"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Enheten administreres"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisasjonen din kontrollerer denne enheten og kan overvåke nettverkstrafikk. Trykk for å få mer informasjon."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Enheten blir slettet"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Laster inn …"</string> <string name="capital_on" msgid="2770685323900821829">"På"</string> <string name="capital_off" msgid="7443704171014626777">"Av"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"avmerket"</string> + <string name="not_checked" msgid="7972320087569023342">"ikke avmerket"</string> <string name="whichApplication" msgid="5432266899591255759">"Fullfør med"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Fullfør handlingen med %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Fullfør handlingen"</string> @@ -1539,7 +1539,7 @@ <string name="launchBrowserDefault" msgid="6328349989932924119">"Vil du starte nettleseren?"</string> <string name="SetupCallDefault" msgid="5581740063237175247">"Vil du besvare anropet?"</string> <string name="activity_resolver_use_always" msgid="5575222334666843269">"Alltid"</string> - <string name="activity_resolver_set_always" msgid="4142825808921411476">"Angi som alltid åpen"</string> + <string name="activity_resolver_set_always" msgid="4142825808921411476">"Alltid"</string> <string name="activity_resolver_use_once" msgid="948462794469672658">"Bare én gang"</string> <string name="activity_resolver_app_settings" msgid="6758823206817748026">"Innstillinger"</string> <string name="activity_resolver_work_profiles_support" msgid="4071345609235361269">"%1$s støtter ikke arbeidsprofiler"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Slå delt skjerm av/på"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Låseskjerm"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skjermdump"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g>-appen i forgrunnsvindu."</string> </resources> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index cabb5c0c49dc..648f47c99871 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"उक्त कार्य प्रोफाइलको प्रशासकीय अनुप्रयोग छैन वा बिग्रेको छ। त्यसले गर्दा, तपाईंको कार्य प्रोफाइल र सम्बन्धित डेटालाई मेटिएको छ। सहायताका लागि आफ्ना प्रशासकलाई सम्पर्क गर्नुहोस्।"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"तपाईंको कार्य प्रोफाइल अब उप्रान्त यस यन्त्रमा उपलब्ध छैन"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"पासवर्ड प्रविष्ट गर्ने अत्यधिक गलत प्रयासहरू भए"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"यन्त्र व्यवस्थित गरिएको छ"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"तपाईंको संगठनले यस यन्त्रको व्यवस्थापन गर्दछ र नेटवर्क ट्राफिकको अनुगमन गर्न सक्छ। विवरणहरूका लागि ट्याप गर्नुहोस्।"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"तपाईंको यन्त्र मेटिनेछ"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"लोड हुँदै..."</string> <string name="capital_on" msgid="2770685323900821829">"चालु"</string> <string name="capital_off" msgid="7443704171014626777">"बन्द"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"जाँच गरिएको"</string> + <string name="not_checked" msgid="7972320087569023342">"जाँच गरिएको छैन"</string> <string name="whichApplication" msgid="5432266899591255759">"प्रयोग गरेर कारबाही पुरा गर्नुहोस्"</string> <!-- String.format failed for translation --> <!-- no translation found for whichApplicationNamed (6969946041713975681) --> @@ -2010,6 +2010,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"विभाजित स्क्रिन टगल गर्नुहोस्"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"लक स्क्रिन"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"स्क्रिनसट"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"पपअप विन्डोमा <xliff:g id="APP_NAME">%1$s</xliff:g> अनुप्रयोग छ।"</string> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 28fdfa5c8889..e248ca1ed1d0 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"De beheer-app van het werkprofiel ontbreekt of is beschadigd. Als gevolg hiervan zijn je werkprofiel en alle gerelateerde gegevens verwijderd. Neem contact op met je beheerder voor hulp."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Je werkprofiel is niet meer beschikbaar op dit apparaat"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Te veel wachtwoordpogingen"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Apparaat wordt beheerd"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Dit apparaat wordt beheerd door je organisatie. Het netwerkverkeer kan worden bijgehouden. Tik voor meer informatie."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Je apparaat wordt gewist"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Laden..."</string> <string name="capital_on" msgid="2770685323900821829">"AAN"</string> <string name="capital_off" msgid="7443704171014626777">"UIT"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"aangevinkt"</string> + <string name="not_checked" msgid="7972320087569023342">"niet aangevinkt"</string> <string name="whichApplication" msgid="5432266899591255759">"Actie voltooien met"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Actie voltooien via %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Actie voltooien"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 23e04b70e06e..7a73cc61633d 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"ଆଡମିନ୍ ଆପ୍ ନାହିଁ କିମ୍ବା ଭୁଲ ଅଛି। ଫଳସ୍ୱରୂପ, ଆପଣଙ୍କ ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ଏବଂ ସମ୍ବନ୍ଧୀୟ ଡାଟା ଡିଲିଟ୍ କରାଯାଇଛି। ସହାୟତା ପାଇଁ ଆପଣଙ୍କ ଆଡମିନଙ୍କୁ ଯୋଗାଯୋଗ କରନ୍ତୁ।"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ଏହି ଡିଭାଇସରେ ଆପଣଙ୍କ ୱର୍କ ପ୍ରୋଫାଇଲ୍ ଆଉ ଉପଲବ୍ଧ ନାହିଁ"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ବହୁତ ଥର ଭୁଲ ପାସ୍ୱର୍ଡ ଲେଖିଛନ୍ତି"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"ଡିଭାଇସକୁ ପରିଚାଳନା କରାଯାଉଛି"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"ଆପଣଙ୍କ ସଂସ୍ଥା ଏହି ଡିଭାଇସକୁ ପରିଚାଳନା କରନ୍ତି ଏବଂ ନେଟୱର୍କ ଟ୍ରାଫିକ୍ ନୀରିକ୍ଷଣ କରନ୍ତି। ବିବରଣୀ ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"ଆପଣଙ୍କ ଡିଭାଇସ୍ ବର୍ତ୍ତମାନ ଲିଭାଯିବ"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"ଲୋଡ୍ କରାଯାଉଛି…"</string> <string name="capital_on" msgid="2770685323900821829">"ଅନ୍"</string> <string name="capital_off" msgid="7443704171014626777">"ଅଫ୍"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ଯାଞ୍ଚ ହୋଇଛି"</string> + <string name="not_checked" msgid="7972320087569023342">"ଯାଞ୍ଚ ହୋଇନାହିଁ"</string> <string name="whichApplication" msgid="5432266899591255759">"ବ୍ୟବହାର କରି କାର୍ଯ୍ୟ ସମ୍ପୂର୍ଣ୍ଣ କରନ୍ତୁ"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ବ୍ୟବହାର କରି କାର୍ଯ୍ୟ ସମ୍ପୂର୍ଣ୍ଣ କରନ୍ତୁ"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"କାର୍ଯ୍ୟ ସମ୍ପୂର୍ଣ୍ଣ କରନ୍ତୁ"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ଦୁଇଟି ସ୍କ୍ରିନ୍ ମଧ୍ୟରେ ଟୋଗଲ୍ କରନ୍ତୁ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ସ୍କ୍ରିନ୍ ଲକ୍ କରନ୍ତୁ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ସ୍କ୍ରିନ୍ସଟ୍ ନିଅନ୍ତୁ"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"ପପ୍-ଅପ୍ ୱିଣ୍ଡୋରେ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପ୍"</string> </resources> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 891f1f15795a..3a245e383bc5 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਜਾਂ ਤਾਂ ਗੁੰਮਸ਼ੁਦਾ ਹੈ ਜਾਂ ਖਰਾਬ ਹੈ। ਨਤੀਜੇ ਵਜੋਂ, ਤੁਹਾਡੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਅਤੇ ਸਬੰਧਿਤ ਡਾਟਾ ਮਿਟਾਇਆ ਗਿਆ ਹੈ। ਸਹਾਇਤਾ ਲਈ ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ਤੁਹਾਡਾ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹੁਣ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ਕਈ ਵਾਰ ਗਲਤ ਪਾਸਵਰਡ ਦਾਖਲ ਕੀਤਾ ਗਿਆ"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਨ ਅਧੀਨ ਹੈ"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"ਤੁਹਾਡਾ ਸੰਗਠਨ ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ ਅਤੇ ਨੈੱਟਵਰਕ ਟਰੈਫਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"ਤੁਹਾਡਾ ਡੀਵਾਈਸ ਮਿਟਾਇਆ ਜਾਏਗਾ"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ..."</string> <string name="capital_on" msgid="2770685323900821829">"ਚਾਲੂ"</string> <string name="capital_off" msgid="7443704171014626777">"ਬੰਦ"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ਨਿਸ਼ਾਨਬੱਧ ਕੀਤਾ ਗਿਆ"</string> + <string name="not_checked" msgid="7972320087569023342">"ਨਿਸ਼ਾਨਬੱਧ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"</string> <string name="whichApplication" msgid="5432266899591255759">"ਇਸਨੂੰ ਵਰਤਦੇ ਹੋਏ ਕਾਰਵਾਈ ਪੂਰੀ ਕਰੋ"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ਵਰਤਦੇ ਹੋਏ ਕਾਰਵਾਈ ਪੂਰੀ ਕਰੋ"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"ਕਾਰਵਾਈ ਪੂਰੀ ਕਰੋ"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ਲਾਕ ਸਕ੍ਰੀਨ"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"ਪੌਪ-ਅੱਪ ਵਿੰਡੋ ਵਿੱਚ <xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ।"</string> </resources> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 811c5d883914..7a86bd561546 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -192,6 +192,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Brakuje aplikacji administratora profilu do pracy lub jest ona uszkodzona. Dlatego Twój profil służbowy i związane z nim dane zostały usunięte. Skontaktuj się ze swoim administratorem, by uzyskać pomoc."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Twój profil służbowy nie jest już dostępny na tym urządzeniu"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Zbyt wiele prób podania hasła"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Urządzenie jest zarządzane"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Twoja organizacja zarządza tym urządzeniem i może monitorować ruch w sieci. Kliknij, by dowiedzieć się więcej."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Twoje urządzenie zostanie wyczyszczone"</string> @@ -1156,10 +1158,8 @@ <string name="loading" msgid="3138021523725055037">"Wczytuję…"</string> <string name="capital_on" msgid="2770685323900821829">"Wł."</string> <string name="capital_off" msgid="7443704171014626777">"Wył."</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"wybrano"</string> + <string name="not_checked" msgid="7972320087569023342">"nie wybrano"</string> <string name="whichApplication" msgid="5432266899591255759">"Wykonaj czynność przez..."</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Wykonaj czynność w aplikacji %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Wykonaj działanie"</string> @@ -2072,6 +2072,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Przełącz podzielony ekran"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ekran blokady"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Zrzut ekranu"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> w wyskakującym okienku."</string> </resources> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index ecd10c32eaeb..3f82a80453f1 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"O app para administrador do perfil de trabalho não foi encontrado ou está corrompido. Consequentemente, seu perfil de trabalho e os dados relacionados foram excluídos. Entre em contato com seu administrador para receber assistência."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Seu perfil de trabalho não está mais disponível neste dispositivo"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Muitas tentativas de senha"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerenciado"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Sua organização gerencia este dispositivo e pode monitorar o tráfego de rede. Toque para ver detalhes."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Seu dispositivo será limpo"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Carregando…"</string> <string name="capital_on" msgid="2770685323900821829">"LIG"</string> <string name="capital_off" msgid="7443704171014626777">"DESL"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"marcado"</string> + <string name="not_checked" msgid="7972320087569023342">"não marcado"</string> <string name="whichApplication" msgid="5432266899591255759">"Complete a ação usando"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Concluir a ação usando %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Concluir ação"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 0cfbf8cb467e..f67c96fa10ba 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"A aplicação de administração do perfil de trabalho está em falta ou danificada. Consequentemente, o seu perfil de trabalho e os dados relacionados foram eliminados. Contacte o gestor para obter assistência."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"O seu perfil de trabalho já não está disponível neste dispositivo"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Demasiadas tentativas de introdução da palavra-passe"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerido"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede. Toque para obter mais detalhes."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"O seu dispositivo será apagado"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"A carregar…"</string> <string name="capital_on" msgid="2770685323900821829">"Ativado"</string> <string name="capital_off" msgid="7443704171014626777">"Desativado"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"selecionado"</string> + <string name="not_checked" msgid="7972320087569023342">"não selecionado"</string> <string name="whichApplication" msgid="5432266899591255759">"Concluir ação utilizando"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Concluir ação utilizando %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Concluir ação"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index ecd10c32eaeb..3f82a80453f1 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"O app para administrador do perfil de trabalho não foi encontrado ou está corrompido. Consequentemente, seu perfil de trabalho e os dados relacionados foram excluídos. Entre em contato com seu administrador para receber assistência."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Seu perfil de trabalho não está mais disponível neste dispositivo"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Muitas tentativas de senha"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"O dispositivo é gerenciado"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Sua organização gerencia este dispositivo e pode monitorar o tráfego de rede. Toque para ver detalhes."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Seu dispositivo será limpo"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Carregando…"</string> <string name="capital_on" msgid="2770685323900821829">"LIG"</string> <string name="capital_off" msgid="7443704171014626777">"DESL"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"marcado"</string> + <string name="not_checked" msgid="7972320087569023342">"não marcado"</string> <string name="whichApplication" msgid="5432266899591255759">"Complete a ação usando"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Concluir a ação usando %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Concluir ação"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index f50103270133..846b9829fa9c 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -190,6 +190,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplicația de administrare a profilului de serviciu lipsește sau este deteriorată. Prin urmare, profilul de serviciu și datele asociate au fost șterse. Pentru asistență, contactați administratorul."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profilul de serviciu nu mai este disponibil pe acest dispozitiv"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Prea multe încercări de introducere a parolei"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Dispozitivul este gestionat"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Organizația dvs. gestionează acest dispozitiv și poate monitoriza traficul în rețea. Atingeți pentru mai multe detalii."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Datele de pe dispozitiv vor fi șterse"</string> @@ -1136,10 +1138,8 @@ <string name="loading" msgid="3138021523725055037">"Se încarcă…"</string> <string name="capital_on" msgid="2770685323900821829">"DA"</string> <string name="capital_off" msgid="7443704171014626777">"NU"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"bifat"</string> + <string name="not_checked" msgid="7972320087569023342">"nebifat"</string> <string name="whichApplication" msgid="5432266899591255759">"Finalizare acțiune utilizând"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Finalizați acțiunea utilizând %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Finalizați acțiunea"</string> @@ -2038,6 +2038,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Activați ecranul împărțit"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ecran de blocare"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Captură de ecran"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> în fereastră pop-up."</string> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index aefc37342bff..19fde9f45fb5 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -192,6 +192,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Приложение для администрирования рабочего профиля отсутствует или повреждено. Из-за этого рабочий профиль и связанные с ним данные были удалены. Если у вас возникли вопросы, обратитесь к администратору."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Ваш рабочий профиль больше не доступен на этом устройстве"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Слишком много попыток ввести пароль."</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Это управляемое устройство"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик. Подробнее…"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Все данные с устройства будут удалены"</string> @@ -1156,10 +1158,8 @@ <string name="loading" msgid="3138021523725055037">"Загрузка…"</string> <string name="capital_on" msgid="2770685323900821829">"I"</string> <string name="capital_off" msgid="7443704171014626777">"O"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"отмечено"</string> + <string name="not_checked" msgid="7972320087569023342">"не отмечено"</string> <string name="whichApplication" msgid="5432266899591255759">"Что использовать?"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Выполнить с помощью приложения \"%1$s\""</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Выполнить действие"</string> @@ -2072,6 +2072,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Включить или выключить разделение экрана"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заблокированный экран"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Скриншот"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" в всплывающем окне."</string> </resources> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 67dfbd395e65..676b48f616f7 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"කාර්යාල පැතිකඩ පාලක යෙදුම නොමැති හෝ දූෂණය වී ඇත. ප්රතිඵලයක් ලෙස ඔබගේ කාර්යාල පැතිකඩ සහ අදාළ දත්ත මකා දමා ඇත. සහය සඳහා ඔබගේ පරිපාලකයා සම්බන්ධ කර ගන්න."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ඔබේ කාර්යාල පැතිකඩ මෙම උපාංගය මත තවදුරටත් ලබා ගැනීමට නොහැකිය"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"මුරපද උත්සාහ කිරීම් ඉතා වැඩි ගණනකි"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"උපාංගය කළමනාකරණය කෙරේ"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"ඔබගේ ආයතනය මෙම උපාංගය කළමනාකරණය කරන අතර එය ජාල තදබදය නිරීක්ෂණය කළ හැක. විස්තර සඳහා තට්ටු කරන්න."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"ඔබගේ උපාංගය මකා දැමෙනු ඇත"</string> @@ -1118,10 +1120,8 @@ <string name="loading" msgid="3138021523725055037">"පූරණය වෙමින්..."</string> <string name="capital_on" msgid="2770685323900821829">"සක්රීයයි"</string> <string name="capital_off" msgid="7443704171014626777">"ක්රියාවිරහිතයි"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"පරීක්ෂා කර ඇත"</string> + <string name="not_checked" msgid="7972320087569023342">"පරීක්ෂා කර නැත"</string> <string name="whichApplication" msgid="5432266899591255759">"පහත භාවිතයෙන් ක්රියාව සම්පූර්ණ කරන්න"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s භාවිතා කරමින් ක්රියාව සම්පුර්ණ කරන්න"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"ක්රියාව සම්පූර්ණ කරන්න"</string> @@ -2006,6 +2006,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"බෙදුම් තිරය ටොගල කරන්න"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"අගුලු තිරය"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"තිර රුව"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"උත්පතන කවුළුව තුළ <xliff:g id="APP_NAME">%1$s</xliff:g> යෙදුම."</string> </resources> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index c1eec993af8a..cde5466db748 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -192,6 +192,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikácia na správu pracovného profilu buď chýba, alebo je poškodená. Z toho dôvodu bol odstránený pracovný profil aj k nemu priradené dáta. Ak potrebujete pomoc, kontaktujte svojho správcu."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Váš pracovný profil už v tomto zariadení nie je k dispozícii"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Príliš veľa pokusov o zadanie hesla"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Zariadenie je spravované"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku. Klepnutím zobrazíte podrobnosti."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Vaše zariadenie bude vymazané"</string> @@ -1156,10 +1158,8 @@ <string name="loading" msgid="3138021523725055037">"Načítava sa…"</string> <string name="capital_on" msgid="2770685323900821829">"I"</string> <string name="capital_off" msgid="7443704171014626777">"O"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"začiarknuté"</string> + <string name="not_checked" msgid="7972320087569023342">"nezačiarknuté"</string> <string name="whichApplication" msgid="5432266899591255759">"Dokončiť akciu pomocou aplikácie"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Dokončiť akciu pomocou aplikácie %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Dokončiť akciu"</string> @@ -2072,6 +2072,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Prepnúť rozdelenú obrazovku"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Uzamknúť obrazovku"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snímka obrazovky"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vo vyskakovacom okne."</string> </resources> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index d15d6a96a70a..04940688c8fc 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -192,6 +192,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Skrbniška aplikacija delovnega profila manjka ali pa je poškodovana, zaradi česar je bil delovni profil s povezanimi podatki izbrisan. Za pomoč se obrnite na skrbnika."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Vaš delovni profil ni več na voljo v tej napravi"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Preveč poskusov vnosa gesla"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Naprava je upravljana"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Vaša organizacija upravlja to napravo in lahko nadzira omrežni promet. Dotaknite se za podrobnosti."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Podatki v napravi bodo izbrisani"</string> @@ -1156,10 +1158,8 @@ <string name="loading" msgid="3138021523725055037">"Nalaganje …"</string> <string name="capital_on" msgid="2770685323900821829">"VKLOPLJENO"</string> <string name="capital_off" msgid="7443704171014626777">"IZKLOPLJENO"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"potrjeno"</string> + <string name="not_checked" msgid="7972320087569023342">"ni potrjeno"</string> <string name="whichApplication" msgid="5432266899591255759">"Dokončanje dejanja z"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Dokončanje dejanja z aplikacijo %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Izvedba dejanja"</string> @@ -2072,6 +2072,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Preklop razdeljenega zaslona"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaklenjen zaslon"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Posnetek zaslona"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v pojavnem oknu."</string> </resources> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 6bf818403a6d..20e6ae513ada 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Aplikacioni i administratorit të profilit të punës mungon ose është dëmtuar. Si rezultat i kësaj, profili yt i punës dhe të dhënat përkatëse janë fshirë. Kontakto me administratorin për ndihmë."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Profili yt i punës nuk është më i disponueshëm në këtë pajisje"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Shumë përpjekje për fjalëkalimin"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Pajisja është e menaxhuar"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Organizata jote e menaxhon këtë pajisje dhe mund të monitorojë trafikun e rrjetit. Trokit për detaje."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Pajisja do të spastrohet"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Po ngarkohet..."</string> <string name="capital_on" msgid="2770685323900821829">"Aktivizuar"</string> <string name="capital_off" msgid="7443704171014626777">"Çaktivizuar"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"u përzgjodh"</string> + <string name="not_checked" msgid="7972320087569023342">"nuk u përzgjodh"</string> <string name="whichApplication" msgid="5432266899591255759">"Përfundo veprimin duke përdorur"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Përfundo veprimin duke përdorur %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Përfundo veprimin"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Kalo tek ekrani i ndarë"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Ekrani i kyçjes"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Pamja e ekranit"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Aplikacioni <xliff:g id="APP_NAME">%1$s</xliff:g> në dritaren kërcyese."</string> </resources> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 37410a761a9e..db53b23d9813 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -190,6 +190,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Апликација за администраторе на профилу за Work недостаје или је оштећена. Због тога су профил за Work и повезани подаци избрисани. Обратите се администратору за помоћ."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Профил за Work више није доступан на овом уређају"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Превише покушаја уноса лозинке"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Уређајем се управља"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Организација управља овим уређајем и може да надгледа мрежни саобраћај. Додирните за детаље."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Уређај ће бити обрисан"</string> @@ -1136,10 +1138,8 @@ <string name="loading" msgid="3138021523725055037">"Учитава се…"</string> <string name="capital_on" msgid="2770685323900821829">"ДА"</string> <string name="capital_off" msgid="7443704171014626777">"НЕ"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"означено је"</string> + <string name="not_checked" msgid="7972320087569023342">"није означено"</string> <string name="whichApplication" msgid="5432266899591255759">"Довршавање радње помоћу"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Завршите радњу помоћу апликације %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Заврши радњу"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index a5b657a4dd96..9e99aec5e9b1 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Administratörsappen för jobbprofilen saknas eller är skadad. Det innebär att jobbprofilen och all relaterad data har raderats. Kontakta administratören om du vill ha hjälp."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Jobbprofilen är inte längre tillgänglig på enheten"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"För många försök med lösenord"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Enheten hanteras"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Organisationen hanterar den här enheten och kan övervaka nätverkstrafiken. Tryck om du vill veta mer."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Enheten kommer att rensas"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Läser in …"</string> <string name="capital_on" msgid="2770685323900821829">"PÅ"</string> <string name="capital_off" msgid="7443704171014626777">"AV"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"markerad"</string> + <string name="not_checked" msgid="7972320087569023342">"inte markerad"</string> <string name="whichApplication" msgid="5432266899591255759">"Slutför åtgärd genom att använda"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Slutför åtgärden med %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Slutför åtgärd"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index d587e2584c97..d7b3555bf2af 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Programu ya msimamizi wa wasifu wa kazini imepotea au ina hitilafu. Kwa sababu hiyo, wasifu wako wa kazini na data husika imefutwa. Wasiliana na msimamizi wako kwa usaidizi."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Wasifu wako wa kazini haupatikani tena kwenye kifaa hiki"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Umejaribu kuweka nenosiri mara nyingi mno"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Kifaa kinadhibitiwa"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Shirika lako linadhibiti kifaa hiki na huenda likafuatilia shughuli kwenye mtandao. Gusa ili upate maelezo zaidi."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Data iliyomo kwenye kifaa chako itafutwa"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Inapakia…"</string> <string name="capital_on" msgid="2770685323900821829">"Washa"</string> <string name="capital_off" msgid="7443704171014626777">"ZIMA"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"imeteuliwa"</string> + <string name="not_checked" msgid="7972320087569023342">"haijateuliwa"</string> <string name="whichApplication" msgid="5432266899591255759">"Kamilisha kitendo ukitumia"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Kamilisha kitendo ukitumia %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Kamilisha kitendo"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Geuza Skrini Iliyogawanywa"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Skrini Iliyofungwa"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Picha ya skrini"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Programu ya <xliff:g id="APP_NAME">%1$s</xliff:g> katika dirisha Ibukizi."</string> </resources> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 90b8bc80e89a..569977c5013e 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"பணிக் கணக்கு நிர்வாகி ஆப்ஸ் இல்லை அல்லது அது சிதைந்துள்ளது. இதன் விளைவாக, உங்கள் பணிக் கணக்குமும் அதனுடன் தொடர்புடைய தரவும் நீக்கப்பட்டன. உதவிக்கு, நிர்வாகியைத் தொடர்புகொள்ளவும்."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"இந்தச் சாதனத்தில் இனி பணிக் கணக்கு கிடைக்காது"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"கடவுச்சொல்லை அதிக முறை தவறாக முயற்சித்துவிட்டீர்கள்"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"சாதனம் நிர்வகிக்கப்படுகிறது"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"உங்கள் நிறுவனம் இந்தச் சாதனத்தை நிர்வகிக்கும், அத்துடன் அது நெட்வொர்க் ட்ராஃபிக்கைக் கண்காணிக்கலாம். விவரங்களுக்கு, தட்டவும்."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"சாதனத் தரவு அழிக்கப்படும்"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"ஏற்றுகிறது..."</string> <string name="capital_on" msgid="2770685323900821829">"ஆன்"</string> <string name="capital_off" msgid="7443704171014626777">"ஆஃப்"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"இயக்கப்பட்டுள்ளது"</string> + <string name="not_checked" msgid="7972320087569023342">"முடக்கப்பட்டுள்ளது"</string> <string name="whichApplication" msgid="5432266899591255759">"இதைப் பயன்படுத்தி செயலை நிறைவுசெய்"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ஐப் பயன்படுத்தி செயலை முடிக்கவும்"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"செயலை முடி"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"திரைப் பிரிப்பை நிலைமாற்று"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"பூட்டுத் திரை"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ஸ்கிரீன்ஷாட்"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸில் உள்ள பாப் அப் சாளரம்."</string> </resources> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 63821aa9008c..9600172079b7 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"కార్యాలయ ప్రొఫైల్ నిర్వాహక యాప్ లేదు లేదా పాడైంది. తత్ఫలితంగా, మీ కార్యాలయ ప్రొఫైల్ మరియు సంబంధిత డేటా తొలగించబడ్డాయి. సహాయం కోసం మీ నిర్వాహకులను సంప్రదించండి."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"ఈ పరికరంలో మీ కార్యాలయ ప్రొఫైల్ ఇప్పుడు అందుబాటులో లేదు"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"చాలా ఎక్కువ పాస్వర్డ్ ప్రయత్నాలు చేసారు"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"పరికరం నిర్వహించబడింది"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"మీ సంస్థ ఈ పరికరాన్ని నిర్వహిస్తుంది మరియు నెట్వర్క్ ట్రాఫిక్ని పర్యవేక్షించవచ్చు. వివరాల కోసం నొక్కండి."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"మీ పరికరంలోని డేటా తొలగించబడుతుంది"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"లోడ్ చేస్తోంది…"</string> <string name="capital_on" msgid="2770685323900821829">"ఆన్లో ఉంది"</string> <string name="capital_off" msgid="7443704171014626777">"ఆఫ్"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"ఎంచుకోబడింది"</string> + <string name="not_checked" msgid="7972320087569023342">"ఎంచుకోలేదు"</string> <string name="whichApplication" msgid="5432266899591255759">"దీన్ని ఉపయోగించి చర్యను పూర్తి చేయండి"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$sను ఉపయోగించి చర్యను పూర్తి చేయి"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"చర్యను పూర్తి చేయి"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"స్క్రీన్ విభజనను టోగుల్ చేయి"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"స్క్రీన్ను లాక్ చేయి"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"స్క్రీన్షాట్"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"పాప్-అప్ విండోలో <xliff:g id="APP_NAME">%1$s</xliff:g> యాప్ ఉంది."</string> </resources> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index d4646b94d388..4dd0d0fa54aa 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"แอปผู้ดูแลระบบโปรไฟล์งานไม่มีอยู่หรือเสียหาย ระบบจึงทำการลบโปรไฟล์งานและข้อมูลที่เกี่ยวข้องของคุณออก โปรดติดต่อผู้ดูแลระบบเพื่อรับความช่วยเหลือ"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"โปรไฟล์งานของคุณไม่สามารถใช้ในอุปกรณ์นี้อีกต่อไป"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"ลองป้อนรหัสผ่านหลายครั้งเกินไป"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"อุปกรณ์มีการจัดการ"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"องค์กรของคุณจัดการอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย แตะเพื่อดูรายละเอียด"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"ระบบจะลบข้อมูลในอุปกรณ์ของคุณ"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"กำลังโหลด..."</string> <string name="capital_on" msgid="2770685323900821829">"เปิด"</string> <string name="capital_off" msgid="7443704171014626777">"ปิด"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"เลือกไว้"</string> + <string name="not_checked" msgid="7972320087569023342">"ยังไม่เลือก"</string> <string name="whichApplication" msgid="5432266899591255759">"ทำงานให้เสร็จโดยใช้"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"ดำเนินการให้เสร็จสมบูรณ์โดยใช้ %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"ทำงานให้เสร็จสิ้น"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"เปิด/ปิดการแบ่งหน้าจอ"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"หน้าจอล็อก"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"ภาพหน้าจอ"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"แอป <xliff:g id="APP_NAME">%1$s</xliff:g> ในหน้าต่างป๊อปอัป"</string> </resources> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 93ec51799fbc..bde4027fd73b 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Nawawala o nasira ang admin app ng profile sa trabaho. Dahil dito, na-delete ang profile mo sa trabaho at nauugnay na data. Makipag-ugnayan sa iyong admin para sa tulong."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Hindi na available sa device na ito ang iyong profile sa trabaho"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Masyadong maraming pagsubok sa password"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Pinamamahalaan ang device"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Pinamamahalaan ng iyong organisasyon ang device na ito, at maaari nitong subaybayan ang trapiko sa network. I-tap para sa mga detalye."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Buburahin ang iyong device"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Naglo-load…"</string> <string name="capital_on" msgid="2770685323900821829">"I-ON"</string> <string name="capital_off" msgid="7443704171014626777">"I-OFF"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"nilagyan ng check"</string> + <string name="not_checked" msgid="7972320087569023342">"hindi nilagyan ng check"</string> <string name="whichApplication" msgid="5432266899591255759">"Kumpletuhin ang pagkilos gamit ang"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Tapusin ang pagkilos gamit ang %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Gawin ang pagkilos"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"I-toggle ang Split Screen"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Lock Screen"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Screenshot"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"<xliff:g id="APP_NAME">%1$s</xliff:g> app sa Pop-up na window."</string> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 1a4d5324de5f..0168ba0af607 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"İş profili yönetici uygulaması eksik ya da bozuk. Bunun sonucunda iş profiliniz ve ilgili veriler silindi. Yardım almak için yöneticiniz ile iletişim kurun."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"İş profiliniz arık bu cihazda kullanılamıyor"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Çok fazla şifre denemesi yapıldı"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Cihaz yönetiliyor"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Kuruluşunuz bu cihazı yönetmekte olup ağ trafiğini izleyebilir. Ayrıntılar için dokunun."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Cihazınız silinecek"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Yükleniyor..."</string> <string name="capital_on" msgid="2770685323900821829">"AÇIK"</string> <string name="capital_off" msgid="7443704171014626777">"KAPALI"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"işaretli"</string> + <string name="not_checked" msgid="7972320087569023342">"işaretli değil"</string> <string name="whichApplication" msgid="5432266899591255759">"İşlemi şunu kullanarak tamamla"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"İşlemi %1$s kullanarak tamamla"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"İşlemi tamamla"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Bölünmüş Ekranı aç/kapat"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Kilit Ekranı"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Ekran görüntüsü"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Pop-up pencerede <xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması."</string> </resources> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index b785e060f610..32042efd98be 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -192,6 +192,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Додаток адміністратора в робочому профілі відсутній або пошкоджений. У результаті ваш робочий профіль і пов’язані з ним дані видалено. Зверніться до свого адміністратора по допомогу."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Робочий профіль більше не доступний на цьому пристрої"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Забагато спроб ввести пароль"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Пристрій контролюється"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Адміністратор вашої організації контролює цей пристрій і відстежує мережевий трафік. Торкніться, щоб дізнатися більше."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"З вашого пристрою буде стерто всі дані"</string> @@ -1156,10 +1158,8 @@ <string name="loading" msgid="3138021523725055037">"Завантаження..."</string> <string name="capital_on" msgid="2770685323900821829">"УВІМК"</string> <string name="capital_off" msgid="7443704171014626777">"ВИМК"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"вибрано"</string> + <string name="not_checked" msgid="7972320087569023342">"не вибрано"</string> <string name="whichApplication" msgid="5432266899591255759">"Завершити дію за доп."</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Завершити дію за допомогою %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Завершити дію"</string> @@ -2072,6 +2072,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Розділити екран"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Заблокувати екран"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Знімок екрана"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> у спливаючому вікні."</string> </resources> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index b54653ed7c62..1dd8911fa4b3 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"دفتری پروفائل کی منتظم ایپ یا تو غائب ہے یا خراب ہے۔ اس کی وجہ سے، آپ کا دفتری پروفائل اور متعلقہ ڈیٹا حذف کر دیے گئے ہیں۔ مدد کیلئے اپنے منتظم سے رابطہ کریں۔"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"آپ کا دفتری پروفائل اس آلہ پر مزید دستیاب نہیں ہے"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"پاس ورڈ کی بہت ساری کوششیں"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"آلہ زیر انتظام ہے"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"آپ کی تنظیم اس آلے کا نظم کرتی ہے اور وہ نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے۔ تفاصیل کیلئے تھپتھپائیں۔"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"آپ کا آلہ صاف کر دیا جائے گا"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"لوڈ ہو رہا ہے…"</string> <string name="capital_on" msgid="2770685323900821829">"آن"</string> <string name="capital_off" msgid="7443704171014626777">"آف"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"چیک کیا گیا"</string> + <string name="not_checked" msgid="7972320087569023342">"چیک نہیں کیا گیا"</string> <string name="whichApplication" msgid="5432266899591255759">"اس کا استعمال کرکے کارروائی مکمل کریں"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s کا استعمال کر کے کارروائی مکمل کریں"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"کارروائی مکمل کریں"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"اسپلٹ اسکرین ٹوگل کریں"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"مقفل اسکرین"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"اسکرین شاٹ"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"پوپ-اپ ونڈو میں <xliff:g id="APP_NAME">%1$s</xliff:g> ایپ۔"</string> </resources> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index c440e5321d46..4b7847d11de9 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Ishchi profilning administrator ilovasi yo‘q yoki buzilgan. Shuning uchun, ishchi profilingiz va unga aloqador ma’lumotlar o‘chirib tashlandi. Yordam olish uchun administratoringizga murojaat qiling."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Bu qurilmada endi ishchi profilingiz mavjud emas"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Parol ko‘p marta xato kiritildi"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Bu – boshqariladigan qurilma"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Tashkilotingiz bu qurilmani boshqaradi va tarmoq trafigini nazorat qilishi mumkin. Tafsilotlar uchun bosing."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Qurilmangizdagi ma’lumotlar o‘chirib tashlanadi"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Yuklanmoqda…"</string> <string name="capital_on" msgid="2770685323900821829">"I"</string> <string name="capital_off" msgid="7443704171014626777">"O"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"belgilandi"</string> + <string name="not_checked" msgid="7972320087569023342">"belgilanmadi"</string> <string name="whichApplication" msgid="5432266899591255759">"Ilovani tanlang"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"“%1$s” bilan ochish"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Amalni bajarish"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index e3623829a8bc..971cf34fd351 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Ứng dụng quản trị hồ sơ công việc bị thiếu hoặc hỏng. Do vậy, hồ sơ công việc của bạn và dữ liệu liên quan đã bị xóa. Hãy liên hệ với quản trị viên của bạn để được trợ giúp."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Hồ sơ công việc của bạn không có sẵn trên thiết bị này nữa"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Quá nhiều lần nhập mật khẩu"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Thiết bị được quản lý"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Tổ chức của bạn sẽ quản lý thiết bị này và có thể theo dõi lưu lượng truy cập mạng. Nhấn để biết chi tiết."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Thiết bị của bạn sẽ bị xóa"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Đang tải…"</string> <string name="capital_on" msgid="2770685323900821829">"BẬT"</string> <string name="capital_off" msgid="7443704171014626777">"TẮT"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"đã chọn"</string> + <string name="not_checked" msgid="7972320087569023342">"chưa chọn"</string> <string name="whichApplication" msgid="5432266899591255759">"Hoàn tất tác vụ đang sử dụng"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Hoàn tất tác vụ bằng %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Hoàn thành tác vụ"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"Bật/tắt chế độ chia đôi màn hình"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Khóa màn hình"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Chụp ảnh màn hình"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"Ứng dụng <xliff:g id="APP_NAME">%1$s</xliff:g> trong Cửa sổ bật lên."</string> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 6df232adec81..d7dd8b19089b 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"工作资料管理应用缺失或损坏,因此系统已删除您的工作资料及相关数据。如需帮助,请与您的管理员联系。"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"您的工作资料已不在此设备上"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"密码尝试次数过多"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"设备为受管理设备"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"贵单位会管理该设备,且可能会监控网络流量。点按即可了解详情。"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"系统将清空您的设备"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"正在加载..."</string> <string name="capital_on" msgid="2770685323900821829">"开启"</string> <string name="capital_off" msgid="7443704171014626777">"关闭"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"已勾选"</string> + <string name="not_checked" msgid="7972320087569023342">"未勾选"</string> <string name="whichApplication" msgid="5432266899591255759">"选择要使用的应用:"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"使用%1$s完成操作"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"完成操作"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"开启/关闭分屏"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"锁定屏幕"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"屏幕截图"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"以弹出式窗口形式打开的<xliff:g id="APP_NAME">%1$s</xliff:g>应用。"</string> </resources> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 41dcbed7001f..1a3784419393 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"工作設定檔管理員應用程式已遺失或損毀。因此,您的工作設定檔和相關資料已刪除。請聯絡您的管理員以取得協助。"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"您的工作設定檔無法再在此裝置上使用"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"密碼輸入錯誤的次數過多"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"裝置已受管理"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"您的機構會管理此裝置,並可能會監控網絡流量。輕按即可瞭解詳情。"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"您的裝置將被清除"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"正在載入..."</string> <string name="capital_on" msgid="2770685323900821829">"開啟"</string> <string name="capital_off" msgid="7443704171014626777">"關"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"已勾選"</string> + <string name="not_checked" msgid="7972320087569023342">"未勾選"</string> <string name="whichApplication" msgid="5432266899591255759">"完成操作需使用"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"完成操作需使用 %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"完成操作"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"切換分割螢幕"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"將畫面上鎖"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"螢幕截圖"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」應用程式在彈出式視窗中顯示。"</string> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index d49df97c2d79..5e655ac1faef 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"工作資料夾管理員應用程式遺失或已毀損,因此系統刪除了你的工作資料夾和相關資料。如需協助,請與你的管理員聯絡。"</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"你的工作資料夾已不在這個裝置上"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"密碼輸入錯誤的次數過多"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"裝置受到管理"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"貴機構會管理這個裝置,且可能監控網路流量。輕觸即可瞭解詳情。"</string> <string name="factory_reset_warning" msgid="6858705527798047809">"你的裝置資料將遭到清除"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"載入中…"</string> <string name="capital_on" msgid="2770685323900821829">"開啟"</string> <string name="capital_off" msgid="7443704171014626777">"關閉"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"已勾選"</string> + <string name="not_checked" msgid="7972320087569023342">"未勾選"</string> <string name="whichApplication" msgid="5432266899591255759">"選擇要使用的應用程式"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"完成操作需使用 %1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"完成操作"</string> @@ -2004,6 +2004,5 @@ <string name="accessibility_system_action_toggle_split_screen_label" msgid="6626177163849387748">"切換分割畫面模式"</string> <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"螢幕鎖定"</string> <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"擷取螢幕畫面"</string> - <!-- no translation found for accessibility_freeform_caption (7873194416838321119) --> - <skip /> + <string name="accessibility_freeform_caption" msgid="7873194416838321119">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」應用程式顯示在彈出式視窗中。"</string> </resources> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index e99b592c395b..5f8d61ebc271 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -188,6 +188,8 @@ <string name="work_profile_deleted_details" msgid="3773706828364418016">"Uhlelo lokusebenza lokulawula lephrofayela yomsebenzi kungenzeka alukho noma lonakele. Njengomphumela, iphrofayela yakho yomsebenzi nedatha ehlobene isusiwe. Xhumana nomlawuli wakho ukuze uthole usizo."</string> <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Iphrofayela yakho yomsebenzi ayisatholakali kule divayisi"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Imizamo yamaphasiwedi eminingi kakhulu"</string> + <!-- no translation found for device_ownership_relinquished (4080886992183195724) --> + <skip /> <string name="network_logging_notification_title" msgid="554983187553845004">"Idivayisi iphethwe"</string> <string name="network_logging_notification_text" msgid="1327373071132562512">"Inhlangano yakho iphethe le divayisi futhi kungenzeka ingaqaphi ithrafikhi yenethiwekhi. Thephela imininingwane."</string> <string name="factory_reset_warning" msgid="6858705527798047809">"Idivayisi yakho izosulwa"</string> @@ -1116,10 +1118,8 @@ <string name="loading" msgid="3138021523725055037">"Iyalayisha…"</string> <string name="capital_on" msgid="2770685323900821829">"VULIWE"</string> <string name="capital_off" msgid="7443704171014626777">"VALIWE"</string> - <!-- no translation found for checked (9179896827054513119) --> - <skip /> - <!-- no translation found for not_checked (7972320087569023342) --> - <skip /> + <string name="checked" msgid="9179896827054513119">"kuhloliwe"</string> + <string name="not_checked" msgid="7972320087569023342">"akuhloliwe"</string> <string name="whichApplication" msgid="5432266899591255759">"Qedela isenzo usebenzisa"</string> <string name="whichApplicationNamed" msgid="6969946041713975681">"Qedela isenzo usebenzisa i-%1$s"</string> <string name="whichApplicationLabel" msgid="7852182961472531728">"Qedela isenzo"</string> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index a0aa18690b51..2d31f4910335 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -5083,11 +5083,14 @@ data (for example, username, password and credit card info) [CHAR LIMIT=NONE] --> <string name="autofill_update_title_with_3types">Update these items in <b><xliff:g id="label" example="MyPass">%4$s</xliff:g></b>: <xliff:g id="type" example="Username">%1$s</xliff:g>, <xliff:g id="type" example="Password">%2$s</xliff:g>, and <xliff:g id="type" example="Credit Card">%3$s</xliff:g> ?</string> - <!-- Label for the autofill save button [CHAR LIMIT=NONE] --> <string name="autofill_save_yes">Save</string> <!-- Label for the autofill cancel button [CHAR LIMIT=NONE] --> <string name="autofill_save_no">No thanks</string> + <!-- Label for the autofill cancel button, saying not to save the filled data at this moment. [CHAR LIMIT=NONE] --> + <string name="autofill_save_notnow">Not now</string> + <!-- Label for the autofill reject button, saying never to save the filled data. [CHAR LIMIT=NONE] --> + <string name="autofill_save_never">Never</string> <!-- Label for the autofill update button [CHAR LIMIT=NONE] --> <string name="autofill_update_yes">Update</string> <!-- Label for the autofill continue button [CHAR LIMIT=NONE] --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e93c9bd458a5..130b31f092e0 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3248,6 +3248,8 @@ <java-symbol type="string" name="autofill_save_title_with_3types" /> <java-symbol type="string" name="autofill_save_yes" /> <java-symbol type="string" name="autofill_save_no" /> + <java-symbol type="string" name="autofill_save_notnow" /> + <java-symbol type="string" name="autofill_save_never" /> <java-symbol type="string" name="autofill_save_type_password" /> <java-symbol type="string" name="autofill_save_type_address" /> <java-symbol type="string" name="autofill_save_type_credit_card" /> diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java index 17fe61d879f3..deb0f182156e 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java @@ -548,8 +548,10 @@ public class TextClassifierTest { } @Test - public void testSuggetsConversationActions_deduplicate() { - if (isTextClassifierDisabled()) return; + public void testSuggestConversationActions_deduplicate() { + Context context = new FakeContextBuilder() + .setIntentComponent(Intent.ACTION_SENDTO, FakeContextBuilder.DEFAULT_COMPONENT) + .build(); ConversationActions.Message message = new ConversationActions.Message.Builder( ConversationActions.Message.PERSON_USER_OTHERS) @@ -560,7 +562,8 @@ public class TextClassifierTest { .setMaxSuggestions(3) .build(); - ConversationActions conversationActions = mClassifier.suggestConversationActions(request); + TextClassifier classifier = new TextClassifierImpl(context, TC_CONSTANTS); + ConversationActions conversationActions = classifier.suggestConversationActions(request); Truth.assertThat(conversationActions.getConversationActions()).isEmpty(); } diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java index 2f1eeda9c4cf..89a3bc070578 100644 --- a/location/java/android/location/GnssStatus.java +++ b/location/java/android/location/GnssStatus.java @@ -34,7 +34,7 @@ import java.util.ArrayList; */ public final class GnssStatus { - // these must match the definitions in gps.h + // These must match the definitions in GNSS HAL. // // Note: these constants are also duplicated in GnssStatusCompat.java in the androidx support // library. if adding a constellation, please update that file as well. @@ -63,9 +63,10 @@ public final class GnssStatus { private static final int SVID_FLAGS_HAS_ALMANAC_DATA = (1 << 1); private static final int SVID_FLAGS_USED_IN_FIX = (1 << 2); private static final int SVID_FLAGS_HAS_CARRIER_FREQUENCY = (1 << 3); + private static final int SVID_FLAGS_HAS_BASEBAND_CN0 = (1 << 4); - private static final int SVID_SHIFT_WIDTH = 8; - private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 4; + private static final int SVID_SHIFT_WIDTH = 12; + private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 8; private static final int CONSTELLATION_TYPE_MASK = 0xf; /** @@ -123,9 +124,10 @@ public final class GnssStatus { */ @NonNull public static GnssStatus wrap(int svCount, int[] svidWithFlags, float[] cn0DbHzs, - float[] elevations, float[] azimuths, float[] carrierFrequencies) { + float[] elevations, float[] azimuths, float[] carrierFrequencies, + float[] basebandCn0DbHzs) { return new GnssStatus(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths, - carrierFrequencies); + carrierFrequencies, basebandCn0DbHzs); } private final int mSvCount; @@ -134,15 +136,17 @@ public final class GnssStatus { private final float[] mElevations; private final float[] mAzimuths; private final float[] mCarrierFrequencies; + private final float[] mBasebandCn0DbHzs; private GnssStatus(int svCount, int[] svidWithFlags, float[] cn0DbHzs, float[] elevations, - float[] azimuths, float[] carrierFrequencies) { + float[] azimuths, float[] carrierFrequencies, float[] basebandCn0DbHzs) { mSvCount = svCount; mSvidWithFlags = svidWithFlags; mCn0DbHzs = cn0DbHzs; mElevations = elevations; mAzimuths = azimuths; mCarrierFrequencies = carrierFrequencies; + mBasebandCn0DbHzs = basebandCn0DbHzs; } /** @@ -284,6 +288,26 @@ public final class GnssStatus { } /** + * Reports whether a valid {@link #getBasebandCn0DbHz(int satelliteIndex)} is available. + * + * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 + */ + public boolean hasBasebandCn0DbHz(@IntRange(from = 0) int satelliteIndex) { + return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_BASEBAND_CN0) != 0; + } + + /** + * Retrieves the baseband carrier-to-noise density of the satellite at the specified index in + * dB-Hz. + * + * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 + */ + @FloatRange(from = 0, to = 63) + public float getBasebandCn0DbHz(@IntRange(from = 0) int satelliteIndex) { + return mBasebandCn0DbHzs[satelliteIndex]; + } + + /** * Returns the string representation of a constellation type. * * @param constellationType the constellation type. @@ -334,6 +358,8 @@ public final class GnssStatus { * @param usedInFix whether the satellite was used in the most recent location fix * @param hasCarrierFrequency whether carrier frequency data is available * @param carrierFrequency satellite carrier frequency in Hz + * @param hasBasebandCn0DbHz whether baseband carrier-to-noise density is available + * @param basebandCn0DbHz baseband carrier-to-noise density in dB-Hz */ @NonNull public Builder addSatellite(@ConstellationType int constellationType, @@ -345,9 +371,12 @@ public final class GnssStatus { boolean hasAlmanac, boolean usedInFix, boolean hasCarrierFrequency, - @FloatRange(from = 0) float carrierFrequency) { + @FloatRange(from = 0) float carrierFrequency, + boolean hasBasebandCn0DbHz, + @FloatRange(from = 0, to = 63) float basebandCn0DbHz) { mSatellites.add(new GnssSvInfo(constellationType, svid, cn0DbHz, elevation, azimuth, - hasEphemeris, hasAlmanac, usedInFix, hasCarrierFrequency, carrierFrequency)); + hasEphemeris, hasAlmanac, usedInFix, hasCarrierFrequency, carrierFrequency, + hasBasebandCn0DbHz, basebandCn0DbHz)); return this; } @@ -371,6 +400,7 @@ public final class GnssStatus { float[] elevations = new float[svCount]; float[] azimuths = new float[svCount]; float[] carrierFrequencies = new float[svCount]; + float[] basebandCn0DbHzs = new float[svCount]; for (int i = 0; i < svidWithFlags.length; i++) { svidWithFlags[i] = mSatellites.get(i).mSvidWithFlags; @@ -387,9 +417,12 @@ public final class GnssStatus { for (int i = 0; i < carrierFrequencies.length; i++) { carrierFrequencies[i] = mSatellites.get(i).mCarrierFrequency; } + for (int i = 0; i < basebandCn0DbHzs.length; i++) { + basebandCn0DbHzs[i] = mSatellites.get(i).mBasebandCn0DbHz; + } return wrap(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths, - carrierFrequencies); + carrierFrequencies, basebandCn0DbHzs); } } @@ -400,21 +433,25 @@ public final class GnssStatus { private final float mElevation; private final float mAzimuth; private final float mCarrierFrequency; + private final float mBasebandCn0DbHz; private GnssSvInfo(int constellationType, int svid, float cn0DbHz, float elevation, float azimuth, boolean hasEphemeris, boolean hasAlmanac, - boolean usedInFix, boolean hasCarrierFrequency, float carrierFrequency) { + boolean usedInFix, boolean hasCarrierFrequency, float carrierFrequency, + boolean hasBasebandCn0DbHz, float basebandCn0DbHz) { mSvidWithFlags = (svid << SVID_SHIFT_WIDTH) | ((constellationType & CONSTELLATION_TYPE_MASK) << CONSTELLATION_TYPE_SHIFT_WIDTH) | (hasEphemeris ? SVID_FLAGS_HAS_EPHEMERIS_DATA : SVID_FLAGS_NONE) | (hasAlmanac ? SVID_FLAGS_HAS_ALMANAC_DATA : SVID_FLAGS_NONE) | (usedInFix ? SVID_FLAGS_USED_IN_FIX : SVID_FLAGS_NONE) - | (hasCarrierFrequency ? SVID_FLAGS_HAS_CARRIER_FREQUENCY : SVID_FLAGS_NONE); + | (hasCarrierFrequency ? SVID_FLAGS_HAS_CARRIER_FREQUENCY : SVID_FLAGS_NONE) + | (hasBasebandCn0DbHz ? SVID_FLAGS_HAS_BASEBAND_CN0 : SVID_FLAGS_NONE); mCn0DbHz = cn0DbHz; mElevation = elevation; mAzimuth = azimuth; mCarrierFrequency = carrierFrequency; + mBasebandCn0DbHz = basebandCn0DbHz; } } } diff --git a/location/java/android/location/IGnssStatusListener.aidl b/location/java/android/location/IGnssStatusListener.aidl index d824cb18765a..1931a005d66f 100644 --- a/location/java/android/location/IGnssStatusListener.aidl +++ b/location/java/android/location/IGnssStatusListener.aidl @@ -28,6 +28,6 @@ oneway interface IGnssStatusListener void onFirstFix(int ttff); void onSvStatusChanged(int svCount, in int[] svidWithFlags, in float[] cn0s, in float[] elevations, in float[] azimuths, - in float[] carrierFreqs); + in float[] carrierFreqs, in float[] basebandCn0s); void onNmeaReceived(long timestamp, String nmea); } diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 75e1cd45689c..c0041722c475 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -2818,9 +2818,10 @@ public class LocationManager { @Override public void onSvStatusChanged(int svCount, int[] svidWithFlags, float[] cn0s, - float[] elevations, float[] azimuths, float[] carrierFreqs) { + float[] elevations, float[] azimuths, float[] carrierFreqs, + float[] basebandCn0s) { GnssStatus localStatus = GnssStatus.wrap(svCount, svidWithFlags, cn0s, - elevations, azimuths, carrierFreqs); + elevations, azimuths, carrierFreqs, basebandCn0s); mGnssStatus = localStatus; execute((callback) -> callback.onSatelliteStatusChanged(localStatus)); } diff --git a/location/tests/locationtests/src/android/location/GnssStatusTest.java b/location/tests/locationtests/src/android/location/GnssStatusTest.java deleted file mode 100644 index 79ea0d61b799..000000000000 --- a/location/tests/locationtests/src/android/location/GnssStatusTest.java +++ /dev/null @@ -1,130 +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 android.location; - -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Log; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.List; -import junit.framework.TestCase; - -/** - * Unit tests for {@link GnssStatus}. - */ -@SmallTest -public class GnssStatusTest extends TestCase { - - private static final String TAG = GnssStatusTest.class.getSimpleName(); - public void setUp() throws Exception { - super.setUp(); - } - - /* - * Create {@link GnssStatus} with default value, verify whether its fields are set correctly. - * - */ - public void testEmptyGnssStatus() throws Exception { - Log.i(TAG, "testEmptyGnssStatus"); - List<SatelliteInfo> svInfos = new ArrayList<>(); - GnssStatus gnssStatus = createGnssStatus(svInfos); - verifyGnssStatus(svInfos, gnssStatus); - } - - /* - * Create {@link GnssStatus} with only one satellite info, verify whether its fields are set - * correctly. - */ - public void testOneSatelliteGnssStatus() throws Exception { - Log.i(TAG, "testOneSatelliteGnssStatus"); - List<SatelliteInfo> svInfos = new ArrayList<>(); - SatelliteInfo svInfo = - new SatelliteInfo(100,1, true, true, true, true, 100f, 20.3f, 45.5f, 100.23f); - svInfos.add(svInfo); - GnssStatus gnssStatus = createGnssStatus(svInfos); - verifyGnssStatus(svInfos, gnssStatus); - } - - /* - * Create {@link GnssStatus} with multiple satellite info, verify whether its fields are set - * correctly. - */ - public void testMultipleSatellitesGnssStatus() throws Exception { - Log.i(TAG, "testMultipleSatellitesGnssStatus"); - List<SatelliteInfo> svInfos = new ArrayList<>(); - SatelliteInfo svInfo1 = - new SatelliteInfo(20, 1,true, true, true, true, 10.1f, 20.3f, 45.5f, 111.23f); - SatelliteInfo svInfo2 = - new SatelliteInfo(50, 2, true, false, true, false, 20.2f, 21.3f, 46.5f, 222.23f); - SatelliteInfo svInfo3 = - new SatelliteInfo(192, 3, false, true, false, true, 30.3f, 22.3f, 47.5f, 333.23f); - SatelliteInfo svInfo4 = - new SatelliteInfo(250, 4, false, false, false, false, 40.4f, 23.3f, 48.5f, 444.23f); - svInfos.add(svInfo1); - svInfos.add(svInfo2); - svInfos.add(svInfo3); - svInfos.add(svInfo4); - GnssStatus gnssStatus = createGnssStatus(svInfos); - verifyGnssStatus(svInfos, gnssStatus); - } - - private void verifyGnssStatus(List<SatelliteInfo> svInfos, GnssStatus gnssStatus) { - Log.i(TAG, String.format("Verifing {0} satellites info.",svInfos.size())); - assertEquals(TAG + "::SatelliteCount", svInfos.size(), - gnssStatus.getSatelliteCount()); - for (int i = 0; i< svInfos.size(); i++) { - SatelliteInfo svInfo = svInfos.get(i); - assertEquals(TAG + "::Svid", svInfo.mSvid, gnssStatus.getSvid(i)); - assertEquals(TAG + "::ConstellationType", svInfo.mConstellationType, - gnssStatus.getConstellationType(i)); - assertEquals(TAG + "::Cn0DbHz", svInfo.mCn0DbHz, gnssStatus.getCn0DbHz(i)); - assertEquals(TAG + "::Elevation", svInfo.mElevation, - gnssStatus.getElevationDegrees(i)); - assertEquals(TAG + "::Azimuth", svInfo.mAzimuth, gnssStatus.getAzimuthDegrees(i)); - assertEquals(TAG + "::CarrierFrequencyHz", svInfo.mCarrierFrequency, - gnssStatus.getCarrierFrequencyHz(i)); - assertEquals(TAG + "::hasEphemerisData", svInfo.mHasEphemris, - gnssStatus.hasEphemerisData(i)); - assertEquals(TAG + "::HasAlmanacData", svInfo.mHasAlmanac, - gnssStatus.hasAlmanacData(i)); - assertEquals(TAG + "::UsedInFix", svInfo.mUsedInFix, gnssStatus.usedInFix(i)); - assertEquals(TAG + "::HasCarrierFrequencyHz", svInfo.mHasCarriesFrequency, - gnssStatus.hasCarrierFrequencyHz(i)); - } - } - - private static GnssStatus createGnssStatus(List<SatelliteInfo> svInfos) throws Exception { - Class<?> intClass = Integer.TYPE; - Class<?> floatArrayClass = Class.forName("[F"); - Class<?> intArrayClass = Class.forName("[I"); - Class[] cArg = new Class[6]; - cArg[0] = intClass; - cArg[1] = intArrayClass; - cArg[2] = floatArrayClass; - cArg[3] = floatArrayClass; - cArg[4] = floatArrayClass; - cArg[5] = floatArrayClass; - Constructor<GnssStatus> ctor = GnssStatus.class.getDeclaredConstructor(cArg); - ctor.setAccessible(true); - return ctor.newInstance(svInfos.size(), - SatelliteInfo.getSvidWithFlagsArray(svInfos), - SatelliteInfo.getCn0sArray(svInfos), - SatelliteInfo.getElevationsArray(svInfos), - SatelliteInfo.getAzimuthsArray(svInfos), - SatelliteInfo.getCarrierFrequencyArray(svInfos)); - } -} diff --git a/location/tests/locationtests/src/android/location/SatelliteInfo.java b/location/tests/locationtests/src/android/location/SatelliteInfo.java deleted file mode 100644 index b6453ef0eabc..000000000000 --- a/location/tests/locationtests/src/android/location/SatelliteInfo.java +++ /dev/null @@ -1,155 +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 android.location; - -import java.util.List; - -/* - * Helper class to store single Satellite info, only used it in the unit test. - */ -public class SatelliteInfo { - private static final int SVID_MAX_BIT_INDEX = 32; - private static final int SVID_SHIFT_WIDTH = 8; - private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 4; - - // Index for the bits in mSvidWithFlag - private static final int GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA_BIT_INDEX = 0; - private static final int GNSS_SV_FLAGS_HAS_ALMANAC_DATA_BIT_INDEX = 1; - private static final int GNSS_SV_FLAGS_USED_IN_FIX_BIT_INDEX = 2; - private static final int GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY_BIT_INDEX = 3; - public int mSvid; - public int mSvidWithFlag; - public float mCn0DbHz; - public float mElevation; - public float mAzimuth; - public float mCarrierFrequency; - - /* - * Flag fields, it stores the same information as svidWithFlag, but in different format, easy for - * the unit test. - */ - public int mConstellationType; - public boolean mHasEphemris; - public boolean mHasAlmanac; - public boolean mUsedInFix; - public boolean mHasCarriesFrequency; - - public SatelliteInfo(int svid, int constellationType, boolean hasEphemris, boolean hasAlmanac, - boolean usedInFix, boolean hasCarriesFrequency, float cn0, float elevation, float azimuth, - float carrierFrequency) { - mSvidWithFlag = - setRange(mSvidWithFlag, constellationType, CONSTELLATION_TYPE_SHIFT_WIDTH, SVID_SHIFT_WIDTH); - mSvidWithFlag = setRange(mSvidWithFlag, svid, SVID_SHIFT_WIDTH, SVID_MAX_BIT_INDEX); - mSvidWithFlag = setBit(mSvidWithFlag, hasEphemris, GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA_BIT_INDEX); - mSvidWithFlag = setBit(mSvidWithFlag, hasAlmanac, GNSS_SV_FLAGS_HAS_ALMANAC_DATA_BIT_INDEX); - mSvidWithFlag = setBit(mSvidWithFlag, usedInFix, GNSS_SV_FLAGS_USED_IN_FIX_BIT_INDEX); - mSvidWithFlag = - setBit(mSvidWithFlag, hasCarriesFrequency, GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY_BIT_INDEX); - this.mSvid = svid; - this.mConstellationType = constellationType; - this.mCn0DbHz = cn0; - this.mElevation = elevation; - this.mAzimuth = azimuth; - this.mCarrierFrequency = carrierFrequency; - this.mHasEphemris = hasEphemris; - this.mHasAlmanac = hasAlmanac; - this.mUsedInFix = usedInFix; - this.mHasCarriesFrequency = hasCarriesFrequency; - } - - /* - * Gernerate svidWithFlags array from svInfos - */ - public static int[] getSvidWithFlagsArray(List<SatelliteInfo> svInfos) { - int[] svidWithFlags = new int[svInfos.size()]; - for (int i = 0; i< svInfos.size(); i++) { - svidWithFlags[i] = svInfos.get(i).mSvidWithFlag; - } - return svidWithFlags; - } - - /* - * Gernerate cn0s array from svInfos - */ - public static float[] getCn0sArray(List<SatelliteInfo> svInfos) { - float[] cn0s = new float[svInfos.size()]; - for (int i = 0; i< svInfos.size(); i++) { - cn0s[i] = svInfos.get(i).mCn0DbHz; - } - return cn0s; - } - - /* - * Gernerate elevations array from svInfos - */ - public static float[] getElevationsArray(List<SatelliteInfo> svInfos) { - float[] elevations = new float[svInfos.size()]; - for (int i = 0; i< svInfos.size(); i++) { - elevations[i] = svInfos.get(i).mElevation; - } - return elevations; - } - - /* - * Gernerate azimuths array from svInfos - */ - public static float[] getAzimuthsArray(List<SatelliteInfo> svInfos) { - float[] azimuths = new float[svInfos.size()]; - for (int i = 0; i< svInfos.size(); i++) { - azimuths[i] = svInfos.get(i).mAzimuth; - } - return azimuths; - } - - /* - * Gernerate carrierFrequency array from svInfos - */ - public static float[] getCarrierFrequencyArray(List<SatelliteInfo> svInfos) { - float[] carrierFrequencies = new float[svInfos.size()]; - for (int i = 0; i< svInfos.size(); i++) { - carrierFrequencies[i] = svInfos.get(i).mCarrierFrequency; - } - return carrierFrequencies; - } - - private int setBit(int targetValue, boolean value, int index) { - if (value) { - targetValue = targetValue | (1 << index); - } else { - targetValue = targetValue & ~(1 << index); - } - return targetValue; - } - - /* - * Set the bit in the range [fromIndex, toIndex), index start from the lowest bit. - * value -> 1 1 0 1 1 0 1 0 - * index -> 7 6 5 4 3 2 1 0 - * This function will set the bit in the range to the lowest X bits of the value. - */ - private int setRange(int targetValue, int value, int fromIndex, int toIndex) { - int rangeLen = toIndex - fromIndex; - int valueMask = (1 << rangeLen) -1; - value &= valueMask; - value = value << fromIndex; - valueMask = valueMask << fromIndex; - targetValue &= (~valueMask); - targetValue |= value; - return targetValue; - } - -}
\ No newline at end of file diff --git a/media/jni/Android.bp b/media/jni/Android.bp index 2f53cbb24129..064ac75d3a84 100644 --- a/media/jni/Android.bp +++ b/media/jni/Android.bp @@ -41,6 +41,7 @@ cc_library_shared { "libmedia_omx", "libmediametrics", "libmediadrm", + "libmediadrmmetrics_consumer", "libhwui", "libui", "liblog", diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index 3833c6bfb676..acda18ea3dc2 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -32,7 +32,9 @@ #include <cutils/properties.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/MediaErrors.h> +#include <mediadrm/DrmMetricsConsumer.h> #include <mediadrm/DrmUtils.h> +#include <mediadrm/IDrmMetricsConsumer.h> #include <mediadrm/IDrm.h> using ::android::os::PersistableBundle; @@ -1889,7 +1891,8 @@ android_media_MediaDrm_native_getMetrics(JNIEnv *env, jobject thiz) // Retrieve current metrics snapshot from drm. PersistableBundle metrics; - status_t err = drm->getMetrics(&metrics); + sp<IDrmMetricsConsumer> consumer(new DrmMetricsConsumer(&metrics)); + status_t err = drm->getMetrics(consumer); if (err != OK) { ALOGE("getMetrics failed: %d", (int)err); return (jobject) NULL; diff --git a/packages/CarSystemUI/src/com/android/systemui/TEST_MAPPING b/packages/CarSystemUI/src/com/android/systemui/TEST_MAPPING index f90947cbeb15..f2bf81102ab3 100644 --- a/packages/CarSystemUI/src/com/android/systemui/TEST_MAPPING +++ b/packages/CarSystemUI/src/com/android/systemui/TEST_MAPPING @@ -1,5 +1,5 @@ { - "auto-postsubmit": [ + "auto-end-to-end-postsubmit": [ { "name": "AndroidAutoUiTests", "options" : [ 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 fb1870a6ea42..7500bcd9b8f7 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java @@ -296,14 +296,42 @@ public class UserGridRecyclerView extends RecyclerView { } } + /** + * Get the maximum number of real (non-guest, non-managed profile) users that can be created + * on the device. This is a dynamic value and it decreases with the increase of the number + * of managed profiles on the device. + * + * <p> It excludes system user in headless system user model. + * + * @return Maximum number of real users that can be created. + */ + private int getMaxSupportedRealUsers() { + int maxSupportedUsers = UserManager.getMaxSupportedUsers(); + if (UserManager.isHeadlessSystemUserMode()) { + maxSupportedUsers -= 1; + } + + List<UserInfo> users = mUserManager.getUsers(/* excludeDying= */ true); + + // Count all users that are managed profiles of another user. + int managedProfilesCount = 0; + for (UserInfo user : users) { + if (user.isManagedProfile()) { + managedProfilesCount++; + } + } + + return maxSupportedUsers - managedProfilesCount; + } + private void showMaxUserLimitReachedDialog() { AlertDialog maxUsersDialog = new Builder(mContext, com.android.internal.R.style.Theme_DeviceDefault_Dialog_Alert) .setTitle(R.string.user_limit_reached_title) .setMessage(getResources().getQuantityString( R.plurals.user_limit_reached_message, - mCarUserManagerHelper.getMaxSupportedRealUsers(), - mCarUserManagerHelper.getMaxSupportedRealUsers())) + getMaxSupportedRealUsers(), + getMaxSupportedRealUsers())) .setPositiveButton(android.R.string.ok, null) .create(); // Sets window flags for the SysUI dialog diff --git a/packages/SystemUI/src/com/android/systemui/dock/DockManager.java b/packages/SystemUI/src/com/android/systemui/dock/DockManager.java index c7637fb42889..b6f7cd04c75f 100644 --- a/packages/SystemUI/src/com/android/systemui/dock/DockManager.java +++ b/packages/SystemUI/src/com/android/systemui/dock/DockManager.java @@ -35,6 +35,12 @@ public interface DockManager { int STATE_DOCKED_HIDE = 2; /** + * Indicates there's no alignment info. This could happen when the device is unable to decide + * its alignment condition. + */ + int ALIGN_STATE_UNKNOWN = -1; + + /** * Indicates there's no alignment issue. */ int ALIGN_STATE_GOOD = 0; diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java index d5f5a5a00500..53053fc27216 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java @@ -17,9 +17,11 @@ package com.android.systemui.globalactions; import static android.app.StatusBarManager.DISABLE2_GLOBAL_ACTIONS; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; +import android.annotation.Nullable; +import android.annotation.StringRes; import android.app.Dialog; -import android.app.KeyguardManager; import android.content.Context; +import android.os.PowerManager; import android.view.View; import android.view.ViewGroup; import android.view.Window; @@ -134,14 +136,22 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks, int color = Utils.getColorAttrDefaultColor(mContext, com.android.systemui.R.attr.wallpaperTextColor); - boolean onKeyguard = mContext.getSystemService( - KeyguardManager.class).isKeyguardLocked(); ProgressBar bar = d.findViewById(R.id.progress); bar.getIndeterminateDrawable().setTint(color); - TextView message = d.findViewById(R.id.text1); - message.setTextColor(color); - if (isReboot) message.setText(R.string.reboot_to_reset_message); + + TextView reasonView = d.findViewById(R.id.text1); + TextView messageView = d.findViewById(R.id.text2); + + reasonView.setTextColor(color); + messageView.setTextColor(color); + + messageView.setText(getRebootMessage(isReboot, reason)); + String rebootReasonMessage = getReasonMessage(reason); + if (rebootReasonMessage != null) { + reasonView.setVisibility(View.VISIBLE); + reasonView.setText(rebootReasonMessage); + } GradientColors colors = Dependency.get(SysuiColorExtractor.class).getNeutralColors(); background.setColor(colors.getMainColor(), false); @@ -149,6 +159,30 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks, d.show(); } + @StringRes + private int getRebootMessage(boolean isReboot, @Nullable String reason) { + if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) { + return R.string.reboot_to_update_reboot; + } else if (reason != null && reason.equals(PowerManager.REBOOT_RECOVERY)) { + return R.string.reboot_to_reset_message; + } else if (isReboot) { + return R.string.reboot_to_reset_message; + } else { + return R.string.shutdown_progress; + } + } + + @Nullable + private String getReasonMessage(@Nullable String reason) { + if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) { + return mContext.getString(R.string.reboot_to_update_title); + } else if (reason != null && reason.equals(PowerManager.REBOOT_RECOVERY)) { + return mContext.getString(R.string.reboot_to_reset_title); + } else { + return null; + } + } + @Override public void disable(int displayId, int state1, int state2, boolean animate) { final boolean disabled = (state2 & DISABLE2_GLOBAL_ACTIONS) != 0; diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java index 70fb535bed57..57961423061f 100644 --- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java @@ -383,7 +383,7 @@ final class FillUi { } child.setOnClickListener((v) -> { if (sVerbose) { - Slog.v(TAG, "Applying " + id + " after " + v + " was clicked"); + Slog.v(TAG, " Cancelling session after " + v + " clicked"); } mCallback.cancelSession(); }); diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java index d7114a0b9a62..8eea04759cdb 100644 --- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java @@ -291,10 +291,17 @@ final class SaveUi { } final TextView noButton = view.findViewById(R.id.autofill_save_no); - if (info.getNegativeActionStyle() == SaveInfo.NEGATIVE_BUTTON_STYLE_REJECT) { - noButton.setText(R.string.save_password_notnow); - } else { - noButton.setText(R.string.autofill_save_no); + final int negativeActionStyle = info.getNegativeActionStyle(); + switch (negativeActionStyle) { + case SaveInfo.NEGATIVE_BUTTON_STYLE_REJECT: + noButton.setText(R.string.autofill_save_notnow); + break; + case SaveInfo.NEGATIVE_BUTTON_STYLE_NEVER: + noButton.setText(R.string.autofill_save_never); + break; + case SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL: + default: + noButton.setText(R.string.autofill_save_no); } noButton.setOnClickListener((v) -> mListener.onCancel(info.getNegativeActionListener())); diff --git a/services/core/java/android/os/UserManagerInternal.java b/services/core/java/android/os/UserManagerInternal.java index 9a7cb3f2eff2..a2e9341bae71 100644 --- a/services/core/java/android/os/UserManagerInternal.java +++ b/services/core/java/android/os/UserManagerInternal.java @@ -15,6 +15,7 @@ */ package android.os; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -22,13 +23,24 @@ import android.content.Context; import android.content.pm.UserInfo; import android.graphics.Bitmap; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * @hide Only for use within the system server. */ public abstract class UserManagerInternal { - public static final int CAMERA_NOT_DISABLED = 0; - public static final int CAMERA_DISABLED_LOCALLY = 1; - public static final int CAMERA_DISABLED_GLOBALLY = 2; + + public static final int OWNER_TYPE_DEVICE_OWNER = 0; + public static final int OWNER_TYPE_PROFILE_OWNER = 1; + public static final int OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE = 2; + public static final int OWNER_TYPE_NO_OWNER = 3; + + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = {OWNER_TYPE_DEVICE_OWNER, OWNER_TYPE_PROFILE_OWNER, + OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE, OWNER_TYPE_NO_OWNER}) + public @interface OwnerType { + } public interface UserRestrictionsListener { /** @@ -47,13 +59,19 @@ public abstract class UserManagerInternal { * * @param userId target user id for the local restrictions. * @param restrictions a bundle of user restrictions. - * @param isDeviceOwner whether {@code userId} corresponds to device owner user id. - * @param cameraRestrictionScope is camera disabled and if so what is the scope of restriction. - * Should be one of {@link #CAMERA_NOT_DISABLED}, {@link #CAMERA_DISABLED_LOCALLY} or - * {@link #CAMERA_DISABLED_GLOBALLY} + * @param restrictionOwnerType determines which admin {@code userId} corresponds to. + * The admin can be either + * {@link UserManagerInternal#OWNER_TYPE_DEVICE_OWNER}, + * {@link UserManagerInternal#OWNER_TYPE_PROFILE_OWNER}, + * {@link UserManagerInternal#OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE} + * or {@link UserManagerInternal#OWNER_TYPE_NO_OWNER}. + * If the admin is a DEVICE_OWNER or a PROFILE_OWNER_ORG_OWNED_DEVICE then + * a restriction may be applied globally depending on which restriction it is, + * otherwise it will be applied just on the current user. + * @see OwnerType */ public abstract void setDevicePolicyUserRestrictions(int userId, @Nullable Bundle restrictions, - boolean isDeviceOwner, int cameraRestrictionScope); + @OwnerType int restrictionOwnerType); /** * Returns the "base" user restrictions. diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java index bc509561163a..e2fe76e94db3 100644 --- a/services/core/java/com/android/server/PackageWatchdog.java +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -247,7 +247,14 @@ public class PackageWatchdog { List<MonitoredPackage> packages = new ArrayList<>(); for (int i = 0; i < packageNames.size(); i++) { // Health checks not available yet so health check state will start INACTIVE - packages.add(new MonitoredPackage(packageNames.get(i), durationMs, false)); + MonitoredPackage pkg = newMonitoredPackage(packageNames.get(i), durationMs, false); + if (pkg != null) { + packages.add(pkg); + } + } + + if (packages.isEmpty()) { + return; } // Sync before we add the new packages to the observers. This will #pruneObservers, @@ -634,16 +641,8 @@ public class PackageWatchdog { if (registeredObserver != null) { Iterator<MonitoredPackage> it = failedPackages.iterator(); while (it.hasNext()) { - String failedPackage = it.next().getName(); - Slog.i(TAG, "Explicit health check failed for package " + failedPackage); - VersionedPackage versionedPkg = getVersionedPackage(failedPackage); - if (versionedPkg == null) { - Slog.w(TAG, "Explicit health check failed but could not find package " - + failedPackage); - // TODO(b/120598832): Skip. We only continue to pass tests for now since - // the tests don't install any packages - versionedPkg = new VersionedPackage(failedPackage, 0L); - } + VersionedPackage versionedPkg = it.next().mPackage; + Slog.i(TAG, "Explicit health check failed for package " + versionedPkg); registeredObserver.execute(versionedPkg); } } @@ -654,7 +653,7 @@ public class PackageWatchdog { @Nullable private VersionedPackage getVersionedPackage(String packageName) { final PackageManager pm = mContext.getPackageManager(); - if (pm == null) { + if (pm == null || TextUtils.isEmpty(packageName)) { return null; } try { @@ -848,7 +847,7 @@ public class PackageWatchdog { public void updatePackagesLocked(List<MonitoredPackage> packages) { for (int pIndex = 0; pIndex < packages.size(); pIndex++) { MonitoredPackage p = packages.get(pIndex); - this.packages.put(p.mName, p); + this.packages.put(p.getName(), p); } } @@ -872,7 +871,7 @@ public class PackageWatchdog { int newState = p.handleElapsedTimeLocked(elapsedMs); if (oldState != HealthCheckState.FAILED && newState == HealthCheckState.FAILED) { - Slog.i(TAG, "Package " + p.mName + " failed health check"); + Slog.i(TAG, "Package " + p.getName() + " failed health check"); failedPackages.add(p); } if (p.isExpiredLocked()) { @@ -925,9 +924,10 @@ public class PackageWatchdog { ATTR_EXPLICIT_HEALTH_CHECK_DURATION)); boolean hasPassedHealthCheck = Boolean.parseBoolean( parser.getAttributeValue(null, ATTR_PASSED_HEALTH_CHECK)); - if (!TextUtils.isEmpty(packageName)) { - packages.add(watchdog.new MonitoredPackage(packageName, duration, - healthCheckDuration, hasPassedHealthCheck)); + MonitoredPackage pkg = watchdog.newMonitoredPackage(packageName, + duration, healthCheckDuration, hasPassedHealthCheck); + if (pkg != null) { + packages.add(pkg); } } catch (NumberFormatException e) { Slog.wtf(TAG, "Skipping package for observer " + observerName, e); @@ -963,6 +963,20 @@ public class PackageWatchdog { int FAILED = 3; } + MonitoredPackage newMonitoredPackage( + String name, long durationMs, boolean hasPassedHealthCheck) { + return newMonitoredPackage(name, durationMs, Long.MAX_VALUE, hasPassedHealthCheck); + } + + MonitoredPackage newMonitoredPackage(String name, long durationMs, long healthCheckDurationMs, + boolean hasPassedHealthCheck) { + VersionedPackage pkg = getVersionedPackage(name); + if (pkg == null) { + return null; + } + return new MonitoredPackage(pkg, durationMs, healthCheckDurationMs, hasPassedHealthCheck); + } + /** * Represents a package and its health check state along with the time * it should be monitored for. @@ -971,8 +985,7 @@ public class PackageWatchdog { * instances of this class. */ class MonitoredPackage { - //TODO(b/120598832): VersionedPackage? - private final String mName; + private final VersionedPackage mPackage; // Times when package failures happen sorted in ascending order @GuardedBy("mLock") private final LongArrayQueue mFailureHistory = new LongArrayQueue(); @@ -996,13 +1009,9 @@ public class PackageWatchdog { @GuardedBy("mLock") private long mHealthCheckDurationMs = Long.MAX_VALUE; - MonitoredPackage(String name, long durationMs, boolean hasPassedHealthCheck) { - this(name, durationMs, Long.MAX_VALUE, hasPassedHealthCheck); - } - - MonitoredPackage(String name, long durationMs, long healthCheckDurationMs, - boolean hasPassedHealthCheck) { - mName = name; + private MonitoredPackage(VersionedPackage pkg, long durationMs, + long healthCheckDurationMs, boolean hasPassedHealthCheck) { + mPackage = pkg; mDurationMs = durationMs; mHealthCheckDurationMs = healthCheckDurationMs; mHasPassedHealthCheck = hasPassedHealthCheck; @@ -1013,7 +1022,7 @@ public class PackageWatchdog { @GuardedBy("mLock") public void writeLocked(XmlSerializer out) throws IOException { out.startTag(null, TAG_PACKAGE); - out.attribute(null, ATTR_NAME, mName); + out.attribute(null, ATTR_NAME, getName()); out.attribute(null, ATTR_DURATION, String.valueOf(mDurationMs)); out.attribute(null, ATTR_EXPLICIT_HEALTH_CHECK_DURATION, String.valueOf(mHealthCheckDurationMs)); @@ -1053,7 +1062,7 @@ public class PackageWatchdog { public int setHealthCheckActiveLocked(long initialHealthCheckDurationMs) { if (initialHealthCheckDurationMs <= 0) { Slog.wtf(TAG, "Cannot set non-positive health check duration " - + initialHealthCheckDurationMs + "ms for package " + mName + + initialHealthCheckDurationMs + "ms for package " + getName() + ". Using total duration " + mDurationMs + "ms instead"); initialHealthCheckDurationMs = mDurationMs; } @@ -1072,7 +1081,7 @@ public class PackageWatchdog { @GuardedBy("mLock") public int handleElapsedTimeLocked(long elapsedMs) { if (elapsedMs <= 0) { - Slog.w(TAG, "Cannot handle non-positive elapsed time for package " + mName); + Slog.w(TAG, "Cannot handle non-positive elapsed time for package " + getName()); return mHealthCheckState; } // Transitions to FAILED if now <= 0 and health check not passed @@ -1105,7 +1114,7 @@ public class PackageWatchdog { /** Returns the monitored package name. */ private String getName() { - return mName; + return mPackage.getPackageName(); } /** @@ -1170,7 +1179,7 @@ public class PackageWatchdog { } else { mHealthCheckState = HealthCheckState.ACTIVE; } - Slog.i(TAG, "Updated health check state for package " + mName + ": " + Slog.i(TAG, "Updated health check state for package " + getName() + ": " + toString(oldState) + " -> " + toString(mHealthCheckState)); return mHealthCheckState; } diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java index 87624359ef85..95582f73035a 100644 --- a/services/core/java/com/android/server/compat/CompatChange.java +++ b/services/core/java/com/android/server/compat/CompatChange.java @@ -38,6 +38,20 @@ import java.util.Map; */ public final class CompatChange extends CompatibilityChangeInfo { + /** + * Callback listener for when compat changes are updated for a package. + * See {@link #registerListener(ChangeListener)} for more details. + */ + public interface ChangeListener { + /** + * Called upon an override change for packageName and the change this listener is + * registered for. Called before the app is killed. + */ + void onCompatChange(String packageName); + } + + ChangeListener mListener = null; + private Map<String, Boolean> mPackageOverrides; public CompatChange(long changeId) { @@ -64,6 +78,15 @@ public final class CompatChange extends CompatibilityChangeInfo { change.getDisabled()); } + void registerListener(ChangeListener listener) { + if (mListener != null) { + throw new IllegalStateException( + "Listener for change " + toString() + " already registered."); + } + mListener = listener; + } + + /** * Force the enabled state of this change for a given package name. The change will only take * effect after that packages process is killed and restarted. @@ -78,6 +101,7 @@ public final class CompatChange extends CompatibilityChangeInfo { mPackageOverrides = new HashMap<>(); } mPackageOverrides.put(pname, enabled); + notifyListener(pname); } /** @@ -89,7 +113,9 @@ public final class CompatChange extends CompatibilityChangeInfo { */ void removePackageOverride(String pname) { if (mPackageOverrides != null) { - mPackageOverrides.remove(pname); + if (mPackageOverrides.remove(pname) != null) { + notifyListener(pname); + } } } @@ -131,4 +157,10 @@ public final class CompatChange extends CompatibilityChangeInfo { } return sb.append(")").toString(); } + + private void notifyListener(String packageName) { + if (mListener != null) { + mListener.onCompatChange(packageName); + } + } } diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index 490cce347188..39c6e7552e3c 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -228,7 +228,7 @@ final class CompatConfig { /** * Removes all overrides previously added via {@link #addOverride(long, String, boolean)} or - * {@link #addAppOverrides(CompatibilityChangeConfig, String)} for a certain package. + * {@link #addOverrides(CompatibilityChangeConfig, String)} for a certain package. * * <p>This restores the default behaviour for the given change and app, once any app * processes have been restarted. @@ -243,6 +243,27 @@ final class CompatConfig { } } + boolean registerListener(long changeId, CompatChange.ChangeListener listener) { + boolean alreadyKnown = true; + synchronized (mChanges) { + CompatChange c = mChanges.get(changeId); + if (c == null) { + alreadyKnown = false; + c = new CompatChange(changeId); + addChange(c); + } + c.registerListener(listener); + } + return alreadyKnown; + } + + @VisibleForTesting + void clearChanges() { + synchronized (mChanges) { + mChanges.clear(); + } + } + /** * Dumps the current list of compatibility config information. * diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 311e24fd5ee2..6ec4b9fbdb93 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -108,6 +108,23 @@ public class PlatformCompat extends IPlatformCompat.Stub { return enabled; } + /** + * Register a listener for change state overrides. Only one listener per change is allowed. + * + * <p>{@code listener.onCompatChange(String)} method is guaranteed to be called with + * packageName before the app is killed upon an override change. The state of a change is not + * guaranteed to change when {@code listener.onCompatChange(String)} is called. + * + * @param changeId to get updates for + * @param listener the listener that will be called upon a potential change for package. + * @throws IllegalStateException if a listener was already registered for changeId + * @returns {@code true} if a change with changeId was already known, or (@code false} + * otherwise. + */ + public boolean registerListener(long changeId, CompatChange.ChangeListener listener) { + return CompatConfig.get().registerListener(changeId, listener); + } + @Override public void setOverrides(CompatibilityChangeConfig overrides, String packageName) { CompatConfig.get().addOverrides(overrides, packageName); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 9a85f952446b..a702ce517f40 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -1557,6 +1557,18 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { if (!connected) { removeCecSwitches(portId); } + + // Turning System Audio Mode off when the AVR is unlugged or standby. + // When the device is not unplugged but reawaken from standby, we check if the System + // Audio Control Feature is enabled or not then decide if turning SAM on/off accordingly. + if (getAvrDeviceInfo() != null && portId == getAvrDeviceInfo().getPortId()) { + if (!connected) { + setSystemAudioMode(false); + } else if (mSystemAudioControlFeatureEnabled != mService.isSystemAudioActivated()){ + setSystemAudioMode(mSystemAudioControlFeatureEnabled); + } + } + // Tv device will have permanent HotplugDetectionAction. List<HotplugDetectionAction> hotplugActions = getActions(HotplugDetectionAction.class); if (!hotplugActions.isEmpty()) { diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index c84745e84646..557ba54b536d 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -1447,11 +1447,13 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private float[] mSvElevations; private float[] mSvAzimuths; private float[] mSvCarrierFreqs; + private float[] mBasebandCn0s; } @NativeEntryPoint private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s, - float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) { + float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs, + float[] basebandCn0s) { SvStatusInfo svStatusInfo = new SvStatusInfo(); svStatusInfo.mSvCount = svCount; svStatusInfo.mSvidWithFlags = svidWithFlags; @@ -1459,6 +1461,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements svStatusInfo.mSvElevations = svElevations; svStatusInfo.mSvAzimuths = svAzimuths; svStatusInfo.mSvCarrierFreqs = svCarrierFreqs; + svStatusInfo.mBasebandCn0s = basebandCn0s; sendMessage(REPORT_SV_STATUS, 0, svStatusInfo); } @@ -1470,7 +1473,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements info.mCn0s, info.mSvElevations, info.mSvAzimuths, - info.mSvCarrierFreqs); + info.mSvCarrierFreqs, + info.mBasebandCn0s); // Log CN0 as part of GNSS metrics mGnssMetrics.logCn0(info.mCn0s, info.mSvCount, info.mSvCarrierFreqs); @@ -1485,7 +1489,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements info.mCn0s, info.mSvElevations, info.mSvAzimuths, - info.mSvCarrierFreqs); + info.mSvCarrierFreqs, + info.mBasebandCn0s); int usedInFixCount = 0; int maxCn0 = 0; int meanCn0 = 0; @@ -1501,13 +1506,15 @@ public class GnssLocationProvider extends AbstractLocationProvider implements if (VERBOSE) { Log.v(TAG, "svid: " + gnssStatus.getSvid(i) + " cn0: " + gnssStatus.getCn0DbHz(i) + + " basebandCn0: " + gnssStatus.getBasebandCn0DbHz(i) + " elev: " + gnssStatus.getElevationDegrees(i) + " azimuth: " + gnssStatus.getAzimuthDegrees(i) + " carrier frequency: " + gnssStatus.getCn0DbHz(i) + (gnssStatus.hasEphemerisData(i) ? " E" : " ") + (gnssStatus.hasAlmanacData(i) ? " A" : " ") + (gnssStatus.usedInFix(i) ? "U" : "") - + (gnssStatus.hasCarrierFrequencyHz(i) ? "F" : "")); + + (gnssStatus.hasCarrierFrequencyHz(i) ? "F" : "") + + (gnssStatus.hasBasebandCn0DbHz(i) ? "B" : "")); } } if (usedInFixCount > 0) { diff --git a/services/core/java/com/android/server/location/GnssStatusListenerHelper.java b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java index d67d0c5fe612..eaf63c87d93f 100644 --- a/services/core/java/com/android/server/location/GnssStatusListenerHelper.java +++ b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java @@ -71,7 +71,8 @@ public abstract class GnssStatusListenerHelper extends RemoteListenerHelper<IGns final float[] cn0s, final float[] elevations, final float[] azimuths, - final float[] carrierFreqs) { + final float[] carrierFreqs, + final float[] basebandCn0s) { foreach((IGnssStatusListener listener, CallerIdentity callerIdentity) -> { if (!hasPermission(mContext, callerIdentity)) { logPermissionDisabledEventNotReported(TAG, callerIdentity.mPackageName, @@ -79,7 +80,7 @@ public abstract class GnssStatusListenerHelper extends RemoteListenerHelper<IGns return; } listener.onSvStatusChanged(svCount, prnWithFlags, cn0s, elevations, azimuths, - carrierFreqs); + carrierFreqs, basebandCn0s); }); } diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java index 8125d0d653ad..9e32d0e81a47 100644 --- a/services/core/java/com/android/server/notification/SnoozeHelper.java +++ b/services/core/java/com/android/server/notification/SnoozeHelper.java @@ -374,9 +374,6 @@ public class SnoozeHelper { return; } NotificationRecord existing = pkgRecords.get(record.getKey()); - if (existing != null && existing.isCanceled) { - return; - } pkgRecords.put(record.getKey(), record); } diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java index 259200b92597..7e478009b6b3 100644 --- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java +++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java @@ -19,6 +19,7 @@ package com.android.server.pm; import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageParser.isApkFile; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; +import static android.os.incremental.IncrementalManager.isIncrementalPath; import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; @@ -309,6 +310,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { final String nativeLibraryRootStr = initialLibraryPaths.nativeLibraryRootDir; final boolean useIsaSpecificSubdirs = initialLibraryPaths.nativeLibraryRootRequiresIsa; + final boolean onIncremental = isIncrementalPath(pkg.codePath); String primaryCpuAbi = null; String secondaryCpuAbi = null; @@ -341,10 +343,18 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { int abi64 = PackageManager.NO_NATIVE_LIBRARIES; if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { if (extractLibs) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); - abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, - nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, - useIsaSpecificSubdirs); + if (onIncremental) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, + "incrementalNativeBinaries"); + abi32 = NativeLibraryHelper.configureNativeBinariesForSupportedAbi(pkg, + handle, nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, + useIsaSpecificSubdirs); + } else { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); + abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, + nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, + useIsaSpecificSubdirs); + } } else { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); abi32 = NativeLibraryHelper.findSupportedAbi( @@ -364,10 +374,18 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { if (extractLibs) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); - abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, - nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, - useIsaSpecificSubdirs); + if (onIncremental) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, + "incrementalNativeBinaries"); + abi64 = NativeLibraryHelper.configureNativeBinariesForSupportedAbi(pkg, + handle, nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, + useIsaSpecificSubdirs); + } else { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); + abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, + nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, + useIsaSpecificSubdirs); + } } else { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); abi64 = NativeLibraryHelper.findSupportedAbi( @@ -418,9 +436,15 @@ final class PackageAbiHelperImpl implements PackageAbiHelper { final int copyRet; if (extractLibs) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); - copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, - nativeLibraryRoot, abiList, useIsaSpecificSubdirs); + if (onIncremental) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "incrementalNativeBinaries"); + copyRet = NativeLibraryHelper.configureNativeBinariesForSupportedAbi(pkg, + handle, nativeLibraryRoot, abiList, useIsaSpecificSubdirs); + } else { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); + copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, + nativeLibraryRoot, abiList, useIsaSpecificSubdirs); + } } else { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 0e075b117b81..b7b54e9cbb26 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -87,6 +87,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.RESTRICTION_NONE; import static android.content.pm.PackageParser.isApkFile; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; +import static android.os.incremental.IncrementalManager.isIncrementalPath; import static android.os.storage.StorageManager.FLAG_STORAGE_CE; import static android.os.storage.StorageManager.FLAG_STORAGE_DE; import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL; @@ -226,6 +227,7 @@ import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; +import android.os.incremental.IncrementalManager; import android.os.storage.DiskInfo; import android.os.storage.IStorageManager; import android.os.storage.StorageEventListener; @@ -1074,6 +1076,8 @@ public class PackageManagerService extends IPackageManager.Stub private Future<?> mPrepareAppDataFuture; + private final IncrementalManager mIncrementalManager; + private static class IFVerificationParams { PackageParser.Package pkg; boolean replacing; @@ -2509,6 +2513,8 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManager = injector.getPermissionManagerServiceInternal(); mSettings = injector.getSettings(); mPermissionManagerService = (IPermissionManager) ServiceManager.getService("permissionmgr"); + mIncrementalManager = + (IncrementalManager) mContext.getSystemService(Context.INCREMENTAL_SERVICE); // CHECKSTYLE:ON IndentationCheck t.traceEnd(); @@ -8798,6 +8804,7 @@ public class PackageManagerService extends IPackageManager.Stub // Full APK verification can be skipped during certificate collection, only if the file is // in verified partition, or can be verified on access (when apk verity is enabled). In both // cases, only data in Signing Block is verified instead of the whole file. + // TODO(b/136132412): skip for Incremental installation final boolean skipVerify = scanSystemPartition || (forceCollect && canSkipForcedPackageVerification(pkg)); collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify); @@ -14675,9 +14682,16 @@ public class PackageManagerService extends IPackageManager.Stub final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); + final boolean onIncremental = mIncrementalManager != null + && isIncrementalPath(beforeCodeFile.getAbsolutePath()); try { - Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); - } catch (ErrnoException e) { + if (onIncremental) { + mIncrementalManager.rename(beforeCodeFile.getAbsolutePath(), + afterCodeFile.getAbsolutePath()); + } else { + Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); + } + } catch (IOException | ErrnoException e) { Slog.w(TAG, "Failed to rename", e); return false; } @@ -14737,6 +14751,11 @@ public class PackageManagerService extends IPackageManager.Stub return false; } + String codePath = codeFile.getAbsolutePath(); + if (mIncrementalManager != null && isIncrementalPath(codePath)) { + mIncrementalManager.closeStorage(codePath); + } + removeCodePathLI(codeFile); if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { @@ -15928,6 +15947,8 @@ public class PackageManagerService extends IPackageManager.Stub & PackageManagerService.SCAN_AS_INSTANT_APP) != 0); final PackageParser.Package pkg = reconciledPkg.pkgSetting.pkg; final String packageName = pkg.packageName; + final boolean onIncremental = mIncrementalManager != null + && isIncrementalPath(pkg.codePath); prepareAppDataAfterInstallLIF(pkg); if (reconciledPkg.prepareResult.clearCodeCache) { clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE @@ -15958,6 +15979,7 @@ public class PackageManagerService extends IPackageManager.Stub // We only need to dexopt if the package meets ALL of the following conditions: // 1) it is not an instant app or if it is then dexopt is enabled via gservices. // 2) it is not debuggable. + // 3) it is not on Incremental File System. // // Note that we do not dexopt instant apps by default. dexopt can take some time to // complete, so we skip this step during installation. Instead, we'll take extra time @@ -15968,7 +15990,8 @@ public class PackageManagerService extends IPackageManager.Stub final boolean performDexopt = (!instantApp || Global.getInt(mContext.getContentResolver(), Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0) - && ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0); + && ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) + && (!onIncremental); if (performDexopt) { // Compile the layout resources. @@ -16200,6 +16223,7 @@ public class PackageManagerService extends IPackageManager.Stub if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) { pkg.setSigningDetails(args.signingDetails); } else { + // TODO(b/136132412): skip for Incremental installation PackageParser.collectCertificates(pkg, false /* skipVerify */); } } catch (PackageParserException e) { diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 232374c6773e..6d86078e92e4 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -504,11 +504,9 @@ class PackageManagerShellCommand extends ShellCommand { getErrPrintWriter().println("Error: no package specified"); return 1; } - userId = translateUserId(userId, true /*allowAll*/, "runPath"); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; - } - return displayPackageFilePath(pkg, userId); + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runPath"); + return displayPackageFilePath(pkg, translatedUserId); } private int runList() throws RemoteException { @@ -730,13 +728,14 @@ class PackageManagerShellCommand extends ShellCommand { final String filter = getNextArg(); - userId = translateUserId(userId, true /*allowAll*/, "runListPackages"); if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; + getFlags |= PackageManager.MATCH_KNOWN_PACKAGES; } + final int translatedUserId = + translateUserId(userId, UserHandle.USER_SYSTEM, "runListPackages"); @SuppressWarnings("unchecked") final ParceledListSlice<PackageInfo> slice = - mInterface.getInstalledPackages(getFlags, userId); + mInterface.getInstalledPackages(getFlags, translatedUserId); final List<PackageInfo> packages = slice.getList(); final int count = packages.size(); @@ -900,29 +899,29 @@ class PackageManagerShellCommand extends ShellCommand { } private int runListStagedSessions() { - final IndentingPrintWriter pw = new IndentingPrintWriter( - getOutPrintWriter(), /* singleIndent */ " ", /* wrapLength */ 120); + try (IndentingPrintWriter pw = new IndentingPrintWriter( + getOutPrintWriter(), /* singleIndent */ " ", /* wrapLength */ 120)) { + final SessionDump sessionDump = new SessionDump(); + String opt; + while ((opt = getNextOption()) != null) { + if (!setSessionFlag(opt, sessionDump)) { + pw.println("Error: Unknown option: " + opt); + return -1; + } + } - SessionDump sessionDump = new SessionDump(); - String opt; - while ((opt = getNextOption()) != null) { - if (!setSessionFlag(opt, sessionDump)) { - pw.println("Error: Unknown option: " + opt); + try { + final List<SessionInfo> stagedSessions = + mInterface.getPackageInstaller().getStagedSessions().getList(); + printSessionList(pw, stagedSessions, sessionDump); + } catch (RemoteException e) { + pw.println("Failure [" + + e.getClass().getName() + " - " + + e.getMessage() + "]"); return -1; } + return 1; } - - try { - List<SessionInfo> stagedSessions = - mInterface.getPackageInstaller().getStagedSessions().getList(); - printSessionList(pw, stagedSessions, sessionDump); - } catch (RemoteException e) { - pw.println("Failure [" - + e.getClass().getName() + " - " - + e.getMessage() + "]"); - return -1; - } - return 1; } private void printSessionList(IndentingPrintWriter pw, List<SessionInfo> stagedSessions, @@ -1357,19 +1356,17 @@ class PackageManagerShellCommand extends ShellCommand { pw.println("Error: package name not specified"); return 1; } - userId = translateUserId(userId, true /*allowAll*/, "runInstallExisting"); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; - } + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runInstallExisting"); int installReason = PackageManager.INSTALL_REASON_UNKNOWN; try { if (waitTillComplete) { final LocalIntentReceiver receiver = new LocalIntentReceiver(); final IPackageInstaller installer = mInterface.getPackageInstaller(); - pw.println("Installing package " + packageName + " for user: " + userId); + pw.println("Installing package " + packageName + " for user: " + translatedUserId); installer.installExistingPackage(packageName, installFlags, installReason, - receiver.getIntentSender(), userId, null); + receiver.getIntentSender(), translatedUserId, null); final Intent result = receiver.getResult(); final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE); @@ -1377,12 +1374,12 @@ class PackageManagerShellCommand extends ShellCommand { return status == PackageInstaller.STATUS_SUCCESS ? 0 : 1; } - final int res = mInterface.installExistingPackageAsUser(packageName, userId, + final int res = mInterface.installExistingPackageAsUser(packageName, translatedUserId, installFlags, installReason, null); if (res == PackageManager.INSTALL_FAILED_INVALID_URI) { throw new NameNotFoundException("Package " + packageName + " doesn't exist"); } - pw.println("Package " + packageName + " installed for user: " + userId); + pw.println("Package " + packageName + " installed for user: " + translatedUserId); return 0; } catch (RemoteException | NameNotFoundException e) { pw.println(e.toString()); @@ -1845,36 +1842,37 @@ class PackageManagerShellCommand extends ShellCommand { return runRemoveSplits(packageName, splitNames); } - userId = translateUserId(userId, true /*allowAll*/, "runUninstall"); + if (userId == UserHandle.USER_ALL) { + flags |= PackageManager.DELETE_ALL_USERS; + } + final int translatedUserId = + translateUserId(userId, UserHandle.USER_SYSTEM, "runUninstall"); final LocalIntentReceiver receiver = new LocalIntentReceiver(); - PackageManagerInternal internal = LocalServices.getService(PackageManagerInternal.class); + final PackageManagerInternal internal = + LocalServices.getService(PackageManagerInternal.class); if (internal.isApexPackage(packageName)) { - internal.uninstallApex(packageName, versionCode, userId, receiver.getIntentSender()); - } else { - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; - flags |= PackageManager.DELETE_ALL_USERS; - } else { - final PackageInfo info = mInterface.getPackageInfo(packageName, - PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId); - if (info == null) { - pw.println("Failure [not installed for " + userId + "]"); - return 1; - } - final boolean isSystem = - (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; - // If we are being asked to delete a system app for just one - // user set flag so it disables rather than reverting to system - // version of the app. - if (isSystem) { - flags |= PackageManager.DELETE_SYSTEM_APP; - } + internal.uninstallApex( + packageName, versionCode, translatedUserId, receiver.getIntentSender()); + } else if ((flags & PackageManager.DELETE_ALL_USERS) != 0) { + final PackageInfo info = mInterface.getPackageInfo(packageName, + PackageManager.MATCH_STATIC_SHARED_LIBRARIES, translatedUserId); + if (info == null) { + pw.println("Failure [not installed for " + translatedUserId + "]"); + return 1; + } + final boolean isSystem = + (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + // If we are being asked to delete a system app for just one + // user set flag so it disables rather than reverting to system + // version of the app. + if (isSystem) { + flags |= PackageManager.DELETE_SYSTEM_APP; } mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName, versionCode), null /*callerPackageName*/, flags, - receiver.getIntentSender(), userId); + receiver.getIntentSender(), translatedUserId); } final Intent result = receiver.getResult(); @@ -1948,8 +1946,10 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } - ClearDataObserver obs = new ClearDataObserver(); - ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId); + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runClear"); + final ClearDataObserver obs = new ClearDataObserver(); + ActivityManager.getService().clearApplicationUserData(pkg, false, obs, translatedUserId); synchronized (obs) { while (!obs.finished) { try { @@ -1991,28 +1991,26 @@ class PackageManagerShellCommand extends ShellCommand { userId = UserHandle.parseUserArg(getNextArgRequired()); } - String pkg = getNextArg(); + final String pkg = getNextArg(); if (pkg == null) { getErrPrintWriter().println("Error: no package or component specified"); return 1; } - userId = translateUserId(userId, true /*allowAll*/, "runSetEnabledSetting"); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; - } - ComponentName cn = ComponentName.unflattenFromString(pkg); + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runSetEnabledSetting"); + final ComponentName cn = ComponentName.unflattenFromString(pkg); if (cn == null) { - mInterface.setApplicationEnabledSetting(pkg, state, 0, userId, + mInterface.setApplicationEnabledSetting(pkg, state, 0, translatedUserId, "shell:" + android.os.Process.myUid()); getOutPrintWriter().println("Package " + pkg + " new state: " + enabledSettingToString( - mInterface.getApplicationEnabledSetting(pkg, userId))); + mInterface.getApplicationEnabledSetting(pkg, translatedUserId))); return 0; } else { - mInterface.setComponentEnabledSetting(cn, state, 0, userId); + mInterface.setComponentEnabledSetting(cn, state, 0, translatedUserId); getOutPrintWriter().println("Component " + cn.toShortString() + " new state: " + enabledSettingToString( - mInterface.getComponentEnabledSetting(cn, userId))); + mInterface.getComponentEnabledSetting(cn, translatedUserId))); return 0; } } @@ -2029,13 +2027,11 @@ class PackageManagerShellCommand extends ShellCommand { getErrPrintWriter().println("Error: no package or component specified"); return 1; } - userId = translateUserId(userId, true /*allowAll*/, "runSetHiddenSetting"); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; - } - mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId); + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runSetHiddenSetting"); + mInterface.setApplicationHiddenSettingAsUser(pkg, state, translatedUserId); getOutPrintWriter().println("Package " + pkg + " new hidden state: " - + mInterface.getApplicationHiddenSettingAsUser(pkg, userId)); + + mInterface.getApplicationHiddenSettingAsUser(pkg, translatedUserId)); return 0; } @@ -2102,16 +2098,14 @@ class PackageManagerShellCommand extends ShellCommand { info = null; } try { - userId = translateUserId(userId, true /*allowAll*/, "runSuspend"); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; - } + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runSuspend"); mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState, ((appExtras.size() > 0) ? appExtras : null), ((launcherExtras.size() > 0) ? launcherExtras : null), - info, callingPackage, userId); + info, callingPackage, translatedUserId); pw.println("Package " + packageName + " new suspended state: " - + mInterface.isPackageSuspendedForUser(packageName, userId)); + + mInterface.isPackageSuspendedForUser(packageName, translatedUserId)); return 0; } catch (RemoteException | IllegalArgumentException e) { pw.println(e.toString()); @@ -2139,11 +2133,12 @@ class PackageManagerShellCommand extends ShellCommand { getErrPrintWriter().println("Error: no permission specified"); return 1; } - userId = translateUserId(userId, true /*allowAll*/, "runGrantRevokePermission"); + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runGrantRevokePermission"); if (grant) { - mPermissionManager.grantRuntimePermission(pkg, perm, userId); + mPermissionManager.grantRuntimePermission(pkg, perm, translatedUserId); } else { - mPermissionManager.revokeRuntimePermission(pkg, perm, userId); + mPermissionManager.revokeRuntimePermission(pkg, perm, translatedUserId); } return 0; } @@ -2327,11 +2322,9 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } - userId = translateUserId(userId, true /*allowAll*/, "runSetAppLink"); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; - } - final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId); + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runSetAppLink"); + final PackageInfo info = mInterface.getPackageInfo(pkg, 0, translatedUserId); if (info == null) { getErrPrintWriter().println("Error: package " + pkg + " not found."); return 1; @@ -2342,7 +2335,7 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } - if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) { + if (!mInterface.updateIntentVerificationStatus(pkg, newMode, translatedUserId)) { getErrPrintWriter().println("Error: unable to update app link status for " + pkg); return 1; } @@ -2371,11 +2364,9 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } - userId = translateUserId(userId, true /*allowAll*/, "runGetAppLink"); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; - } - final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId); + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runGetAppLink"); + final PackageInfo info = mInterface.getPackageInfo(pkg, 0, translatedUserId); if (info == null) { getErrPrintWriter().println("Error: package " + pkg + " not found."); return 1; @@ -2388,7 +2379,7 @@ class PackageManagerShellCommand extends ShellCommand { } getOutPrintWriter().println(linkStateToString( - mInterface.getIntentVerificationStatus(pkg, userId))); + mInterface.getIntentVerificationStatus(pkg, translatedUserId))); return 0; } @@ -2565,9 +2556,11 @@ class PackageManagerShellCommand extends ShellCommand { getErrPrintWriter().println("Error: valid value not specified"); return 1; } - IUserManager um = IUserManager.Stub.asInterface( + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runSetUserRestriction"); + final IUserManager um = IUserManager.Stub.asInterface( ServiceManager.getService(Context.USER_SERVICE)); - um.setUserRestriction(restriction, value, userId); + um.setUserRestriction(restriction, value, translatedUserId); return 0; } @@ -2763,14 +2756,15 @@ class PackageManagerShellCommand extends ShellCommand { } pkgName = componentName.getPackageName(); } - userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate"); + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runSetHomeActivity"); final CompletableFuture<Boolean> future = new CompletableFuture<>(); final RemoteCallback callback = new RemoteCallback(res -> future.complete(res != null)); try { IRoleManager roleManager = android.app.role.IRoleManager.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.ROLE_SERVICE)); roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, pkgName, - 0, userId, callback); + 0, translatedUserId, callback); boolean success = future.get(); if (success) { pw.println("Success"); @@ -2859,14 +2853,12 @@ class PackageManagerShellCommand extends ShellCommand { } } - userId = translateUserId(userId, true /*allowAll*/, "runSetHarmfulAppWarning"); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; - } + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runSetHarmfulAppWarning"); final String packageName = getNextArgRequired(); final String warning = getNextArg(); - mInterface.setHarmfulAppWarning(packageName, warning, userId); + mInterface.setHarmfulAppWarning(packageName, warning, translatedUserId); return 0; } @@ -2884,12 +2876,10 @@ class PackageManagerShellCommand extends ShellCommand { } } - userId = translateUserId(userId, true /*allowAll*/, "runGetHarmfulAppWarning"); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; - } + final int translatedUserId = + translateUserId(userId, UserHandle.USER_NULL, "runGetHarmfulAppWarning"); final String packageName = getNextArgRequired(); - final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId); + final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, translatedUserId); if (!TextUtils.isEmpty(warning)) { getOutPrintWriter().println(warning); return 0; @@ -2917,21 +2907,22 @@ class PackageManagerShellCommand extends ShellCommand { throw new IllegalArgumentException("ABI " + abi + " not supported on this device"); } - private int translateUserId(int userId, boolean allowAll, String logContext) { - return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), - userId, allowAll, true, logContext, "pm command"); + private int translateUserId(int userId, int allUserId, String logContext) { + final boolean allowAll = (allUserId != UserHandle.USER_NULL); + final int translatedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), + Binder.getCallingUid(), userId, allowAll, true, logContext, "pm command"); + return translatedUserId == UserHandle.USER_ALL ? allUserId : translatedUserId; } private int doCreateSession(SessionParams params, String installerPackageName, int userId) throws RemoteException { - userId = translateUserId(userId, true /*allowAll*/, "doCreateSession"); if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_SYSTEM; params.installFlags |= PackageManager.INSTALL_ALL_USERS; } - + final int translatedUserId = + translateUserId(userId, UserHandle.USER_SYSTEM, "doCreateSession"); final int sessionId = mInterface.getPackageInstaller() - .createSession(params, installerPackageName, userId); + .createSession(params, installerPackageName, translatedUserId); return sessionId; } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 814433829733..faff394d495c 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1634,13 +1634,14 @@ public class UserManagerService extends IUserManager.Stub { * See {@link UserManagerInternal#setDevicePolicyUserRestrictions} */ private void setDevicePolicyUserRestrictionsInner(@UserIdInt int userId, - @Nullable Bundle restrictions, boolean isDeviceOwner, int cameraRestrictionScope) { + @Nullable Bundle restrictions, + @UserManagerInternal.OwnerType int restrictionOwnerType) { final Bundle global = new Bundle(); final Bundle local = new Bundle(); // Sort restrictions into local and global ensuring they don't overlap. - UserRestrictionsUtils.sortToGlobalAndLocal(restrictions, isDeviceOwner, - cameraRestrictionScope, global, local); + UserRestrictionsUtils.sortToGlobalAndLocal(restrictions, restrictionOwnerType, global, + local); boolean globalChanged, localChanged; synchronized (mRestrictionsLock) { @@ -1650,7 +1651,7 @@ public class UserManagerService extends IUserManager.Stub { localChanged = updateRestrictionsIfNeededLR( userId, local, mDevicePolicyLocalUserRestrictions); - if (isDeviceOwner) { + if (restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) { // Remember the global restriction owner userId to be able to make a distinction // in getUserRestrictionSource on who set local policies. mDeviceOwnerUserId = userId; @@ -4484,9 +4485,9 @@ public class UserManagerService extends IUserManager.Stub { private class LocalService extends UserManagerInternal { @Override public void setDevicePolicyUserRestrictions(@UserIdInt int userId, - @Nullable Bundle restrictions, boolean isDeviceOwner, int cameraRestrictionScope) { - UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId, restrictions, - isDeviceOwner, cameraRestrictionScope); + @Nullable Bundle restrictions, @OwnerType int restrictionOwnerType) { + UserManagerService.this.setDevicePolicyUserRestrictionsInner(userId, + restrictions, restrictionOwnerType); } @Override diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java index 3be51c58798e..f071c65cc772 100644 --- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java +++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java @@ -194,7 +194,18 @@ public class UserRestrictionsUtils { UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS, UserManager.DISALLOW_RUN_IN_BACKGROUND, UserManager.DISALLOW_UNMUTE_MICROPHONE, - UserManager.DISALLOW_UNMUTE_DEVICE + UserManager.DISALLOW_UNMUTE_DEVICE, + UserManager.DISALLOW_CAMERA + ); + + /** + * Special user restrictions that are applied globally when set by the profile owner of a + * managed profile that was created during the device provisioning flow. + */ + private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS = + Sets.newArraySet( + UserManager.DISALLOW_CONFIG_DATE_TIME, + UserManager.DISALLOW_CAMERA ); /** @@ -419,15 +430,9 @@ public class UserRestrictionsUtils { * Takes restrictions that can be set by device owner, and sort them into what should be applied * globally and what should be applied only on the current user. */ - public static void sortToGlobalAndLocal(@Nullable Bundle in, boolean isDeviceOwner, - int cameraRestrictionScope, - @NonNull Bundle global, @NonNull Bundle local) { - // Camera restriction (as well as all others) goes to at most one bundle. - if (cameraRestrictionScope == UserManagerInternal.CAMERA_DISABLED_GLOBALLY) { - global.putBoolean(UserManager.DISALLOW_CAMERA, true); - } else if (cameraRestrictionScope == UserManagerInternal.CAMERA_DISABLED_LOCALLY) { - local.putBoolean(UserManager.DISALLOW_CAMERA, true); - } + public static void sortToGlobalAndLocal(@Nullable Bundle in, + @UserManagerInternal.OwnerType int restrictionOwnerType, @NonNull Bundle global, + @NonNull Bundle local) { if (in == null || in.size() == 0) { return; } @@ -435,7 +440,7 @@ public class UserRestrictionsUtils { if (!in.getBoolean(key)) { continue; } - if (isGlobal(isDeviceOwner, key)) { + if (isGlobal(restrictionOwnerType, key)) { global.putBoolean(key, true); } else { local.putBoolean(key, true); @@ -446,9 +451,13 @@ public class UserRestrictionsUtils { /** * Whether given user restriction should be enforced globally. */ - private static boolean isGlobal(boolean isDeviceOwner, String key) { - return (isDeviceOwner && - (PRIMARY_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key))) + private static boolean isGlobal(@UserManagerInternal.OwnerType int restrictionOwnerType, + String key) { + return ((restrictionOwnerType == UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) && ( + PRIMARY_USER_ONLY_RESTRICTIONS.contains(key) || GLOBAL_RESTRICTIONS.contains(key))) + || ((restrictionOwnerType + == UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE) + && PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS.contains(key)) || PROFILE_GLOBAL_RESTRICTIONS.contains(key) || DEVICE_OWNER_ONLY_RESTRICTIONS.contains(key); } diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java index 0a6b38fb2e9a..6da8fb4b1edb 100644 --- a/services/core/java/com/android/server/power/ShutdownThread.java +++ b/services/core/java/com/android/server/power/ShutdownThread.java @@ -47,8 +47,8 @@ import android.util.TimingsTraceLog; import android.view.WindowManager; import com.android.internal.telephony.ITelephony; -import com.android.server.RescueParty; import com.android.server.LocalServices; +import com.android.server.RescueParty; import com.android.server.pm.PackageManagerService; import com.android.server.statusbar.StatusBarManagerInternal; @@ -307,7 +307,9 @@ public final class ShutdownThread extends Thread { com.android.internal.R.string.reboot_to_update_reboot)); } } else if (mReason != null && mReason.equals(PowerManager.REBOOT_RECOVERY)) { - if (RescueParty.isAttemptingFactoryReset()) { + if (showSysuiReboot()) { + return null; + } else if (RescueParty.isAttemptingFactoryReset()) { // We're not actually doing a factory reset yet; we're rebooting // to ask the user if they'd like to reset, so give them a less // scary dialog message. diff --git a/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java index fd8cc24b658b..3c79b2399fa3 100644 --- a/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java +++ b/services/core/java/com/android/server/timedetector/SimpleTimeDetectorStrategy.java @@ -16,9 +16,11 @@ package com.android.server.timedetector; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AlarmManager; +import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.content.Intent; import android.util.Slog; @@ -27,6 +29,8 @@ import android.util.TimestampedValue; import com.android.internal.telephony.TelephonyIntents; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * An implementation of TimeDetectorStrategy that passes only NITZ suggestions to @@ -38,10 +42,22 @@ public final class SimpleTimeDetectorStrategy implements TimeDetectorStrategy { private final static String TAG = "timedetector.SimpleTimeDetectorStrategy"; + @IntDef({ ORIGIN_PHONE, ORIGIN_MANUAL }) + @Retention(RetentionPolicy.SOURCE) + public @interface Origin {} + + /** Used when a time value originated from a telephony signal. */ + @Origin + private static final int ORIGIN_PHONE = 1; + + /** Used when a time value originated from a user / manual settings. */ + @Origin + private static final int ORIGIN_MANUAL = 2; + /** * CLOCK_PARANOIA: The maximum difference allowed between the expected system clock time and the * actual system clock time before a warning is logged. Used to help identify situations where - * there is something other than this class setting the system clock. + * there is something other than this class setting the system clock automatically. */ private static final long SYSTEM_CLOCK_PARANOIA_THRESHOLD_MILLIS = 2 * 1000; @@ -52,11 +68,11 @@ public final class SimpleTimeDetectorStrategy implements TimeDetectorStrategy { @Nullable private PhoneTimeSuggestion mLastPhoneSuggestion; // Information about the last time signal received: Used when toggling auto-time. - @Nullable private TimestampedValue<Long> mLastSystemClockTime; - private boolean mLastSystemClockTimeSendNetworkBroadcast; + @Nullable private TimestampedValue<Long> mLastAutoSystemClockTime; + private boolean mLastAutoSystemClockTimeSendNetworkBroadcast; // System clock state. - @Nullable private TimestampedValue<Long> mLastSystemClockTimeSet; + @Nullable private TimestampedValue<Long> mLastAutoSystemClockTimeSet; @Override public void initialize(@NonNull Callback callback) { @@ -78,17 +94,18 @@ public final class SimpleTimeDetectorStrategy implements TimeDetectorStrategy { return; } // Always store the last NITZ value received, regardless of whether we go on to use it to - // update the system clock. This is so that we can validate future NITZ signals. + // update the system clock. This is so that we can validate future phone suggestions. mLastPhoneSuggestion = timeSuggestion; // System clock update logic. + final TimestampedValue<Long> newUtcTime = timeSuggestion.getUtcTime(); + setSystemClockIfRequired(ORIGIN_PHONE, newUtcTime, timeSuggestion); + } - // Historically, Android has sent a telephony broadcast only when setting the time using - // NITZ. - final boolean sendNetworkBroadcast = true; - + @Override + public void suggestManualTime(ManualTimeSuggestion timeSuggestion) { final TimestampedValue<Long> newUtcTime = timeSuggestion.getUtcTime(); - setSystemClockIfRequired(newUtcTime, sendNetworkBroadcast); + setSystemClockIfRequired(ORIGIN_MANUAL, newUtcTime, timeSuggestion); } private static boolean validateNewPhoneSuggestion(@NonNull PhoneTimeSuggestion newSuggestion, @@ -110,16 +127,31 @@ public final class SimpleTimeDetectorStrategy implements TimeDetectorStrategy { } private void setSystemClockIfRequired( - TimestampedValue<Long> time, boolean sendNetworkBroadcast) { - - // Store the last candidate we've seen in all cases so we can set the system clock - // when/if time detection is enabled. - mLastSystemClockTime = time; - mLastSystemClockTimeSendNetworkBroadcast = sendNetworkBroadcast; - - if (!mCallback.isTimeDetectionEnabled()) { - Slog.d(TAG, "setSystemClockIfRequired: Time detection is not enabled. time=" + time); - return; + @Origin int origin, TimestampedValue<Long> time, Object cause) { + // Historically, Android has sent a TelephonyIntents.ACTION_NETWORK_SET_TIME broadcast only + // when setting the time using NITZ. + boolean sendNetworkBroadcast = origin == ORIGIN_PHONE; + + boolean isOriginAutomatic = isOriginAutomatic(origin); + if (isOriginAutomatic) { + // Store the last auto time candidate we've seen in all cases so we can set the system + // clock when/if time detection is off but later enabled. + mLastAutoSystemClockTime = time; + mLastAutoSystemClockTimeSendNetworkBroadcast = sendNetworkBroadcast; + + if (!mCallback.isAutoTimeDetectionEnabled()) { + Slog.d(TAG, "setSystemClockIfRequired: Auto time detection is not enabled." + + " time=" + time + + ", cause=" + cause); + return; + } + } else { + if (mCallback.isAutoTimeDetectionEnabled()) { + Slog.d(TAG, "setSystemClockIfRequired: Auto time detection is enabled." + + " time=" + time + + ", cause=" + cause); + return; + } } mCallback.acquireWakeLock(); @@ -127,37 +159,44 @@ public final class SimpleTimeDetectorStrategy implements TimeDetectorStrategy { long elapsedRealtimeMillis = mCallback.elapsedRealtimeMillis(); long actualTimeMillis = mCallback.systemClockMillis(); - // CLOCK_PARANOIA : Check to see if this class owns the clock or if something else - // may be setting the clock. - if (mLastSystemClockTimeSet != null) { - long expectedTimeMillis = TimeDetectorStrategy.getTimeAt( - mLastSystemClockTimeSet, elapsedRealtimeMillis); - long absSystemClockDifference = Math.abs(expectedTimeMillis - actualTimeMillis); - if (absSystemClockDifference > SYSTEM_CLOCK_PARANOIA_THRESHOLD_MILLIS) { - Slog.w(TAG, "System clock has not tracked elapsed real time clock. A clock may" - + " be inaccurate or something unexpectedly set the system clock." - + " elapsedRealtimeMillis=" + elapsedRealtimeMillis - + " expectedTimeMillis=" + expectedTimeMillis - + " actualTimeMillis=" + actualTimeMillis); + if (isOriginAutomatic) { + // CLOCK_PARANOIA : Check to see if this class owns the clock or if something else + // may be setting the clock. + if (mLastAutoSystemClockTimeSet != null) { + long expectedTimeMillis = TimeDetectorStrategy.getTimeAt( + mLastAutoSystemClockTimeSet, elapsedRealtimeMillis); + long absSystemClockDifference = Math.abs(expectedTimeMillis - actualTimeMillis); + if (absSystemClockDifference > SYSTEM_CLOCK_PARANOIA_THRESHOLD_MILLIS) { + Slog.w(TAG, + "System clock has not tracked elapsed real time clock. A clock may" + + " be inaccurate or something unexpectedly set the system" + + " clock." + + " elapsedRealtimeMillis=" + elapsedRealtimeMillis + + " expectedTimeMillis=" + expectedTimeMillis + + " actualTimeMillis=" + actualTimeMillis); + } } } - final String reason = "New time signal"; adjustAndSetDeviceSystemClock( - time, sendNetworkBroadcast, elapsedRealtimeMillis, actualTimeMillis, reason); + time, sendNetworkBroadcast, elapsedRealtimeMillis, actualTimeMillis, cause); } finally { mCallback.releaseWakeLock(); } } + private static boolean isOriginAutomatic(@Origin int origin) { + return origin == ORIGIN_PHONE; + } + @Override public void handleAutoTimeDetectionToggle(boolean enabled) { // If automatic time detection is enabled we update the system clock instantly if we can. // Conversely, if automatic time detection is disabled we leave the clock as it is. if (enabled) { - if (mLastSystemClockTime != null) { + if (mLastAutoSystemClockTime != null) { // Only send the network broadcast if the last candidate would have caused one. - final boolean sendNetworkBroadcast = mLastSystemClockTimeSendNetworkBroadcast; + final boolean sendNetworkBroadcast = mLastAutoSystemClockTimeSendNetworkBroadcast; mCallback.acquireWakeLock(); try { @@ -165,7 +204,7 @@ public final class SimpleTimeDetectorStrategy implements TimeDetectorStrategy { long actualTimeMillis = mCallback.systemClockMillis(); final String reason = "Automatic time detection enabled."; - adjustAndSetDeviceSystemClock(mLastSystemClockTime, sendNetworkBroadcast, + adjustAndSetDeviceSystemClock(mLastAutoSystemClockTime, sendNetworkBroadcast, elapsedRealtimeMillis, actualTimeMillis, reason); } finally { mCallback.releaseWakeLock(); @@ -174,22 +213,22 @@ public final class SimpleTimeDetectorStrategy implements TimeDetectorStrategy { } else { // CLOCK_PARANOIA: We are losing "control" of the system clock so we cannot predict what // it should be in future. - mLastSystemClockTimeSet = null; + mLastAutoSystemClockTimeSet = null; } } @Override public void dump(@NonNull PrintWriter pw, @Nullable String[] args) { pw.println("mLastPhoneSuggestion=" + mLastPhoneSuggestion); - pw.println("mLastSystemClockTimeSet=" + mLastSystemClockTimeSet); - pw.println("mLastSystemClockTime=" + mLastSystemClockTime); - pw.println("mLastSystemClockTimeSendNetworkBroadcast=" - + mLastSystemClockTimeSendNetworkBroadcast); + pw.println("mLastAutoSystemClockTimeSet=" + mLastAutoSystemClockTimeSet); + pw.println("mLastAutoSystemClockTime=" + mLastAutoSystemClockTime); + pw.println("mLastAutoSystemClockTimeSendNetworkBroadcast=" + + mLastAutoSystemClockTimeSendNetworkBroadcast); } private void adjustAndSetDeviceSystemClock( TimestampedValue<Long> newTime, boolean sendNetworkBroadcast, - long elapsedRealtimeMillis, long actualSystemClockMillis, String reason) { + long elapsedRealtimeMillis, long actualSystemClockMillis, Object cause) { // Adjust for the time that has elapsed since the signal was received. long newSystemClockMillis = TimeDetectorStrategy.getTimeAt(newTime, elapsedRealtimeMillis); @@ -203,20 +242,20 @@ public final class SimpleTimeDetectorStrategy implements TimeDetectorStrategy { + " system clock are close enough." + " elapsedRealtimeMillis=" + elapsedRealtimeMillis + " newTime=" + newTime - + " reason=" + reason + + " cause=" + cause + " systemClockUpdateThreshold=" + systemClockUpdateThreshold + " absTimeDifference=" + absTimeDifference); return; } Slog.d(TAG, "Setting system clock using time=" + newTime - + " reason=" + reason + + " cause=" + cause + " elapsedRealtimeMillis=" + elapsedRealtimeMillis + " newTimeMillis=" + newSystemClockMillis); mCallback.setSystemClock(newSystemClockMillis); // CLOCK_PARANOIA : Record the last time this class set the system clock. - mLastSystemClockTimeSet = newTime; + mLastAutoSystemClockTimeSet = newTime; if (sendNetworkBroadcast) { // Send a broadcast that telephony code used to send after setting the clock. diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorService.java b/services/core/java/com/android/server/timedetector/TimeDetectorService.java index ee42279f7d50..09309751d493 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorService.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorService.java @@ -19,6 +19,7 @@ package com.android.server.timedetector; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.timedetector.ITimeDetectorService; +import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.content.ContentResolver; import android.content.Context; @@ -97,7 +98,7 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub { @Override public void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSignal) { - enforceSetTimePermission(); + enforceSuggestPhoneTimePermission(); Objects.requireNonNull(timeSignal); long idToken = Binder.clearCallingIdentity(); @@ -110,10 +111,25 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub { } } + @Override + public void suggestManualTime(@NonNull ManualTimeSuggestion timeSignal) { + enforceSuggestManualTimePermission(); + Objects.requireNonNull(timeSignal); + + long idToken = Binder.clearCallingIdentity(); + try { + synchronized (mStrategyLock) { + mTimeDetectorStrategy.suggestManualTime(timeSignal); + } + } finally { + Binder.restoreCallingIdentity(idToken); + } + } + @VisibleForTesting public void handleAutoTimeDetectionToggle() { synchronized (mStrategyLock) { - final boolean timeDetectionEnabled = mCallback.isTimeDetectionEnabled(); + final boolean timeDetectionEnabled = mCallback.isAutoTimeDetectionEnabled(); mTimeDetectorStrategy.handleAutoTimeDetectionToggle(timeDetectionEnabled); } } @@ -128,7 +144,11 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub { } } - private void enforceSetTimePermission() { + private void enforceSuggestPhoneTimePermission() { + mContext.enforceCallingPermission(android.Manifest.permission.SET_TIME, "set time"); + } + + private void enforceSuggestManualTimePermission() { mContext.enforceCallingPermission(android.Manifest.permission.SET_TIME, "set time"); } -}
\ No newline at end of file +} diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java index 7c2a945854f5..b60cebf57b45 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategy.java @@ -18,6 +18,7 @@ package com.android.server.timedetector; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.content.Intent; import android.util.TimestampedValue; @@ -47,7 +48,7 @@ public interface TimeDetectorStrategy { int systemClockUpdateThresholdMillis(); /** Returns true if automatic time detection is enabled. */ - boolean isTimeDetectionEnabled(); + boolean isAutoTimeDetectionEnabled(); /** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */ void acquireWakeLock(); @@ -71,9 +72,12 @@ public interface TimeDetectorStrategy { /** Initialize the strategy. */ void initialize(@NonNull Callback callback); - /** Process the suggested time. */ + /** Process the suggested time from telephony sources. */ void suggestPhoneTime(@NonNull PhoneTimeSuggestion timeSuggestion); + /** Process the suggested manually entered time. */ + void suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion); + /** Handle the auto-time setting being toggled on or off. */ void handleAutoTimeDetectionToggle(boolean enabled); diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java index 77b9e6281086..42d59d51c6af 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyCallbackImpl.java @@ -72,7 +72,7 @@ public final class TimeDetectorStrategyCallbackImpl implements TimeDetectorStrat } @Override - public boolean isTimeDetectionEnabled() { + public boolean isAutoTimeDetectionEnabled() { try { return Settings.Global.getInt(mContentResolver, Settings.Global.AUTO_TIME) != 0; } catch (Settings.SettingNotFoundException snfe) { diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 3bc28383cf29..a0f5628761fb 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -704,20 +704,22 @@ Return<void> GnssCallback::gnssSvStatusCbImpl(const T& svStatus) { jfloatArray elevArray = env->NewFloatArray(listSize); jfloatArray azimArray = env->NewFloatArray(listSize); jfloatArray carrierFreqArray = env->NewFloatArray(listSize); + jfloatArray basebandCn0Array = env->NewFloatArray(listSize); jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0); jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0); jfloat* elev = env->GetFloatArrayElements(elevArray, 0); jfloat* azim = env->GetFloatArrayElements(azimArray, 0); jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0); + jfloat* basebandCn0s = env->GetFloatArrayElements(basebandCn0Array, 0); /* * Read GNSS SV info. */ for (size_t i = 0; i < listSize; ++i) { enum ShiftWidth: uint8_t { - SVID_SHIFT_WIDTH = 8, - CONSTELLATION_TYPE_SHIFT_WIDTH = 4 + SVID_SHIFT_WIDTH = 12, + CONSTELLATION_TYPE_SHIFT_WIDTH = 8 }; const IGnssCallback_V1_0::GnssSvInfo& info = getGnssSvInfoOfIndex(svStatus, i); @@ -728,6 +730,8 @@ Return<void> GnssCallback::gnssSvStatusCbImpl(const T& svStatus) { elev[i] = info.elevationDegrees; azim[i] = info.azimuthDegrees; carrierFreq[i] = info.carrierFrequencyHz; + // TODO(b/144850155): fill svidWithFlags with hasBasebandCn0DbHz based on HAL versions + basebandCn0s[i] = 0.0; } env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0); @@ -735,10 +739,11 @@ Return<void> GnssCallback::gnssSvStatusCbImpl(const T& svStatus) { env->ReleaseFloatArrayElements(elevArray, elev, 0); env->ReleaseFloatArrayElements(azimArray, azim, 0); env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0); + env->ReleaseFloatArrayElements(basebandCn0Array, basebandCn0s, 0); env->CallVoidMethod(mCallbacksObj, method_reportSvStatus, static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray, - carrierFreqArray); + carrierFreqArray, basebandCn0Array); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Void(); @@ -1545,7 +1550,7 @@ static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(ZLandroid/location/Location;)V"); method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); - method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V"); + method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F[F)V"); method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V"); method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V"); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index b03349218e91..f04c1c421666 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -137,6 +137,8 @@ import android.app.admin.StartInstallingUpdateCallback; import android.app.admin.SystemUpdateInfo; import android.app.admin.SystemUpdatePolicy; import android.app.backup.IBackupManager; +import android.app.timedetector.ManualTimeSuggestion; +import android.app.timedetector.TimeDetector; import android.app.trust.TrustManager; import android.app.usage.UsageStatsManagerInternal; import android.compat.annotation.ChangeId; @@ -1956,6 +1958,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return mContext.getSystemService(AlarmManager.class); } + TimeDetector getTimeDetector() { + return mContext.getSystemService(TimeDetector.class); + } + ConnectivityManager getConnectivityManager() { return mContext.getSystemService(ConnectivityManager.class); } @@ -5568,8 +5574,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void enforceProfileOwnerOfCorpOwnedDevice(ActiveAdmin admin) { - if (!isProfileOwnerOfOrganizationOwnedDevicte(admin)) { + private void enforceProfileOwnerOfOrganizationOwnedDevice(ActiveAdmin admin) { + if (!isProfileOwnerOfOrganizationOwnedDevice(admin)) { throw new SecurityException(String.format("Provided admin %s is either not a profile " + "owner or not on a corporate-owned device.", admin)); } @@ -6639,7 +6645,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } boolean calledByProfileOwnerOnOrgOwnedDevice = - isProfileOwnerOfOrganizationOwnedDevicte(admin); + isProfileOwnerOfOrganizationOwnedDevice(admin); if (calledOnParentInstance && !calledByProfileOwnerOnOrgOwnedDevice) { throw new SecurityException("Wiping the entire device can only be done by a profile" @@ -8020,7 +8026,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { * {@code getActiveAdminForCallerLocked} or one of the similar variants, not caller-supplied * input. */ - private boolean isProfileOwnerOfOrganizationOwnedDevicte(@Nullable ActiveAdmin admin) { + private boolean isProfileOwnerOfOrganizationOwnedDevice(@Nullable ActiveAdmin admin) { if (admin == null) { return false; } @@ -10223,8 +10229,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { final boolean isDeviceOwner = mOwners.isDeviceOwnerUserId(userId); final Bundle userRestrictions; - // Whether device owner enforces camera restriction. - boolean disallowCameraGlobally = false; + final int restrictionOwnerType; if (isDeviceOwner) { final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); @@ -10232,33 +10237,45 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return; // Shouldn't happen. } userRestrictions = deviceOwner.userRestrictions; - // DO can disable camera globally. - disallowCameraGlobally = deviceOwner.disableCamera; + addOrRemoveDisableCameraRestriction(userRestrictions, deviceOwner); + restrictionOwnerType = UserManagerInternal.OWNER_TYPE_DEVICE_OWNER; } else { final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId); userRestrictions = profileOwner != null ? profileOwner.userRestrictions : null; - } + addOrRemoveDisableCameraRestriction(userRestrictions, userId); - // Whether any admin enforces camera restriction. - final int cameraRestrictionScope = - getCameraRestrictionScopeLocked(userId, disallowCameraGlobally); + if (isProfileOwnerOfOrganizationOwnedDevice(profileOwner)) { + restrictionOwnerType = + UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE; + } else if (profileOwner != null) { + restrictionOwnerType = UserManagerInternal.OWNER_TYPE_PROFILE_OWNER; + } else { + restrictionOwnerType = UserManagerInternal.OWNER_TYPE_NO_OWNER; + } + } mUserManagerInternal.setDevicePolicyUserRestrictions(userId, userRestrictions, - isDeviceOwner, cameraRestrictionScope); + restrictionOwnerType); } } - /** - * Get the scope of camera restriction for a given user if any. - */ - private int getCameraRestrictionScopeLocked(int userId, boolean disallowCameraGlobally) { - if (disallowCameraGlobally) { - return UserManagerInternal.CAMERA_DISABLED_GLOBALLY; - } else if (getCameraDisabled( - /* who= */ null, userId, /* mergeDeviceOwnerRestriction= */ false)) { - return UserManagerInternal.CAMERA_DISABLED_LOCALLY; + private void addOrRemoveDisableCameraRestriction(Bundle userRestrictions, ActiveAdmin admin) { + if (userRestrictions == null) return; + if (admin.disableCamera) { + userRestrictions.putBoolean(UserManager.DISALLOW_CAMERA, true); + } else { + userRestrictions.remove(UserManager.DISALLOW_CAMERA); + } + } + + private void addOrRemoveDisableCameraRestriction(Bundle userRestrictions, int userId) { + if (userRestrictions == null) return; + if (getCameraDisabled(/* who= */ null, userId, /* mergeDeviceOwnerRestriction= */ + false)) { + userRestrictions.putBoolean(UserManager.DISALLOW_CAMERA, true); + } else { + userRestrictions.remove(UserManager.DISALLOW_CAMERA); } - return UserManagerInternal.CAMERA_NOT_DISABLED; } @Override @@ -10987,31 +11004,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void setLocationEnabled(ComponentName who, boolean locationEnabled) { Preconditions.checkNotNull(who, "ComponentName is null"); - int userId = mInjector.userHandleGetCallingUserId(); - - synchronized (getLockObject()) { - getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + enforceDeviceOwner(who); - if (!isDeviceOwner(who, userId) && !isCurrentUserDemo()) { - throw new SecurityException( - "Permission denial: Profile owners cannot update location settings"); - } - } + UserHandle userHandle = mInjector.binderGetCallingUserHandle(); + mInjector.binderWithCleanCallingIdentity( + () -> mInjector.getLocationManager().setLocationEnabledForUser(locationEnabled, + userHandle)); - long ident = mInjector.binderClearCallingIdentity(); - try { - mInjector.getLocationManager().setLocationEnabledForUser( - locationEnabled, UserHandle.of(userId)); - DevicePolicyEventLogger - .createEvent(DevicePolicyEnums.SET_SECURE_SETTING) - .setAdmin(who) - .setStrings(Settings.Secure.LOCATION_MODE, Integer.toString( - locationEnabled ? Settings.Secure.LOCATION_MODE_ON - : Settings.Secure.LOCATION_MODE_OFF)) - .write(); - } finally { - mInjector.binderRestoreCallingIdentity(ident); - } + DevicePolicyEventLogger + .createEvent(DevicePolicyEnums.SET_SECURE_SETTING) + .setAdmin(who) + .setStrings(Settings.Secure.LOCATION_MODE, Integer.toString( + locationEnabled ? Settings.Secure.LOCATION_MODE_ON + : Settings.Secure.LOCATION_MODE_OFF)) + .write(); } @Override @@ -11022,7 +11028,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (mInjector.settingsGlobalGetInt(Global.AUTO_TIME, 0) == 1) { return false; } - mInjector.binderWithCleanCallingIdentity(() -> mInjector.getAlarmManager().setTime(millis)); + ManualTimeSuggestion manualTimeSuggestion = TimeDetector.createManualTimeSuggestion( + millis, "DevicePolicyManagerService: setTime"); + mInjector.binderWithCleanCallingIdentity( + () -> mInjector.getTimeDetector().suggestManualTime(manualTimeSuggestion)); return true; } diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index 0be5fe02f0fe..cf7919b38f2e 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -41,6 +41,7 @@ android_test { "hamcrest-library", "servicestests-utils", "xml-writer-device-lib", + "service-appsearch", "service-jobscheduler", ], diff --git a/services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java b/services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java new file mode 100644 index 000000000000..73279cb5bb22 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java @@ -0,0 +1,93 @@ +/* + * 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.appsearch.impl; + +import static com.google.common.truth.Truth.assertThat; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class FakeIcingTest { + @Test + public void query() { + FakeIcing icing = new FakeIcing(); + icing.put("uri:cat", "The cat said meow"); + icing.put("uri:dog", "The dog said woof"); + + assertThat(icing.query("meow")).containsExactly("uri:cat"); + assertThat(icing.query("said")).containsExactly("uri:cat", "uri:dog"); + assertThat(icing.query("fred")).isEmpty(); + } + + @Test + public void queryNorm() { + FakeIcing icing = new FakeIcing(); + icing.put("uri:cat", "The cat said meow"); + icing.put("uri:dog", "The dog said woof"); + + assertThat(icing.query("the")).containsExactly("uri:cat", "uri:dog"); + assertThat(icing.query("The")).containsExactly("uri:cat", "uri:dog"); + assertThat(icing.query("tHe")).containsExactly("uri:cat", "uri:dog"); + } + + @Test + public void get() { + FakeIcing icing = new FakeIcing(); + icing.put("uri:cat", "The cat said meow"); + assertThat(icing.get("uri:cat")).isEqualTo("The cat said meow"); + } + + @Test + public void replace() { + FakeIcing icing = new FakeIcing(); + icing.put("uri:cat", "The cat said meow"); + icing.put("uri:dog", "The dog said woof"); + + assertThat(icing.query("meow")).containsExactly("uri:cat"); + assertThat(icing.query("said")).containsExactly("uri:cat", "uri:dog"); + assertThat(icing.get("uri:cat")).isEqualTo("The cat said meow"); + + // Replace + icing.put("uri:cat", "The cat said purr"); + icing.put("uri:bird", "The cat said tweet"); + + assertThat(icing.query("meow")).isEmpty(); + assertThat(icing.query("said")).containsExactly("uri:cat", "uri:dog", "uri:bird"); + assertThat(icing.get("uri:cat")).isEqualTo("The cat said purr"); + } + + @Test + public void delete() { + FakeIcing icing = new FakeIcing(); + icing.put("uri:cat", "The cat said meow"); + icing.put("uri:dog", "The dog said woof"); + + assertThat(icing.query("meow")).containsExactly("uri:cat"); + assertThat(icing.query("said")).containsExactly("uri:cat", "uri:dog"); + assertThat(icing.get("uri:cat")).isEqualTo("The cat said meow"); + + // Delete + icing.delete("uri:cat"); + icing.delete("uri:notreal"); + + assertThat(icing.query("meow")).isEmpty(); + assertThat(icing.query("said")).containsExactly("uri:dog"); + assertThat(icing.get("uri:cat")).isNull(); + } +} diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java new file mode 100644 index 000000000000..c406876c5cee --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java @@ -0,0 +1,272 @@ +/* + * 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.compat; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.eq; +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 static org.mockito.internal.verification.VerificationModeFactory.times; +import static org.testng.Assert.assertThrows; + +import android.compat.Compatibility; +import android.content.Context; +import android.content.pm.PackageManager; + +import com.android.internal.compat.CompatibilityChangeConfig; + +import com.google.common.collect.ImmutableSet; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class PlatformCompatTest { + private static final String PACKAGE_NAME = "my.package"; + + @Mock + private Context mContext; + @Mock + private PackageManager mPackageManager; + @Mock + CompatChange.ChangeListener mListener1, mListener2; + + + @Before + public void setUp() throws Exception { + when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mPackageManager.getPackageUid(eq(PACKAGE_NAME), eq(0))).thenThrow( + new PackageManager.NameNotFoundException()); + CompatConfig.get().clearChanges(); + } + + @Test + public void testRegisterListenerToSameIdThrows() { + PlatformCompat pc = new PlatformCompat(mContext); + + // Registering a listener to change 1 is successful. + pc.registerListener(1, mListener1); + // Registering a listener to change 2 is successful. + pc.registerListener(2, mListener1); + // Trying to register another listener to change id 1 fails. + assertThrows(IllegalStateException.class, () -> pc.registerListener(1, mListener1)); + } + + @Test + public void testRegisterListenerReturn() { + PlatformCompat pc = new PlatformCompat(mContext); + + pc.setOverrides( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of())), + PACKAGE_NAME); + + // Change id 1 is known (added in setOverrides). + assertThat(pc.registerListener(1, mListener1)).isTrue(); + // Change 2 is unknown. + assertThat(pc.registerListener(2, mListener1)).isFalse(); + } + + @Test + public void testListenerCalledOnSetOverrides() { + PlatformCompat pc = new PlatformCompat(mContext); + + pc.registerListener(1, mListener1); + pc.registerListener(2, mListener1); + + pc.setOverrides( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of(2L))), + PACKAGE_NAME); + + verify(mListener1, times(2)).onCompatChange(PACKAGE_NAME); + } + + @Test + public void testListenerNotCalledOnWrongPackage() { + PlatformCompat pc = new PlatformCompat(mContext); + + pc.registerListener(1, mListener1); + pc.registerListener(2, mListener1); + + pc.setOverridesForTest( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of(2L))), + PACKAGE_NAME); + + verify(mListener1, never()).onCompatChange("other.package"); + } + + @Test + public void testListenerCalledOnSetOverridesTwoListeners() { + PlatformCompat pc = new PlatformCompat(mContext); + pc.registerListener(1, mListener1); + + final ImmutableSet<Long> enabled = ImmutableSet.of(1L); + final ImmutableSet<Long> disabled = ImmutableSet.of(2L); + + pc.setOverrides( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(enabled, disabled)), + PACKAGE_NAME); + + verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); + verify(mListener2, never()).onCompatChange(PACKAGE_NAME); + + reset(mListener1); + reset(mListener2); + + pc.registerListener(2, mListener2); + + pc.setOverrides( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(enabled, disabled)), + PACKAGE_NAME); + + verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); + verify(mListener2, times(1)).onCompatChange(PACKAGE_NAME); + } + + @Test + public void testListenerCalledOnSetOverridesForTest() { + PlatformCompat pc = new PlatformCompat(mContext); + + pc.registerListener(1, mListener1); + pc.registerListener(2, mListener1); + + pc.setOverridesForTest( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of(2L))), + PACKAGE_NAME); + + verify(mListener1, times(2)).onCompatChange(PACKAGE_NAME); + } + + @Test + public void testListenerCalledOnSetOverridesTwoListenersForTest() { + PlatformCompat pc = new PlatformCompat(mContext); + pc.registerListener(1, mListener1); + + final ImmutableSet<Long> enabled = ImmutableSet.of(1L); + final ImmutableSet<Long> disabled = ImmutableSet.of(2L); + + pc.setOverridesForTest( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(enabled, disabled)), + PACKAGE_NAME); + + verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); + verify(mListener2, never()).onCompatChange(PACKAGE_NAME); + + reset(mListener1); + reset(mListener2); + + pc.registerListener(2, mListener2); + pc.setOverridesForTest( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(enabled, disabled)), + PACKAGE_NAME); + + verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); + verify(mListener2, times(1)).onCompatChange(PACKAGE_NAME); + } + + @Test + public void testListenerCalledOnClearOverrides() { + PlatformCompat pc = new PlatformCompat(mContext); + + pc.registerListener(1, mListener1); + pc.registerListener(2, mListener2); + + pc.setOverrides( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of())), + PACKAGE_NAME); + verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); + verify(mListener2, never()).onCompatChange(PACKAGE_NAME); + + reset(mListener1); + reset(mListener2); + + pc.clearOverrides(PACKAGE_NAME); + verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); + verify(mListener2, never()).onCompatChange(PACKAGE_NAME); + } + + @Test + public void testListenerCalledOnClearOverridesMultipleOverrides() { + PlatformCompat pc = new PlatformCompat(mContext); + + pc.registerListener(1, mListener1); + pc.registerListener(2, mListener2); + + pc.setOverrides( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of(2L))), + PACKAGE_NAME); + verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); + verify(mListener2, times(1)).onCompatChange(PACKAGE_NAME); + + reset(mListener1); + reset(mListener2); + + pc.clearOverrides(PACKAGE_NAME); + verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); + verify(mListener2, times(1)).onCompatChange(PACKAGE_NAME); + } + + @Test + public void testListenerCalledOnClearOverrideExists() { + PlatformCompat pc = new PlatformCompat(mContext); + + pc.registerListener(1, mListener1); + pc.registerListener(2, mListener2); + + pc.setOverrides( + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(ImmutableSet.of(1L), ImmutableSet.of())), + PACKAGE_NAME); + verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); + verify(mListener2, never()).onCompatChange(PACKAGE_NAME); + + reset(mListener1); + reset(mListener2); + + pc.clearOverride(1, PACKAGE_NAME); + verify(mListener1, times(1)).onCompatChange(PACKAGE_NAME); + verify(mListener2, never()).onCompatChange(PACKAGE_NAME); + } + + @Test + public void testListenerCalledOnClearOverrideDoesntExist() { + PlatformCompat pc = new PlatformCompat(mContext); + + pc.registerListener(1, mListener1); + + pc.clearOverride(1, PACKAGE_NAME); + // Listener not called when a non existing override is removed. + verify(mListener1, never()).onCompatChange(PACKAGE_NAME); + } + + +} diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java index 64ea59d2fa2d..f86bacf67901 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java @@ -22,6 +22,7 @@ import android.app.IActivityTaskManager; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.backup.IBackupManager; +import android.app.timedetector.TimeDetector; import android.app.usage.UsageStatsManagerInternal; import android.content.Context; import android.content.Intent; @@ -229,6 +230,11 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi AlarmManager getAlarmManager() {return services.alarmManager;} @Override + TimeDetector getTimeDetector() { + return services.timeDetector; + } + + @Override LockPatternUtils newLockPatternUtils() { return services.lockPatternUtils; } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index ed55aebdea02..162e7669cbc0 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -26,9 +26,6 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM; import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; import static android.app.admin.DevicePolicyManager.WIPE_EUICC; import static android.app.admin.PasswordMetrics.computeForPassword; -import static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY; -import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY; -import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback; @@ -66,6 +63,7 @@ import android.app.admin.DeviceAdminReceiver; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.PasswordMetrics; +import android.app.timedetector.ManualTimeSuggestion; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Intent; @@ -82,6 +80,7 @@ import android.os.Bundle; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; +import android.os.UserManagerInternal; import android.platform.test.annotations.Presubmit; import android.provider.Settings; import android.security.KeyChain; @@ -1154,9 +1153,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( - eq(UserHandle.USER_SYSTEM), - eq(null), - eq(true), eq(CAMERA_NOT_DISABLED)); + eq(UserHandle.USER_SYSTEM), eq(null), + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)); verify(getServices().usageStatsManagerInternal).setActiveAdminApps( null, UserHandle.USER_SYSTEM); @@ -1725,8 +1723,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(defaultRestrictions), - eq(true) /* isDeviceOwner */, - eq(CAMERA_NOT_DISABLED) + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) ); reset(getServices().userManagerInternal); @@ -1741,7 +1738,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER), - eq(true), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)); reset(getServices().userManagerInternal); dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); @@ -1749,7 +1746,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS, UserManager.DISALLOW_ADD_USER), - eq(true), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)); reset(getServices().userManagerInternal); DpmTestUtils.assertRestrictions( @@ -1767,7 +1764,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), - eq(true), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)); reset(getServices().userManagerInternal); DpmTestUtils.assertRestrictions( @@ -1783,7 +1780,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(), - eq(true), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)); reset(getServices().userManagerInternal); assertNoDeviceOwnerRestrictions(); @@ -1797,7 +1794,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME, UserManager.DISALLOW_UNMUTE_MICROPHONE), - eq(true), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)); reset(getServices().userManagerInternal); dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME); @@ -1809,7 +1806,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER), - eq(true), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)); reset(getServices().userManagerInternal); dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN); @@ -1817,16 +1814,16 @@ public class DevicePolicyManagerTest extends DpmTestBase { eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, UserManager.DISALLOW_ADD_USER), - eq(true), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)); reset(getServices().userManagerInternal); dpm.setCameraDisabled(admin1, true); verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(UserHandle.USER_SYSTEM), - // DISALLOW_CAMERA will be applied to both local and global. + // DISALLOW_CAMERA will be applied globally. MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, - UserManager.DISALLOW_ADD_USER), - eq(true), eq(CAMERA_DISABLED_GLOBALLY)); + UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_CAMERA), + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER)); reset(getServices().userManagerInternal); } @@ -1872,7 +1869,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(DpmMockContext.CALLER_USER_HANDLE), MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES), - eq(false), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER)); reset(getServices().userManagerInternal); dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); @@ -1880,7 +1877,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { eq(DpmMockContext.CALLER_USER_HANDLE), MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, UserManager.DISALLOW_OUTGOING_CALLS), - eq(false), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER)); reset(getServices().userManagerInternal); DpmTestUtils.assertRestrictions( @@ -1903,7 +1900,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(DpmMockContext.CALLER_USER_HANDLE), MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), - eq(false), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER)); reset(getServices().userManagerInternal); DpmTestUtils.assertRestrictions( @@ -1924,7 +1921,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(DpmMockContext.CALLER_USER_HANDLE), MockUtils.checkUserRestrictions(), - eq(false), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER)); reset(getServices().userManagerInternal); DpmTestUtils.assertRestrictions( @@ -1946,20 +1943,52 @@ public class DevicePolicyManagerTest extends DpmTestBase { eq(DpmMockContext.CALLER_USER_HANDLE), MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME, UserManager.DISALLOW_UNMUTE_MICROPHONE), - eq(false), eq(CAMERA_NOT_DISABLED)); + eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER)); reset(getServices().userManagerInternal); dpm.setCameraDisabled(admin1, true); verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(DpmMockContext.CALLER_USER_HANDLE), MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME, - UserManager.DISALLOW_UNMUTE_MICROPHONE), - eq(false), eq(CAMERA_DISABLED_LOCALLY)); + UserManager.DISALLOW_UNMUTE_MICROPHONE, UserManager.DISALLOW_CAMERA), + eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER)); reset(getServices().userManagerInternal); // TODO Make sure restrictions are written to the file. } + public void testSetUserRestriction_asPoOfOrgOwnedDevice() throws Exception { + setupProfileOwner(); + + final long ident = mServiceContext.binder.clearCallingIdentity(); + configureContextForAccess(mServiceContext, true); + + mServiceContext.binder.callingUid = + UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, + DpmMockContext.CALLER_MANAGED_PROVISIONING_UID); + try { + runAsCaller(mServiceContext, dpms, dpm -> { + dpm.markProfileOwnerOnOrganizationOwnedDevice(admin1); + }); + } finally { + mServiceContext.binder.restoreCallingIdentity(ident); + } + + dpm.addUserRestriction(admin1, UserManager.DISALLOW_CONFIG_DATE_TIME); + verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( + eq(DpmMockContext.CALLER_USER_HANDLE), + MockUtils.checkUserRestrictions(UserManager.DISALLOW_CONFIG_DATE_TIME), + eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE)); + reset(getServices().userManagerInternal); + + dpm.setCameraDisabled(admin1, true); + verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( + eq(DpmMockContext.CALLER_USER_HANDLE), + MockUtils.checkUserRestrictions(UserManager.DISALLOW_CONFIG_DATE_TIME, + UserManager.DISALLOW_CAMERA), + eq(UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE)); + reset(getServices().userManagerInternal); + } public void testDefaultEnabledUserRestrictions() throws Exception { mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); @@ -1994,8 +2023,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(defaultRestrictions), - eq(true) /* isDeviceOwner */, - eq(CAMERA_NOT_DISABLED) + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) ); reset(getServices().userManagerInternal); @@ -2035,10 +2063,9 @@ public class DevicePolicyManagerTest extends DpmTestBase { dpm.getUserRestrictions(admin1) ); verify(getServices().userManagerInternal, atLeast(1)).setDevicePolicyUserRestrictions( - eq(UserHandle.USER_SYSTEM), - MockUtils.checkUserRestrictions(newDefaultEnabledRestriction), - eq(true) /* isDeviceOwner */, - eq(CAMERA_NOT_DISABLED) + eq(UserHandle.USER_SYSTEM), + MockUtils.checkUserRestrictions(newDefaultEnabledRestriction), + eq(UserManagerInternal.OWNER_TYPE_DEVICE_OWNER) ); reset(getServices().userManagerInternal); @@ -3588,7 +3615,19 @@ public class DevicePolicyManagerTest extends DpmTestBase { mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; setupDeviceOwner(); dpm.setTime(admin1, 0); - verify(getServices().alarmManager).setTime(0); + + BaseMatcher<ManualTimeSuggestion> hasZeroTime = new BaseMatcher<ManualTimeSuggestion>() { + @Override + public boolean matches(Object item) { + final ManualTimeSuggestion suggestion = (ManualTimeSuggestion) item; + return suggestion.getUtcTime().getValue() == 0; + } + @Override + public void describeTo(Description description) { + description.appendText("ManualTimeSuggestion{utcTime.value=0}"); + } + }; + verify(getServices().timeDetector).suggestManualTime(argThat(hasZeroTime)); } public void testSetTimeFailWithPO() throws Exception { diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java index bd513dc083be..1a67576c218f 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java @@ -207,6 +207,8 @@ public class DpmMockContext extends MockContext { switch (name) { case Context.ALARM_SERVICE: return mMockSystemServices.alarmManager; + case Context.TIME_DETECTOR_SERVICE: + return mMockSystemServices.timeDetector; case Context.USER_SERVICE: return mMockSystemServices.userManager; case Context.POWER_SERVICE: diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java index b0d0303a82d9..c9273642635e 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java @@ -31,6 +31,7 @@ import android.app.IActivityManager; import android.app.IActivityTaskManager; import android.app.NotificationManager; import android.app.backup.IBackupManager; +import android.app.timedetector.TimeDetector; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; import android.content.ContentValues; @@ -111,6 +112,7 @@ public class MockSystemServices { public final TelephonyManager telephonyManager; public final AccountManager accountManager; public final AlarmManager alarmManager; + public final TimeDetector timeDetector; public final KeyChain.KeyChainConnection keyChainConnection; /** Note this is a partial mock, not a real mock. */ public final PackageManager packageManager; @@ -152,6 +154,7 @@ public class MockSystemServices { telephonyManager = mock(TelephonyManager.class); accountManager = mock(AccountManager.class); alarmManager = mock(AlarmManager.class); + timeDetector = mock(TimeDetector.class); keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS); // Package manager is huge, so we use a partial mock instead. diff --git a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java index 2cc5323e56a2..1a630ffa7097 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java @@ -122,13 +122,15 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase { final Bundle local = new Bundle(); final Bundle global = new Bundle(); - UserRestrictionsUtils.sortToGlobalAndLocal(null, false /* isDeviceOwner */, - UserManagerInternal.CAMERA_NOT_DISABLED, global, local); + UserRestrictionsUtils.sortToGlobalAndLocal(null, + UserManagerInternal.OWNER_TYPE_PROFILE_OWNER, + global, local); assertEquals(0, global.size()); assertEquals(0, local.size()); - UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY, false /* isDeviceOwner */, - UserManagerInternal.CAMERA_NOT_DISABLED, global, local); + UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY, + UserManagerInternal.OWNER_TYPE_PROFILE_OWNER, + global, local); assertEquals(0, global.size()); assertEquals(0, local.size()); @@ -140,8 +142,10 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase { UserManager.DISALLOW_CONFIG_TETHERING, UserManager.DISALLOW_OUTGOING_BEAM, UserManager.DISALLOW_APPS_CONTROL, - UserManager.ENSURE_VERIFY_APPS - ), true /* isDeviceOwner */, UserManagerInternal.CAMERA_NOT_DISABLED, global, local); + UserManager.ENSURE_VERIFY_APPS, + UserManager.DISALLOW_CAMERA + ), UserManagerInternal.OWNER_TYPE_DEVICE_OWNER, + global, local); assertRestrictions(newRestrictions( @@ -154,7 +158,10 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase { // These can only be set by DO. UserManager.DISALLOW_USB_FILE_TRANSFER, - UserManager.DISALLOW_CONFIG_TETHERING + UserManager.DISALLOW_CONFIG_TETHERING, + + // This can be set by DO or PO of organisation owned device + UserManager.DISALLOW_CAMERA ), global); assertRestrictions(newRestrictions( @@ -174,8 +181,10 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase { UserManager.DISALLOW_CONFIG_TETHERING, UserManager.DISALLOW_OUTGOING_BEAM, UserManager.DISALLOW_APPS_CONTROL, - UserManager.ENSURE_VERIFY_APPS - ), false /* isDeviceOwner */, UserManagerInternal.CAMERA_NOT_DISABLED, global, local); + UserManager.ENSURE_VERIFY_APPS, + UserManager.DISALLOW_CAMERA + ), UserManagerInternal.OWNER_TYPE_PROFILE_OWNER, + global, local); assertRestrictions(newRestrictions( // This one is global no matter who sets it. @@ -193,23 +202,47 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase { // These can only be set by DO. UserManager.DISALLOW_USB_FILE_TRANSFER, - UserManager.DISALLOW_CONFIG_TETHERING + UserManager.DISALLOW_CONFIG_TETHERING, + + // This can be set by DO or PO of organisation owned device + UserManager.DISALLOW_CAMERA ), local); + local.clear(); + global.clear(); + + // Restrictions set by PO of organisation owned device + UserRestrictionsUtils.sortToGlobalAndLocal(newRestrictions( + UserManager.DISALLOW_CONFIG_DATE_TIME + ), UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE, + global, local); + + assertRestrictions(newRestrictions( + // This user restriction is global when set by PO of org owned device + UserManager.DISALLOW_CONFIG_DATE_TIME + ), global); + assertEquals(0, local.size()); } public void testSortToLocalAndGlobalWithCameraDisabled() { final Bundle local = new Bundle(); final Bundle global = new Bundle(); - UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY, false, - UserManagerInternal.CAMERA_DISABLED_GLOBALLY, global, local); + UserRestrictionsUtils.sortToGlobalAndLocal(newRestrictions(UserManager.DISALLOW_CAMERA), + UserManagerInternal.OWNER_TYPE_DEVICE_OWNER, global, local); + assertRestrictions(newRestrictions(UserManager.DISALLOW_CAMERA), global); + assertEquals(0, local.size()); + global.clear(); + + UserRestrictionsUtils.sortToGlobalAndLocal(newRestrictions(UserManager.DISALLOW_CAMERA), + UserManagerInternal.OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE, global, + local); assertRestrictions(newRestrictions(UserManager.DISALLOW_CAMERA), global); assertEquals(0, local.size()); global.clear(); - UserRestrictionsUtils.sortToGlobalAndLocal(Bundle.EMPTY, false, - UserManagerInternal.CAMERA_DISABLED_LOCALLY, global, local); + UserRestrictionsUtils.sortToGlobalAndLocal(newRestrictions(UserManager.DISALLOW_CAMERA), + UserManagerInternal.OWNER_TYPE_PROFILE_OWNER, global, local); assertEquals(0, global.size()); assertRestrictions(newRestrictions(UserManager.DISALLOW_CAMERA), local); } diff --git a/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java b/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java index b49845ae4006..317fd4d566ae 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/SimpleTimeZoneDetectorStrategyTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.content.Intent; import android.icu.util.Calendar; @@ -36,6 +37,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.time.Duration; + @RunWith(AndroidJUnit4.class) public class SimpleTimeZoneDetectorStrategyTest { @@ -47,6 +50,8 @@ public class SimpleTimeZoneDetectorStrategyTest { private static final int ARBITRARY_PHONE_ID = 123456; + private static final long ONE_DAY_MILLIS = Duration.ofDays(1).toMillis(); + private Script mScript; @Before @@ -55,7 +60,7 @@ public class SimpleTimeZoneDetectorStrategyTest { } @Test - public void testSuggestPhoneTime_nitz_timeDetectionEnabled() { + public void testSuggestPhoneTime_autoTimeEnabled() { Scenario scenario = SCENARIO_1; mScript.pokeFakeClocks(scenario) .pokeTimeDetectionEnabled(true); @@ -67,7 +72,8 @@ public class SimpleTimeZoneDetectorStrategyTest { mScript.simulateTimePassing(clockIncrement) .simulatePhoneTimeSuggestion(timeSuggestion) - .verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis); + .verifySystemClockWasSetAndResetCallTracking( + expectSystemClockMillis, true /* expectNetworkBroadcast */); } @Test @@ -103,7 +109,8 @@ public class SimpleTimeZoneDetectorStrategyTest { // Send the first time signal. It should be used. mScript.simulatePhoneTimeSuggestion(timeSuggestion1) - .verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis1); + .verifySystemClockWasSetAndResetCallTracking( + expectSystemClockMillis1, true /* expectNetworkBroadcast */); // Now send another time signal, but one that is too similar to the last one and should be // ignored. @@ -130,11 +137,12 @@ public class SimpleTimeZoneDetectorStrategyTest { TimeDetectorStrategy.getTimeAt(utcTime3, mScript.peekElapsedRealtimeMillis()); mScript.simulatePhoneTimeSuggestion(timeSuggestion3) - .verifySystemClockWasSetAndResetCallTracking(expectSystemClockMillis3); + .verifySystemClockWasSetAndResetCallTracking( + expectSystemClockMillis3, true /* expectNetworkBroadcast */); } @Test - public void testSuggestPhoneTime_nitz_timeDetectionDisabled() { + public void testSuggestPhoneTime_autoTimeDisabled() { Scenario scenario = SCENARIO_1; mScript.pokeFakeClocks(scenario) .pokeTimeDetectionEnabled(false); @@ -146,7 +154,7 @@ public class SimpleTimeZoneDetectorStrategyTest { } @Test - public void testSuggestPhoneTime_nitz_invalidNitzReferenceTimesIgnored() { + public void testSuggestPhoneTime_invalidNitzReferenceTimesIgnored() { Scenario scenario = SCENARIO_1; final int systemClockUpdateThreshold = 2000; mScript.pokeFakeClocks(scenario) @@ -161,7 +169,8 @@ public class SimpleTimeZoneDetectorStrategyTest { long expectedSystemClockMillis1 = TimeDetectorStrategy.getTimeAt(utcTime1, mScript.peekElapsedRealtimeMillis()); mScript.simulatePhoneTimeSuggestion(timeSuggestion1) - .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1); + .verifySystemClockWasSetAndResetCallTracking( + expectedSystemClockMillis1, true /* expectNetworkBroadcast */); // The UTC time increment should be larger than the system clock update threshold so we // know it shouldn't be ignored for other reasons. @@ -197,7 +206,8 @@ public class SimpleTimeZoneDetectorStrategyTest { PhoneTimeSuggestion timeSuggestion4 = createPhoneTimeSuggestion(ARBITRARY_PHONE_ID, utcTime4); mScript.simulatePhoneTimeSuggestion(timeSuggestion4) - .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis4); + .verifySystemClockWasSetAndResetCallTracking( + expectedSystemClockMillis4, true /* expectNetworkBroadcast */); } @Test @@ -229,7 +239,8 @@ public class SimpleTimeZoneDetectorStrategyTest { // Turn on auto time detection. mScript.simulateAutoTimeDetectionToggle() - .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1); + .verifySystemClockWasSetAndResetCallTracking( + expectedSystemClockMillis1, true /* expectNetworkBroadcast */); // Turn off auto time detection. mScript.simulateAutoTimeDetectionToggle() @@ -256,7 +267,99 @@ public class SimpleTimeZoneDetectorStrategyTest { // Turn on auto time detection. mScript.simulateAutoTimeDetectionToggle() - .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis2); + .verifySystemClockWasSetAndResetCallTracking( + expectedSystemClockMillis2, true /* expectNetworkBroadcast */); + } + + @Test + public void testSuggestManualTime_autoTimeDisabled() { + Scenario scenario = SCENARIO_1; + mScript.pokeFakeClocks(scenario) + .pokeTimeDetectionEnabled(false); + + ManualTimeSuggestion timeSuggestion = scenario.createManualTimeSuggestionForActual(); + final int clockIncrement = 1000; + long expectSystemClockMillis = scenario.getActualTimeMillis() + clockIncrement; + + mScript.simulateTimePassing(clockIncrement) + .simulateManualTimeSuggestion(timeSuggestion) + .verifySystemClockWasSetAndResetCallTracking( + expectSystemClockMillis, false /* expectNetworkBroadcast */); + } + + @Test + public void testSuggestManualTime_retainsAutoSignal() { + Scenario scenario = SCENARIO_1; + + // Configure the start state. + mScript.pokeFakeClocks(scenario) + .pokeTimeDetectionEnabled(true); + + // Simulate a phone suggestion. + PhoneTimeSuggestion phoneTimeSuggestion = + scenario.createPhoneTimeSuggestionForActual(ARBITRARY_PHONE_ID); + long expectedAutoClockMillis = phoneTimeSuggestion.getUtcTime().getValue(); + final int clockIncrement = 1000; + + // Simulate the passage of time. + mScript.simulateTimePassing(clockIncrement); + expectedAutoClockMillis += clockIncrement; + + mScript.simulatePhoneTimeSuggestion(phoneTimeSuggestion) + .verifySystemClockWasSetAndResetCallTracking( + expectedAutoClockMillis, true /* expectNetworkBroadcast */); + + // Simulate the passage of time. + mScript.simulateTimePassing(clockIncrement); + expectedAutoClockMillis += clockIncrement; + + // Switch to manual. + mScript.simulateAutoTimeDetectionToggle() + .verifySystemClockWasNotSetAndResetCallTracking(); + + // Simulate the passage of time. + mScript.simulateTimePassing(clockIncrement); + expectedAutoClockMillis += clockIncrement; + + + // Simulate a manual suggestion 1 day different from the auto suggestion. + long manualTimeMillis = SCENARIO_1.getActualTimeMillis() + ONE_DAY_MILLIS; + long expectedManualClockMillis = manualTimeMillis; + ManualTimeSuggestion manualTimeSuggestion = createManualTimeSuggestion(manualTimeMillis); + mScript.simulateManualTimeSuggestion(manualTimeSuggestion) + .verifySystemClockWasSetAndResetCallTracking( + expectedManualClockMillis, false /* expectNetworkBroadcast */); + + // Simulate the passage of time. + mScript.simulateTimePassing(clockIncrement); + expectedAutoClockMillis += clockIncrement; + + // Switch back to auto. + mScript.simulateAutoTimeDetectionToggle(); + + mScript.verifySystemClockWasSetAndResetCallTracking( + expectedAutoClockMillis, true /* expectNetworkBroadcast */); + + // Switch back to manual - nothing should happen to the clock. + mScript.simulateAutoTimeDetectionToggle() + .verifySystemClockWasNotSetAndResetCallTracking(); + } + + /** + * Manual suggestions should be ignored if auto time is enabled. + */ + @Test + public void testSuggestManualTime_autoTimeEnabled() { + Scenario scenario = SCENARIO_1; + mScript.pokeFakeClocks(scenario) + .pokeTimeDetectionEnabled(true); + + ManualTimeSuggestion timeSuggestion = scenario.createManualTimeSuggestionForActual(); + final int clockIncrement = 1000; + + mScript.simulateTimePassing(clockIncrement) + .simulateManualTimeSuggestion(timeSuggestion) + .verifySystemClockWasNotSetAndResetCallTracking(); } /** @@ -280,7 +383,7 @@ public class SimpleTimeZoneDetectorStrategyTest { } @Override - public boolean isTimeDetectionEnabled() { + public boolean isAutoTimeDetectionEnabled() { return mTimeDetectionEnabled; } @@ -426,8 +529,13 @@ public class SimpleTimeZoneDetectorStrategyTest { return this; } + Script simulateManualTimeSuggestion(ManualTimeSuggestion timeSuggestion) { + mSimpleTimeDetectorStrategy.suggestManualTime(timeSuggestion); + return this; + } + Script simulateAutoTimeDetectionToggle() { - boolean enabled = !mFakeCallback.isTimeDetectionEnabled(); + boolean enabled = !mFakeCallback.isAutoTimeDetectionEnabled(); mFakeCallback.pokeTimeDetectionEnabled(enabled); mSimpleTimeDetectorStrategy.handleAutoTimeDetectionToggle(enabled); return this; @@ -445,9 +553,12 @@ public class SimpleTimeZoneDetectorStrategyTest { return this; } - Script verifySystemClockWasSetAndResetCallTracking(long expectSystemClockMillis) { + Script verifySystemClockWasSetAndResetCallTracking( + long expectSystemClockMillis, boolean expectNetworkBroadcast) { mFakeCallback.verifySystemClockWasSet(expectSystemClockMillis); - mFakeCallback.verifyIntentWasBroadcast(); + if (expectNetworkBroadcast) { + mFakeCallback.verifyIntentWasBroadcast(); + } mFakeCallback.resetCallTracking(); return this; } @@ -486,6 +597,12 @@ public class SimpleTimeZoneDetectorStrategyTest { return createPhoneTimeSuggestion(phoneId, time); } + ManualTimeSuggestion createManualTimeSuggestionForActual() { + TimestampedValue<Long> time = new TimestampedValue<>( + mInitialDeviceRealtimeMillis, mActualTimeMillis); + return new ManualTimeSuggestion(time); + } + static class Builder { private long mInitialDeviceSystemClockMillis; @@ -525,6 +642,12 @@ public class SimpleTimeZoneDetectorStrategyTest { return timeSuggestion; } + private ManualTimeSuggestion createManualTimeSuggestion(long timeMillis) { + TimestampedValue<Long> utcTime = + new TimestampedValue<>(mScript.peekElapsedRealtimeMillis(), timeMillis); + return new ManualTimeSuggestion(utcTime); + } + private static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute, int second) { Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/UTC")); diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java index cfd8a457d2f0..4efe771a4e95 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.timedetector.ManualTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.content.Context; import android.content.pm.PackageManager; @@ -90,6 +91,19 @@ public class TimeDetectorServiceTest { } @Test + public void testSuggestManualTime() { + doNothing().when(mMockContext).enforceCallingPermission(anyString(), any()); + + ManualTimeSuggestion manualTimeSuggestion = createManualTimeSuggestion(); + mTimeDetectorService.suggestManualTime(manualTimeSuggestion); + + verify(mMockContext).enforceCallingPermission( + eq(android.Manifest.permission.SET_TIME), + anyString()); + mStubbedTimeDetectorStrategy.verifySuggestManualTimeCalled(manualTimeSuggestion); + } + + @Test public void testDump() { when(mMockContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)) .thenReturn(PackageManager.PERMISSION_GRANTED); @@ -102,13 +116,13 @@ public class TimeDetectorServiceTest { @Test public void testAutoTimeDetectionToggle() { - when(mMockCallback.isTimeDetectionEnabled()).thenReturn(true); + when(mMockCallback.isAutoTimeDetectionEnabled()).thenReturn(true); mTimeDetectorService.handleAutoTimeDetectionToggle(); mStubbedTimeDetectorStrategy.verifyHandleAutoTimeDetectionToggleCalled(true); - when(mMockCallback.isTimeDetectionEnabled()).thenReturn(false); + when(mMockCallback.isAutoTimeDetectionEnabled()).thenReturn(false); mTimeDetectorService.handleAutoTimeDetectionToggle(); @@ -123,10 +137,16 @@ public class TimeDetectorServiceTest { return suggestion; } + private static ManualTimeSuggestion createManualTimeSuggestion() { + TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L); + return new ManualTimeSuggestion(timeValue); + } + private static class StubbedTimeDetectorStrategy implements TimeDetectorStrategy { // Call tracking. private PhoneTimeSuggestion mLastPhoneSuggestion; + private ManualTimeSuggestion mLastManualSuggestion; private Boolean mLastAutoTimeDetectionToggle; private boolean mDumpCalled; @@ -141,6 +161,12 @@ public class TimeDetectorServiceTest { } @Override + public void suggestManualTime(ManualTimeSuggestion timeSuggestion) { + resetCallTracking(); + mLastManualSuggestion = timeSuggestion; + } + + @Override public void handleAutoTimeDetectionToggle(boolean enabled) { resetCallTracking(); mLastAutoTimeDetectionToggle = enabled; @@ -154,12 +180,17 @@ public class TimeDetectorServiceTest { void resetCallTracking() { mLastPhoneSuggestion = null; + mLastManualSuggestion = null; mLastAutoTimeDetectionToggle = null; mDumpCalled = false; } - void verifySuggestPhoneTimeCalled(PhoneTimeSuggestion expectedSignal) { - assertEquals(expectedSignal, mLastPhoneSuggestion); + void verifySuggestPhoneTimeCalled(PhoneTimeSuggestion expectedSuggestion) { + assertEquals(expectedSuggestion, mLastPhoneSuggestion); + } + + public void verifySuggestManualTimeCalled(ManualTimeSuggestion expectedSuggestion) { + assertEquals(expectedSuggestion, mLastManualSuggestion); } void verifyHandleAutoTimeDetectionToggleCalled(boolean expectedEnable) { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java index 36175a93f667..5841e59ab3a0 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java @@ -350,6 +350,26 @@ public class SnoozeHelperTest extends UiServiceTestCase { } @Test + public void testUpdateAfterCancel() throws Exception { + // snooze a notification + NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); + mSnoozeHelper.snooze(r , 1000); + + // cancel the notification + mSnoozeHelper.cancel(UserHandle.USER_SYSTEM, false); + + // update the notification + r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); + mSnoozeHelper.update(UserHandle.USER_SYSTEM, r); + + // verify callback is called when repost (snooze is expired) + verify(mCallback, never()).repost(anyInt(), any(NotificationRecord.class)); + mSnoozeHelper.repost(r.getKey(), UserHandle.USER_SYSTEM); + verify(mCallback, times(1)).repost(UserHandle.USER_SYSTEM, r); + assertFalse(r.isCanceled); + } + + @Test public void testGetSnoozedByUser() throws Exception { NotificationRecord r = getNotificationRecord("pkg", 1, "one", UserHandle.SYSTEM); NotificationRecord r2 = getNotificationRecord("pkg", 2, "two", UserHandle.SYSTEM); diff --git a/core/java/android/service/carrier/CarrierIdentifier.aidl b/telephony/java/android/service/carrier/CarrierIdentifier.aidl index 48b13983050d..48b13983050d 100644 --- a/core/java/android/service/carrier/CarrierIdentifier.aidl +++ b/telephony/java/android/service/carrier/CarrierIdentifier.aidl diff --git a/core/java/android/service/carrier/CarrierIdentifier.java b/telephony/java/android/service/carrier/CarrierIdentifier.java index af5bf7475f95..af5bf7475f95 100644 --- a/core/java/android/service/carrier/CarrierIdentifier.java +++ b/telephony/java/android/service/carrier/CarrierIdentifier.java diff --git a/core/java/android/service/carrier/CarrierService.java b/telephony/java/android/service/carrier/CarrierService.java index eefc1b70bac9..eefc1b70bac9 100644 --- a/core/java/android/service/carrier/CarrierService.java +++ b/telephony/java/android/service/carrier/CarrierService.java diff --git a/core/java/android/service/carrier/ICarrierService.aidl b/telephony/java/android/service/carrier/ICarrierService.aidl index ac6f9614d8f5..ac6f9614d8f5 100644 --- a/core/java/android/service/carrier/ICarrierService.aidl +++ b/telephony/java/android/service/carrier/ICarrierService.aidl diff --git a/core/java/android/service/euicc/DownloadSubscriptionResult.aidl b/telephony/java/android/service/euicc/DownloadSubscriptionResult.aidl index b625fd6d3cb4..b625fd6d3cb4 100644 --- a/core/java/android/service/euicc/DownloadSubscriptionResult.aidl +++ b/telephony/java/android/service/euicc/DownloadSubscriptionResult.aidl diff --git a/core/java/android/service/euicc/DownloadSubscriptionResult.java b/telephony/java/android/service/euicc/DownloadSubscriptionResult.java index 3b1a2c9def4f..3b1a2c9def4f 100644 --- a/core/java/android/service/euicc/DownloadSubscriptionResult.java +++ b/telephony/java/android/service/euicc/DownloadSubscriptionResult.java diff --git a/core/java/android/service/euicc/EuiccProfileInfo.aidl b/telephony/java/android/service/euicc/EuiccProfileInfo.aidl index 321021b5273c..321021b5273c 100644 --- a/core/java/android/service/euicc/EuiccProfileInfo.aidl +++ b/telephony/java/android/service/euicc/EuiccProfileInfo.aidl diff --git a/core/java/android/service/euicc/EuiccProfileInfo.java b/telephony/java/android/service/euicc/EuiccProfileInfo.java index 6c357ccdd03d..6c357ccdd03d 100644 --- a/core/java/android/service/euicc/EuiccProfileInfo.java +++ b/telephony/java/android/service/euicc/EuiccProfileInfo.java diff --git a/core/java/android/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java index bc6a9e848e2a..bc6a9e848e2a 100644 --- a/core/java/android/service/euicc/EuiccService.java +++ b/telephony/java/android/service/euicc/EuiccService.java diff --git a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl b/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl index c2636a16edee..c2636a16edee 100644 --- a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl +++ b/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.aidl diff --git a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java b/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java index c7a985160730..c7a985160730 100644 --- a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java +++ b/telephony/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java diff --git a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl b/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl index 791ad9b469ef..791ad9b469ef 100644 --- a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl +++ b/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.aidl diff --git a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java b/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java index abd4065c754a..abd4065c754a 100644 --- a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java +++ b/telephony/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java diff --git a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl b/telephony/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl index 6003b79462da..6003b79462da 100644 --- a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl +++ b/telephony/java/android/service/euicc/GetEuiccProfileInfoListResult.aidl diff --git a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java b/telephony/java/android/service/euicc/GetEuiccProfileInfoListResult.java index 9add38e40d9b..9add38e40d9b 100644 --- a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java +++ b/telephony/java/android/service/euicc/GetEuiccProfileInfoListResult.java diff --git a/core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl b/telephony/java/android/service/euicc/IDeleteSubscriptionCallback.aidl index aff8f1b7b346..aff8f1b7b346 100644 --- a/core/java/android/service/euicc/IDeleteSubscriptionCallback.aidl +++ b/telephony/java/android/service/euicc/IDeleteSubscriptionCallback.aidl diff --git a/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl b/telephony/java/android/service/euicc/IDownloadSubscriptionCallback.aidl index 50ecbebf5e84..50ecbebf5e84 100644 --- a/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl +++ b/telephony/java/android/service/euicc/IDownloadSubscriptionCallback.aidl diff --git a/core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl b/telephony/java/android/service/euicc/IEraseSubscriptionsCallback.aidl index 34b53cc71dfb..34b53cc71dfb 100644 --- a/core/java/android/service/euicc/IEraseSubscriptionsCallback.aidl +++ b/telephony/java/android/service/euicc/IEraseSubscriptionsCallback.aidl diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/telephony/java/android/service/euicc/IEuiccService.aidl index 2acc47aae919..2acc47aae919 100644 --- a/core/java/android/service/euicc/IEuiccService.aidl +++ b/telephony/java/android/service/euicc/IEuiccService.aidl diff --git a/core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl b/telephony/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl index ad69ef132428..ad69ef132428 100644 --- a/core/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl +++ b/telephony/java/android/service/euicc/IGetDefaultDownloadableSubscriptionListCallback.aidl diff --git a/core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl b/telephony/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl index 01f187ed11e2..01f187ed11e2 100644 --- a/core/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl +++ b/telephony/java/android/service/euicc/IGetDownloadableSubscriptionMetadataCallback.aidl diff --git a/core/java/android/service/euicc/IGetEidCallback.aidl b/telephony/java/android/service/euicc/IGetEidCallback.aidl index e405a981c85a..e405a981c85a 100644 --- a/core/java/android/service/euicc/IGetEidCallback.aidl +++ b/telephony/java/android/service/euicc/IGetEidCallback.aidl diff --git a/core/java/android/service/euicc/IGetEuiccInfoCallback.aidl b/telephony/java/android/service/euicc/IGetEuiccInfoCallback.aidl index c0611825ff0f..c0611825ff0f 100644 --- a/core/java/android/service/euicc/IGetEuiccInfoCallback.aidl +++ b/telephony/java/android/service/euicc/IGetEuiccInfoCallback.aidl diff --git a/core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl b/telephony/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl index 0485f7be29d3..0485f7be29d3 100644 --- a/core/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl +++ b/telephony/java/android/service/euicc/IGetEuiccProfileInfoListCallback.aidl diff --git a/core/java/android/service/euicc/IGetOtaStatusCallback.aidl b/telephony/java/android/service/euicc/IGetOtaStatusCallback.aidl index f6678889ccc7..f6678889ccc7 100644 --- a/core/java/android/service/euicc/IGetOtaStatusCallback.aidl +++ b/telephony/java/android/service/euicc/IGetOtaStatusCallback.aidl diff --git a/core/java/android/service/euicc/IOtaStatusChangedCallback.aidl b/telephony/java/android/service/euicc/IOtaStatusChangedCallback.aidl index caec75f13f61..caec75f13f61 100644 --- a/core/java/android/service/euicc/IOtaStatusChangedCallback.aidl +++ b/telephony/java/android/service/euicc/IOtaStatusChangedCallback.aidl diff --git a/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl b/telephony/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl index 340401fe89cb..340401fe89cb 100644 --- a/core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl +++ b/telephony/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl diff --git a/core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl b/telephony/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl index b8f984d1c28b..b8f984d1c28b 100644 --- a/core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl +++ b/telephony/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl diff --git a/core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl b/telephony/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl index 0aa66978bb91..0aa66978bb91 100644 --- a/core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl +++ b/telephony/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java index 79b375675588..fe273b267e98 100644 --- a/telephony/java/android/telephony/LocationAccessPolicy.java +++ b/telephony/java/android/telephony/LocationAccessPolicy.java @@ -193,6 +193,17 @@ public final class LocationAccessPolicy { } } + private static String getAppOpsString(String manifestPermission) { + switch (manifestPermission) { + case Manifest.permission.ACCESS_FINE_LOCATION: + return AppOpsManager.OPSTR_FINE_LOCATION; + case Manifest.permission.ACCESS_COARSE_LOCATION: + return AppOpsManager.OPSTR_COARSE_LOCATION; + default: + return null; + } + } + private static LocationPermissionResult checkAppLocationPermissionHelper(Context context, LocationPermissionQuery query, String permissionToCheck) { String locationTypeForLog = @@ -206,8 +217,8 @@ public final class LocationAccessPolicy { if (hasManifestPermission) { // Only check the app op if the app has the permission. int appOpMode = context.getSystemService(AppOpsManager.class) - .noteOpNoThrow(AppOpsManager.permissionToOpCode(permissionToCheck), - query.callingUid, query.callingPackage, query.callingFeatureId, null); + .noteOpNoThrow(getAppOpsString(permissionToCheck), query.callingUid, + query.callingPackage, query.callingFeatureId, null); if (appOpMode == AppOpsManager.MODE_ALLOWED) { // If the app did everything right, return without logging. return LocationPermissionResult.ALLOWED; diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java index fad70d2da8be..c7f952954d5f 100644 --- a/telephony/java/android/telephony/SmsCbMessage.java +++ b/telephony/java/android/telephony/SmsCbMessage.java @@ -29,6 +29,7 @@ import android.telephony.CbGeoUtils.Geometry; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; import java.util.List; /** @@ -407,13 +408,17 @@ public final class SmsCbMessage implements Parcelable { } /** - * Get the warning area coordinates information represent by polygons and circles. - * @return a list of geometries, {@link Nullable} means there is no coordinate information - * associated to this message. + * Get the warning area coordinates information represented by polygons and circles. + * @return a list of geometries, or an empty list if there is no coordinate information + * associated with this message. * @hide */ - @Nullable + @SystemApi + @NonNull public List<Geometry> getGeometries() { + if (mGeometries == null) { + return new ArrayList<>(); + } return mGeometries; } @@ -720,6 +725,6 @@ public final class SmsCbMessage implements Parcelable { * @return {@code True} if this message needs geo-fencing check. */ public boolean needGeoFencingCheck() { - return mMaximumWaitTimeSec > 0 && mGeometries != null; + return mMaximumWaitTimeSec > 0 && mGeometries != null && !mGeometries.isEmpty(); } } diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java index 45b236c307c3..0208c3a0a0de 100644 --- a/test-mock/src/android/test/mock/MockContext.java +++ b/test-mock/src/android/test/mock/MockContext.java @@ -470,6 +470,13 @@ public class MockContext extends Context { } @Override + public void sendOrderedBroadcast(Intent intent, String receiverPermission, String receiverAppOp, + Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, + String initialData, Bundle initialExtras) { + throw new UnsupportedOperationException(); + } + + @Override public void sendStickyBroadcast(Intent intent) { throw new UnsupportedOperationException(); } diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index 06b58fda5b7d..e30878157a26 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -670,11 +670,11 @@ public class PackageWatchdogTest { public void testPackageHealthCheckStateTransitions() { TestController controller = new TestController(); PackageWatchdog wd = createWatchdog(controller, true /* withPackagesReady */); - MonitoredPackage m1 = wd.new MonitoredPackage(APP_A, LONG_DURATION, + MonitoredPackage m1 = wd.newMonitoredPackage(APP_A, LONG_DURATION, false /* hasPassedHealthCheck */); - MonitoredPackage m2 = wd.new MonitoredPackage(APP_B, LONG_DURATION, false); - MonitoredPackage m3 = wd.new MonitoredPackage(APP_C, LONG_DURATION, false); - MonitoredPackage m4 = wd.new MonitoredPackage(APP_D, LONG_DURATION, SHORT_DURATION, true); + MonitoredPackage m2 = wd.newMonitoredPackage(APP_B, LONG_DURATION, false); + MonitoredPackage m3 = wd.newMonitoredPackage(APP_C, LONG_DURATION, false); + MonitoredPackage m4 = wd.newMonitoredPackage(APP_D, LONG_DURATION, SHORT_DURATION, true); // Verify transition: inactive -> active -> passed // Verify initially inactive diff --git a/tests/net/java/com/android/internal/util/BitUtilsTest.java b/tests/net/java/com/android/internal/util/BitUtilsTest.java index 01fb0df2d47e..d2fbdce9771a 100644 --- a/tests/net/java/com/android/internal/util/BitUtilsTest.java +++ b/tests/net/java/com/android/internal/util/BitUtilsTest.java @@ -21,11 +21,14 @@ import static com.android.internal.util.BitUtils.bytesToLEInt; import static com.android.internal.util.BitUtils.getUint16; import static com.android.internal.util.BitUtils.getUint32; import static com.android.internal.util.BitUtils.getUint8; +import static com.android.internal.util.BitUtils.packBits; import static com.android.internal.util.BitUtils.uint16; import static com.android.internal.util.BitUtils.uint32; import static com.android.internal.util.BitUtils.uint8; +import static com.android.internal.util.BitUtils.unpackBits; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -34,6 +37,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Random; @SmallTest @RunWith(AndroidJUnit4.class) @@ -110,20 +115,66 @@ public class BitUtilsTest { @Test public void testUnsignedGetters() { - ByteBuffer b = ByteBuffer.allocate(4); - b.putInt(0xffff); + ByteBuffer b = ByteBuffer.allocate(4); + b.putInt(0xffff); - assertEquals(0x0, getUint8(b, 0)); - assertEquals(0x0, getUint8(b, 1)); - assertEquals(0xff, getUint8(b, 2)); - assertEquals(0xff, getUint8(b, 3)); + assertEquals(0x0, getUint8(b, 0)); + assertEquals(0x0, getUint8(b, 1)); + assertEquals(0xff, getUint8(b, 2)); + assertEquals(0xff, getUint8(b, 3)); - assertEquals(0x0, getUint16(b, 0)); - assertEquals(0xffff, getUint16(b, 2)); + assertEquals(0x0, getUint16(b, 0)); + assertEquals(0xffff, getUint16(b, 2)); - b.rewind(); - b.putInt(0xffffffff); - assertEquals(0xffffffffL, getUint32(b, 0)); + b.rewind(); + b.putInt(0xffffffff); + assertEquals(0xffffffffL, getUint32(b, 0)); + } + + @Test + public void testBitsPacking() { + BitPackingTestCase[] testCases = { + new BitPackingTestCase(0, ints()), + new BitPackingTestCase(1, ints(0)), + new BitPackingTestCase(2, ints(1)), + new BitPackingTestCase(3, ints(0, 1)), + new BitPackingTestCase(4, ints(2)), + new BitPackingTestCase(6, ints(1, 2)), + new BitPackingTestCase(9, ints(0, 3)), + new BitPackingTestCase(~Long.MAX_VALUE, ints(63)), + new BitPackingTestCase(~Long.MAX_VALUE + 1, ints(0, 63)), + new BitPackingTestCase(~Long.MAX_VALUE + 2, ints(1, 63)), + }; + for (BitPackingTestCase tc : testCases) { + int[] got = unpackBits(tc.packedBits); + assertTrue( + "unpackBits(" + + tc.packedBits + + "): expected " + + Arrays.toString(tc.bits) + + " but got " + + Arrays.toString(got), + Arrays.equals(tc.bits, got)); + } + for (BitPackingTestCase tc : testCases) { + long got = packBits(tc.bits); + assertEquals( + "packBits(" + + Arrays.toString(tc.bits) + + "): expected " + + tc.packedBits + + " but got " + + got, + tc.packedBits, + got); + } + + long[] moreTestCases = { + 0, 1, -1, 23895, -908235, Long.MAX_VALUE, Long.MIN_VALUE, new Random().nextLong(), + }; + for (long l : moreTestCases) { + assertEquals(l, packBits(unpackBits(l))); + } } static byte[] bytes(int b1, int b2, int b3, int b4) { @@ -133,4 +184,18 @@ public class BitUtilsTest { static byte b(int i) { return (byte) i; } + + static int[] ints(int... array) { + return array; + } + + static class BitPackingTestCase { + final int[] bits; + final long packedBits; + + BitPackingTestCase(long packedBits, int[] bits) { + this.bits = bits; + this.packedBits = packedBits; + } + } } diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h index 56bff8fe0fe8..aea24329c431 100644 --- a/tools/aapt2/cmd/Link.h +++ b/tools/aapt2/cmd/Link.h @@ -264,8 +264,8 @@ class LinkCommand : public Command { &options_.keep_raw_values); AddOptionalFlag("--no-compress-regex", "Do not compress extensions matching the regular expression. Remember to\n" - " use the '$' symbol for end of line. Uses a non case-sensitive\n" - " ECMAScript regular expression grammar.", + "use the '$' symbol for end of line. Uses a case-sensitive ECMAScript" + "regular expression grammar.", &no_compress_regex); AddOptionalSwitch("--warn-manifest-validation", "Treat manifest validation errors as warnings.", diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp index e2c65ba74271..7214f1a68d2c 100644 --- a/tools/aapt2/cmd/Util.cpp +++ b/tools/aapt2/cmd/Util.cpp @@ -436,9 +436,9 @@ void SetLongVersionCode(xml::Element* manifest, uint64_t version) { } std::regex GetRegularExpression(const std::string &input) { - // Standard ECMAScript grammar plus case insensitive. + // Standard ECMAScript grammar. std::regex case_insensitive( - input, std::regex_constants::icase | std::regex_constants::ECMAScript); + input, std::regex_constants::ECMAScript); return case_insensitive; } diff --git a/tools/aapt2/cmd/Util_test.cpp b/tools/aapt2/cmd/Util_test.cpp index 2f090bb1c552..ac1f981d753c 100644 --- a/tools/aapt2/cmd/Util_test.cpp +++ b/tools/aapt2/cmd/Util_test.cpp @@ -383,13 +383,32 @@ TEST (UtilTest, AdjustSplitConstraintsForMinSdk) { EXPECT_NE(*adjusted_contraints[1].configs.begin(), ConfigDescription::DefaultConfig()); } -// TODO(127793905): Enable test -/*TEST(UtilTest, RegularExperssions) { +TEST (UtilTest, RegularExperssionsSimple) { std::string valid(".bc$"); std::regex expression = GetRegularExpression(valid); EXPECT_TRUE(std::regex_search("file.abc", expression)); EXPECT_TRUE(std::regex_search("file.123bc", expression)); EXPECT_FALSE(std::regex_search("abc.zip", expression)); -}*/ +} + +TEST (UtilTest, RegularExpressionComplex) { + std::string valid("\\.(d|D)(e|E)(x|X)$"); + std::regex expression = GetRegularExpression(valid); + EXPECT_TRUE(std::regex_search("file.dex", expression)); + EXPECT_TRUE(std::regex_search("file.DEX", expression)); + EXPECT_TRUE(std::regex_search("file.dEx", expression)); + EXPECT_FALSE(std::regex_search("file.dexx", expression)); + EXPECT_FALSE(std::regex_search("dex.file", expression)); + EXPECT_FALSE(std::regex_search("file.adex", expression)); +} + +TEST (UtilTest, RegularExpressionNonEnglish) { + std::string valid("\\.(k|K)(o|O)(ń|Ń)(c|C)(ó|Ó)(w|W)(k|K)(a|A)$"); + std::regex expression = GetRegularExpression(valid); + EXPECT_TRUE(std::regex_search("file.końcówka", expression)); + EXPECT_TRUE(std::regex_search("file.KOŃCÓWKA", expression)); + EXPECT_TRUE(std::regex_search("file.kOńcÓwkA", expression)); + EXPECT_FALSE(std::regex_search("file.koncowka", expression)); +} } // namespace aapt diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index dfdc075043f6..e08a11e0b924 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -1984,8 +1984,8 @@ public class WifiConfiguration implements Parcelable { public boolean isLinked(WifiConfiguration config) { if (config != null) { if (config.linkedConfigurations != null && linkedConfigurations != null) { - if (config.linkedConfigurations.get(configKey()) != null - && linkedConfigurations.get(config.configKey()) != null) { + if (config.linkedConfigurations.get(getKey()) != null + && linkedConfigurations.get(config.getKey()) != null) { return true; } } @@ -2344,31 +2344,18 @@ public class WifiConfiguration implements Parcelable { return KeyMgmt.NONE; } - /* @hide - * Cache the config key, this seems useful as a speed up since a lot of - * lookups in the config store are done and based on this key. - */ - String mCachedConfigKey; - - /** @hide - * return the string used to calculate the hash in WifiConfigStore - * and uniquely identify this WifiConfiguration + /** + * Return a String that can be used to uniquely identify this WifiConfiguration. + * <br /> + * Note: Do not persist this value! This value is not guaranteed to remain backwards compatible. */ - public String configKey(boolean allowCached) { - String key; - if (allowCached && mCachedConfigKey != null) { - key = mCachedConfigKey; - } else if (providerFriendlyName != null) { - key = FQDN + KeyMgmt.strings[KeyMgmt.WPA_EAP]; - if (!shared) { - key += "-" + Integer.toString(UserHandle.getUserId(creatorUid)); - } - } else { - key = getSsidAndSecurityTypeString(); - if (!shared) { - key += "-" + Integer.toString(UserHandle.getUserId(creatorUid)); - } - mCachedConfigKey = key; + @NonNull + public String getKey() { + String key = providerFriendlyName == null + ? getSsidAndSecurityTypeString() + : FQDN + KeyMgmt.strings[KeyMgmt.WPA_EAP]; + if (!shared) { + key += "-" + UserHandle.getUserId(creatorUid); } return key; } @@ -2397,13 +2384,6 @@ public class WifiConfiguration implements Parcelable { return key; } - /** @hide - * get configKey, force calculating the config string - */ - public String configKey() { - return configKey(false); - } - /** @hide */ @UnsupportedAppUsage public IpConfiguration getIpConfiguration() { @@ -2589,7 +2569,6 @@ public class WifiConfiguration implements Parcelable { linkedConfigurations = new HashMap<String, Integer>(); linkedConfigurations.putAll(source.linkedConfigurations); } - mCachedConfigKey = null; //force null configKey validatedInternetAccess = source.validatedInternetAccess; isLegacyPasspointConfig = source.isLegacyPasspointConfig; ephemeral = source.ephemeral; diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java index 246e96f4ce3f..a5ca82c50627 100644 --- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java +++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java @@ -116,6 +116,16 @@ public final class WifiNetworkSuggestion implements Parcelable { */ private int mCarrierId; + /** + * Whether this network is shared credential with user to allow user manually connect. + */ + private boolean mIsUserAllowed; + + /** + * Whether the setIsUserAllowedToManuallyConnect have been called. + */ + private boolean mIsUserAllowedBeenSet; + public Builder() { mSsid = null; mBssid = null; @@ -129,6 +139,8 @@ public final class WifiNetworkSuggestion implements Parcelable { mIsAppInteractionRequired = false; mIsUserInteractionRequired = false; mIsMetered = false; + mIsUserAllowed = true; + mIsUserAllowedBeenSet = false; mPriority = UNASSIGNED_PRIORITY; mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID; } @@ -365,6 +377,27 @@ public final class WifiNetworkSuggestion implements Parcelable { return this; } + /** + * Specifies whether the network credentials provided with this suggestion can be used by + * the user to explicitly (manually) connect to this network. If true this network will + * appear in the Wi-Fi Picker (in Settings) and the user will be able to select and connect + * to it with the provided credentials. If false, the user will need to enter network + * credentials and the resulting configuration will become a user saved network. + * <p> + * <li>Note: Only valid for secure (non-open) networks. + * <li>If not set, defaults to true (i.e. allow user to manually connect) for secure + * networks and false for open networks.</li> + * + * @param isAllowed {@code true} to indicate that the credentials may be used by the user to + * manually connect to the network, {@code false} otherwise. + * @return Instance of {@link Builder} to enable chaining of the builder method. + */ + public @NonNull Builder setIsUserAllowedToManuallyConnect(boolean isAllowed) { + mIsUserAllowed = isAllowed; + mIsUserAllowedBeenSet = true; + return this; + } + private void setSecurityParamsInWifiConfiguration( @NonNull WifiConfiguration configuration) { if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network. @@ -516,6 +549,13 @@ public final class WifiNetworkSuggestion implements Parcelable { throw new IllegalStateException("invalid bssid for suggestion"); } wifiConfiguration = buildWifiConfiguration(); + if (wifiConfiguration.isOpenNetwork()) { + if (mIsUserAllowedBeenSet && mIsUserAllowed) { + throw new IllegalStateException("Open network should not be " + + "setIsUserAllowedToManuallyConnect to true"); + } + mIsUserAllowed = false; + } } return new WifiNetworkSuggestion( @@ -523,6 +563,7 @@ public final class WifiNetworkSuggestion implements Parcelable { mPasspointConfiguration, mIsAppInteractionRequired, mIsUserInteractionRequired, + mIsUserAllowed, Process.myUid(), ActivityThread.currentApplication().getApplicationContext().getOpPackageName()); } @@ -564,12 +605,20 @@ public final class WifiNetworkSuggestion implements Parcelable { */ public final String suggestorPackageName; + /** + * Whether app share credential with the user, allow user use provided credential to + * connect network manually. + * @hide + */ + public final boolean isUserAllowedToManuallyConnect; + /** @hide */ public WifiNetworkSuggestion() { this.wifiConfiguration = null; this.passpointConfiguration = null; this.isAppInteractionRequired = false; this.isUserInteractionRequired = false; + this.isUserAllowedToManuallyConnect = true; this.suggestorUid = -1; this.suggestorPackageName = null; } @@ -579,6 +628,7 @@ public final class WifiNetworkSuggestion implements Parcelable { @Nullable PasspointConfiguration passpointConfiguration, boolean isAppInteractionRequired, boolean isUserInteractionRequired, + boolean isUserAllowedToManuallyConnect, int suggestorUid, @NonNull String suggestorPackageName) { checkNotNull(networkConfiguration); checkNotNull(suggestorPackageName); @@ -587,6 +637,7 @@ public final class WifiNetworkSuggestion implements Parcelable { this.isAppInteractionRequired = isAppInteractionRequired; this.isUserInteractionRequired = isUserInteractionRequired; + this.isUserAllowedToManuallyConnect = isUserAllowedToManuallyConnect; this.suggestorUid = suggestorUid; this.suggestorPackageName = suggestorPackageName; } @@ -600,6 +651,7 @@ public final class WifiNetworkSuggestion implements Parcelable { in.readParcelable(null), // PasspointConfiguration in.readBoolean(), // isAppInteractionRequired in.readBoolean(), // isUserInteractionRequired + in.readBoolean(), // isSharedCredentialWithUser in.readInt(), // suggestorUid in.readString() // suggestorPackageName ); @@ -622,6 +674,7 @@ public final class WifiNetworkSuggestion implements Parcelable { dest.writeParcelable(passpointConfiguration, flags); dest.writeBoolean(isAppInteractionRequired); dest.writeBoolean(isUserInteractionRequired); + dest.writeBoolean(isUserAllowedToManuallyConnect); dest.writeInt(suggestorUid); dest.writeString(suggestorPackageName); } @@ -666,6 +719,7 @@ public final class WifiNetworkSuggestion implements Parcelable { .append(", FQDN=").append(wifiConfiguration.FQDN) .append(", isAppInteractionRequired=").append(isAppInteractionRequired) .append(", isUserInteractionRequired=").append(isUserInteractionRequired) + .append(", isUserAllowedToManuallyConnect=").append(isUserAllowedToManuallyConnect) .append(", suggestorUid=").append(suggestorUid) .append(", suggestorPackageName=").append(suggestorPackageName) .append("]"); diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java index 699008905f0a..ce085f55b0dd 100644 --- a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java +++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java @@ -64,12 +64,13 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE, suggestion.wifiConfiguration.meteredOverride); assertEquals(-1, suggestion.wifiConfiguration.priority); + assertEquals(false, suggestion.isUserAllowedToManuallyConnect); } /** * Validate correctness of WifiNetworkSuggestion object created by * {@link WifiNetworkSuggestion.Builder#build()} for WPA_EAP network which requires - * app interaction and has a priority of zero set. + * app interaction, not share credential and has a priority of zero set. */ @Test public void @@ -78,6 +79,7 @@ public class WifiNetworkSuggestionTest { .setSsid(TEST_SSID) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsAppInteractionRequired(true) + .setIsUserAllowedToManuallyConnect(false) .setPriority(0) .build(); @@ -91,6 +93,7 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE, suggestion.wifiConfiguration.meteredOverride); assertEquals(0, suggestion.wifiConfiguration.priority); + assertEquals(false, suggestion.isUserAllowedToManuallyConnect); } /** @@ -118,6 +121,7 @@ public class WifiNetworkSuggestionTest { assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED, suggestion.wifiConfiguration.meteredOverride); assertEquals(-1, suggestion.wifiConfiguration.priority); + assertTrue(suggestion.isUserAllowedToManuallyConnect); } /** @@ -138,6 +142,7 @@ public class WifiNetworkSuggestionTest { .get(WifiConfiguration.KeyMgmt.OWE)); assertNull(suggestion.wifiConfiguration.preSharedKey); assertTrue(suggestion.wifiConfiguration.requirePMF); + assertFalse(suggestion.isUserAllowedToManuallyConnect); } /** @@ -149,6 +154,7 @@ public class WifiNetworkSuggestionTest { WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() .setSsid(TEST_SSID) .setWpa3Passphrase(TEST_PRESHARED_KEY) + .setIsUserAllowedToManuallyConnect(true) .build(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); @@ -157,6 +163,7 @@ public class WifiNetworkSuggestionTest { assertEquals("\"" + TEST_PRESHARED_KEY + "\"", suggestion.wifiConfiguration.preSharedKey); assertTrue(suggestion.wifiConfiguration.requirePMF); + assertTrue(suggestion.isUserAllowedToManuallyConnect); } @@ -186,6 +193,7 @@ public class WifiNetworkSuggestionTest { assertNull(suggestion.wifiConfiguration.preSharedKey); // allowedSuiteBCiphers are set according to the loaded certificate and cannot be tested // here. + assertTrue(suggestion.isUserAllowedToManuallyConnect); } /** @@ -205,6 +213,7 @@ public class WifiNetworkSuggestionTest { assertTrue(suggestion.isAppInteractionRequired); assertEquals(suggestion.wifiConfiguration.meteredOverride, WifiConfiguration.METERED_OVERRIDE_METERED); + assertTrue(suggestion.isUserAllowedToManuallyConnect); } /** @@ -439,7 +448,7 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion( - configuration, null, false, true, TEST_UID, TEST_PACKAGE_NAME); + configuration, null, false, true, true, TEST_UID, TEST_PACKAGE_NAME); Parcel parcelW = Parcel.obtain(); suggestion.writeToParcel(parcelW, 0); @@ -506,7 +515,7 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, true, false, TEST_UID, + new WifiNetworkSuggestion(configuration, null, true, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiConfiguration configuration1 = new WifiConfiguration(); @@ -514,7 +523,7 @@ public class WifiNetworkSuggestionTest { configuration1.BSSID = TEST_BSSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, true, TEST_UID, + new WifiNetworkSuggestion(configuration1, null, false, true, true, TEST_UID, TEST_PACKAGE_NAME); assertEquals(suggestion, suggestion1); @@ -531,14 +540,14 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID_1; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration1, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); assertNotEquals(suggestion, suggestion1); @@ -555,14 +564,14 @@ public class WifiNetworkSuggestionTest { configuration.BSSID = TEST_BSSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration1, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); assertNotEquals(suggestion, suggestion1); @@ -578,14 +587,14 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiConfiguration configuration1 = new WifiConfiguration(); configuration1.SSID = TEST_SSID; configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration1, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration1, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); assertNotEquals(suggestion, suggestion1); @@ -601,11 +610,11 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = - new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID, + new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiNetworkSuggestion suggestion1 = - new WifiNetworkSuggestion(configuration, null, false, false, TEST_UID_OTHER, + new WifiNetworkSuggestion(configuration, null, false, false, true, TEST_UID_OTHER, TEST_PACKAGE_NAME); assertNotEquals(suggestion, suggestion1); @@ -621,10 +630,10 @@ public class WifiNetworkSuggestionTest { configuration.SSID = TEST_SSID; configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion( - configuration, null, false, false, TEST_UID, TEST_PACKAGE_NAME); + configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME); WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion( - configuration, null, false, false, TEST_UID, TEST_PACKAGE_NAME_OTHER); + configuration, null, false, false, true, TEST_UID, TEST_PACKAGE_NAME_OTHER); assertNotEquals(suggestion, suggestion1); } @@ -664,4 +673,17 @@ public class WifiNetworkSuggestionTest { .build(); assertNotEquals(suggestion, suggestion1); } + + /** + * Ensure {@link WifiNetworkSuggestion.Builder#build()} throws an exception + * when {@link WifiNetworkSuggestion.Builder#setIsUserAllowedToManuallyConnect(boolean)} to + * true on a open network suggestion. + */ + @Test(expected = IllegalStateException.class) + public void testSetIsUserAllowedToManuallyConnectToWithOpenNetwork() { + WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder() + .setSsid(TEST_SSID) + .setIsUserAllowedToManuallyConnect(true) + .build(); + } } |