diff options
1063 files changed, 14228 insertions, 3993 deletions
diff --git a/Ravenwood.bp b/Ravenwood.bp index c73e04896173..4791640239b3 100644 --- a/Ravenwood.bp +++ b/Ravenwood.bp @@ -149,6 +149,7 @@ java_library { installable: false, srcs: [":services.fakes-sources"], libs: [ + "ravenwood-framework", "services.core.ravenwood", ], jarjar_rules: ":ravenwood-services-jarjar-rules", @@ -204,6 +205,7 @@ android_ravenwood_libgroup { // Provide runtime versions of utils linked in below "junit", "truth", + "ravenwood-framework", "ravenwood-junit-impl", "mockito-ravenwood-prebuilt", "inline-mockito-ravenwood-prebuilt", @@ -218,6 +220,7 @@ android_ravenwood_libgroup { libs: [ "junit", "truth", + "ravenwood-framework", "ravenwood-junit", "mockito-ravenwood-prebuilt", "inline-mockito-ravenwood-prebuilt", diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/VectorDrawablePerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/VectorDrawablePerfTest.java index d14e93e553f6..80a9c06b549e 100644 --- a/apct-tests/perftests/core/src/android/graphics/perftests/VectorDrawablePerfTest.java +++ b/apct-tests/perftests/core/src/android/graphics/perftests/VectorDrawablePerfTest.java @@ -27,8 +27,8 @@ import android.perftests.utils.BenchmarkState; import android.perftests.utils.BitmapUtils; import android.perftests.utils.PerfStatusReporter; import android.perftests.utils.PerfTestActivity; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.rule.ActivityTestRule; import androidx.test.runner.AndroidJUnit4; diff --git a/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java b/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java index aa47e0a29695..80cd86cf9a5b 100644 --- a/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/AdditionPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java index 97ab6c7cd6b4..2f6c37832d04 100644 --- a/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ArrayCopyPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java index bb452d394d47..d17add767257 100644 --- a/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ArrayIterationPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java index ff6d46f6db7f..3a57db8f323f 100644 --- a/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ArrayListIterationPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java index e0c12dd660e2..3fb3bc8c0ff2 100644 --- a/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/BigIntegerPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java index 04ef09e4b682..2a1b5d1cc6ce 100644 --- a/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/BufferedZipFilePerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java index 4ae88b88b090..5f599ea85eb4 100644 --- a/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ClassLoaderResourcePerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Assert; diff --git a/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java index 5e73916d5f5b..ea249848daad 100644 --- a/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ClonePerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java index 3ebaa4cd0bfa..82247dcee772 100644 --- a/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/DeepArrayOpsPerfTest.java @@ -18,7 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java b/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java index da94ae118900..0bebf04c6897 100644 --- a/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/FieldAccessPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java index 9446d99c959d..55c1027e1add 100644 --- a/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/HashedCollectionsPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java index be2a7e97f775..da60a7773528 100644 --- a/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ImtConflictPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java index ca9977974a8a..6d9d0c92ff25 100644 --- a/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/MethodInvocationPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java index 8496fbecb6bd..09b09771e9de 100644 --- a/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/MultiplicationPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java index bb794249e9f4..ba21ed33bdb2 100644 --- a/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ReferenceGetPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java index 05a3e1201a00..293752ee5dd1 100644 --- a/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ReferencePerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java index 65a2fdbae304..528b751d1551 100644 --- a/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/SmallBigIntegerPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java b/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java index 4f5c54d6a847..1f301acd1dc6 100644 --- a/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/StringDexCachePerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java index 08ad92694013..4268325f8c64 100644 --- a/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/StringIterationPerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java index 20f1309bd8e6..6363e9c3ef21 100644 --- a/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/SystemArrayCopyPerfTest.java @@ -18,7 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java b/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java index 7e71976fdc9d..cb3d3acb337f 100644 --- a/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/VirtualVersusInterfacePerfTest.java @@ -18,8 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java b/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java index b1b594d64324..5be8ee6e67e2 100644 --- a/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/XmlSerializePerfTest.java @@ -18,7 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/XmlSerializerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/XmlSerializerPerfTest.java index 412cb5acbf8b..a37b89ddf033 100644 --- a/apct-tests/perftests/core/src/android/libcore/XmlSerializerPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/XmlSerializerPerfTest.java @@ -18,9 +18,9 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Xml; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import libcore.util.XmlObjectFactory; diff --git a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java index 3a45d4045d62..ed669beae1ce 100644 --- a/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ZipFilePerfTest.java @@ -18,7 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java b/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java index 2e89518ec9fb..d239a054fac7 100644 --- a/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/ZipFileReadPerfTest.java @@ -18,7 +18,8 @@ package android.libcore; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java index d38d5197b937..487295c03c0e 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/AnnotatedElementPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java index cc56868468e5..adc5d8c2bb3e 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/BidiPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java index 662694b1b5d1..286d70339c5f 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/BigIntegerPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java index 2c0473eda830..d6462024a380 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/BitSetPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java index 6a2ce5847daa..b887f4033462 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/BreakIteratorPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/BulkPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/BulkPerfTest.java index b7b7e83f147c..e4eaf12e9dcb 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/BulkPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/BulkPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java index 9ac36d076c7b..cb2438e519da 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java index 5dd9d6e2bc2c..9ee927cfc353 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/ByteBufferScalarVersusVectorPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java index 0a598998bced..e4a4db739235 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/CharacterPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java index 8da13a9b7f91..858c101fc33e 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/CharsetForNamePerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java index 048c50f044c8..a2fb7d7f83d8 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/CharsetPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java index b753006e193e..2047444a7f52 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/CharsetUtf8PerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.icu.lang.UCharacter; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java index 1d33fcb250b9..4ce8b41de403 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/ChecksumPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java index 35730ec753f1..6a7ec1ad62e9 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/CipherInputStreamPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java index 42b058815bfe..238c028fa0cf 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/CipherPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java index 6728e73d0c4b..7e5566055fb4 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/CollatorPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java index 69197c3325f4..100798a7957b 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/CollectionsPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java index 4dba1391438c..b6784a8d3867 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/DateFormatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java index f3eddab0e77c..52f98738481f 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java index 2bf04180fa79..610542061107 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/DecimalFormatSymbolsPerfTest.java @@ -17,8 +17,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java index c3320a4e5a20..fae74a5e8620 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/DefaultCharsetPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java index 7c52ac424a2a..2915363786f3 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/DnsPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java index d13335906ec6..dd7e5cc1057b 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/DoPrivilegedPerfTest.java @@ -18,15 +18,14 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; - import java.security.AccessController; import java.security.PrivilegedAction; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java index 38904af7edd7..e034a47e79d2 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/DoublePerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java index 839120336697..fe1b599cc5ad 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/EqualsHashCodePerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java index 7712aeef4161..ecbfc7169945 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java index 783136a5b3a2..0c14d64c27a9 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/FilePerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java index a995f5caa183..7d7d83b3fdbf 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/FloatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java index 94c4f0807cbc..08dda5314eac 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/FormatterPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/IdnPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/IdnPerfTest.java index c60930f99682..a09ad809a6a2 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/IdnPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/IdnPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantDivisionPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantDivisionPerfTest.java index abcc972b0ac3..be22814ef8f4 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantDivisionPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantDivisionPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantMultiplicationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantMultiplicationPerfTest.java index c9f06166e33b..4337c903ecd6 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantMultiplicationPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantMultiplicationPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantRemainderPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantRemainderPerfTest.java index 78f744c1b938..1b6c5026e1f6 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/IntConstantRemainderPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/IntConstantRemainderPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/IntegralToStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/IntegralToStringPerfTest.java index 5129fcbfb247..0aa854ecfa80 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/IntegralToStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/IntegralToStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/KeyPairGeneratorPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/KeyPairGeneratorPerfTest.java index 80c448732b59..9b3d7a044720 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/KeyPairGeneratorPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/KeyPairGeneratorPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/LoopingBackwardsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/LoopingBackwardsPerfTest.java index c9b0cbe1bedb..1a9e19aeb78d 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/LoopingBackwardsPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/LoopingBackwardsPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/MathPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/MathPerfTest.java index 4c2d7fb7e663..a8a704c09d6d 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/MathPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/MathPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/MessageDigestPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/MessageDigestPerfTest.java index 2dc947a613d2..6da9666db23b 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/MessageDigestPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/MessageDigestPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/MutableIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/MutableIntPerfTest.java index d9d4bb5d0ae1..060d18fb3de3 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/MutableIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/MutableIntPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatPerfTest.java index dae185e1209c..7cb3b2283779 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java index 5ff2b225d64f..272b45a3affe 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/NumberFormatTrivialFormatLongPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/PriorityQueuePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/PriorityQueuePerfTest.java index 48450b4616e6..c3a09662fd1f 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/PriorityQueuePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/PriorityQueuePerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/PropertyAccessPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/PropertyAccessPerfTest.java index 21ccba5cc2e7..2ac56bed1910 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/PropertyAccessPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/PropertyAccessPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ProviderPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ProviderPerfTest.java index f7bcf12c858e..7ad0141c8471 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/ProviderPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/ProviderPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/RandomPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/RandomPerfTest.java index d8bff4cc20d1..c7b6cb5a190c 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/RandomPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/RandomPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/RealToStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/RealToStringPerfTest.java index 2542df90896f..44e5f227b00a 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/RealToStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/RealToStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ReflectionPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ReflectionPerfTest.java index b06662ccd9b5..6e00b10838a6 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/ReflectionPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/ReflectionPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java index 694d609cd950..5a9b5c36d0d3 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/SSLLoopbackPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import libcore.java.security.TestKeyStore; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java index bdbbcb0da006..6d48cf26c971 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/SSLSocketFactoryPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java index 5ad62dedcae7..86416291f26d 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/SchemePrefixPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java index 1ec22d217109..afd1191a07fa 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/SerializationPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java index a9a0788f6136..6c261332aa99 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/SignaturePerfTest.java @@ -17,7 +17,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java index c25b0ce6d7d9..274b51f6fae4 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/SimpleDateFormatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java index eeccb5bd64f4..b4c427beac65 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StrictMathPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java index 10fa8b93acaf..2235cc5611a4 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StringBuilderPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java index 6854c0de9387..9ab50005e62a 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StringEqualsPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import junit.framework.Assert; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java index 79ff646bbfff..b1e749cc538c 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StringIsEmptyPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java index 8dbf9f58fbf8..9e5759171a6f 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StringLengthPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java index 36db014b75a5..a80514c72e95 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StringPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java index 5b4423a32831..78ae3952719b 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StringReplaceAllPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java index 4d5c792295b9..73911c71c351 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StringReplacePerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java index 2bb25ac56694..1539271c2b3c 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StringSplitPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java index c004d959b9b3..0d5e62b4268c 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StringToBytesPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java index 15516fc1c51c..ecdf809f1610 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/StringToRealPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java index f2565550c6c5..2b2a6b5727de 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/ThreadLocalPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java index 8274512e1501..6eb8fccf5b2a 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/TimeZonePerfTest.java @@ -18,8 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java index ae1e8bce42ac..288c646ec67d 100644 --- a/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/regression/XMLEntitiesPerfTest.java @@ -18,7 +18,8 @@ package android.libcore.regression; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import junitparams.JUnitParamsRunner; import junitparams.Parameters; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java index e7bb8f84d671..003c957d894f 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java index 5bac46af4630..4f216181d5e3 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java index 1005a70e96e0..210014ad3f6e 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java index 5224ad3b5911..22c68273bf12 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectGetStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java index 06696ef0773b..5b391091253b 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java index a784c524a4c5..883e8a76586b 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java index 4ce0078ff1c1..50bc85c31280 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java index 587e201c4e17..13fa2bf7d230 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/ReflectSetStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java index e06b53434438..85c9bae9a9d9 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java index 0fd16a02e22c..2b8f430440f5 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java index 7ad42d057588..246fa43d0dca 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java index 76e1f47251cf..d12ffae25c5e 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeAcquireStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java index b4b78408a45f..5ced1157cb73 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java index 09ed167cef35..b955d506fe85 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java index 920d2e4767e5..601ff3461f5b 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java index 55ed789d1227..0e567f9568e6 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java index ea3057b3f54f..6be287006f42 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java index 20558aa92f48..84c186bd24e6 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeReleaseStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java index d7b1d2989c0e..b093234b2bc5 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java index d138dc979b1d..0d2037b4ab27 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandexchangeStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java index 36153f2b7037..ee31973c308a 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java index bf4fbc4eeefb..0571fefe2a43 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java index d3c1b36bd3a6..f619dabdd50a 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java index 90e69a168391..fc443fa362bc 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleCompareandsetStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java index 96bc1049fad4..bf3d58b68692 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java index 2679494eb6de..1f4bc31f24c6 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java index 170dce76d9c8..2085552e91dd 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java index 11d12db39397..d9c7d7b7695e 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetAcquireStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java index bd2a6008e239..acd2533a38e4 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java index 99a09cda367f..de9944a8c274 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetArrayLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java index db83606bdb54..a8639292cbb3 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewBigEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java index 4a8f92461301..4999b9bf6850 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetByteArrayViewLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java index 4e4a9ee980fd..ee80a6f72c93 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java index 3e7de1d08a0e..ec29f7a33b39 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java index 67d53b34c4d6..ee6a669f2f83 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java index 470a1ce0fb71..1702b84e703b 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java index 8a982c23b1cb..514ddb9c4b11 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java index 2c17a698b5e7..fbcee6906bd7 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetOpaqueStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java index 099b1f4f6d82..2c5658810b05 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java index 7f6b4b8b637e..8fce69e62033 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java index 8592d30f58f0..ef530607bb56 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java index 539bd2aa8e8c..64c08983a063 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java index a36a7b6d39a2..939100c47c05 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java index 90d2a70691ad..728b1995ff52 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetVolatileStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java index 4e5fcf32edd2..bf5ef99ff456 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianFloatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java index fd0abf85abfc..d15705e9106d 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java index 9272b1164d07..222a60da3550 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianFloatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java index a896d0a8e3e7..7436476b5329 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddAcquireStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java index 671b0a3c7c83..cca97f42e4b7 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianFloatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java index 1eb3f9277d56..170ee7313891 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java index f23d5e269154..184f796ad61c 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianFloatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java index 161379851ce6..7e75c44089ff 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java index 14f1c002812f..39c386b645d8 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianFloatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java index 8327caf0a124..04ab5310655c 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddReleaseStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java index 6c211fb5371b..b71351fca81c 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianFloatPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java index d02cd735e753..e3955c051890 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandaddStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java index 0777586dadd9..adf05a6befb1 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java index 24a949f7b73c..4d657d9a3511 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndAcquireStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java index 4b94bbe5d86d..dc6417416917 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java index 1784c0557442..25d5631308ef 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java index f85d3eeae9aa..de2d5489dbcc 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndReleaseStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java index 81f6779e9820..36544c6f8f50 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseAndStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java index 9436fadfde72..fb36d0cb495f 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java index 9ebc45848003..4194b12a4a6e 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrAcquireStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java index ea159a123d21..355c6e823803 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java index a42ec7e93c05..401079d0bece 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java index 6f1007e553cf..322dcbf7453e 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrReleaseStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java index 6a738181104b..c98281416012 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseOrStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java index e9a365bd72a4..0b1cb32528ff 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java index fc9191cc2b77..473707201782 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorAcquireStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java index 5919a1dc32c9..204cd70b2f9e 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java index 313e5806cbf7..b3ffed7de91a 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java index 9c8b3ae1b939..d0ab8de4502d 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorReleaseStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java index ea618cc405be..b378b684114e 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandbitwiseXorStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java index df6f470450ea..c7c66fe20513 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java index 63fd7406cee4..98d6bd71c610 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java index a96031e673cf..206358f21c1d 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java index 3bc25fbbf524..0532e73c9d66 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetAcquireStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java index 7ffdf11d0fa6..f192d7153fce 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java index cc7f3be26319..0a8909c6c7b5 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java index 8d54c00f0fe1..bfcb0f410256 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java index 22e92dd06330..c6b0509d619b 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java index 08ddc8b0227c..45a01eda2fd5 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java index 429e090642e9..30472811d5d6 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetReleaseStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java index d5b31f66cab5..6f1f1a016039 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java index 8667aaa961a4..c4d279f37a4c 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleGetandsetStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java index aa202469eb93..c4f600593067 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java index 9e0210fbd72c..a6858c261eb0 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetArrayLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java index d48916886341..a994cbeaf02c 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewBigEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java index b06d7eff199d..65412ec84aa4 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetByteArrayViewLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java index 84469375c7e2..573b0ff277cc 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java index 34540a31ad78..fe3c0fc04a84 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java index c79b5133afd5..f398899880ce 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java index 028130ddef96..74931205fd3e 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java index 06a5a8ce8ceb..5e7326985c9d 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java index 78eefc89c8fd..9a217d1fd142 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetOpaqueStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java index cd1bd4824175..1ce2270ecc58 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java index 6c0740c7169e..ed84528fe869 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java index b95f24b0a1e8..aeb96404a223 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java index b03cf826c7f4..8959a0c3d50c 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetReleaseStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java index c98c09274102..400772231d48 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java index 625cfc77e15b..732315862eb2 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java index 58319b3f6326..f4119c28b826 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java index f741542411f5..9b9c2612fe25 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java index 87f6a7832526..f125384706ca 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java index 610345f69051..2ad605d83d04 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleSetVolatileStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java index 519d4fd6179b..5ef3bf00204b 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java index 322cf639e81d..0c4ed66fc6b7 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java index f8ccbadf682f..db6bd2429e26 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java index 16f1059d150f..d2b0bf76158f 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetAcquireStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java index c7084fe63b06..3cd5ae6533b6 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java index 9d526b8687ca..6ddfc25deca9 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java index 8372f6ccffbb..375f0bc08027 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java index 87e47e76984f..7e2492ace1dd 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java index aa2e1049e302..190118c551e6 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java index ebaa0801e894..484ba1b88183 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetPlainStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java index d90356a02fa6..80e4e153a41f 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java index 6db995a7fd0b..fa26c59304f9 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java index ecea19e2036a..16bf2a208870 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java index ab86284729c2..e1716dede024 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetReleaseStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java index 23a33f54fcb9..dc6f2adfe951 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianIntPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java index 270b5adccde1..d1096c629ed8 100644 --- a/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java +++ b/apct-tests/perftests/core/src/android/libcore/varhandles/VarHandleWeakcompareandsetStaticFieldLittleEndianStringPerfTest.java @@ -18,8 +18,8 @@ package android.libcore.varhandles; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/apex/jobscheduler/service/aconfig/alarm.aconfig b/apex/jobscheduler/service/aconfig/alarm.aconfig index 3b9b4e70b310..bb0f3cbd5257 100644 --- a/apex/jobscheduler/service/aconfig/alarm.aconfig +++ b/apex/jobscheduler/service/aconfig/alarm.aconfig @@ -9,3 +9,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "start_user_before_scheduled_alarms" + namespace: "multiuser" + description: "Persist list of users with alarms scheduled and wakeup stopped users before alarms are due" + bug: "314907186" +} diff --git a/cmds/idmap2/tests/FabricatedOverlayTests.cpp b/cmds/idmap2/tests/FabricatedOverlayTests.cpp index 6b1c7e83c826..15109d99a6fd 100644 --- a/cmds/idmap2/tests/FabricatedOverlayTests.cpp +++ b/cmds/idmap2/tests/FabricatedOverlayTests.cpp @@ -144,7 +144,7 @@ TEST(FabricatedOverlayTests, SerializeAndDeserialize) { "com.example.target:string/string1", Res_value::TYPE_STRING, "foobar", "") .Build(); ASSERT_TRUE(overlay); - TemporaryFile tf; + TempFrroFile tf; std::ofstream out(tf.path); ASSERT_TRUE((*overlay).ToBinaryStream(out)); out.close(); diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index a384305da43d..c85619c1e4bf 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -274,7 +274,7 @@ TEST(IdmapTests, FabricatedOverlay) { .Build(); ASSERT_TRUE(frro); - TemporaryFile tf; + TempFrroFile tf; std::ofstream out(tf.path); ASSERT_TRUE((*frro).ToBinaryStream(out)); out.close(); @@ -467,9 +467,9 @@ TEST(IdmapTests, CreateIdmapDataInlineResources) { TEST(IdmapTests, IdmapHeaderIsUpToDate) { fclose(stderr); // silence expected warnings from libandroidfw - const std::string target_apk_path = kIdmapRawTargetPath; - const std::string overlay_apk_path = kIdmapRawOverlayPath; - const std::string overlay_name = kIdmapRawOverlayName; + const std::string target_apk_path {kIdmapRawTargetPath}; + const std::string overlay_apk_path {kIdmapRawOverlayPath}; + const std::string overlay_name {kIdmapRawOverlayName}; const PolicyBitmask policies = kIdmapRawDataPolicies; const uint32_t target_crc = kIdmapRawDataTargetCrc; const uint32_t overlay_crc = kIdmapRawOverlayCrc; diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp index db44c23a41f9..1d2255378018 100644 --- a/cmds/idmap2/tests/ResourceMappingTests.cpp +++ b/cmds/idmap2/tests/ResourceMappingTests.cpp @@ -217,7 +217,7 @@ TEST(ResourceMappingTests, FabricatedOverlay) { .Build(); ASSERT_TRUE(frro); - TemporaryFile tf; + TempFrroFile tf; std::ofstream out(tf.path); ASSERT_TRUE((*frro).ToBinaryStream(out)); out.close(); diff --git a/cmds/idmap2/tests/TestHelpers.h b/cmds/idmap2/tests/TestHelpers.h index cdc0b8fbb87e..bf01c32c4c86 100644 --- a/cmds/idmap2/tests/TestHelpers.h +++ b/cmds/idmap2/tests/TestHelpers.h @@ -17,11 +17,15 @@ #ifndef IDMAP2_TESTS_TESTHELPERS_H_ #define IDMAP2_TESTS_TESTHELPERS_H_ +#include <stdio.h> #include <string> +#include <string_view> #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "android-base/file.h" + namespace android::idmap2 { const unsigned char kIdmapRawData[] = { @@ -197,12 +201,23 @@ const unsigned int kIdmapRawDataOffset = 0x54; const unsigned int kIdmapRawDataTargetCrc = 0x1234; const unsigned int kIdmapRawOverlayCrc = 0x5678; const unsigned int kIdmapRawDataPolicies = 0x11; -inline const std::string kIdmapRawTargetPath = "targetX.apk"; -inline const std::string kIdmapRawOverlayPath = "overlayX.apk"; -inline const std::string kIdmapRawOverlayName = "OverlayName"; +inline const std::string_view kIdmapRawTargetPath = "targetX.apk"; +inline const std::string_view kIdmapRawOverlayPath = "overlayX.apk"; +inline const std::string_view kIdmapRawOverlayName = "OverlayName"; std::string GetTestDataPath(); +class TempFrroFile : public TemporaryFile { +public: + TempFrroFile() { + std::string new_path = path; + new_path += ".frro"; + ::rename(path, new_path.c_str()); + const auto new_len = new_path.copy(path, sizeof(path) - 1); + path[new_len] = '\0'; + } +}; + class Idmap2Tests : public testing::Test { protected: void SetUp() override { diff --git a/core/api/current.txt b/core/api/current.txt index b4c3f44b4ec4..62980ed5bd69 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -13119,7 +13119,6 @@ package android.content.pm { field public static final String FEATURE_CAMERA_LEVEL_FULL = "android.hardware.camera.level.full"; field public static final String FEATURE_CANT_SAVE_STATE = "android.software.cant_save_state"; field public static final String FEATURE_COMPANION_DEVICE_SETUP = "android.software.companion_device_setup"; - field @FlaggedApi("android.view.inputmethod.concurrent_input_methods") public static final String FEATURE_CONCURRENT_INPUT_METHODS = "android.software.concurrent_input_methods"; field @Deprecated public static final String FEATURE_CONNECTION_SERVICE = "android.software.connectionservice"; field public static final String FEATURE_CONSUMER_IR = "android.hardware.consumerir"; field public static final String FEATURE_CONTROLS = "android.software.controls"; diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 1718452548b3..2922dd9ef5ae 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -15316,12 +15316,12 @@ package android.telephony { method @Deprecated public boolean getDataEnabled(int); method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getDefaultRespondViaMessageApplication(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getDeviceSoftwareVersion(int); - method @FlaggedApi("android.permission.flags.get_emergency_role_holder_api_enabled") @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getEmergencyAssistancePackage(); + method @FlaggedApi("android.permission.flags.get_emergency_role_holder_api_enabled") @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getEmergencyAssistancePackageName(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); - method @FlaggedApi("com.android.server.telecom.flags.telecom_resolve_hidden_dependencies") @Nullable @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_LAST_KNOWN_CELL_ID}) public android.telephony.CellIdentity getLastKnownCellIdentity(); + method @FlaggedApi("com.android.server.telecom.flags.get_last_known_cell_identity") @Nullable @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_LAST_KNOWN_CELL_ID}) public android.telephony.CellIdentity getLastKnownCellIdentity(); method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); method public int getMaxNumberOfSimultaneouslyActiveSims(); method public static long getMaxNumberVerificationTimeoutMillis(); diff --git a/core/java/android/accessibilityservice/BrailleDisplayControllerImpl.java b/core/java/android/accessibilityservice/BrailleDisplayControllerImpl.java index cac1dc4e04a9..f1df33657279 100644 --- a/core/java/android/accessibilityservice/BrailleDisplayControllerImpl.java +++ b/core/java/android/accessibilityservice/BrailleDisplayControllerImpl.java @@ -25,9 +25,11 @@ import android.hardware.usb.UsbDevice; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; +import android.os.SystemProperties; import android.view.accessibility.AccessibilityInteractionClient; import android.view.accessibility.Flags; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FunctionalUtils; import java.io.IOException; @@ -36,24 +38,46 @@ import java.util.concurrent.Executor; /** * Default implementation of {@link BrailleDisplayController}. + * + * @hide */ // BrailleDisplayControllerImpl is not an API, but it implements BrailleDisplayController APIs. // This @FlaggedApi annotation tells the linter that this method delegates API checks to its // callers. @FlaggedApi(Flags.FLAG_BRAILLE_DISPLAY_HID) -final class BrailleDisplayControllerImpl implements BrailleDisplayController { +@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) +public final class BrailleDisplayControllerImpl implements BrailleDisplayController { private final AccessibilityService mAccessibilityService; private final Object mLock; + private final boolean mIsHidrawSupported; private IBrailleDisplayConnection mBrailleDisplayConnection; private Executor mCallbackExecutor; private BrailleDisplayCallback mCallback; + /** + * Read-only property that returns whether HIDRAW access is supported on this device. + * + * <p>Defaults to true. + * + * <p>Device manufacturers without HIDRAW kernel support can set this to false in + * the device's product makefile. + */ + private static final boolean IS_HIDRAW_SUPPORTED = SystemProperties.getBoolean( + "ro.accessibility.support_hidraw", true); + BrailleDisplayControllerImpl(AccessibilityService accessibilityService, Object lock) { + this(accessibilityService, lock, IS_HIDRAW_SUPPORTED); + } + + @VisibleForTesting + public BrailleDisplayControllerImpl(AccessibilityService accessibilityService, + Object lock, boolean isHidrawSupported) { mAccessibilityService = accessibilityService; mLock = lock; + mIsHidrawSupported = isHidrawSupported; } @Override @@ -113,6 +137,11 @@ final class BrailleDisplayControllerImpl implements BrailleDisplayController { createConnection, @NonNull Executor callbackExecutor, @NonNull BrailleDisplayCallback callback) { BrailleDisplayController.checkApiFlagIsEnabled(); + if (!mIsHidrawSupported) { + callbackExecutor.execute(() -> callback.onConnectionFailed( + BrailleDisplayCallback.FLAG_ERROR_CANNOT_ACCESS)); + return; + } if (isConnected()) { throw new IllegalStateException( "This service already has a connected Braille display"); diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 083705bca09e..b25ebf69d14c 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -14071,7 +14071,7 @@ public class DevicePolicyManager { public void setAuditLogEnabled(boolean enabled) { throwIfParentInstance("setAuditLogEnabled"); try { - mService.setAuditLogEnabled(mContext.getPackageName(), true); + mService.setAuditLogEnabled(mContext.getPackageName(), enabled); } catch (RemoteException re) { re.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig index 10954aba955c..e1a69139d88d 100644 --- a/core/java/android/app/admin/flags/flags.aconfig +++ b/core/java/android/app/admin/flags/flags.aconfig @@ -149,3 +149,10 @@ flag { description: "Allow to query whether MTE is enabled or not to check for compliance for enterprise policy" bug: "322777918" } + +flag { + name: "esim_management_ux_enabled" + namespace: "enterprise" + description: "Enable UX changes for esim management" + bug: "295301164" +} diff --git a/core/java/android/app/backup/BackupManagerMonitor.java b/core/java/android/app/backup/BackupManagerMonitor.java index 812bf8e6be6a..c66478f6cf84 100644 --- a/core/java/android/app/backup/BackupManagerMonitor.java +++ b/core/java/android/app/backup/BackupManagerMonitor.java @@ -145,6 +145,25 @@ public class BackupManagerMonitor { */ public static final String EXTRA_LOG_OPERATION_TYPE = "android.app.backup.extra.OPERATION_TYPE"; + /** + * List of system components that do not support restore in a V-> U OS downgrade, even if + * restoreAnyVersion is set to true. + * Read from Settings.Secure.V_TO_U_RESTORE_DENYLIST + * + * @hide + */ + public static final String EXTRA_LOG_V_TO_U_DENYLIST = "android.app.backup.extra.V_TO_U_DENYLIST"; + + /** + * List of system components that support restore in a V-> U OS downgrade, even if + * restoreAnyVersion is set to false. + * Read from Settings.Secure.V_TO_U_RESTORE_ALLOWLIST + * + * @hide + */ + public static final String EXTRA_LOG_V_TO_U_ALLOWLIST = + "android.app.backup.extra.V_TO_U_ALLOWLIST"; + // TODO complete this list with all log messages. And document properly. public static final int LOG_EVENT_ID_FULL_BACKUP_CANCEL = 4; public static final int LOG_EVENT_ID_ILLEGAL_KEY = 5; @@ -241,6 +260,15 @@ public class BackupManagerMonitor { /** Agent error during {@link PerformUnifiedRestoreTask#restoreFinished()} @hide */ public static final int LOG_EVENT_ID_AGENT_FAILURE = 69; + /** V to U restore attempt, pkg is eligible + @hide */ + public static final int LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE = 70; + /** V to U restore attempt, pkg is not eligible + @hide */ + public static final int LOG_EVENT_ID_V_TO_U_RESTORE_PKG_NOT_ELIGIBLE = 71; + /** V to U restore attempt, allowlist and denlist are set + @hide */ + public static final int LOG_EVENT_ID_V_TO_U_RESTORE_SET_LIST = 72; /** * This method will be called each time something important happens on BackupManager. diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java index 48ea846e8d50..631772556879 100644 --- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java +++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java @@ -40,6 +40,7 @@ import java.util.Objects; public class ActivityConfigurationChangeItem extends ActivityTransactionItem { private Configuration mConfiguration; + private ActivityWindowInfo mActivityWindowInfo; @Override public void preExecute(@NonNull ClientTransactionHandler client) { @@ -55,8 +56,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem { // TODO(lifecycler): detect if PIP or multi-window mode changed and report it here. Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged"); client.handleActivityConfigurationChanged(r, mConfiguration, INVALID_DISPLAY, - // TODO(b/287582673): add ActivityWindowInfo - new ActivityWindowInfo()); + mActivityWindowInfo); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); } @@ -73,7 +73,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem { /** Obtain an instance initialized with provided params. */ @NonNull public static ActivityConfigurationChangeItem obtain(@NonNull IBinder activityToken, - @NonNull Configuration config) { + @NonNull Configuration config, @NonNull ActivityWindowInfo activityWindowInfo) { ActivityConfigurationChangeItem instance = ObjectPool.obtain(ActivityConfigurationChangeItem.class); if (instance == null) { @@ -81,6 +81,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem { } instance.setActivityToken(activityToken); instance.mConfiguration = new Configuration(config); + instance.mActivityWindowInfo = new ActivityWindowInfo(activityWindowInfo); return instance; } @@ -89,6 +90,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem { public void recycle() { super.recycle(); mConfiguration = null; + mActivityWindowInfo = null; ObjectPool.recycle(this); } @@ -100,12 +102,14 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem { public void writeToParcel(@NonNull Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeTypedObject(mConfiguration, flags); + dest.writeTypedObject(mActivityWindowInfo, flags); } /** Read from Parcel. */ private ActivityConfigurationChangeItem(@NonNull Parcel in) { super(in); mConfiguration = in.readTypedObject(Configuration.CREATOR); + mActivityWindowInfo = in.readTypedObject(ActivityWindowInfo.CREATOR); } public static final @NonNull Creator<ActivityConfigurationChangeItem> CREATOR = @@ -128,7 +132,8 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem { return false; } final ActivityConfigurationChangeItem other = (ActivityConfigurationChangeItem) o; - return Objects.equals(mConfiguration, other.mConfiguration); + return Objects.equals(mConfiguration, other.mConfiguration) + && Objects.equals(mActivityWindowInfo, other.mActivityWindowInfo); } @Override @@ -136,12 +141,14 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem { int result = 17; result = 31 * result + super.hashCode(); result = 31 * result + Objects.hashCode(mConfiguration); + result = 31 * result + Objects.hashCode(mActivityWindowInfo); return result; } @Override public String toString() { return "ActivityConfigurationChange{" + super.toString() - + ",config=" + mConfiguration + "}"; + + ",config=" + mConfiguration + + ",activityWindowInfo=" + mActivityWindowInfo + "}"; } } diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl index cec49c710d92..533fa512dae8 100644 --- a/core/java/android/content/pm/ILauncherApps.aidl +++ b/core/java/android/content/pm/ILauncherApps.aidl @@ -67,6 +67,7 @@ interface ILauncherApps { List<String> getPreInstalledSystemPackages(in UserHandle user); IntentSender getAppMarketActivityIntent(String callingPackage, String packageName, in UserHandle user); + IntentSender getPrivateSpaceSettingsIntent(); void showAppDetailsAsUser(in IApplicationThread caller, String callingPackage, String callingFeatureId, in ComponentName component, in Rect sourceBounds, in Bundle opts, in UserHandle user); diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index e437925693af..6bb9c33afb6a 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -899,6 +899,28 @@ public class LauncherApps { } /** + * Returns {@link IntentSender} which can be used to start the Private Space Settings Activity. + * + * <p> Caller should have {@link android.app.role.RoleManager.ROLE_HOME} and either of the + * permissions required.</p> + * + * @return {@link IntentSender} object which launches the Private Space Settings Activity, if + * successful, null otherwise. + * @hide + */ + @Nullable + @FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE) + @RequiresPermission(conditional = true, + anyOf = {ACCESS_HIDDEN_PROFILES_FULL, ACCESS_HIDDEN_PROFILES}) + public IntentSender getPrivateSpaceSettingsIntent() { + try { + return mService.getPrivateSpaceSettingsIntent(); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + + /** * Returns the activity info for a given intent and user handle, if it resolves. Otherwise it * returns null. * diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 240cff34ef36..9f2f74b66eb3 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4202,15 +4202,6 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and - * {@link #hasSystemFeature}: The device supports multiple concurrent IME sessions. - */ - @FlaggedApi("android.view.inputmethod.concurrent_input_methods") - @SdkConstant(SdkConstantType.FEATURE) - public static final String FEATURE_CONCURRENT_INPUT_METHODS = - "android.software.concurrent_input_methods"; - - /** - * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device supports device policy enforcement via device admins. */ @SdkConstant(SdkConstantType.FEATURE) diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java index ecffe9e5a8b2..faa2c7018d6f 100644 --- a/core/java/android/database/sqlite/SQLiteConnection.java +++ b/core/java/android/database/sqlite/SQLiteConnection.java @@ -392,8 +392,6 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen return; } - Log.i(TAG, walFile.getAbsolutePath() + " " + size + " bytes: Bigger than " - + threshold + "; truncating"); try { executeForString("PRAGMA wal_checkpoint(TRUNCATE)", null, null); mConfiguration.shouldTruncateWalFile = false; diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java index 5e523c0112b1..78c8954cfe5f 100644 --- a/core/java/android/database/sqlite/SQLiteOpenHelper.java +++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java @@ -377,8 +377,7 @@ public abstract class SQLiteOpenHelper implements AutoCloseable { if (writable) { throw ex; } - Log.e(TAG, "Couldn't open " + mName - + " for writing (will try read-only):", ex); + Log.e(TAG, "Couldn't open database for writing (will try read-only):", ex); params = params.toBuilder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build(); db = SQLiteDatabase.openDatabase(filePath, params); } @@ -425,11 +424,6 @@ public abstract class SQLiteOpenHelper implements AutoCloseable { } onOpen(db); - - if (db.isReadOnly()) { - Log.w(TAG, "Opened " + mName + " in read-only mode"); - } - mDatabase = db; return db; } finally { diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 7119730c6984..d2e4a614202f 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -753,20 +753,7 @@ public final class CameraManager { @FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP) public CameraDevice.CameraDeviceSetup getCameraDeviceSetup(@NonNull String cameraId) throws CameraAccessException { - if (cameraId == null) { - throw new IllegalArgumentException("cameraId was null"); - } - - if (CameraManagerGlobal.sCameraServiceDisabled) { - throw new CameraAccessException(CameraAccessException.CAMERA_DISABLED, - "No cameras available on device"); - } - - if (!Arrays.asList(CameraManagerGlobal.get().getCameraIdList()).contains(cameraId)) { - throw new IllegalArgumentException( - "Camera ID '" + cameraId + "' not available on device."); - } - + // isCameraDeviceSetup does all the error checking we need. if (!isCameraDeviceSetupSupported(cameraId)) { throw new UnsupportedOperationException( "CameraDeviceSetup is not supported for Camera ID: " + cameraId); @@ -819,12 +806,8 @@ public final class CameraManager { throw new IllegalArgumentException("Camera ID was null"); } - if (CameraManagerGlobal.sCameraServiceDisabled) { - throw new CameraAccessException(CameraAccessException.CAMERA_DISABLED, - "No cameras available on device"); - } - - if (!Arrays.asList(CameraManagerGlobal.get().getCameraIdList()).contains(cameraId)) { + if (CameraManagerGlobal.sCameraServiceDisabled + || !Arrays.asList(CameraManagerGlobal.get().getCameraIdList()).contains(cameraId)) { throw new IllegalArgumentException( "Camera ID '" + cameraId + "' not available on device."); } diff --git a/core/java/android/os/IVibratorManagerService.aidl b/core/java/android/os/IVibratorManagerService.aidl index 65e498e14475..8b1577cb4b1c 100644 --- a/core/java/android/os/IVibratorManagerService.aidl +++ b/core/java/android/os/IVibratorManagerService.aidl @@ -41,5 +41,5 @@ interface IVibratorManagerService { // There is no order guarantee with respect to the two-way APIs above like // vibrate/isVibrating/cancel. oneway void performHapticFeedback(int uid, int deviceId, String opPkg, int constant, - boolean always, String reason); + boolean always, String reason, boolean fromIme); } diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index 3950c25675d8..2fe115f49099 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -623,14 +623,14 @@ public final class MessageQueue { // Message is to be inserted at tail or middle of queue. Usually we don't have to // wake up the event queue unless there is a barrier at the head of the queue and // the message is the earliest asynchronous message in the queue. - // + needWake = mBlocked && p.target == null && msg.isAsynchronous(); + // For readability, we split this portion of the function into two blocks based on // whether tail tracking is enabled. This has a minor implication for the case // where tail tracking is disabled. See the comment below. if (Flags.messageQueueTailTracking()) { - needWake = mBlocked && p.target == null && msg.isAsynchronous() - && mAsyncMessageCount == 0; if (when >= mLast.when) { + needWake = needWake && mAsyncMessageCount == 0; msg.next = null; mLast.next = msg; mLast = msg; @@ -643,6 +643,9 @@ public final class MessageQueue { if (p == null || when < p.when) { break; } + if (needWake && p.isAsynchronous()) { + needWake = false; + } } if (p == null) { /* Inserting at tail of queue */ @@ -652,7 +655,6 @@ public final class MessageQueue { prev.next = msg; } } else { - needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; for (;;) { prev = p; diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java index 04c257b92e29..2a62c24a86e1 100644 --- a/core/java/android/os/SystemVibrator.java +++ b/core/java/android/os/SystemVibrator.java @@ -206,12 +206,13 @@ public class SystemVibrator extends Vibrator { } @Override - public void performHapticFeedback(int constant, boolean always, String reason) { + public void performHapticFeedback( + int constant, boolean always, String reason, boolean fromIme) { if (mVibratorManager == null) { Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager."); return; } - mVibratorManager.performHapticFeedback(constant, always, reason); + mVibratorManager.performHapticFeedback(constant, always, reason, fromIme); } @Override diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java index 8e8392302824..c80bcac2624f 100644 --- a/core/java/android/os/SystemVibratorManager.java +++ b/core/java/android/os/SystemVibratorManager.java @@ -147,14 +147,15 @@ public class SystemVibratorManager extends VibratorManager { } @Override - public void performHapticFeedback(int constant, boolean always, String reason) { + public void performHapticFeedback(int constant, boolean always, String reason, + boolean fromIme) { if (mService == null) { Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager service."); return; } try { mService.performHapticFeedback( - mUid, mContext.getDeviceId(), mPackageName, constant, always, reason); + mUid, mContext.getDeviceId(), mPackageName, constant, always, reason, fromIme); } catch (RemoteException e) { Log.w(TAG, "Failed to perform haptic feedback.", e); } @@ -244,8 +245,9 @@ public class SystemVibratorManager extends VibratorManager { } @Override - public void performHapticFeedback(int effectId, boolean always, String reason) { - SystemVibratorManager.this.performHapticFeedback(effectId, always, reason); + public void performHapticFeedback(int effectId, boolean always, String reason, + boolean fromIme) { + SystemVibratorManager.this.performHapticFeedback(effectId, always, reason, fromIme); } @Override diff --git a/core/java/android/os/VibrationAttributes.java b/core/java/android/os/VibrationAttributes.java index 46705a31f395..9df5b850188f 100644 --- a/core/java/android/os/VibrationAttributes.java +++ b/core/java/android/os/VibrationAttributes.java @@ -289,6 +289,15 @@ public final class VibrationAttributes implements Parcelable { } /** + * Return the original {@link AudioAttributes} used to create the vibration attributes. + * @hide + */ + @AudioAttributes.AttributeUsage + public int getOriginalAudioUsage() { + return mOriginalAudioUsage; + } + + /** * Return the flags. * @return a combined mask of all flags */ @@ -405,8 +414,8 @@ public final class VibrationAttributes implements Parcelable { return "VibrationAttributes{" + "mUsage=" + usageToString() + ", mAudioUsage= " + AudioAttributes.usageToString(mOriginalAudioUsage) - + ", mFlags=" + mFlags + ", mCategory=" + categoryToString() + + ", mFlags=" + mFlags + '}'; } diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java index 2fc24142acf2..4b2d4eb833ff 100644 --- a/core/java/android/os/Vibrator.java +++ b/core/java/android/os/Vibrator.java @@ -534,10 +534,12 @@ public abstract class Vibrator { * {@code false} if the vibration for the haptic feedback should respect the applicable * vibration intensity settings. * @param reason the reason for this haptic feedback. + * @param fromIme the haptic feedback is performed from an IME. * * @hide */ - public void performHapticFeedback(int constant, boolean always, String reason) { + public void performHapticFeedback(int constant, boolean always, String reason, + boolean fromIme) { Log.w(TAG, "performHapticFeedback is not supported"); } diff --git a/core/java/android/os/VibratorManager.java b/core/java/android/os/VibratorManager.java index e0b6a9fd28f0..513c4bd7ec0c 100644 --- a/core/java/android/os/VibratorManager.java +++ b/core/java/android/os/VibratorManager.java @@ -146,9 +146,11 @@ public abstract class VibratorManager { * vibration intensity settings applicable to the corresponding vibration. * {@code false} otherwise. * @param reason the reason for this haptic feedback. + * @param fromIme the haptic feedback is performed from an IME. * @hide */ - public void performHapticFeedback(int constant, boolean always, String reason) { + public void performHapticFeedback(int constant, boolean always, String reason, + boolean fromIme) { Log.w(TAG, "performHapticFeedback is not supported"); } diff --git a/core/java/android/os/vibrator/VibrationConfig.java b/core/java/android/os/vibrator/VibrationConfig.java index bcdb98282679..a14a2c7e54ca 100644 --- a/core/java/android/os/vibrator/VibrationConfig.java +++ b/core/java/android/os/vibrator/VibrationConfig.java @@ -224,17 +224,19 @@ public class VibrationConfig { @Override public String toString() { return "VibrationConfig{" - + "mHapticChannelMaxVibrationAmplitude=" + mHapticChannelMaxVibrationAmplitude + + "mIgnoreVibrationsOnWirelessCharger=" + mIgnoreVibrationsOnWirelessCharger + + ", mHapticChannelMaxVibrationAmplitude=" + mHapticChannelMaxVibrationAmplitude + ", mRampStepDurationMs=" + mRampStepDurationMs + ", mRampDownDurationMs=" + mRampDownDurationMs + + ", mRequestVibrationParamsForUsages=" + + Arrays.toString(getRequestVibrationParamsForUsagesNames()) + + ", mRequestVibrationParamsTimeoutMs=" + mRequestVibrationParamsTimeoutMs + ", mDefaultAlarmIntensity=" + mDefaultAlarmVibrationIntensity + ", mDefaultHapticFeedbackIntensity=" + mDefaultHapticFeedbackIntensity + ", mDefaultMediaIntensity=" + mDefaultMediaVibrationIntensity + ", mDefaultNotificationIntensity=" + mDefaultNotificationVibrationIntensity + ", mDefaultRingIntensity=" + mDefaultRingVibrationIntensity - + ", mRequestVibrationParamsTimeoutMs=" + mRequestVibrationParamsTimeoutMs - + ", mRequestVibrationParamsForUsages=" + Arrays.toString( - getRequestVibrationParamsForUsagesNames()) + + ", mDefaultKeyboardVibrationEnabled=" + mDefaultKeyboardVibrationEnabled + "}"; } @@ -246,9 +248,13 @@ public class VibrationConfig { public void dumpWithoutDefaultSettings(IndentingPrintWriter pw) { pw.println("VibrationConfig:"); pw.increaseIndent(); + pw.println("ignoreVibrationsOnWirelessCharger = " + mIgnoreVibrationsOnWirelessCharger); pw.println("hapticChannelMaxAmplitude = " + mHapticChannelMaxVibrationAmplitude); pw.println("rampStepDurationMs = " + mRampStepDurationMs); pw.println("rampDownDurationMs = " + mRampDownDurationMs); + pw.println("requestVibrationParamsForUsages = " + + Arrays.toString(getRequestVibrationParamsForUsagesNames())); + pw.println("requestVibrationParamsTimeoutMs = " + mRequestVibrationParamsTimeoutMs); pw.decreaseIndent(); } diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index 8495f3747573..fa9f03da6372 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -247,8 +247,6 @@ public final class PermissionManager { private final LegacyPermissionManager mLegacyPermissionManager; - private final VirtualDeviceManager mVirtualDeviceManager; - private final ArrayMap<PackageManager.OnPermissionsChangedListener, IOnPermissionsChangeListener> mPermissionListeners = new ArrayMap<>(); private PermissionUsageHelper mUsageHelper; @@ -269,7 +267,6 @@ public final class PermissionManager { mPermissionManager = IPermissionManager.Stub.asInterface(ServiceManager.getServiceOrThrow( "permissionmgr")); mLegacyPermissionManager = context.getSystemService(LegacyPermissionManager.class); - mVirtualDeviceManager = context.getSystemService(VirtualDeviceManager.class); } /** @@ -1918,14 +1915,18 @@ public final class PermissionManager { if (deviceId == Context.DEVICE_ID_DEFAULT) { persistentDeviceId = VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT; } else if (android.companion.virtual.flags.Flags.vdmPublicApis()) { - VirtualDevice virtualDevice = mVirtualDeviceManager.getVirtualDevice(deviceId); - if (virtualDevice == null) { - Slog.e(LOG_TAG, "Virtual device is not found with device Id " + deviceId); - return null; - } - persistentDeviceId = virtualDevice.getPersistentDeviceId(); - if (persistentDeviceId == null) { - Slog.e(LOG_TAG, "Cannot find persistent device Id for " + deviceId); + VirtualDeviceManager virtualDeviceManager = mContext.getSystemService( + VirtualDeviceManager.class); + if (virtualDeviceManager != null) { + VirtualDevice virtualDevice = virtualDeviceManager.getVirtualDevice(deviceId); + if (virtualDevice == null) { + Slog.e(LOG_TAG, "Virtual device is not found with device Id " + deviceId); + return null; + } + persistentDeviceId = virtualDevice.getPersistentDeviceId(); + if (persistentDeviceId == null) { + Slog.e(LOG_TAG, "Cannot find persistent device Id for " + deviceId); + } } } else { Slog.e(LOG_TAG, "vdmPublicApis flag is not enabled when device Id " + deviceId diff --git a/core/java/android/provider/E2eeContactKeysManager.java b/core/java/android/provider/E2eeContactKeysManager.java index b69441700b0a..09c93e383b5c 100644 --- a/core/java/android/provider/E2eeContactKeysManager.java +++ b/core/java/android/provider/E2eeContactKeysManager.java @@ -76,12 +76,14 @@ import java.util.Objects; public final class E2eeContactKeysManager { /** * The authority for the end-to-end encryption contact keys provider. + * * @hide */ public static final String AUTHORITY = "com.android.contactkeys.contactkeysprovider"; /** * A content:// style uri to the authority for the end-to-end encryption contact keys provider. + * * @hide */ @NonNull @@ -112,9 +114,9 @@ public final class E2eeContactKeysManager { * The inserted/updated end-to-end encryption contact key is owned by the caller app. * * @param lookupKey value that references the contact - * @param deviceId an app-specified identifier for the device + * @param deviceId an app-specified identifier for the device * @param accountId an app-specified identifier for the account - * @param keyValue the raw bytes for the key (max size is {@link #getMaxKeySizeBytes} bytes) + * @param keyValue the raw bytes for the key (max size is {@link #getMaxKeySizeBytes} bytes) */ @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) public void updateOrInsertE2eeContactKey(@NonNull String lookupKey, @@ -138,9 +140,8 @@ public final class E2eeContactKeysManager { * accountId and inferred caller package name. * * @param lookupKey the value that references the contact - * @param deviceId an app-specified identifier for the device + * @param deviceId an app-specified identifier for the device * @param accountId an app-specified identifier for the account - * * @return a {@link E2eeContactKey} object containing the contact key information, * or null if no contact key is found. */ @@ -170,7 +171,6 @@ public final class E2eeContactKeysManager { * The keys will be stripped of deviceId, timeUpdated and keyValue data. * * @param lookupKey the value that references the contact - * * @return a list of {@link E2eeContactKey} objects containing the contact key * information, or an empty list if no keys are found. */ @@ -199,7 +199,6 @@ public final class E2eeContactKeysManager { * the caller app. * * @param lookupKey the value that references the contact - * * @return a list of {@link E2eeContactKey} objects containing the end-to-end encryption * contact key information, or an empty list if no keys are found. */ @@ -227,11 +226,10 @@ public final class E2eeContactKeysManager { * Updates an end-to-end encryption contact key entry's local verification state that belongs * to the caller app. * - * @param lookupKey the value that references the contact - * @param deviceId an app-specified identifier for the device - * @param accountId an app-specified identifier for the account + * @param lookupKey the value that references the contact + * @param deviceId an app-specified identifier for the device + * @param accountId an app-specified identifier for the account * @param localVerificationState the new local verification state - * * @return true if the entry was updated, false otherwise. */ @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) @@ -257,14 +255,12 @@ public final class E2eeContactKeysManager { * Updates an end-to-end encryption contact key entry's local verification state that belongs * to the app identified by ownerPackageName. * - * @param lookupKey the value that references the contact - * @param deviceId an app-specified identifier for the device - * @param accountId an app-specified identifier for the account - * @param ownerPackageName the package name of the app that owns the key + * @param lookupKey the value that references the contact + * @param deviceId an app-specified identifier for the device + * @param accountId an app-specified identifier for the account + * @param ownerPackageName the package name of the app that owns the key * @param localVerificationState the new local verification state - * * @return true if the entry was updated, false otherwise. - * * @hide */ @SystemApi @@ -296,11 +292,10 @@ public final class E2eeContactKeysManager { * Updates an end-to-end encryption contact key entry's remote verification state that belongs * to the caller app. * - * @param lookupKey the value that references the contact - * @param deviceId an app-specified identifier for the device - * @param accountId an app-specified identifier for the account + * @param lookupKey the value that references the contact + * @param deviceId an app-specified identifier for the device + * @param accountId an app-specified identifier for the account * @param remoteVerificationState the new remote verification state - * * @return true if the entry was updated, false otherwise. */ @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) @@ -326,14 +321,12 @@ public final class E2eeContactKeysManager { * Updates an end-to-end encryption contact key entry's remote verification state that belongs * to the app identified by ownerPackageName. * - * @param lookupKey the value that references the contact - * @param deviceId an app-specified identifier for the device - * @param accountId an app-specified identifier for the account - * @param ownerPackageName the package name of the app that owns the key + * @param lookupKey the value that references the contact + * @param deviceId an app-specified identifier for the device + * @param accountId an app-specified identifier for the account + * @param ownerPackageName the package name of the app that owns the key * @param remoteVerificationState the new remote verification state - * * @return true if the entry was updated, false otherwise. - * * @hide */ @SystemApi @@ -374,9 +367,8 @@ public final class E2eeContactKeysManager { * Removes an end-to-end encryption contact key entry that belongs to the caller app. * * @param lookupKey the value that references the contact - * @param deviceId an app-specified identifier for the device + * @param deviceId an app-specified identifier for the device * @param accountId an app-specified identifier for the account - * * @return true if the entry was removed, false otherwise. */ @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) @@ -397,11 +389,10 @@ public final class E2eeContactKeysManager { /** * Inserts a new entry into the end-to-end encryption self keys table or updates one if it * already exists. - - * @param deviceId an app-specified identifier for the device - * @param accountId an app-specified identifier for the account - * @param keyValue the raw bytes for the key (max size is {@link #getMaxKeySizeBytes} bytes) * + * @param deviceId an app-specified identifier for the device + * @param accountId an app-specified identifier for the account + * @param keyValue the raw bytes for the key (max size is {@link #getMaxKeySizeBytes} bytes) * @return true if the entry was added or updated, false otherwise. */ @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) @@ -432,10 +423,9 @@ public final class E2eeContactKeysManager { /** * Updates an end-to-end encryption self key entry's remote verification state. * - * @param deviceId an app-specified identifier for the device - * @param accountId an app-specified identifier for the account + * @param deviceId an app-specified identifier for the device + * @param accountId an app-specified identifier for the account * @param remoteVerificationState the new remote verification state - * * @return true if the entry was updated, false otherwise. */ @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) @@ -459,13 +449,11 @@ public final class E2eeContactKeysManager { * Updates an end-to-end encryption self key entry's remote verification state that belongs to * the app identified by ownerPackageName. * - * @param deviceId an app-specified identifier for the device - * @param accountId an app-specified identifier for the account - * @param ownerPackageName the package name of the app that owns the key + * @param deviceId an app-specified identifier for the device + * @param accountId an app-specified identifier for the account + * @param ownerPackageName the package name of the app that owns the key * @param remoteVerificationState the new remote verification state - * * @return true if the entry was updated, false otherwise. - * * @hide */ @SystemApi @@ -502,9 +490,8 @@ public final class E2eeContactKeysManager { * Returns an end-to-end encryption self key entry given the deviceId and the inferred package * name of the caller. * - * @param deviceId an app-specified identifier for the device + * @param deviceId an app-specified identifier for the device * @param accountId an app-specified identifier for the account - * * @return a {@link E2eeSelfKey} object containing the end-to-end encryption self key * information, or null if no self key is found. */ @@ -579,9 +566,9 @@ public final class E2eeContactKeysManager { /** * Removes an end-to-end encryption self key entry given the deviceId and the inferred * package name of the caller. - * @param deviceId an app-specified identifier for the device - * @param accountId an app-specified identifier for the account * + * @param deviceId an app-specified identifier for the device + * @param accountId an app-specified identifier for the account * @return true if the entry was removed, false otherwise. */ @RequiresPermission(android.Manifest.permission.WRITE_CONTACTS) @@ -608,6 +595,7 @@ public final class E2eeContactKeysManager { /** * Possible values of verification state. + * * @hide */ @IntDef(prefix = {"VERIFICATION_STATE_"}, value = { @@ -616,7 +604,8 @@ public final class E2eeContactKeysManager { VERIFICATION_STATE_VERIFIED }) @Retention(RetentionPolicy.SOURCE) - public @interface VerificationState {} + public @interface VerificationState { + } /** * Unverified state of a contact end to end encrypted key. @@ -634,7 +623,8 @@ public final class E2eeContactKeysManager { /** @hide */ public static final class E2eeContactKeys { - private E2eeContactKeys() {} + private E2eeContactKeys() { + } /** * <p> @@ -808,34 +798,7 @@ public final class E2eeContactKeysManager { /** * A parcelable class encapsulating other users' end to end encrypted contact key. */ - public static final class E2eeContactKey implements Parcelable { - /** - * An app-specified identifier for the device for which the end-to-end encryption - * contact key can be used. - */ - private final String mDeviceId; - - /** - * An app-specified identifier for the account for which the end-to-end encryption - * contact key can be used. - * Usually a phone number. - */ - private final String mAccountId; - - /** - * Owner application package name. - */ - private final String mOwnerPackageName; - - /** - * Timestamp at which the key was updated. - */ - private final long mTimeUpdated; - - /** - * The raw bytes for the key. - */ - private final byte[] mKeyValue; + public static final class E2eeContactKey extends E2eeBaseKey implements Parcelable { /** * Describes the local verification state for the key, for instance QR-code based @@ -844,12 +807,6 @@ public final class E2eeContactKeysManager { private final int mLocalVerificationState; /** - * Describes the remote verification state for the key, for instance through a key - * transparency server. - */ - private final int mRemoteVerificationState; - - /** * The display name for the contact. */ private final String mDisplayName; @@ -873,77 +830,15 @@ public final class E2eeContactKeysManager { @VerificationState int remoteVerificationState, @Nullable String displayName, @Nullable String phoneNumber, @Nullable String emailAddress) { - this.mDeviceId = deviceId; - this.mAccountId = accountId; - this.mOwnerPackageName = ownerPackageName; - this.mTimeUpdated = timeUpdated; - this.mKeyValue = keyValue == null ? null : Arrays.copyOf(keyValue, keyValue.length); + super(deviceId, accountId, ownerPackageName, timeUpdated, keyValue, + remoteVerificationState); this.mLocalVerificationState = localVerificationState; - this.mRemoteVerificationState = remoteVerificationState; this.mDisplayName = displayName; this.mPhoneNumber = phoneNumber; this.mEmailAddress = emailAddress; } /** - * Gets the app-specified identifier for the device for which the end-to-end encryption - * contact key can be used. - * Returns null if the app doesn't have the required visibility into - * the end-to-end encryption contact key. - * - * @return An app-specified identifier for the device. - */ - @Nullable - public String getDeviceId() { - return mDeviceId; - } - - /** - * Gets the app-specified identifier for the account for which the end-to-end encryption - * contact key can be used. - * Usually a phone number. - * - * @return An app-specified identifier for the account. - */ - @NonNull - public String getAccountId() { - return mAccountId; - } - - /** - * Gets the owner application package name. - * - * @return The owner application package name. - */ - @NonNull - public String getOwnerPackageName() { - return mOwnerPackageName; - } - - /** - * Gets the timestamp at which the key was updated. Returns -1 if the app doesn't have the - * required visibility into the end-to-end encryption contact key. - * - * @return The timestamp at which the key was updated in the System.currentTimeMillis() - * base. - */ - public long getTimeUpdated() { - return mTimeUpdated; - } - - /** - * Gets the raw bytes for the key. - * Returns null if the app doesn't have the required visibility into - * the end-to-end encryption contact key. - * - * @return A copy of the raw bytes for the key. - */ - @Nullable - public byte[] getKeyValue() { - return mKeyValue == null ? null : Arrays.copyOf(mKeyValue, mKeyValue.length); - } - - /** * Gets the local verification state for the key, for instance QR-code based verification. * * @return The local verification state for the key. @@ -953,16 +848,6 @@ public final class E2eeContactKeysManager { } /** - * Gets the remote verification state for the key, for instance through a key transparency - * server. - * - * @return The remote verification state for the key. - */ - public @VerificationState int getRemoteVerificationState() { - return mRemoteVerificationState; - } - - /** * Gets the display name for the contact. * * @return The display name for the contact. @@ -1079,46 +964,126 @@ public final class E2eeContactKeysManager { /** * A parcelable class encapsulating self end to end encrypted contact key. */ - public static final class E2eeSelfKey implements Parcelable { + public static final class E2eeSelfKey extends E2eeBaseKey implements Parcelable { /** - * An app-specified identifier for the device for which the end-to-end encryption - * contact key can be used. + * @hide + */ + public E2eeSelfKey(@Nullable String deviceId, @NonNull String accountId, + @NonNull String ownerPackageName, long timeUpdated, @Nullable byte[] keyValue, + @VerificationState int remoteVerificationState) { + super(deviceId, accountId, ownerPackageName, timeUpdated, keyValue, + remoteVerificationState); + } + + @Override + public int hashCode() { + return Objects.hash(mDeviceId, mAccountId, mOwnerPackageName, mTimeUpdated, + Arrays.hashCode(mKeyValue), mRemoteVerificationState); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) return false; + if (obj == this) return true; + + if (!(obj instanceof E2eeSelfKey toCompare)) { + return false; + } + + return Objects.equals(mDeviceId, toCompare.mDeviceId) + && Objects.equals(mAccountId, toCompare.mAccountId) + && Objects.equals(mOwnerPackageName, toCompare.mOwnerPackageName) + && mTimeUpdated == toCompare.mTimeUpdated + && Arrays.equals(mKeyValue, toCompare.mKeyValue) + && mRemoteVerificationState == toCompare.mRemoteVerificationState; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString8(mDeviceId); + dest.writeString8(mAccountId); + dest.writeString8(mOwnerPackageName); + dest.writeLong(mTimeUpdated); + dest.writeInt(mKeyValue != null ? mKeyValue.length : ARRAY_IS_NULL); + if (mKeyValue != null) { + dest.writeByteArray(mKeyValue); + } + dest.writeInt(mRemoteVerificationState); + } + + @Override + public int describeContents() { + return 0; + } + + @NonNull + public static final Creator<E2eeSelfKey> CREATOR = + new Creator<>() { + @Override + public E2eeSelfKey createFromParcel(Parcel source) { + String deviceId = source.readString8(); + String accountId = source.readString8(); + String ownerPackageName = source.readString8(); + long timeUpdated = source.readLong(); + int keyValueLength = source.readInt(); + byte[] keyValue; + if (keyValueLength > 0) { + keyValue = new byte[keyValueLength]; + source.readByteArray(keyValue); + } else { + keyValue = null; + } + int remoteVerificationState = source.readInt(); + return new E2eeSelfKey(deviceId, accountId, ownerPackageName, + timeUpdated, keyValue, remoteVerificationState); + } + + @Override + public E2eeSelfKey[] newArray(int size) { + return new E2eeSelfKey[size]; + } + }; + } + + /** + * An abstract class that's extended by self and contact key classes. + * + * @hide + */ + abstract static class E2eeBaseKey { + /** + * An app-specified identifier for the device for which the key can be used. */ - private final String mDeviceId; + protected final String mDeviceId; /** - * An app-specified identifier for the account for which the end-to-end encryption - * contact key can be used. + * An app-specified identifier for the account for which the key can be used. * Usually a phone number. */ - private final String mAccountId; + protected final String mAccountId; /** * Owner application package name. */ - private final String mOwnerPackageName; + protected final String mOwnerPackageName; /** * Timestamp at which the key was updated. */ - private final long mTimeUpdated; + protected final long mTimeUpdated; /** * The raw bytes for the key. */ - private final byte[] mKeyValue; - + protected final byte[] mKeyValue; /** - * Describes the remote verification state for the key, for instance through a key - * transparency server. + * Describes the remote verification state for the end-to-end encryption key, for instance + * through a key transparency server. */ - private final int mRemoteVerificationState; + protected final int mRemoteVerificationState; - /** - * @hide - */ - public E2eeSelfKey(@Nullable String deviceId, @NonNull String accountId, + protected E2eeBaseKey(@Nullable String deviceId, @NonNull String accountId, @NonNull String ownerPackageName, long timeUpdated, @Nullable byte[] keyValue, @VerificationState int remoteVerificationState) { this.mDeviceId = deviceId; @@ -1131,9 +1096,9 @@ public final class E2eeContactKeysManager { /** * Gets the app-specified identifier for the device for which the end-to-end encryption - * contact key can be used. + * key can be used. * Returns null if the app doesn't have the required visibility into - * the end-to-end encryption contact key. + * the end-to-end encryption key. * * @return An app-specified identifier for the device. */ @@ -1144,10 +1109,10 @@ public final class E2eeContactKeysManager { /** * Gets the app-specified identifier for the account for which the end-to-end encryption - * contact key can be used. + * key can be used. * Usually a phone number. * - * @return An app-specified identifier for the device. + * @return An app-specified identifier for the account. */ @NonNull public String getAccountId() { @@ -1165,8 +1130,8 @@ public final class E2eeContactKeysManager { } /** - * Gets the timestamp at which the key was updated. Returns -1 if the app doesn't have the - * required visibility into the end-to-end encryption contact key. + * Gets the timestamp at which the end-to-end encryption key was updated. Returns -1 if + * the app doesn't have the required visibility into the key. * * @return The timestamp at which the key was updated in the System.currentTimeMillis() * base. @@ -1176,11 +1141,11 @@ public final class E2eeContactKeysManager { } /** - * Gets the raw bytes for the key. + * Gets the raw bytes for the end-to-end encryption key. * Returns null if the app doesn't have the required visibility into - * the end-to-end encryption contact key. + * the end-to-end encryption key. * - * @return A copy of the raw bytes for the key. + * @return A copy of the raw bytes for the end-to-end encryption key. */ @Nullable public byte[] getKeyValue() { @@ -1188,82 +1153,13 @@ public final class E2eeContactKeysManager { } /** - * Gets the remote verification state for the key, for instance through a key transparency - * server. + * Gets the remote verification state for the end-to-end encryption key, for instance + * through a key transparency server. * - * @return The remote verification state for the key. + * @return The remote verification state for the end-to-end encryption key. */ public @VerificationState int getRemoteVerificationState() { return mRemoteVerificationState; } - - @Override - public int hashCode() { - return Objects.hash(mDeviceId, mAccountId, mOwnerPackageName, mTimeUpdated, - Arrays.hashCode(mKeyValue), mRemoteVerificationState); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) return false; - if (obj == this) return true; - - if (!(obj instanceof E2eeSelfKey toCompare)) { - return false; - } - - return Objects.equals(mDeviceId, toCompare.mDeviceId) - && Objects.equals(mAccountId, toCompare.mAccountId) - && Objects.equals(mOwnerPackageName, toCompare.mOwnerPackageName) - && mTimeUpdated == toCompare.mTimeUpdated - && Arrays.equals(mKeyValue, toCompare.mKeyValue) - && mRemoteVerificationState == toCompare.mRemoteVerificationState; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeString8(mDeviceId); - dest.writeString8(mAccountId); - dest.writeString8(mOwnerPackageName); - dest.writeLong(mTimeUpdated); - dest.writeInt(mKeyValue != null ? mKeyValue.length : ARRAY_IS_NULL); - if (mKeyValue != null) { - dest.writeByteArray(mKeyValue); - } - dest.writeInt(mRemoteVerificationState); - } - - @Override - public int describeContents() { - return 0; - } - - @NonNull - public static final Creator<E2eeSelfKey> CREATOR = - new Creator<>() { - @Override - public E2eeSelfKey createFromParcel(Parcel source) { - String deviceId = source.readString8(); - String accountId = source.readString8(); - String ownerPackageName = source.readString8(); - long timeUpdated = source.readLong(); - int keyValueLength = source.readInt(); - byte[] keyValue; - if (keyValueLength > 0) { - keyValue = new byte[keyValueLength]; - source.readByteArray(keyValue); - } else { - keyValue = null; - } - int remoteVerificationState = source.readInt(); - return new E2eeSelfKey(deviceId, accountId, ownerPackageName, - timeUpdated, keyValue, remoteVerificationState); - } - - @Override - public E2eeSelfKey[] newArray(int size) { - return new E2eeSelfKey[size]; - } - }; } } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 20b4857bdd4d..51585af10f5d 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -471,6 +471,21 @@ public final class Settings { "android.settings.ACCESSIBILITY_COLOR_MOTION_SETTINGS"; /** + * Activity Action: Show settings to allow configuration of accessibility color contrast. + * <p> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. + * <p> + * Input: Nothing. + * <p> + * Output: Nothing. + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_ACCESSIBILITY_COLOR_CONTRAST_SETTINGS = + "android.settings.ACCESSIBILITY_COLOR_CONTRAST_SETTINGS"; + + /** * Activity Action: Show settings to allow configuration of Reduce Bright Colors. * <p> * In some cases, a matching Activity may not exist, so ensure you diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 264b53c6ee40..d8210742e331 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -174,6 +174,23 @@ public class StatusBarNotification implements Parcelable { return sbnKey; } + /** + * @return Whether the Entry is a group child by the app or system + * @hide + */ + public boolean isAppOrSystemGroupChild() { + return isGroup() && !getNotification().isGroupSummary(); + } + + + /** + * @return Whether the Entry is a group summary by the app or system + * @hide + */ + public boolean isAppOrSystemGroupSummary() { + return isGroup() && getNotification().isGroupSummary(); + } + private String groupKey() { if (overrideGroupKey != null) { return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey; diff --git a/core/java/android/tracing/flags.aconfig b/core/java/android/tracing/flags.aconfig index b1bca96c5c09..cedba85f55dc 100644 --- a/core/java/android/tracing/flags.aconfig +++ b/core/java/android/tracing/flags.aconfig @@ -8,7 +8,7 @@ flag { } flag { - name: "perfetto_protolog" + name: "perfetto_protolog_tracing" namespace: "windowing_tools" description: "Migrate protolog to Perfetto" bug: "276432490" diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index d68a47c54d4b..e126836020b4 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -148,13 +148,13 @@ interface IWindowSession { int seqId); @UnsupportedAppUsage - boolean performHapticFeedback(int effectId, boolean always); + boolean performHapticFeedback(int effectId, boolean always, boolean fromIme); /** * Called by attached views to perform predefined haptic feedback without requiring VIBRATE * permission. */ - oneway void performHapticFeedbackAsync(int effectId, boolean always); + oneway void performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme); /** * Initiate the drag operation itself diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java index f5f4fd9f7042..9099f9855eab 100644 --- a/core/java/android/view/PointerIcon.java +++ b/core/java/android/view/PointerIcon.java @@ -428,13 +428,11 @@ public final class PointerIcon implements Parcelable { private BitmapDrawable getBitmapDrawableFromVectorDrawable(Resources resources, VectorDrawable vectorDrawable) { - Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(), - vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); - // BitmapDrawables and Bitmap have a default density of DisplayMetrics.DENSITY_DEVICE, - // (which is deprecated in favor of DENSITY_DEVICE_STABLE/resources.densityDpi). In - // rare cases when device density differs from the resource density, the bitmap will - // scale as the BitmapDrawable is created. Avoid by explicitly setting density here. - bitmap.setDensity(resources.getDisplayMetrics().densityDpi); + // Ensure we pass the display metrics into the Bitmap constructor so that it is initialized + // with the correct density. + Bitmap bitmap = Bitmap.createBitmap(resources.getDisplayMetrics(), + vectorDrawable.getIntrinsicWidth(), + vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888, true /* hasAlpha */); Canvas canvas = new Canvas(bitmap); vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); vectorDrawable.draw(canvas); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 042af1f0fb15..828004b6b235 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -25,6 +25,7 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_LOW; import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL; import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE; import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED; import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_BOUNDS; import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW; @@ -10404,7 +10405,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Sets content sensitivity mode to determine whether this view displays sensitive content. + * Sets content sensitivity mode to determine whether this view displays sensitive content + * (e.g. username, password etc.). The system may improve user privacy i.e. hide content + * drawn by a sensitive view from screen sharing and recording. * * @param mode {@link #CONTENT_SENSITIVITY_AUTO}, {@link #CONTENT_SENSITIVITY_NOT_SENSITIVE} * or {@link #CONTENT_SENSITIVITY_SENSITIVE} @@ -16815,10 +16818,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mAttachInfo.mViewRootImpl.getWindowVisibleDisplayFrame(outRect); return; } - // The view is not attached to a display so we don't have a context. - // Make a best guess about the display size. - Display d = DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY); - d.getRectSize(outRect); + // TODO (b/327559224): Refine the behavior to better reflect the window environment with API + // doc updates. + final WindowManager windowManager = mContext.getSystemService(WindowManager.class); + final WindowMetrics metrics = windowManager.getMaximumWindowMetrics(); + final Insets insets = metrics.getWindowInsets().getInsets( + WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout()); + outRect.set(metrics.getBounds()); + outRect.inset(insets); + outRect.offsetTo(0, 0); } /** @@ -28371,15 +28379,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } final boolean always = (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0; + boolean fromIme = false; + if (mAttachInfo.mViewRootImpl != null) { + fromIme = mAttachInfo.mViewRootImpl.mWindowAttributes.type == TYPE_INPUT_METHOD; + } if (Flags.useVibratorHapticFeedback()) { if (!mAttachInfo.canPerformHapticFeedback()) { return false; } getSystemVibrator().performHapticFeedback( - feedbackConstant, always, "View#performHapticFeedback"); + feedbackConstant, always, "View#performHapticFeedback", fromIme); return true; } - return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant, always); + return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant, always, fromIme); } private Vibrator getSystemVibrator() { @@ -31422,7 +31434,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, interface Callbacks { void playSoundEffect(int effectId); - boolean performHapticFeedback(int effectId, boolean always); + boolean performHapticFeedback(int effectId, boolean always, boolean fromIme); } /** @@ -33770,8 +33782,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mMinusTwoFrameIntervalMillis = mMinusOneFrameIntervalMillis; mMinusOneFrameIntervalMillis = timeIntervalMillis; - if (mMinusOneFrameIntervalMillis - mMinusTwoFrameIntervalMillis >= 30 - && timeIntervalMillis < 2) { + mLastUpdateTimeMillis = currentTimeMillis; + if (mMinusTwoFrameIntervalMillis >= 30 && timeIntervalMillis < 2) { return; } if (timeIntervalMillis >= INFREQUENT_UPDATE_INTERVAL_MILLIS) { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 333cbb39d9c7..708751a25053 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -9201,18 +9201,18 @@ public final class ViewRootImpl implements ViewParent, * {@inheritDoc} */ @Override - public boolean performHapticFeedback(int effectId, boolean always) { + public boolean performHapticFeedback(int effectId, boolean always, boolean fromIme) { if ((mDisplay.getFlags() & Display.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) { return false; } try { if (USE_ASYNC_PERFORM_HAPTIC_FEEDBACK) { - mWindowSession.performHapticFeedbackAsync(effectId, always); + mWindowSession.performHapticFeedbackAsync(effectId, always, fromIme); return true; } else { // Original blocking binder call path. - return mWindowSession.performHapticFeedback(effectId, always); + return mWindowSession.performHapticFeedback(effectId, always, fromIme); } } catch (RemoteException e) { return false; diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index fbebe1e726b7..561d979f2f9d 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -528,28 +528,7 @@ public final class WindowInsets { @FlaggedApi(Flags.FLAG_CUSTOMIZABLE_WINDOW_HEADERS) @NonNull public List<Rect> getBoundingRects(@InsetsType int typeMask) { - Rect[] allRects = null; - for (int i = FIRST; i <= LAST; i = i << 1) { - if ((typeMask & i) == 0) { - continue; - } - final Rect[] rects = mTypeBoundingRectsMap[indexOf(i)]; - if (rects == null) { - continue; - } - if (allRects == null) { - allRects = rects; - } else { - final Rect[] concat = new Rect[allRects.length + rects.length]; - System.arraycopy(allRects, 0, concat, 0, allRects.length); - System.arraycopy(rects, 0, concat, allRects.length, rects.length); - allRects = concat; - } - } - if (allRects == null) { - return Collections.emptyList(); - } - return Arrays.asList(allRects); + return getBoundingRects(mTypeBoundingRectsMap, typeMask); } /** @@ -577,16 +556,28 @@ public final class WindowInsets { * * @param typeMask the insets type for which to obtain the bounding rectangles * @return the bounding rectangles + * @throws IllegalArgumentException If the caller tries to query {@link Type#ime()}. Bounding + * rects are not available if the IME isn't visible as the + * height of the IME is dynamic depending on the + * {@link EditorInfo} of the currently focused view, as well + * as the UI state of the IME. */ @FlaggedApi(Flags.FLAG_CUSTOMIZABLE_WINDOW_HEADERS) @NonNull public List<Rect> getBoundingRectsIgnoringVisibility(@InsetsType int typeMask) { + if ((typeMask & IME) != 0) { + throw new IllegalArgumentException("Unable to query the bounding rects for IME"); + } + return getBoundingRects(mTypeMaxBoundingRectsMap, typeMask); + } + + private List<Rect> getBoundingRects(Rect[][] typeBoundingRectsMap, @InsetsType int typeMask) { Rect[] allRects = null; for (int i = FIRST; i <= LAST; i = i << 1) { if ((typeMask & i) == 0) { continue; } - final Rect[] rects = mTypeMaxBoundingRectsMap[indexOf(i)]; + final Rect[] rects = typeBoundingRectsMap[indexOf(i)]; if (rects == null) { continue; } diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 2b2c50725749..22d8ed91d455 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -479,13 +479,13 @@ public class WindowlessWindowManager implements IWindowSession { } @Override - public boolean performHapticFeedback(int effectId, boolean always) { + public boolean performHapticFeedback(int effectId, boolean always, boolean fromIme) { return false; } @Override - public void performHapticFeedbackAsync(int effectId, boolean always) { - performHapticFeedback(effectId, always); + public void performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme) { + performHapticFeedback(effectId, always, fromIme); } @Override diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index fcc8344cbcd9..68940d699076 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1153,6 +1153,7 @@ public final class InputMethodManager { } final boolean startInput; synchronized (mH) { + mImeDispatcher.clear(); if (getBindSequenceLocked() != sequence) { return; } diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java index 00c482722fa3..95ecd47e3037 100644 --- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java +++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java @@ -134,6 +134,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.security.PublicKey; @@ -639,9 +640,10 @@ public class ParsingPackageUtils { pkg.setSigningDetails(SigningDetails.UNKNOWN); } - if (Flags.aslInApkAppMetadataSource() - && ArrayUtils.contains(assets.list(""), APP_METADATA_FILE_NAME)) { - pkg.setAppMetadataFileInApk(true); + if (Flags.aslInApkAppMetadataSource()) { + try (InputStream in = assets.open(APP_METADATA_FILE_NAME)) { + pkg.setAppMetadataFileInApk(true); + } catch (Exception e) { } } return input.success(pkg); diff --git a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java index d9ac5a9fe47a..30de5468001a 100644 --- a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java +++ b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java @@ -61,7 +61,7 @@ public class LegacyProtoLogImpl implements IProtoLog { private static final int PER_CHUNK_SIZE = 1024; private static final String TAG = "ProtoLog"; private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L; - static final String PROTOLOG_VERSION = "1.0.0"; + static final String PROTOLOG_VERSION = "2.0.0"; private static final int DEFAULT_PER_CHUNK_SIZE = 0; private final File mLogFile; diff --git a/core/java/com/android/internal/protolog/ProtoLogImpl.java b/core/java/com/android/internal/protolog/ProtoLogImpl.java index 78bed9478d84..896538564c2f 100644 --- a/core/java/com/android/internal/protolog/ProtoLogImpl.java +++ b/core/java/com/android/internal/protolog/ProtoLogImpl.java @@ -98,7 +98,7 @@ public class ProtoLogImpl { */ public static synchronized IProtoLog getSingleInstance() { if (sServiceInstance == null) { - if (android.tracing.Flags.perfettoProtolog()) { + if (android.tracing.Flags.perfettoProtologTracing()) { sServiceInstance = new PerfettoProtoLogImpl(sViewerConfigPath); } else { diff --git a/core/jni/LayoutlibLoader.cpp b/core/jni/LayoutlibLoader.cpp index 06d5eb305ff0..d5f17da0a072 100644 --- a/core/jni/LayoutlibLoader.cpp +++ b/core/jni/LayoutlibLoader.cpp @@ -364,7 +364,7 @@ using namespace android; // Called right before aborting by LOG_ALWAYS_FATAL. Print the pending exception. void abort_handler(const char* abort_message) { - ALOGE("Abort to abort the process..."); + ALOGE("About to abort the process..."); JNIEnv* env = NULL; if (javaVM->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { diff --git a/core/proto/android/server/vibrator/vibratormanagerservice.proto b/core/proto/android/server/vibrator/vibratormanagerservice.proto index db99e5b53875..9151958e2b94 100644 --- a/core/proto/android/server/vibrator/vibratormanagerservice.proto +++ b/core/proto/android/server/vibrator/vibratormanagerservice.proto @@ -79,11 +79,28 @@ message CombinedVibrationEffectProto { repeated int32 delays = 2; } +// Next Tag: 5 message VibrationAttributesProto { option (.android.msg_privacy).dest = DEST_AUTOMATIC; optional int32 usage = 1; optional int32 audio_usage = 2; optional int32 flags = 3; + optional int32 category = 4; +} + +// Next Tag: 4 +message VibrationParamProto { + option (.android.msg_privacy).dest = DEST_AUTOMATIC; + optional VibrationScaleParamProto scale = 1; + optional int64 create_time = 2; + optional bool is_from_request = 3; +} + +// Next Tag: 3 +message VibrationScaleParamProto { + option (.android.msg_privacy).dest = DEST_AUTOMATIC; + optional int32 types_mask = 1; + optional float scale = 2; } // Next Tag: 9 @@ -132,16 +149,19 @@ message VibrationProto { } } -// Next Tag: 25 +// Next Tag: 29 message VibratorManagerServiceDumpProto { option (.android.msg_privacy).dest = DEST_AUTOMATIC; repeated int32 vibrator_ids = 1; optional VibrationProto current_vibration = 2; optional bool is_vibrating = 3; + optional int32 is_vibrator_controller_registered = 27; optional VibrationProto current_external_vibration = 4; optional bool vibrator_under_external_control = 5; optional bool low_power_mode = 6; optional bool vibrate_on = 24; + optional bool keyboard_vibration_on = 25; + optional int32 default_vibration_amplitude = 26; optional int32 alarm_intensity = 18; optional int32 alarm_default_intensity = 19; optional int32 haptic_feedback_intensity = 7; @@ -158,5 +178,6 @@ message VibratorManagerServiceDumpProto { repeated VibrationProto previous_notification_vibrations = 14; repeated VibrationProto previous_alarm_vibrations = 15; repeated VibrationProto previous_vibrations = 16; - repeated VibrationProto previous_external_vibrations = 17; + repeated VibrationParamProto previous_vibration_params = 28; + reserved 17; // prev previous_external_vibrations }
\ No newline at end of file diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 6cd2c4e277ea..73877b8cf0c0 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Hervat werkapps?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Hervat"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Noodgeval"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Stel ’n skermslot"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Stel skermslot"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Stel ’n skermslot op dié toestel om jou privaat ruimte te gebruik"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Program is nie beskikbaar nie"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nie op die oomblik beskikbaar nie."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> is nie beskikbaar nie"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index b485b4bdd5f0..e513a07722ed 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"የሥራ መተግበሪያዎች ከቆሙበት ይቀጥሉ?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"ከቆመበት ቀጥል"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"ድንገተኛ አደጋ"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"ማያ ገጽ መቆለፊያን ያቀናብሩ"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"ማያ ገጽ መቆለፊያውን ያቀናብሩ"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"የግል ቦታዎን ለመጠቀም፣ በዚህ መሣሪያ ላይ ማያ ገጽ መቆለፊያን ያቀናብሩ"</string> <string name="app_blocked_title" msgid="7353262160455028160">"መተግበሪያ አይገኝም"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> አሁን አይገኝም።"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> አይገኝም"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index b12c1154f038..95fa5db05b64 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1990,6 +1990,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"أتريد إعادة تفعيل تطبيقات العمل؟"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"إعادة التفعيل"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"الطوارئ"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"ضبط قفل شاشة"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"ضبط قفل الشاشة"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"لاستخدام مساحتك الخاصة، يجب ضبط قفل شاشة على هذا الجهاز."</string> <string name="app_blocked_title" msgid="7353262160455028160">"التطبيق غير متاح"</string> <string name="app_blocked_message" msgid="542972921087873023">"تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> غير متاح الآن."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"تطبيق <xliff:g id="ACTIVITY">%1$s</xliff:g> غير متاح"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 01705ad6cd68..9fb71492a79e 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"কাম সম্পৰ্কীয় এপ্ আনপজ কৰিবনে?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"আনপজ কৰক"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"জৰুৰীকালীন"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"এটা স্ক্ৰীন লক ছেট কৰক"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"স্ক্ৰীন লক ছেট কৰা"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"আপোনাৰ প্ৰাইভেট স্পেচ ব্যৱহাৰ কৰিবলৈ এই ডিভাইচটোত স্ক্ৰীন লক ছেট কৰক"</string> <string name="app_blocked_title" msgid="7353262160455028160">"এপ্টো উপলব্ধ নহয়"</string> <string name="app_blocked_message" msgid="542972921087873023">"এই মুহূৰ্তত <xliff:g id="APP_NAME">%1$s</xliff:g> উপলব্ধ নহয়।"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> উপলব্ধ নহয়"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 4ed5f5eadd5b..5c3c652bb629 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"İş tətbiqi üzrə pauza bitsin?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Pauzanı bitirin"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Fövqəladə hal"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Ekran kilidi ayarlayın"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Ekran kilidi ayarlayın"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Bu cihazda ekran kilidi ayarlamaqla şəxsi sahədən istifadə edin"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Tətbiq əlçatan deyil"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> hazırda əlçatan deyil."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> əlçatan deyil"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index b31dca411edb..bda2a5542088 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Uključiti poslovne aplikacije?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Ponovo aktiviraj"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Hitan slučaj"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Podesite zaključavanje ekrana"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Podesi zaključavanje ekrana"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Da biste koristili privatni prostor, podesite zaključavanje ekrana na ovom uređaju"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – nije dostupno"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 2bd78e9080c1..38b8e4354445 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -1988,6 +1988,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Уключыць працоўныя праграмы?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Уключыць"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Экстранны выпадак"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Наладзьце блакіроўку экрана"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Наладзіць блакіроўку экрана"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Каб выкарыстоўваць прыватную прастору, на прыладзе неабходна наладзіць блакіроўку экрана"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Праграма недаступная"</string> <string name="app_blocked_message" msgid="542972921087873023">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" цяпер недаступная."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"Недаступна: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index dc1e92ca7037..77933bae46f4 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Отмяна на паузата за служ. прил.?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Отмяна на паузата"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Спешен случай"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Настройте заключване на екрана"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Заключване на екрана"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"За да ползвате частното си пространство, настройте заключване на екрана"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Приложението не е достъпно"</string> <string name="app_blocked_message" msgid="542972921087873023">"В момента няма достъп до <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> не е налице"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 5dbaad626ab9..b7c7399afbb5 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"অফিসের অ্যাপ আনপজ করতে চান?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"আনপজ করুন"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"জরুরি"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"\'স্ক্রিন লক\' সেট-আপ করুন"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"\'স্ক্রিন লক\' ফিচার সেট করুন"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"নিজের প্রাইভেট স্পেস ব্যবহার করতে এই ডিভাইসে \'স্ক্রিন লক\' সেট করুন"</string> <string name="app_blocked_title" msgid="7353262160455028160">"অ্যাপ পাওয়া যাচ্ছে না"</string> <string name="app_blocked_message" msgid="542972921087873023">"এই মুহূর্তে <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপ পাওয়া যাচ্ছে না।"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> উপলভ্য নেই"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 838a2db90408..90af6303b179 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Pokrenuti poslovne aplikacije?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Ponovo pokreni"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Hitan slučaj"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Postavite zaključavanje ekrana"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Postavite zaključavanje ekrana"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Da koristite privatni prostor, postavite zaklj. ekr. na ur."</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"Nedostupno: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index feb67c42ccf6..f20d334f4a1f 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Reactivar les apps de treball?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Reactiva"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergència"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Defineix un bloqueig de pantalla"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Defineix un bloqueig de pantalla"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Per utilitzar l\'espai privat, defineix un bloq. de pantalla"</string> <string name="app_blocked_title" msgid="7353262160455028160">"L\'aplicació no està disponible"</string> <string name="app_blocked_message" msgid="542972921087873023">"Ara mateix, <xliff:g id="APP_NAME">%1$s</xliff:g> no està disponible."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no està disponible"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 1c0529a71e59..d60389047e08 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1988,6 +1988,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Zrušit pozastavení pracovních aplikací?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Zrušit pozastavení"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Stav nouze"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Nastavení zámku obrazovky"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Nastavit zámek obrazovky"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Pokud chcete používat soukromý prostor, nastavte na tomto zařízení zámek obrazovky"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikace není k dispozici"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> v tuto chvíli není k dispozici."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> není k dispozici"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 3010dc7ec883..fc73fa71b82d 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -522,7 +522,7 @@ <string name="permdesc_vibrate" msgid="8733343234582083721">"Tillader, at appen kan administrere vibratoren."</string> <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Tillader, at appen bruger vibration."</string> <string name="permlab_callPhone" msgid="1798582257194643320">"ringe direkte op til telefonnumre"</string> - <string name="permdesc_callPhone" msgid="7892422187827695656">"Tillader, at appen kan ringe til telefonnumre uden din indgriben. Dette kan resultere i uventede debiteringer eller opkald. Vær opmærksom på, at dette ikke giver appen tilladelse til at ringe til alarmnumre. Skadelige apps kan koste dig penge ved at foretage opkald uden din bekræftelse eller ved at ringe op til operatørkoder, hvilket resulterer i, at indgående opkald automatisk viderestilles til et andet nummer."</string> + <string name="permdesc_callPhone" msgid="7892422187827695656">"Tillader, at appen kan ringe til telefonnumre uden din indgriben. Dette kan resultere i uventede opkrævninger eller opkald. Vær opmærksom på, at dette ikke giver appen tilladelse til at ringe til alarmnumre. Skadelige apps kan koste dig penge ved at foretage opkald uden din bekræftelse eller ved at ringe op til operatørkoder, hvilket resulterer i, at indgående opkald automatisk viderestilles til et andet nummer."</string> <string name="permlab_accessImsCallService" msgid="442192920714863782">"få adgang til chat-opkaldstjeneste"</string> <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Tillader, at appen kan bruge chat-tjenesten til at foretage opkald, uden du gør noget."</string> <string name="permlab_readPhoneState" msgid="8138526903259297969">"læse telefonens status og identitet"</string> @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Vil du genoptage arbejdsapps?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Genoptag"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Nødopkald"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Konfigurer en skærmlås"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Konfigurer skærmlås"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Konfigurer en skærmlås på enheden for at bruge dit private område"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgængelig"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgængelig lige nu."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> er ikke understøttet"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 803b96720a01..9faf515f9d44 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -477,9 +477,9 @@ <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Ermöglicht der App, die Anrufliste deines Android TV-Geräts zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Du solltest wissen, dass dies von schädlichen Apps genutzt werden kann, um Einträge in der Anrufliste zu löschen oder zu ändern."</string> <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Ermöglicht der App, die Anrufliste deines Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so die Einträge in der Anrufliste löschen oder sie ändern."</string> <string name="permlab_bodySensors" msgid="662918578601619569">"Zugriff auf Daten des Körpersensors, etwa Herzfrequenz, wenn in Benutzung"</string> - <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ermöglicht der App den Zugriff auf Daten des Körpersensors, etwa solche zur Herzfrequenz, zur Temperatur und zum Blutsauerstoffanteil, während die App in Benutzung ist."</string> + <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Ermöglicht der App den Zugriff auf Daten des Körpersensors, etwa solche zur Herzfrequenz, zur Temperatur und zur Sauerstoffsättigung, während die App in Benutzung ist."</string> <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Zugriff auf Daten des Körpersensors, etwa Herzfrequenz, wenn im Hintergrund"</string> - <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ermöglicht der App den Zugriff auf Daten des Körpersensors, etwa solche zur Herzfrequenz, zur Temperatur und zum Blutsauerstoffanteil, während die App im Hintergrund ist."</string> + <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Ermöglicht der App den Zugriff auf Daten des Körpersensors, etwa solche zur Herzfrequenz, zur Temperatur und zur Sauerstoffsättigung, während die App im Hintergrund ist."</string> <string name="permlab_readCalendar" msgid="6408654259475396200">"Kalendertermine und Details lesen"</string> <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Diese App kann alle auf deinem Tablet gespeicherten Kalendertermine lesen und deine Kalenderdaten teilen oder speichern."</string> <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Diese App kann alle auf deinem Android TV-Gerät gespeicherten Kalendertermine lesen und die Kalenderdaten teilen oder speichern."</string> @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Geschäftliche Apps nicht mehr pausieren?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Nicht mehr pausieren"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Notruf"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Displaysperre einrichten"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Displaysperre einrichten"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Richte zur Nutzung des privaten Bereichs auf dem Gerät die Displaysperre ein"</string> <string name="app_blocked_title" msgid="7353262160455028160">"App ist nicht verfügbar"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ist derzeit nicht verfügbar."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nicht verfügbar"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index c030d25ecada..eafaf3257113 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Αναίρ. παύσης εφαρμ. εργασιών;"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Αναίρεση παύσης"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Έκτακτη ανάγκη"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Ρυθμίστε ένα κλείδωμα οθόνης"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Ρύθμιση κλειδώματος οθόνης"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Ορίστε κλείδωμα οθόνης"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Η εφαρμογή δεν είναι διαθέσιμη"</string> <string name="app_blocked_message" msgid="542972921087873023">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν είναι διαθέσιμη αυτήν τη στιγμή."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> δεν διατίθεται"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index cecdce61f3e2..7dd6a5c668df 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Unpause work apps?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Unpause"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergency"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Set a screen lock"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Set screen lock"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"To use your private space, set a screen lock on this device"</string> <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index c3cf40402b42..58c015b5ddd9 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Unpause work apps?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Unpause"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergency"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Set a screen lock"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Set screen lock"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"To use your private space, set a screen lock on this device"</string> <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index cda0168b4600..fd0cdd520a8f 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Unpause work apps?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Unpause"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergency"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Set a screen lock"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Set screen lock"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"To use your private space, set a screen lock on this device"</string> <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index f979e270448c..3dfadb2d3771 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Unpause work apps?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Unpause"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergency"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Set a screen lock"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Set screen lock"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"To use your private space, set a screen lock on this device"</string> <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index e620c35f89ad..6c6f1c98fbaa 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Unpause work apps?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Unpause"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergency"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Set a screen lock"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Set screen lock"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"To use your private space, set a screen lock on this device"</string> <string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index da500d7d50eb..d7af663c8b98 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -109,7 +109,7 @@ <string name="serviceClassPAD" msgid="6850244583416306321">"PAD"</string> <string name="roamingText0" msgid="7793257871609854208">"Indicador de roaming activado"</string> <string name="roamingText1" msgid="5073028598334616445">"Indicador de roaming desactivado"</string> - <string name="roamingText2" msgid="2834048284153110598">"Indicador de roaming titilando"</string> + <string name="roamingText2" msgid="2834048284153110598">"Indicador de roaming parpadeando"</string> <string name="roamingText3" msgid="831690234035748988">"Fuera del vecindario"</string> <string name="roamingText4" msgid="2171252529065590728">"Fuera de construcción"</string> <string name="roamingText5" msgid="4294671587635796641">"Roaming: sistema preferido"</string> @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"¿Reanudar apps de trabajo?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Reanudar"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergencia"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Configura bloqueo de pantalla"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Conf. un bloqueo de pantalla"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Para usar esp. privado, configura un bloqueo de pantalla"</string> <string name="app_blocked_title" msgid="7353262160455028160">"La app no está disponible"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible en este momento."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no disponible"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 35cd1ebe784f..02e29c0c0e5a 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"¿Reactivar apps de trabajo?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Reactivar"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergencia"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Define un bloqueo de pantalla"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Establecer bloqueo de pantalla"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Para usar el espacio privado, define un bloqueo de pantalla"</string> <string name="app_blocked_title" msgid="7353262160455028160">"La aplicación no está disponible"</string> <string name="app_blocked_message" msgid="542972921087873023">"En estos momentos, <xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no disponible"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 24ee88437930..2fe8731d9cda 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Kas lõpetada töörakenduste peatamine?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Lõpeta peatamine"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Hädaolukord"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Seadistage ekraanilukk"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Seadistage ekraanilukk"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Seadistage oma privaatse ruumi jaoks seadmele ekraanilukk"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Rakendus ei ole saadaval"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole praegu saadaval."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ei ole saadaval"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 583f8a995d43..c28191a6d36c 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Laneko aplikazioak berraktibatu?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Berraktibatu"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Larrialdia"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Ezarri pantailaren blokeoa"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Ezarri pantailaren blokeoa"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Eremu pribatua erabiltzeko, ezarri pantailaren blokeoa gailuan"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikazioa ez dago erabilgarri"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ez dago erabilgarri une honetan."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ez dago erabilgarri"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 52de6dac5f28..d419cee4eef5 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"مکث برنامههای کاری لغو شود؟"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"لغو مکث"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"اضطراری"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"قفل صفحه تنظیم کنید"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"تنظیم قفل صفحه"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"برای استفاده از فضای خصوصی، قفل صفحه تنظیم کنید"</string> <string name="app_blocked_title" msgid="7353262160455028160">"برنامه در دسترس نیست"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> درحالحاضر در دسترس نیست."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> دردسترس نیست"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 20d4c14c8c86..11d5604bae58 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Laita työsovellukset päälle?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Laita päälle"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Hätätilanne"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Näytön lukituksen asettaminen"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Aseta näytön lukitus"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Edellyttää näytön lukitusta"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Sovellus ei ole käytettävissä"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole nyt käytettävissä."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ei käytettävissä"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index b6349427b89c..bec2f1fdcbe3 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Réactiver les applis pros?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Réactiver"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Urgence"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Config. Verrouillage d\'écran"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Config. Verrouillage d\'écran"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Config. VÉ pour util. Esp. pr."</string> <string name="app_blocked_title" msgid="7353262160455028160">"L\'application n\'est pas accessible"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas accessible pour le moment."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non accessible"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index f0ed3d6290b5..d76b1ef70716 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Réactiver les applis pro ?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Réactiver"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Urgence"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Définir verrouillage écran"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Activer verrouillage écran"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Pour utiliser votre espace privé, définissez un verrouillage de l\'écran sur cet appareil"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Application non disponible"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas disponible pour le moment."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponible"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index da791af2ec3a..6b7507a65081 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Reactivar apps do traballo?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Reactivar"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emerxencia"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Define un bloqueo de pantalla"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Define un bloqueo de pantalla"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Para usar o espazo privado, define un bloqueo de pantalla"</string> <string name="app_blocked_title" msgid="7353262160455028160">"A aplicación non está dispoñible"</string> <string name="app_blocked_message" msgid="542972921087873023">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> non está dispoñible neste momento."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non está dispoñible"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 8f6affa7a91e..9f4919dfadde 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"ઑફિસની થોભાવેલી ઍપ ચાલુ કરીએ?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"ફરી ચાલુ કરો"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"ઇમર્જન્સી"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"સ્ક્રીન લૉક સેટ કરો"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"સ્ક્રીન લૉક સેટ કરો"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"તમારી ખાનગી સ્પેસનો ઉપયોગ કરવા, આ ડિવાઇસ પર સ્ક્રીન લૉક સેટ કરો"</string> <string name="app_blocked_title" msgid="7353262160455028160">"ઍપ ઉપલબ્ધ નથી"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> હાલમાં ઉપલબ્ધ નથી."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ઉપલબ્ધ નથી"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 53b39ffed09b..6e91d3a2de8d 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"वर्क ऐप्लिकेशन चालू करने हैं?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"चालू करें"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"आपातकालीन कॉल"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"स्क्रीन लॉक सेट करें"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"स्क्रीन लॉक सेट करें"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"प्राइवेट स्पेस के लिए, इस डिवाइस पर स्क्रीन लॉक सेट करें"</string> <string name="app_blocked_title" msgid="7353262160455028160">"ऐप्लिकेशन उपलब्ध नहीं है"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> इस समय उपलब्ध नहीं है."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> उपलब्ध नहीं है"</string> @@ -2359,9 +2362,9 @@ <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"इससे साथी ऐप्लिकेशन को बैकग्राउंड में फ़ोरग्राउंड सेवाएं चलाने की अनुमति मिलती है."</string> <string name="mic_access_on_toast" msgid="2666925317663845156">"माइक्रोफ़ोन इस्तेमाल किया जा सकता है"</string> <string name="mic_access_off_toast" msgid="8111040892954242437">"माइक्रोफ़ोन को ब्लॉक किया गया है"</string> - <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"कॉन्टेंट डिसप्ले नहीं किया जा सकता"</string> + <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"स्क्रीन शेयर नहीं की जा सकती"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"कोई दूसरा केबल इस्तेमाल करके फिर से कोशिश करें"</string> - <string name="connected_display_thermally_unavailable_notification_content" msgid="9205758199439955949">"आपका डिवाइस बहुत गर्म हो गया है. जब तक यह ठंडा नहीं हो जाता, तब तक दूसरे डिवाइस पर इसकी स्क्रीन डिसप्ले नहीं की जा सकती"</string> + <string name="connected_display_thermally_unavailable_notification_content" msgid="9205758199439955949">"आपका डिवाइस बहुत गर्म हो गया है. जब तक यह ठंडा नहीं हो जाता, तब तक दूसरे डिवाइस पर इसकी स्क्रीन शेयर नहीं की जा सकती"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dual screen की सुविधा चालू है"</string> <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>, कॉन्टेंट दिखाने के लिए दोनों स्क्रीन का इस्तेमाल कर रहा है"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 9af2496fadf1..4682f8477df9 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Pokrenuti poslovne aplikacije?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Ponovno pokreni"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Hitni slučaj"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Postavite zaključavanje zaslona"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Postavi zaključavanje zaslona"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Za upotrebu privatnog prostora postavite zaključavanje zaslona na ovom uređaju"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutačno nije dostupna."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – nije dostupno"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 17f80d12a1fe..bde17d0e3052 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Feloldja a munkahelyi appokat?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Szüneteltetés feloldása"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Vészhelyzet"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Állítson be képernyőzárat"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Képernyőzár beállítása"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"A magánterület használatához állítson be képernyőzárat"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Az alkalmazás nem hozzáférhető"</string> <string name="app_blocked_message" msgid="542972921087873023">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> jelenleg nem hozzáférhető."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"A(z) <xliff:g id="ACTIVITY">%1$s</xliff:g> nem áll rendelkezése"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 51d0dedbef5a..8caacd3709c2 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Վերսկսե՞լ աշխ. հավելվածները"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Վերսկսել"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Արտակարգ իրավիճակ"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Կարգավորեք էկրանի կողպումը"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Կարգավորել էկրանի կողպումը"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Մասնավոր տարածքն օգտագործելու համար այս սարքում կարգավորեք էկրանի կողպումը"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Հավելվածը հասանելի չէ"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածն այս պահին հասանելի չէ։"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g>՝ անհասանելի է"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 29dc27307f36..2020a75dd578 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Batalkan jeda aplikasi kerja?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Batalkan jeda"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Darurat"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Setel kunci layar"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Setel kunci layar"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Untuk menggunakan ruang pribadi, setel kunci layar di perangkat ini"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikasi tidak tersedia"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia saat ini."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> tidak tersedia"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index ca702fa3e68c..f25a4b430ae7 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Ljúka hléi vinnuforrita?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Ljúka hléi"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Neyðartilvik"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Stilltu skjálás"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Stilltu skjálás"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Stilltu skjálás í tækinu til að nota leynirými"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Forrit er ekki tiltækt"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ekki tiltækt núna."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ekki í boði"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 2cb3d3d9826d..06fa36f60e0b 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Riattivare le app di lavoro?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Riattiva"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergenza"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Imposta un blocco schermo"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Imposta il blocco schermo"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Per utilizzare il tuo spazio privato, imposta un blocco schermo sul dispositivo"</string> <string name="app_blocked_title" msgid="7353262160455028160">"L\'app non è disponibile"</string> <string name="app_blocked_message" msgid="542972921087873023">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> non è al momento disponibile."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non disponibile"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 3e7c79e050de..1a609b9aa717 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"להפעיל את האפליקציות לעבודה?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"ביטול ההשהיה"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"שיחת חירום"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"הגדרת נעילת מסך"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"הגדרה של נעילת מסך"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"כדי להשתמש במרחב הפרטי יש להגדיר נעילת מסך במכשיר"</string> <string name="app_blocked_title" msgid="7353262160455028160">"האפליקציה לא זמינה"</string> <string name="app_blocked_message" msgid="542972921087873023">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא זמינה בשלב זה."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> לא זמינה"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 576a495fbdb9..688450e412fb 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"仕事用アプリの停止解除"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"停止解除"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"緊急通報"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"画面ロックの設定"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"画面ロックを設定"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"プライベート スペースには画面ロックの設定が必要です"</string> <string name="app_blocked_title" msgid="7353262160455028160">"アプリの利用不可"</string> <string name="app_blocked_message" msgid="542972921087873023">"現在 <xliff:g id="APP_NAME">%1$s</xliff:g> はご利用になれません。"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g>は利用できません"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 571ae42169c5..a1e489a0dc62 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"კვლავ გააქტიურდეს სამსახურის აპები?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"გააქტიურება"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"საგანგებო სიტუაცია"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"ეკრანის დაბლოკვის დაყენება"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"ეკრანის დაბლოკვის დაყენება"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"კერძო სივრცის გამოსაყენებლად დააყენეთ ამ მოწყობილობაზე ეკრანის დაბლოკვა"</string> <string name="app_blocked_title" msgid="7353262160455028160">"აპი მიუწვდომელია"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ამჟამად მიუწვდომელია."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> მიუწვდომელია"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 4f50140b34e6..0bef068286e1 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Жұмыс қолданбаларын қайта қосасыз ба?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Қайта қосу"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Құтқару қызметіне қоңырау шалу"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Экран құлпын орнатыңыз"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Экран құлпын орнату"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Құпия кеңістігіңізді қолдану үшін осы құрылғыда экран құлпын орнатыңыз."</string> <string name="app_blocked_title" msgid="7353262160455028160">"Қолданба қолжетімді емес"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> қазір қолжетімді емес."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> қолжетімсіз"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 8c33299df473..1f805bfd83d5 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"ឈប់ផ្អាកកម្មវិធីការងារឬ?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"ឈប់ផ្អាក"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"ពេលមានអាសន្ន"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"កំណត់ការចាក់សោអេក្រង់"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"កំណត់ការចាក់សោអេក្រង់"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"ដើម្បីប្រើលំហឯកជនរបស់អ្នក សូមកំណត់ការចាក់សោអេក្រង់នៅលើឧបករណ៍នេះ"</string> <string name="app_blocked_title" msgid="7353262160455028160">"មិនអាចប្រើកម្មវិធីនេះបានទេ"</string> <string name="app_blocked_message" msgid="542972921087873023">"មិនអាចប្រើ <xliff:g id="APP_NAME">%1$s</xliff:g> នៅពេលនេះបានទេ។"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"មិនអាចប្រើ <xliff:g id="ACTIVITY">%1$s</xliff:g> បានទេ"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index e106f1692a1f..c3fab520a924 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"ಕೆಲಸದ ಆ್ಯಪ್ ವಿರಾಮ ರದ್ದುಮಾಡಬೇಕೇ"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"ವಿರಾಮವನ್ನು ರದ್ದುಗೊಳಿಸಿ"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"ತುರ್ತು"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸೆಟ್ ಮಾಡಿ"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸೆಟ್ ಮಾಡಿ"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"ನಿಮ್ಮ ಪ್ರೈವೆಟ್ ಸ್ಪೇಸ್ ಅನ್ನು ಬಳಸಲು, ಈ ಸಾಧನದಲ್ಲಿ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸೆಟ್ ಮಾಡಿ"</string> <string name="app_blocked_title" msgid="7353262160455028160">"ಆ್ಯಪ್ ಲಭ್ಯವಿಲ್ಲ"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಇದೀಗ ಲಭ್ಯವಿಲ್ಲ."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ಲಭ್ಯವಿಲ್ಲ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index ff480c5428b4..9b7556ab607b 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"직장 앱 일시중지를 해제하시겠습니까?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"일시중지 해제"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"긴급 전화"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"화면 잠금 설정"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"화면 잠금 설정"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"비공개 스페이스를 사용하려면 이 기기에 화면 잠금을 설정하세요"</string> <string name="app_blocked_title" msgid="7353262160455028160">"앱을 사용할 수 없습니다"</string> <string name="app_blocked_message" msgid="542972921087873023">"현재 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 사용할 수 없습니다."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 사용할 수 없음"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index e44689d839cc..71c128d013ef 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Жумуш колдонмолорун иштетесизби?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Иштетүү"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Шашылыш чалуу"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Экран кулпусун коюп алыңыз"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Экран кулпусун коюу"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Жеке мейкиндикти колдонуу үчүн бул түзмөктүн экранын кулпулаңыз"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Колдонмо учурда жеткиликсиз"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> учурда жеткиликсиз"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> жеткиликсиз"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 1f6c1a1594a9..8c19e7b785b3 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"ຍົກເລີກການຢຸດຊົ່ວຄາວແອັບບ່ອນເຮັດວຽກບໍ?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"ຍົກເລີກການຢຸດຊົ່ວຄາວ"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"ສຸກເສີນ"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"ຕັ້ງການລັອກໜ້າຈໍ"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"ຕັ້ງການລັອກໜ້າຈໍ"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"ເພື່ອໃຊ້ພື້ນທີ່ສ່ວນບຸກຄົນ, ໃຫ້ຕັ້ງລັອກໜ້າຈໍຢູ່ອຸປະກອນນີ້"</string> <string name="app_blocked_title" msgid="7353262160455028160">"ແອັບບໍ່ສາມາດໃຊ້ໄດ້"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ສາມາດໃຊ້ໄດ້ໃນຕອນນີ້."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"ບໍ່ສາມາດໃຊ້ <xliff:g id="ACTIVITY">%1$s</xliff:g> ໄດ້"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 0196351bacb4..bf227d04961e 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -1988,6 +1988,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Atš. darbo progr. pristabd.?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Atšaukti pristabdymą"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Pagalbos tarnyba"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Ekrano užrako nustatymas"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Nustatykite ekrano užraktą"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Jei norite naudoti privačią erdvę, nustatykite ekrano užraktą šiame įrenginyje"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Programa nepasiekiama."</string> <string name="app_blocked_message" msgid="542972921087873023">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ šiuo metu nepasiekiama."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"„<xliff:g id="ACTIVITY">%1$s</xliff:g>“ nepasiekiama"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 46aae3f62458..a575e2a527bb 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Vai aktivizēt darba lietotnes?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Aktivizēt"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Ārkārtas zvans"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Iestatiet ekrāna bloķēšanu"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Iestatīt ekrāna bloķēšanu"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Lai izmantotu privāto telpu, iestatiet ekrāna bloķēšanu."</string> <string name="app_blocked_title" msgid="7353262160455028160">"Lietotne nav pieejama"</string> <string name="app_blocked_message" msgid="542972921087873023">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> pašlaik nav pieejama."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nav pieejams"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 1c85e473fdb9..0ff49ed82943 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Да се актив. работните аплик.?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Прекини ја паузата"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Итен случај"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Поставете заклучување екран"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Поставување заклучување екран"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"За да користите „Приватен простор“, поставете заклучување екран на уредов"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Апликацијата не е достапна"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> не е достапна во моментов."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> е недостапна"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 9917448c1e0d..2648a3855646 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"വർക്ക് ആപ്പുകൾ പുനരാരംഭിക്കണോ?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"പുനരാരംഭിക്കുക"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"അടിയന്തരം"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"സ്ക്രീൻ ലോക്ക് സജ്ജീകരിക്കൂ"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"സ്ക്രീൻ ലോക്ക് സജ്ജീകരിക്കൂ"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"സ്വകാര്യ സ്പേസിന്, ഇതിൽ സ്ക്രീൻ ലോക്ക് സജ്ജീകരിക്കൂ"</string> <string name="app_blocked_title" msgid="7353262160455028160">"ആപ്പ് ലഭ്യമല്ല"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ഇപ്പോൾ ലഭ്യമല്ല."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ലഭ്യമല്ല"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 48d926ccf4e2..c7f85246cb8f 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Ажлын аппыг үргэлжлүүлэх үү?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Үргэлжлүүлэх"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Яаралтай тусламж"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Дэлгэцийн түгжээ тохируулах"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Дэлгэцийн түгжээ тохируулах"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Хаалттай орон зайгаа ашиглах бол уг төхөөрөмжид дэлгэцийн түгжээ тохируулна уу"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Апп боломжгүй байна"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> яг одоо боломжгүй байна."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> боломжгүй байна"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 8fb6b0f01960..0c625c7399af 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"वर्क ॲप्स पुन्हा सुरू करायची?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"पुन्हा सुरू करा"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"आणीबाणी"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"स्क्रीन लॉक सेट करा"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"स्क्रीन लॉक सेट करा"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"तुमची खाजगी स्पेस वापरण्यास, या डिव्हाइसवर स्क्रीन लॉक सेट करा"</string> <string name="app_blocked_title" msgid="7353262160455028160">"ॲप उपलब्ध नाही"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> आता उपलब्ध नाही."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> उपलब्ध नाही"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 7112ed389f99..9c81b7900403 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Nyahjeda apl kerja?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Nyahjeda"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Kecemasan"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Tetapkan kunci skrin"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Tetapkan kunci skrin"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Tetapkan kunci skrin pada peranti untuk guna ruang privasi"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Apl tidak tersedia"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia sekarang."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> tidak tersedia"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 2c3e7b743afe..2d603bc4abe5 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"အလုပ်သုံးအက်ပ် ပြန်ဖွင့်မလား။"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"ပြန်ဖွင့်ရန်"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"အရေးပေါ်"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"ဖန်သားပြင်လော့ခ် သတ်မှတ်ပါ"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"ဖန်သားပြင်လော့ခ် သတ်မှတ်ရန်"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"သင့်သီးသန့်နေရာသုံးရန် ဤစက်၌ ဖန်သားပြင်လော့ခ် သတ်မှတ်ပါ"</string> <string name="app_blocked_title" msgid="7353262160455028160">"အက်ပ်ကို မရနိုင်ပါ"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ယခု မရနိုင်ပါ။"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> မရနိုင်ပါ"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 541e1b540570..2ea9d4031b71 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Vil du slå på jobbapper igjen?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Slå på"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Nød"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Angi en skjermlås"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Angi skjermlås"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"For å bruke det private området, angi en skjermlås på enheten"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgjengelig"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgjengelig for øyeblikket."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> er utilgjengelig"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 8c951e0a9dab..b7996f7938ee 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"कामसम्बन्धी एपहरू अनपज गर्ने हो?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"अनपज गर्नुहोस्"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"आपत्कालीन"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"स्क्रिन लक सेटअप गर्नुहोस्"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"स्क्रिन लक सेटअप गर्नुहोस्"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"निजी स्पेस प्रयोग गर्न यो डिभाइसमा स्क्रिन लक सेटअप गर्नुहोस्"</string> <string name="app_blocked_title" msgid="7353262160455028160">"एप उपलब्ध छैन"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> अहिले उपलब्ध छैन।"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> उपलब्ध छैन"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index bbcc2aa88440..8b60b530677f 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Werk-apps hervatten?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Hervatten"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Noodgeval"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Schermvergrendeling instellen"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Schermvergrendeling instellen"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Als je je privéruimte wilt gebruiken, stel je een schermvergrendeling op dit apparaat in"</string> <string name="app_blocked_title" msgid="7353262160455028160">"App is niet beschikbaar"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is momenteel niet beschikbaar."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> niet beschikbaar"</string> @@ -2359,7 +2362,7 @@ <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Hiermee kan een bijbehorende app services op de voorgrond vanuit de achtergrond starten."</string> <string name="mic_access_on_toast" msgid="2666925317663845156">"Microfoon is beschikbaar"</string> <string name="mic_access_off_toast" msgid="8111040892954242437">"Microfoon is geblokkeerd"</string> - <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Kan niet spiegelen naar scherm"</string> + <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Kan niet mirroren naar scherm"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Gebruik een andere kabel en probeer het opnieuw"</string> <string name="connected_display_thermally_unavailable_notification_content" msgid="9205758199439955949">"Je apparaat is te warm en kan pas naar het scherm mirroren als het is afgekoeld"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index d8bcbd10f5f5..b3e62aaf8d9b 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"ୱାର୍କ ଆପ୍ସକୁ ପୁଣି ଚାଲୁ କରିବେ?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"ଜରୁରୀକାଳୀନ"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"ଏକ ସ୍କ୍ରିନ୍ ଲକ୍ ସେଟ୍ କରନ୍ତୁ"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"ସ୍କ୍ରିନ ଲକ ସେଟ କରନ୍ତୁ"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"ଆପଣଙ୍କ ପ୍ରାଇଭେଟ ସ୍ପେସ ବ୍ୟବହାର କରିବାକୁ ଏହି ଡିଭାଇସରେ ଏକ ସ୍କ୍ରିନ ଲକ ସେଟ କରନ୍ତୁ"</string> <string name="app_blocked_title" msgid="7353262160455028160">"ଆପ୍ ଉପଲବ୍ଧ ନାହିଁ"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବର୍ତ୍ତମାନ ଉପଲବ୍ଧ ନାହିଁ।"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ଉପଲବ୍ଧ ନାହିଁ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index b762d6621d92..283813d17e9d 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਰੋਕ ਹਟਾਈਏ?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"ਰੋਕ ਹਟਾਓ"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"ਐਮਰਜੈਂਸੀ"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"ਸਕ੍ਰੀਨ ਲਾਕ ਸੈੱਟ ਕਰੋ"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"ਸਕ੍ਰੀਨ ਲਾਕ ਸੈੱਟ ਕਰੋ"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"ਆਪਣੀ ਪ੍ਰਾਈਵੇਟ ਸਪੇਸ ਵਰਤਣ ਲਈ, ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਕ੍ਰੀਨ ਲਾਕ ਸੈੱਟ ਕਰੋ"</string> <string name="app_blocked_title" msgid="7353262160455028160">"ਐਪ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਇਸ ਵੇਲੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 5f3e683d8053..5e0e67020e63 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1988,6 +1988,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Cofnąć wstrzymanie aplikacji służbowych?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Cofnij wstrzymanie"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Połączenie alarmowe"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Ustaw blokadę ekranu"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Ustaw blokadę ekranu"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Aby korzystać z przestrzeni prywatnej, ustaw na tym urządzeniu blokadę ekranu"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacja jest niedostępna"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest obecnie niedostępna."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – brak dostępu"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 9887bf6d5db6..3ccb86a918cc 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Reativar apps de trabalho?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Reativar"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergência"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Defina um bloqueio de tela"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Definir bloqueio de tela"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Para usar o espaço privado, defina um bloqueio de tela neste dispositivo"</string> <string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string> <string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 9903acb3a4ab..f26eb786865e 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Retomar apps de trabalho?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Retomar"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergência"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Defina um bloqueio de ecrã"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Definir bloqueio de ecrã"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Para usar espaço privado, defina bloqueio de ecrã no disp."</string> <string name="app_blocked_title" msgid="7353262160455028160">"A app não está disponível"</string> <string name="app_blocked_message" msgid="542972921087873023">"De momento, a app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 9887bf6d5db6..3ccb86a918cc 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Reativar apps de trabalho?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Reativar"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergência"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Defina um bloqueio de tela"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Definir bloqueio de tela"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Para usar o espaço privado, defina um bloqueio de tela neste dispositivo"</string> <string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string> <string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 73d92fbe6fd6..049ef0ce0bd9 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Reactivezi aplicații de lucru?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Reactivează"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Urgență"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Setează o blocare a ecranului"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Setează blocarea ecranului"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Ca să folosești spațiul privat, setează blocarea ecranului pe acest dispozitiv"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplicația nu este disponibilă"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu este disponibilă momentan."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nu este disponibilă"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 5b434a56f8ec..8abfb65ce224 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1988,6 +1988,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Включить рабочие приложения?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Включить"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Экстренный вызов"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Настройте блокировку экрана"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Настроить блокировку экрана"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Чтобы использовать личное пространство, настройте блокировку экрана на этом устройстве."</string> <string name="app_blocked_title" msgid="7353262160455028160">"Приложение недоступно"</string> <string name="app_blocked_message" msgid="542972921087873023">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" сейчас недоступно."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"Недоступно: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 5a271180499f..5078ee0f2d1d 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"කාර්ය යෙදුම් විරාම නොකරන්න ද?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"විරාම නොකරන්න"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"හදිසි අවස්ථාව"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"තිර අගුලක් සකසන්න"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"තිර අගුල සකසන්න"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"ඔබේ රහසිගත අවකාශය භාවිතා කිරීමට, මෙම උපාංගයේ තිර අගුලක් සකසන්න"</string> <string name="app_blocked_title" msgid="7353262160455028160">"යෙදුම ලබා ගත නොහැකිය"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> මේ දැන් ලබා ගත නොහැකිය."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> නොතිබේ"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 16a56d3156f1..a10cc4860f70 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1988,6 +1988,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Zrušiť pozast. prac. aplikácií?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Zrušiť pozastavenie"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Tiesňová linka"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Nastavte zámku obrazovky"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Nastavte zámku obrazovky"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Ak chcete používať súkromný priestor, nastavte v tomto zariadení zámku obrazovky"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikácia nie je dostupná"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> nie je teraz dostupná."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nie je k dispozícii"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 79a275ca7089..70eb803b1511 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1988,6 +1988,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Želite znova aktivirati delovne aplikacije?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Znova aktiviraj"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Nujni primer"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Nastavitev zaklepanja zaslona"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Nastavite zaklepanje zaslona"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Če želite uporabljati zasebni prostor, v tej napravi nastavite zaklepanje zaslona"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija ni na voljo"</string> <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno ni na voljo."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"»<xliff:g id="ACTIVITY">%1$s</xliff:g>« ni na voljo"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index fc2e71590b9a..61d815de10e7 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Hiq nga pauza apl. e punës?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Hiq nga pauza"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Urgjenca"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Cakto një kyçje ekrani"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Cakto kyçjen e ekranit"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Për të përdorur hapësirën private, cakto një kyçje ekrani në këtë pajisje"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacioni nuk ofrohet"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk ofrohet për momentin."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nuk ofrohet"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 4f9ce47d4a90..f0c8a209ebd7 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1987,6 +1987,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Укључити пословне апликације?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Поново активирај"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Хитан случај"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Подесите закључавање екрана"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Подеси закључавање екрана"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Да бисте користили приватни простор, подесите закључавање екрана на овом уређају"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Апликација није доступна"</string> <string name="app_blocked_message" msgid="542972921087873023">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> тренутно није доступна."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – није доступно"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 7f0a2014b5f0..79cdce4cf39b 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1489,7 +1489,7 @@ <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Tillåter att en app begär paketborttagning."</string> <string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"får be om tillstånd att ignorera batterioptimering"</string> <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Appen får be om tillstånd att ignorera batterioptimering."</string> - <string name="permlab_queryAllPackages" msgid="2928450604653281650">"fråga alla paket"</string> + <string name="permlab_queryAllPackages" msgid="2928450604653281650">"sök efter alla paket"</string> <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Tillåter att en app ser alla installerade paket."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Peka två gånger för zoomkontroll"</string> <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Det gick inte att lägga till widgeten."</string> @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Vill du återuppta jobbappar?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Återuppta"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Nödsituation"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Ställ in ett skärmlås"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Ställ in skärmlås"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Ställ in ett skärmlås för enheten om du vill använda ditt privata område."</string> <string name="app_blocked_title" msgid="7353262160455028160">"Appen är inte tillgänglig"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> är inte tillgängligt just nu."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> är inte tillgänglig"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 4d004402a6ba..4111f3a12b12 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Je, ungependa kuacha kusitisha programu za kazini?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Acha kusitisha"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Simu za dharura"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Weka mbinu ya kufunga skrini"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Weka mbinu ya kufunga skrini"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Ili utumie sehemu ya faragha, weka mbinu ya kufunga skrini kwenye kifaa hiki"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Programu haipatikani"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> haipatikani hivi sasa."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> haipatikani"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index f962728c8b30..3d339239a1f5 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"பணி ஆப்ஸை மீண்டும் இயக்கவா?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"மீண்டும் இயக்கு"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"அவசர அழைப்பு"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"திரைப் பூட்டை அமையுங்கள்"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"திரைப் பூட்டை அமை"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"ரகசிய இடத்தைப் பயன்படுத்த, சாதனத்தில் திரைப் பூட்டை அமையுங்கள்"</string> <string name="app_blocked_title" msgid="7353262160455028160">"இந்த ஆப்ஸ் இப்போது கிடைப்பதில்லை"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் இப்போது கிடைப்பதில்லை."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> இல்லை"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 30c28129e8c5..5887cd34646a 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"వర్క్ యాప్స్ అన్పాజ్ చేయాలా?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"అన్పాజ్ చేయండి"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"ఎమర్జెన్సీ"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"స్క్రీన్ లాక్ను సెట్ చేయండి"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"స్క్రీన్ లాక్ను సెట్ చేయండి"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"మీ ప్రైవేట్ స్పేస్ను ఉపయోగించడానికి, ఈ పరికరంలో స్క్రీన్ లాక్ సెట్ చేయండి"</string> <string name="app_blocked_title" msgid="7353262160455028160">"యాప్ అందుబాటులో లేదు"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రస్తుతం అందుబాటులో లేదు."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> అందుబాటులో లేదు"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index c92d6139147b..51ff5ae7e662 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"ยกเลิกการหยุดแอปงานชั่วคราวไหม"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"ยกเลิกการหยุดชั่วคราว"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"ฉุกเฉิน"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"ตั้งล็อกหน้าจอ"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"ตั้งล็อกหน้าจอ"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"หากต้องการใช้พื้นที่ส่วนตัว ให้ตั้งการล็อกหน้าจอในอุปกรณ์นี้"</string> <string name="app_blocked_title" msgid="7353262160455028160">"แอปไม่พร้อมใช้งาน"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่พร้อมใช้งานในขณะนี้"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ไม่พร้อมใช้งาน"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index d9443349d691..43ce6bcd28d3 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"I-unpause ang mga work app?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"I-unpause"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergency"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Magtakda ng lock ng screen"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Itakda ang lock ng screen"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Para gamitin ang iyong pribadong space, magtakda ng lock ng screen sa device na ito."</string> <string name="app_blocked_title" msgid="7353262160455028160">"Hindi available ang app"</string> <string name="app_blocked_message" msgid="542972921087873023">"Hindi available sa ngayon ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"Hindi available ang <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index dfae3016beb3..1df9b8d4d56a 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"İş uygulamaları devam ettirilsin mi?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Devam ettir"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Acil durum"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Ekran kilidi ayarlayın"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Ekran kilidi ayarla"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Özel alanı kullanmak için cihazda ekran kilidi ayarlayın"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Uygulama kullanılamıyor"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması şu anda kullanılamıyor."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> kullanılamıyor"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index c8fa2108e6d3..903261c18058 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1988,6 +1988,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Увімкнути робочі додатки?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Увімкнути"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Екстрений виклик"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Налаштуйте блокування екрана"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Налаштувати блокування екрана"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Для доступу до приватного простору налаштуйте блокування екрана"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Додаток недоступний"</string> <string name="app_blocked_message" msgid="542972921087873023">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> зараз недоступний."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"Недоступно: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 5ad1f1832077..bed6cf872a45 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"ورک ایپس کو غیر موقوف کریں؟"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"غیر موقوف کریں"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"ایمرجنسی"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"اسکرین لاک سیٹ کریں"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"اسکرین لاک سیٹ کریں"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"اپنی نجی اسپیس استعمال کرنے کیلئے، اس آلہ پر اسکرین لاک سیٹ کریں"</string> <string name="app_blocked_title" msgid="7353262160455028160">"ایپ دستیاب نہیں ہے"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ابھی دستیاب نہیں ہے۔"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> دستیاب نہیں ہے"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index a3ffb9c62ad5..131689883154 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Ishga oid ilovalar qaytarilsinmi?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Davom ettirish"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Favqulodda holat"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Ekran qulfini sozlash"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Ekran qulfini sozlash"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Maxfiy makon ishlatish uchun bu qurilma ekran qulfini sozlang"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Ilova ishlamayapti"</string> <string name="app_blocked_message" msgid="542972921087873023">"Ayni vaqtda <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi ishlamayapti."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> kanali ish faoliyatida emas"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 8f52be0cb10d..4587a625cb13 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Tiếp tục dùng ứng dụng công việc?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Tiếp tục dùng"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Khẩn cấp"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Đặt phương thức khoá màn hình"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Đặt phương thức khoá màn hình"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Để dùng không gian riêng tư, hãy thiết lập một phương thức khoá màn hình trên thiết bị này"</string> <string name="app_blocked_title" msgid="7353262160455028160">"Ứng dụng này không dùng được"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> hiện không dùng được."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"Không hỗ trợ <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 28f563d2f170..c58c0dee0a05 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"是否为工作应用解除暂停状态?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"解除暂停"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"紧急呼叫"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"设置一种屏锁方式"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"设置屏锁方式"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"若要使用私密空间,请在此设备上设置屏锁方式"</string> <string name="app_blocked_title" msgid="7353262160455028160">"应用无法使用"</string> <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g>目前无法使用。"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g>不可用"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 59a2abd442eb..b72569a90909 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"要取消暫停工作應用程式嗎?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"取消暫停"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"撥打緊急電話"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"設定螢幕鎖定"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"設定螢幕鎖定"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"如要使用私人空間,請在此裝置上設定螢幕鎖定功能"</string> <string name="app_blocked_title" msgid="7353262160455028160">"無法使用應用程式"</string> <string name="app_blocked_message" msgid="542972921087873023">"目前無法使用「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"無法使用「<xliff:g id="ACTIVITY">%1$s</xliff:g>」"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 2233668ba404..3c7619c9131d 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"要解除工作應用程式的暫停狀態嗎?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"取消暫停"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"撥打緊急電話"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"設定螢幕鎖定功能"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"設定螢幕鎖定功能"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"如要使用私人空間,請在這部裝置設定螢幕鎖定功能"</string> <string name="app_blocked_title" msgid="7353262160455028160">"應用程式無法使用"</string> <string name="app_blocked_message" msgid="542972921087873023">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」目前無法使用。"</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"無法存取「<xliff:g id="ACTIVITY">%1$s</xliff:g>」"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 176c3743825d..c9dd914de07a 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1986,6 +1986,9 @@ <string name="work_mode_off_title" msgid="6367463960165135829">"Susa ukumisa ama-app omsebenzi?"</string> <string name="work_mode_turn_on" msgid="5316648862401307800">"Qhubekisa"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Isimo esiphuthumayo"</string> + <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Setha ukukhiya isikrini"</string> + <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Setha ukukhiya isikrini"</string> + <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Ukuze usebenzise isikhala esigodliwe, setha ukukhiya kwesikrini kule divayisi."</string> <string name="app_blocked_title" msgid="7353262160455028160">"Uhlelo lokusebenza alutholakali"</string> <string name="app_blocked_message" msgid="542972921087873023">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayitholakali khona manje."</string> <string name="app_streaming_blocked_title" msgid="6090945835898766139">"okungatholakali <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 6134e788be82..967edde83cc9 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4101,6 +4101,13 @@ <!-- How close vibration request should be when they're aggregated for dumpsys, in ms. --> <integer name="config_previousVibrationsDumpAggregationTimeMillisLimit">1000</integer> + <!-- How long history of vibration control service should be kept for the dumpsys. --> + <integer name="config_vibratorControlServiceDumpSizeLimit">50</integer> + + <!-- How close requests to vibration control service should be when they're aggregated for + dumpsys, in ms. --> + <integer name="config_vibratorControlServiceDumpAggregationTimeMillisLimit">60000</integer> + <!-- The default vibration strength, must be between 1 and 255 inclusive. --> <integer name="config_defaultVibrationAmplitude">255</integer> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 2f5183fc1455..a1804672da73 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2083,6 +2083,8 @@ <java-symbol type="integer" name="config_recentVibrationsDumpSizeLimit" /> <java-symbol type="integer" name="config_previousVibrationsDumpSizeLimit" /> <java-symbol type="integer" name="config_previousVibrationsDumpAggregationTimeMillisLimit" /> + <java-symbol type="integer" name="config_vibratorControlServiceDumpSizeLimit" /> + <java-symbol type="integer" name="config_vibratorControlServiceDumpAggregationTimeMillisLimit" /> <java-symbol type="integer" name="config_defaultVibrationAmplitude" /> <java-symbol type="dimen" name="config_hapticChannelMaxVibrationAmplitude" /> <java-symbol type="dimen" name="config_keyboardHapticFeedbackFixedAmplitude" /> @@ -4364,6 +4366,7 @@ <java-symbol type="dimen" name="seekbar_thumb_exclusion_max_size" /> <java-symbol type="layout" name="chooser_az_label_row" /> <java-symbol type="string" name="chooser_all_apps_button_label" /> + <java-symbol type="anim" name="resolver_close_anim" /> <java-symbol type="anim" name="resolver_launch_anim" /> <java-symbol type="style" name="Animation.DeviceDefault.Activity.Resolver" /> diff --git a/core/res/res/xml/bookmarks.xml b/core/res/res/xml/bookmarks.xml index 3087aaaefd41..22d02262c388 100644 --- a/core/res/res/xml/bookmarks.xml +++ b/core/res/res/xml/bookmarks.xml @@ -33,7 +33,7 @@ --> <bookmarks> <bookmark - category="android.intent.category.APP_BROWSER" + role="android.app.role.BROWSER" shortcut="b" /> <bookmark category="android.intent.category.APP_CONTACTS" @@ -51,7 +51,7 @@ category="android.intent.category.APP_MUSIC" shortcut="p" /> <bookmark - category="android.intent.category.APP_MESSAGING" + role="android.app.role.SMS" shortcut="s" /> <bookmark category="android.intent.category.APP_CALCULATOR" diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java index fbb446b5bc23..36a64303cddd 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java @@ -22,8 +22,8 @@ import android.hardware.radio.ProgramList; import android.hardware.radio.ProgramSelector; import android.hardware.radio.RadioManager; import android.hardware.radio.UniqueProgramIdentifier; -import android.test.suitebuilder.annotation.MediumTest; +import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase; diff --git a/core/tests/ConnectivityManagerTest/Android.bp b/core/tests/ConnectivityManagerTest/Android.bp index beaf17615f1d..f17a28d22c17 100644 --- a/core/tests/ConnectivityManagerTest/Android.bp +++ b/core/tests/ConnectivityManagerTest/Android.bp @@ -27,7 +27,10 @@ android_test { "android.test.runner", "android.test.base", ], - static_libs: ["junit"], + static_libs: [ + "junit", + "androidx.test.rules", + ], // Include all test java files. srcs: ["src/**/*.java"], platform_apis: true, diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java index 2d291ffc70ed..32da1d848183 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java @@ -22,7 +22,8 @@ import android.net.NetworkInfo.State; import android.net.wifi.WifiManager; import android.os.SystemClock; import android.provider.Settings; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import com.android.connectivitymanagertest.ConnectivityManagerTestBase; import com.android.connectivitymanagertest.ConnectivityManagerTestRunner; diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java index 23135dd15690..9443766e567b 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java @@ -22,9 +22,9 @@ import android.net.wifi.WifiConfiguration.GroupCipher; import android.net.wifi.WifiConfiguration.PairwiseCipher; import android.net.wifi.WifiConfiguration.Protocol; import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; import android.os.Bundle; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import com.android.connectivitymanagertest.ConnectivityManagerTestBase; import com.android.connectivitymanagertest.WifiAssociationTestRunner; diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java index b37daa3371f9..9c61647db0c2 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java @@ -18,7 +18,8 @@ package com.android.connectivitymanagertest.functional; import android.net.wifi.WifiConfiguration; import android.os.SystemClock; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; import com.android.connectivitymanagertest.ConnectivityManagerTestBase; import com.android.connectivitymanagertest.WifiConfigurationHelper; diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java index 4b82c3debcf5..993b9efdaf06 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java @@ -29,9 +29,10 @@ import android.os.Environment; import android.os.PowerManager; import android.os.SystemClock; import android.provider.Settings; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; +import androidx.test.filters.LargeTest; + import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner; import com.android.connectivitymanagertest.ConnectivityManagerTestBase; import com.android.connectivitymanagertest.WifiConfigurationHelper; diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java index 5c2f388a5dc4..9dc3fced829c 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java @@ -17,19 +17,19 @@ package com.android.connectivitymanagertest.unit; import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.Context; import android.net.NetworkInfo; -import android.net.wifi.WifiManager; +import android.net.wifi.SupplicantState; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WifiConfiguration.Status; -import android.net.wifi.SupplicantState; - -import android.test.suitebuilder.annotation.LargeTest; +import android.net.wifi.WifiManager; import android.test.AndroidTestCase; +import androidx.test.filters.LargeTest; + import java.util.List; /** diff --git a/core/tests/bandwidthtests/Android.bp b/core/tests/bandwidthtests/Android.bp index d0b42f783bef..8645b39da5a8 100644 --- a/core/tests/bandwidthtests/Android.bp +++ b/core/tests/bandwidthtests/Android.bp @@ -31,6 +31,9 @@ android_test { "org.apache.http.legacy", "android.test.base", ], - static_libs: ["junit"], + static_libs: [ + "junit", + "androidx.test.rules", + ], platform_apis: true, } diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java index 4b42f4ae9888..b2c85a243836 100644 --- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java +++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java @@ -30,9 +30,10 @@ import android.os.Process; import android.os.SystemClock; import android.telephony.TelephonyManager; import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; +import androidx.test.filters.LargeTest; + import com.android.bandwidthtest.util.BandwidthTestUtil; import com.android.bandwidthtest.util.ConnectionUtil; diff --git a/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java b/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java index aaa199d4c814..e8b295bd5fdb 100644 --- a/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java +++ b/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java @@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; import android.hardware.usb.UsbDevice; import android.platform.test.annotations.RequiresFlagsEnabled; @@ -58,6 +59,7 @@ public class BrailleDisplayControllerImplTest { @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + private AccessibilityService mAccessibilityService; private BrailleDisplayController mBrailleDisplayController; @Mock @@ -76,12 +78,13 @@ public class BrailleDisplayControllerImplTest { @Before public void test() { MockitoAnnotations.initMocks(this); - AccessibilityService accessibilityService = spy(new TestAccessibilityService()); - doReturn((Executor) Runnable::run).when(accessibilityService).getMainExecutor(); - doReturn(TEST_SERVICE_CONNECTION_ID).when(accessibilityService).getConnectionId(); + mAccessibilityService = spy(new TestAccessibilityService()); + doReturn((Executor) Runnable::run).when(mAccessibilityService).getMainExecutor(); + doReturn(TEST_SERVICE_CONNECTION_ID).when(mAccessibilityService).getConnectionId(); AccessibilityInteractionClient.addConnection(TEST_SERVICE_CONNECTION_ID, mAccessibilityServiceConnection, /*initializeCache=*/false); - mBrailleDisplayController = accessibilityService.getBrailleDisplayController(); + mBrailleDisplayController = new BrailleDisplayControllerImpl( + mAccessibilityService, new Object(), /*isHidrawSupported=*/true); } // Automated CTS tests only use the BluetoothDevice version of BrailleDisplayController#connect @@ -104,4 +107,17 @@ public class BrailleDisplayControllerImplTest { assertThrows(IllegalStateException.class, () -> mBrailleDisplayController.connect(usbDevice, mBrailleDisplayCallback)); } + + @Test + public void connect_HidrawNotSupported_callsOnConnectionFailed() { + BrailleDisplayController controller = new BrailleDisplayControllerImpl( + mAccessibilityService, new Object(), /*isHidrawSupported=*/false); + UsbDevice usbDevice = Mockito.mock(UsbDevice.class); + + controller.connect(usbDevice, mBrailleDisplayCallback); + + verify(mBrailleDisplayCallback).onConnectionFailed( + BrailleDisplayController.BrailleDisplayCallback.FLAG_ERROR_CANNOT_ACCESS); + verifyZeroInteractions(mAccessibilityServiceConnection); + } } diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java index 64c17bdfa731..d115bf306b45 100644 --- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java +++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java @@ -247,7 +247,7 @@ public class ActivityThreadTest { newConfig.smallestScreenWidthDp++; transaction = newTransaction(activityThread); transaction.addTransactionItem(ActivityConfigurationChangeItem.obtain( - activity.getActivityToken(), newConfig)); + activity.getActivityToken(), newConfig, new ActivityWindowInfo())); appThread.scheduleTransaction(transaction); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); @@ -455,11 +455,11 @@ public class ActivityThreadTest { transaction = newTransaction(activityThread); transaction.addTransactionItem(ActivityConfigurationChangeItem.obtain( - activity.getActivityToken(), activityConfigLandscape)); + activity.getActivityToken(), activityConfigLandscape, new ActivityWindowInfo())); transaction.addTransactionItem(ConfigurationChangeItem.obtain( processConfigPortrait, DEVICE_ID_INVALID)); transaction.addTransactionItem(ActivityConfigurationChangeItem.obtain( - activity.getActivityToken(), activityConfigPortrait)); + activity.getActivityToken(), activityConfigPortrait, new ActivityWindowInfo())); appThread.scheduleTransaction(transaction); activity.mTestLatch.await(TIMEOUT_SEC, TimeUnit.SECONDS); @@ -883,7 +883,7 @@ public class ActivityThreadTest { private static ClientTransaction newActivityConfigTransaction(@NonNull Activity activity, @NonNull Configuration config) { final ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem.obtain( - activity.getActivityToken(), config); + activity.getActivityToken(), config, new ActivityWindowInfo()); final ClientTransaction transaction = newTransaction(activity); transaction.addTransactionItem(item); diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java index 85a1b4ee3ebd..4db5d1bf4f67 100644 --- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java +++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionItemTest.java @@ -107,7 +107,7 @@ public class ClientTransactionItemTest { @Test public void testActivityConfigurationChangeItem_getContextToUpdate() { final ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem - .obtain(mActivityToken, mConfiguration); + .obtain(mActivityToken, mConfiguration, new ActivityWindowInfo()); final Context context = item.getContextToUpdate(mHandler); assertEquals(mActivity, context); diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java index 906558f7603b..31ea6759c710 100644 --- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java @@ -82,7 +82,8 @@ public class ObjectPoolTests { @Test public void testRecycleActivityConfigurationChangeItem() { - testRecycle(() -> ActivityConfigurationChangeItem.obtain(mActivityToken, config())); + testRecycle(() -> ActivityConfigurationChangeItem.obtain(mActivityToken, config(), + new ActivityWindowInfo())); } @Test diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java index dbb090fe795b..75347bf2c8de 100644 --- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java @@ -95,8 +95,11 @@ public class TransactionParcelTests { @Test public void testActivityConfigChange() { // Write to parcel + final ActivityWindowInfo activityWindowInfo = new ActivityWindowInfo(); + activityWindowInfo.set(true /* isEmbedded */, new Rect(0, 0, 500, 1000), + new Rect(0, 0, 500, 500)); ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem.obtain( - mActivityToken, config()); + mActivityToken, config(), activityWindowInfo); writeAndPrepareForReading(item); // Read from parcel and assert @@ -300,7 +303,7 @@ public class TransactionParcelTests { // Write to parcel NewIntentItem callback1 = NewIntentItem.obtain(mActivityToken, new ArrayList<>(), true); ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain( - mActivityToken, config()); + mActivityToken, config(), new ActivityWindowInfo()); StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken, 78 /* configChanges */); @@ -327,7 +330,7 @@ public class TransactionParcelTests { // Write to parcel NewIntentItem callback1 = NewIntentItem.obtain(mActivityToken, new ArrayList<>(), true); ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain( - mActivityToken, config()); + mActivityToken, config(), new ActivityWindowInfo()); ClientTransaction transaction = ClientTransaction.obtain(null /* client */); transaction.addTransactionItem(callback1); diff --git a/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java b/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java index 9dce899aa92d..da40f2adec6f 100644 --- a/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java +++ b/core/tests/coretests/src/android/app/usage/ParcelableUsageEventListTest.java @@ -29,8 +29,8 @@ import android.app.usage.UsageEvents.Event; import android.content.res.Configuration; import android.os.Parcel; import android.os.PersistableBundle; -import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; diff --git a/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java b/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java index fae714842b9b..3618543e3ae3 100644 --- a/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java +++ b/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java @@ -18,8 +18,7 @@ package android.app.usage; import static junit.framework.Assert.fail; -import android.test.suitebuilder.annotation.SmallTest; - +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.ArrayUtils; diff --git a/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java b/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java index da3a465ade7e..b61104d6f389 100644 --- a/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java +++ b/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java @@ -27,7 +27,8 @@ import android.hardware.biometrics.face.IFace; import android.hardware.biometrics.face.SensorProps; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Rule; diff --git a/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java b/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java index 613089c8777d..f058c160373c 100644 --- a/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java +++ b/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java @@ -27,7 +27,8 @@ import android.hardware.biometrics.fingerprint.IFingerprint; import android.hardware.biometrics.fingerprint.SensorProps; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Rule; @@ -38,7 +39,6 @@ import org.mockito.junit.MockitoRule; import java.util.function.Function; - @Presubmit @SmallTest public class FingerprintSensorConfigurationsTest { diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java index 7c58de67ded6..1a242eff73b1 100644 --- a/core/tests/coretests/src/android/view/ViewRootImplTest.java +++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java @@ -451,7 +451,7 @@ public class ViewRootImplTest { ViewRootImpl viewRootImpl = new ViewRootImpl(sContext, display); boolean result = viewRootImpl.performHapticFeedback( - HapticFeedbackConstants.CONTEXT_CLICK, true); + HapticFeedbackConstants.CONTEXT_CLICK, true, false /* fromIme */); assertThat(result).isFalse(); } diff --git a/core/tests/featureflagtests/src/android/util/FeatureFlagUtilsTest.java b/core/tests/featureflagtests/src/android/util/FeatureFlagUtilsTest.java index 316042874201..cb8b0db07249 100644 --- a/core/tests/featureflagtests/src/android/util/FeatureFlagUtilsTest.java +++ b/core/tests/featureflagtests/src/android/util/FeatureFlagUtilsTest.java @@ -24,9 +24,9 @@ import static junit.framework.Assert.assertTrue; import android.content.Context; import android.os.SystemProperties; import android.provider.Settings; -import android.test.suitebuilder.annotation.SmallTest; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; diff --git a/core/tests/systemproperties/Android.bp b/core/tests/systemproperties/Android.bp index 21aa3c44044b..ed52cccfb9b9 100644 --- a/core/tests/systemproperties/Android.bp +++ b/core/tests/systemproperties/Android.bp @@ -14,9 +14,9 @@ android_test { dxflags: ["--core-library"], static_libs: [ "android-common", - "frameworks-core-util-lib", "androidx.test.rules", "androidx.test.ext.junit", + "frameworks-core-util-lib", "ravenwood-junit", ], libs: [ diff --git a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java index ea65de088c07..d98120f535d8 100644 --- a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java +++ b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java @@ -24,7 +24,8 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.platform.test.ravenwood.RavenwoodRule; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import org.junit.Rule; import org.junit.Test; diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 4edfb0943ad5..051e73f4d4c8 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -584,6 +584,8 @@ applications that come with the platform <permission name="android.permission.DOMAIN_VERIFICATION_AGENT"/> <!-- Permission required for CTS test CtsInputTestCases --> <permission name="android.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW" /> + <!-- Permission required for CTS test - PackageManagerShellCommandInstallTest --> + <permission name="android.permission.EMERGENCY_INSTALL_PACKAGES" /> </privapp-permissions> <privapp-permissions package="com.android.statementservice"> diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index e8c7a53ddcff..0231d3abd19e 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -1,5 +1,5 @@ { - "version": "1.0.0", + "version": "2.0.0", "messages": { "7286191062634870297": { "message": "Binding proc %s with config %s", diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java index 08b7bb89d10c..39cfacec8447 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitContainer.java @@ -201,7 +201,7 @@ class SplitContainer { return null; } return new SplitInfo(primaryActivityStack, secondaryActivityStack, - mCurrentSplitAttributes, mToken); + mCurrentSplitAttributes, SplitInfo.Token.createFromBinder(mToken)); } static boolean shouldFinishPrimaryWithSecondary(@NonNull SplitRule splitRule) { diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index ae3a854baf9f..038d0081ead8 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -35,6 +35,7 @@ import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_INFO_CHA import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED; import static android.window.TaskFragmentTransaction.TYPE_TASK_FRAGMENT_VANISHED; +import static androidx.window.extensions.embedding.ActivityEmbeddingOptionsProperties.KEY_ACTIVITY_STACK_TOKEN; import static androidx.window.extensions.embedding.ActivityEmbeddingOptionsProperties.KEY_OVERLAY_TAG; import static androidx.window.extensions.embedding.SplitContainer.getFinishPrimaryWithSecondaryBehavior; import static androidx.window.extensions.embedding.SplitContainer.getFinishSecondaryWithPrimaryBehavior; @@ -112,10 +113,6 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen static final boolean ENABLE_SHELL_TRANSITIONS = SystemProperties.getBoolean("persist.wm.debug.shell_transit", true); - // TODO(b/295993745): remove after prebuilt library is updated. - private static final String KEY_ACTIVITY_STACK_TOKEN = - "androidx.window.extensions.embedding.ActivityStackToken"; - @VisibleForTesting @GuardedBy("mLock") final SplitPresenter mPresenter; @@ -554,7 +551,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen } @Override - public void updateActivityStackAttributes(@NonNull IBinder activityStackToken, + public void updateActivityStackAttributes(@NonNull ActivityStack.Token activityStackToken, @NonNull ActivityStackAttributes attributes) { if (!Flags.activityEmbeddingOverlayPresentationFlag()) { return; @@ -563,7 +560,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen Objects.requireNonNull(attributes); synchronized (mLock) { - final TaskFragmentContainer container = getContainer(activityStackToken); + final TaskFragmentContainer container = getContainer(activityStackToken.getRawToken()); if (container == null) { Log.w(TAG, "Cannot find TaskFragmentContainer for token:" + activityStackToken); return; @@ -583,13 +580,14 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @Override @Nullable - public ParentContainerInfo getParentContainerInfo(@NonNull IBinder activityStackToken) { + public ParentContainerInfo getParentContainerInfo( + @NonNull ActivityStack.Token activityStackToken) { if (!Flags.activityEmbeddingOverlayPresentationFlag()) { return null; } Objects.requireNonNull(activityStackToken); synchronized (mLock) { - final TaskFragmentContainer container = getContainer(activityStackToken); + final TaskFragmentContainer container = getContainer(activityStackToken.getRawToken()); if (container == null) { return null; } @@ -601,7 +599,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @Override @Nullable - public IBinder getActivityStackToken(@NonNull String tag) { + public ActivityStack.Token getActivityStackToken(@NonNull String tag) { if (!Flags.activityEmbeddingOverlayPresentationFlag()) { return null; } @@ -612,7 +610,8 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen if (taskFragmentContainer == null) { return null; } - return taskFragmentContainer.getTaskFragmentToken(); + return ActivityStack.Token.createFromBinder(taskFragmentContainer + .getTaskFragmentToken()); } } @@ -2761,8 +2760,10 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // TODO(b/232042367): Consolidate the activity create handling so that we can handle // cross-process the same as normal. - IBinder activityStackToken = options.getBinder(KEY_ACTIVITY_STACK_TOKEN); - if (activityStackToken != null) { + final Bundle bundle = options.getBundle(KEY_ACTIVITY_STACK_TOKEN); + if (bundle != null) { + final IBinder activityStackToken = ActivityStack.Token.readFromBundle(bundle) + .getRawToken(); // Put activityStack token to #KEY_LAUNCH_TASK_FRAGMENT_TOKEN to launch the activity // into the taskFragment associated with the token. options.putBinder(KEY_LAUNCH_TASK_FRAGMENT_TOKEN, activityStackToken); diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java index 6fe8e50f105f..a6bf99d4add5 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java @@ -367,7 +367,8 @@ class TaskFragmentContainer { if (activities == null) { return null; } - return new ActivityStack(activities, isEmpty(), mToken, mOverlayTag); + return new ActivityStack(activities, isEmpty(), + ActivityStack.Token.createFromBinder(mToken), mOverlayTag); } /** Adds the activity that will be reparented to this container. */ diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java index 34d43ad56bb4..28fbadbebe7f 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java @@ -399,7 +399,8 @@ public class OverlayPresentationTest { new ActivityStackAttributes.Builder().build())); assertThrows(NullPointerException.class, () -> - mSplitController.updateActivityStackAttributes(new Binder(), null)); + mSplitController.updateActivityStackAttributes( + ActivityStack.Token.createFromBinder(new Binder()), null)); verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any(), any()); } @@ -408,7 +409,8 @@ public class OverlayPresentationTest { public void testUpdateActivityStackAttributes_nullContainer_earlyReturn() { final TaskFragmentContainer container = mSplitController.newContainer(mActivity, mActivity.getTaskId()); - mSplitController.updateActivityStackAttributes(container.getTaskFragmentToken(), + mSplitController.updateActivityStackAttributes( + ActivityStack.Token.createFromBinder(container.getTaskFragmentToken()), new ActivityStackAttributes.Builder().build()); verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any(), any()); @@ -418,7 +420,8 @@ public class OverlayPresentationTest { public void testUpdateActivityStackAttributes_notOverlay_earlyReturn() { final TaskFragmentContainer container = createMockTaskFragmentContainer(mActivity); - mSplitController.updateActivityStackAttributes(container.getTaskFragmentToken(), + mSplitController.updateActivityStackAttributes( + ActivityStack.Token.createFromBinder(container.getTaskFragmentToken()), new ActivityStackAttributes.Builder().build()); verify(mSplitPresenter, never()).applyActivityStackAttributes(any(), any(), any(), any()); @@ -431,7 +434,8 @@ public class OverlayPresentationTest { final ActivityStackAttributes attrs = new ActivityStackAttributes.Builder().build(); final IBinder token = container.getTaskFragmentToken(); - mSplitController.updateActivityStackAttributes(token, attrs); + mSplitController.updateActivityStackAttributes(ActivityStack.Token.createFromBinder(token), + attrs); verify(mSplitPresenter).applyActivityStackAttributes(any(), eq(container), eq(attrs), any()); diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java index b60943a60076..00f8b5925d66 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java @@ -1437,7 +1437,7 @@ public class SplitControllerTest { @Test public void testUpdateSplitAttributes_nullParams_throwException() { assertThrows(NullPointerException.class, - () -> mSplitController.updateSplitAttributes(null, SPLIT_ATTRIBUTES)); + () -> mSplitController.updateSplitAttributes((IBinder) null, SPLIT_ATTRIBUTES)); final SplitContainer splitContainer = mock(SplitContainer.class); final IBinder token = new Binder(); diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp index 0ecf1f8f1feb..8829d1b9e0e1 100644 --- a/libs/WindowManager/Shell/Android.bp +++ b/libs/WindowManager/Shell/Android.bp @@ -212,76 +212,3 @@ android_library { plugins: ["dagger2-compiler"], use_resource_processor: true, } - -android_app { - name: "WindowManagerShellRobolectric", - platform_apis: true, - static_libs: [ - "WindowManager-Shell", - ], - manifest: "multivalentTests/AndroidManifestRobolectric.xml", - use_resource_processor: true, -} - -android_robolectric_test { - name: "WMShellRobolectricTests", - instrumentation_for: "WindowManagerShellRobolectric", - upstream: true, - java_resource_dirs: [ - "multivalentTests/robolectric/config", - ], - srcs: [ - "multivalentTests/src/**/*.kt", - ], - // TODO(b/323188766): Include BubbleStackViewTest once the robolectric issue is fixed. - exclude_srcs: ["multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt"], - static_libs: [ - "junit", - "androidx.test.runner", - "androidx.test.rules", - "androidx.test.ext.junit", - "mockito-robolectric-prebuilt", - "mockito-kotlin2", - "truth", - ], -} - -android_test { - name: "WMShellMultivalentTestsOnDevice", - srcs: [ - "multivalentTests/src/**/*.kt", - ], - static_libs: [ - "WindowManager-Shell", - "junit", - "androidx.test.runner", - "androidx.test.rules", - "androidx.test.ext.junit", - "frameworks-base-testutils", - "mockito-kotlin2", - "mockito-target-extended-minus-junit4", - "truth", - "platform-test-annotations", - "platform-test-rules", - ], - libs: [ - "android.test.base", - "android.test.runner", - ], - jni_libs: [ - "libdexmakerjvmtiagent", - "libstaticjvmtiagent", - ], - kotlincflags: ["-Xjvm-default=all"], - optimize: { - enabled: false, - }, - test_suites: ["device-tests"], - platform_apis: true, - certificate: "platform", - aaptflags: [ - "--extra-packages", - "com.android.wm.shell", - ], - manifest: "multivalentTests/AndroidManifest.xml", -} diff --git a/libs/WindowManager/Shell/multivalentTests/Android.bp b/libs/WindowManager/Shell/multivalentTests/Android.bp new file mode 100644 index 000000000000..1686d0d54dc4 --- /dev/null +++ b/libs/WindowManager/Shell/multivalentTests/Android.bp @@ -0,0 +1,97 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], + default_team: "trendy_team_multitasking_windowing", +} + +android_app { + name: "WindowManagerShellRobolectric", + platform_apis: true, + static_libs: [ + "WindowManager-Shell", + ], + manifest: "AndroidManifestRobolectric.xml", + use_resource_processor: true, +} + +android_robolectric_test { + name: "WMShellRobolectricTests", + instrumentation_for: "WindowManagerShellRobolectric", + upstream: true, + java_resource_dirs: [ + "robolectric/config", + ], + srcs: [ + "src/**/*.kt", + ], + // TODO(b/323188766): Include BubbleStackViewTest once the robolectric issue is fixed. + exclude_srcs: ["src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt"], + static_libs: [ + "junit", + "androidx.test.runner", + "androidx.test.rules", + "androidx.test.ext.junit", + "mockito-robolectric-prebuilt", + "mockito-kotlin2", + "truth", + ], + auto_gen_config: true, +} + +android_test { + name: "WMShellMultivalentTestsOnDevice", + srcs: [ + "src/**/*.kt", + ], + static_libs: [ + "WindowManager-Shell", + "junit", + "androidx.test.runner", + "androidx.test.rules", + "androidx.test.ext.junit", + "frameworks-base-testutils", + "mockito-kotlin2", + "mockito-target-extended-minus-junit4", + "truth", + "platform-test-annotations", + "platform-test-rules", + ], + libs: [ + "android.test.base", + "android.test.runner", + ], + jni_libs: [ + "libdexmakerjvmtiagent", + "libstaticjvmtiagent", + ], + kotlincflags: ["-Xjvm-default=all"], + optimize: { + enabled: false, + }, + test_suites: ["device-tests"], + platform_apis: true, + certificate: "platform", + aaptflags: [ + "--extra-packages", + "com.android.wm.shell", + ], + manifest: "AndroidManifest.xml", +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java index 93893e33d2d5..ef9bf008b294 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java @@ -51,7 +51,7 @@ public class ProtoLogController implements ShellCommandHandler.ShellCommandActio final ILogger logger = pw::println; switch (args[0]) { case "status": { - if (android.tracing.Flags.perfettoProtolog()) { + if (android.tracing.Flags.perfettoProtologTracing()) { pw.println("(Deprecated) legacy command. Use Perfetto commands instead."); return false; } @@ -59,7 +59,7 @@ public class ProtoLogController implements ShellCommandHandler.ShellCommandActio return true; } case "start": { - if (android.tracing.Flags.perfettoProtolog()) { + if (android.tracing.Flags.perfettoProtologTracing()) { pw.println("(Deprecated) legacy command. Use Perfetto commands instead."); return false; } @@ -67,7 +67,7 @@ public class ProtoLogController implements ShellCommandHandler.ShellCommandActio return true; } case "stop": { - if (android.tracing.Flags.perfettoProtolog()) { + if (android.tracing.Flags.perfettoProtologTracing()) { pw.println("(Deprecated) legacy command. Use Perfetto commands instead."); return false; } @@ -101,7 +101,7 @@ public class ProtoLogController implements ShellCommandHandler.ShellCommandActio return mShellProtoLog.stopLoggingToLogcat(groups, logger) == 0; } case "save-for-bugreport": { - if (android.tracing.Flags.perfettoProtolog()) { + if (android.tracing.Flags.perfettoProtologTracing()) { pw.println("(Deprecated) legacy command"); return false; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java index 194eb47c9360..dae62ac74483 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitDecorManager.java @@ -138,8 +138,10 @@ public class SplitDecorManager extends WindowlessWindowManager { mViewHost.setView(rootLayout, lp); } - /** Releases the surfaces for split decor. */ - public void release(SurfaceControl.Transaction t) { + /** + * Cancels any currently running animations. + */ + public void cancelRunningAnimations() { if (mFadeAnimator != null) { if (mFadeAnimator.isRunning()) { mFadeAnimator.cancel(); @@ -152,6 +154,11 @@ public class SplitDecorManager extends WindowlessWindowManager { } mScreenshotAnimator = null; } + } + + /** Releases the surfaces for split decor. */ + public void release(SurfaceControl.Transaction t) { + cancelRunningAnimations(); if (mViewHost != null) { mViewHost.release(); mViewHost = null; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index 53caddb52f23..6b2d544c192a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -510,16 +510,18 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } } - /** Updates divide position and split bounds base on the ratio within root bounds. */ + /** + * Updates divide position and split bounds base on the ratio within root bounds. Falls back + * to middle position if the provided SnapTarget is not supported. + */ public void setDivideRatio(@PersistentSnapPosition int snapPosition) { final DividerSnapAlgorithm.SnapTarget snapTarget = mDividerSnapAlgorithm.findSnapTarget( snapPosition); - if (snapTarget == null) { - throw new IllegalArgumentException("No SnapTarget for position " + snapPosition); - } - - setDividePosition(snapTarget.position, false /* applyLayoutChange */); + setDividePosition(snapTarget != null + ? snapTarget.position + : mDividerSnapAlgorithm.getMiddleTarget().position, + false /* applyLayoutChange */); } /** Resets divider position. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index f757e1c88cb8..fb3c35b6a1e3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -201,9 +201,11 @@ public abstract class WMShellModule { @Provides static WindowDecorViewModel provideWindowDecorViewModel( Context context, + @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler, @ShellMainThread Choreographer mainChoreographer, ShellInit shellInit, + IWindowManager windowManager, ShellCommandHandler shellCommandHandler, ShellTaskOrganizer taskOrganizer, DisplayController displayController, @@ -216,10 +218,12 @@ public abstract class WMShellModule { if (DesktopModeStatus.isEnabled()) { return new DesktopModeWindowDecorViewModel( context, + mainExecutor, mainHandler, mainChoreographer, shellInit, shellCommandHandler, + windowManager, taskOrganizer, displayController, shellController, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index c7daf561f682..87e372cc304c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -63,6 +63,7 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.os.RemoteException; import android.os.SystemProperties; +import android.util.Rational; import android.view.Choreographer; import android.view.Display; import android.view.Surface; @@ -126,6 +127,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, SystemProperties.getInt( "persist.wm.debug.extra_content_overlay_fade_out_delay_ms", 400); + private static final float PIP_ASPECT_RATIO_MISMATCH_THRESHOLD = 0.005f; + private final Context mContext; private final SyncTransactionQueue mSyncTransactionQueue; private final PipBoundsState mPipBoundsState; @@ -767,6 +770,37 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mPictureInPictureParams.getTitle()); mPipParamsChangedForwarder.notifySubtitleChanged( mPictureInPictureParams.getSubtitle()); + + if (mPictureInPictureParams.hasSourceBoundsHint() + && mPictureInPictureParams.hasSetAspectRatio()) { + Rational sourceRectHintAspectRatio = new Rational( + mPictureInPictureParams.getSourceRectHint().width(), + mPictureInPictureParams.getSourceRectHint().height()); + if (sourceRectHintAspectRatio.compareTo( + mPictureInPictureParams.getAspectRatio()) != 0) { + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "Aspect ratio of source rect hint (%d/%d) does not match the provided " + + "aspect ratio value (%d/%d). Consider matching them for " + + "improved animation. Future releases might override the " + + "value to match.", + mPictureInPictureParams.getSourceRectHint().width(), + mPictureInPictureParams.getSourceRectHint().height(), + mPictureInPictureParams.getAspectRatio().getNumerator(), + mPictureInPictureParams.getAspectRatio().getDenominator()); + } + if (Math.abs(sourceRectHintAspectRatio.floatValue() + - mPictureInPictureParams.getAspectRatioFloat()) + > PIP_ASPECT_RATIO_MISMATCH_THRESHOLD) { + ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "Aspect ratio of source rect hint (%f) does not match the provided " + + "aspect ratio value (%f) and is above threshold of %f. " + + "Consider matching them for improved animation. Future " + + "releases might override the value to match.", + sourceRectHintAspectRatio.floatValue(), + mPictureInPictureParams.getAspectRatioFloat(), + PIP_ASPECT_RATIO_MISMATCH_THRESHOLD); + } + } } mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java index 1d9fdeb92715..1a53a1d10dd2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java @@ -403,25 +403,23 @@ class SplitScreenTransitions { IBinder startResizeTransition(WindowContainerTransaction wct, Transitions.TransitionHandler handler, @Nullable TransitionConsumedCallback consumedCallback, - @Nullable TransitionFinishedCallback finishCallback) { + @Nullable TransitionFinishedCallback finishCallback, + @NonNull SplitDecorManager mainDecor, @NonNull SplitDecorManager sideDecor) { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, + " splitTransition deduced Resize split screen."); + ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "setResizeTransition: hasPendingResize=%b", + mPendingResize != null); if (mPendingResize != null) { + mainDecor.cancelRunningAnimations(); + sideDecor.cancelRunningAnimations(); mPendingResize.cancel(null); mAnimations.clear(); onFinish(null /* wct */); } IBinder transition = mTransitions.startTransition(TRANSIT_CHANGE, wct, handler); - setResizeTransition(transition, consumedCallback, finishCallback); - return transition; - } - - void setResizeTransition(@NonNull IBinder transition, - @Nullable TransitionConsumedCallback consumedCallback, - @Nullable TransitionFinishedCallback finishCallback) { mPendingResize = new TransitSession(transition, consumedCallback, finishCallback); - ProtoLog.v(WM_SHELL_TRANSITIONS, " splitTransition " - + " deduced Resize split screen"); - ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "setResizeTransition"); + return transition; } void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 7a1595fdbf01..2321869d2f4a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -2308,10 +2308,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, if (ENABLE_SHELL_TRANSITIONS) { mSplitLayout.setDividerInteractive(false, false, "onSplitResizeStart"); mSplitTransitions.startResizeTransition(wct, this, (aborted) -> { - mSplitLayout.setDividerInteractive(true, false, "onSplitResizeConsumed"); - }, (finishWct, t) -> { - mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish"); - }); + mSplitLayout.setDividerInteractive(true, false, "onSplitResizeConsumed"); + }, (finishWct, t) -> { + mSplitLayout.setDividerInteractive(true, false, "onSplitResizeFinish"); + }, mMainStage.getSplitDecorManager(), mSideStage.getSplitDecorManager()); } else { // Only need screenshot for legacy case because shell transition should screenshot // itself during transition. @@ -3515,7 +3515,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, return; } - final int stageType = isMainStage ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE; + // If visible, we preserve the app and keep it running. If an app becomes + // unsupported in the bg, break split without putting anything on top + boolean splitScreenVisible = isSplitScreenVisible(); + int stageType = STAGE_TYPE_UNDEFINED; + if (splitScreenVisible) { + stageType = isMainStage ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE; + } final WindowContainerTransaction wct = new WindowContainerTransaction(); prepareExitSplitScreen(stageType, wct); clearSplitPairedInRecents(EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW); @@ -3524,7 +3530,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, Log.w(TAG, splitFailureMessage("onNoLongerSupportMultiWindow", "app package " + taskInfo.baseActivity.getPackageName() + " does not support splitscreen, or is a controlled activity type")); - mSplitUnsupportedToast.show(); + if (splitScreenVisible) { + mSplitUnsupportedToast.show(); + } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java index 96eaa1edbae4..91e9601c6a27 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java @@ -190,6 +190,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL mRelayoutParams.mShadowRadiusId = shadowRadiusID; mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw; mRelayoutParams.mSetTaskPositionAndCrop = setTaskCropAndPosition; + mRelayoutParams.mAllowCaptionInputFallthrough = false; relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult); // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index caa894fcbbc7..8d798a3035f6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -48,9 +48,13 @@ import android.graphics.Region; import android.hardware.input.InputManager; import android.os.Handler; import android.os.Looper; +import android.os.RemoteException; +import android.util.Log; import android.util.SparseArray; import android.view.Choreographer; import android.view.GestureDetector; +import android.view.ISystemGestureExclusionListener; +import android.view.IWindowManager; import android.view.InputChannel; import android.view.InputEvent; import android.view.InputEventReceiver; @@ -73,6 +77,7 @@ import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; +import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.desktopmode.DesktopModeStatus; @@ -88,6 +93,7 @@ import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionRegionListener; +import com.android.wm.shell.windowdecor.extension.TaskInfoKt; import java.io.PrintWriter; import java.util.Optional; @@ -102,6 +108,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private static final String TAG = "DesktopModeWindowDecorViewModel"; private final DesktopModeWindowDecoration.Factory mDesktopModeWindowDecorFactory; + private final IWindowManager mWindowManager; + private final ShellExecutor mMainExecutor; private final ActivityTaskManager mActivityTaskManager; private final ShellCommandHandler mShellCommandHandler; private final ShellTaskOrganizer mTaskOrganizer; @@ -112,6 +120,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private final DisplayController mDisplayController; private final SyncTransactionQueue mSyncQueue; private final Optional<DesktopTasksController> mDesktopTasksController; + private final InputManager mInputManager; + private boolean mTransitionDragActive; private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>(); @@ -135,14 +145,31 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { new DesktopModeKeyguardChangeListener(); private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final DisplayInsetsController mDisplayInsetsController; + private final Region mExclusionRegion = Region.obtain(); private boolean mInImmersiveMode; + private final ISystemGestureExclusionListener mGestureExclusionListener = + new ISystemGestureExclusionListener.Stub() { + @Override + public void onSystemGestureExclusionChanged(int displayId, + Region systemGestureExclusion, Region systemGestureExclusionUnrestricted) { + if (mContext.getDisplayId() != displayId) { + return; + } + mMainExecutor.execute(() -> { + mExclusionRegion.set(systemGestureExclusion); + }); + } + }; + public DesktopModeWindowDecorViewModel( Context context, + ShellExecutor shellExecutor, Handler mainHandler, Choreographer mainChoreographer, ShellInit shellInit, ShellCommandHandler shellCommandHandler, + IWindowManager windowManager, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, @@ -154,10 +181,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { ) { this( context, + shellExecutor, mainHandler, mainChoreographer, shellInit, shellCommandHandler, + windowManager, taskOrganizer, displayController, shellController, @@ -174,10 +203,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { @VisibleForTesting DesktopModeWindowDecorViewModel( Context context, + ShellExecutor shellExecutor, Handler mainHandler, Choreographer mainChoreographer, ShellInit shellInit, ShellCommandHandler shellCommandHandler, + IWindowManager windowManager, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, @@ -190,6 +221,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { Supplier<SurfaceControl.Transaction> transactionFactory, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { mContext = context; + mMainExecutor = shellExecutor; mMainHandler = mainHandler; mMainChoreographer = mainChoreographer; mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class); @@ -201,10 +233,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mTransitions = transitions; mDesktopTasksController = desktopTasksController; mShellCommandHandler = shellCommandHandler; + mWindowManager = windowManager; mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory; mInputMonitorFactory = inputMonitorFactory; mTransactionFactory = transactionFactory; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; + mInputManager = mContext.getSystemService(InputManager.class); shellInit.addInitCallback(this::onInit, this); } @@ -216,6 +250,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { new DesktopModeOnInsetsChangedListener()); mDesktopTasksController.ifPresent(c -> c.setOnTaskResizeAnimationListener( new DeskopModeOnTaskResizeAnimationListener())); + try { + mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener, + mContext.getDisplayId()); + } catch (RemoteException e) { + Log.e(TAG, "Failed to register window manager callbacks", e); + } } @Override @@ -315,12 +355,19 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener, View.OnGenericMotionListener , DragDetector.MotionEventHandler { private static final int CLOSE_MAXIMIZE_MENU_DELAY_MS = 150; + private final int mTaskId; private final WindowContainerToken mTaskToken; private final DragPositioningCallback mDragPositioningCallback; private final DragDetector mDragDetector; private final GestureDetector mGestureDetector; + /** + * Whether to pilfer the next motion event to send cancellations to the windows below. + * Useful when the caption window is spy and the gesture should be handle by the system + * instead of by the app for their custom header content. + */ + private boolean mShouldPilferCaptionEvents; private boolean mIsDragging; private boolean mTouchscreenInUse; private boolean mHasLongClicked; @@ -438,6 +485,40 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId); moveTaskToFront(decoration.mTaskInfo); + final int actionMasked = e.getActionMasked(); + final boolean isDown = actionMasked == MotionEvent.ACTION_DOWN; + final boolean isUpOrCancel = actionMasked == MotionEvent.ACTION_CANCEL + || actionMasked == MotionEvent.ACTION_UP; + if (isDown) { + final boolean downInCustomizableCaptionRegion = + decoration.checkTouchEventInCustomizableRegion(e); + final boolean downInExclusionRegion = mExclusionRegion.contains( + (int) e.getRawX(), (int) e.getRawY()); + final boolean isTransparentCaption = + TaskInfoKt.isTransparentCaptionBarAppearance(decoration.mTaskInfo); + // The caption window may be a spy window when the caption background is + // transparent, which means events will fall through to the app window. Make + // sure to cancel these events if they do not happen in the intersection of the + // customizable region and what the app reported as exclusion areas, because + // the drag-move or other caption gestures should take priority outside those + // regions. + mShouldPilferCaptionEvents = !(downInCustomizableCaptionRegion + && downInExclusionRegion && isTransparentCaption); + } + + if (!mShouldPilferCaptionEvents) { + // The event will be handled by a window below. + return false; + } + // Otherwise pilfer so that windows below receive cancellations for this gesture, and + // continue normal handling as a caption gesture. + if (mInputManager != null) { + mInputManager.pilferPointers(v.getViewRootImpl().getInputToken()); + } + if (isUpOrCancel) { + // Gesture is finished, reset state. + mShouldPilferCaptionEvents = false; + } if (!mHasLongClicked && id != R.id.maximize_window) { decoration.closeMaximizeMenuIfNeeded(e); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index 74f460bf1226..9e999ae52835 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -56,6 +56,7 @@ import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.desktopmode.DesktopTasksController; +import com.android.wm.shell.windowdecor.extension.TaskInfoKt; import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowDecorationViewHolder; import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder; import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder; @@ -337,6 +338,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin controlsElement.mWidthResId = R.dimen.desktop_mode_right_edge_buttons_width; controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END; relayoutParams.mOccludingCaptionElements.add(controlsElement); + relayoutParams.mAllowCaptionInputFallthrough = + TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo); } if (DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ taskInfo.isFocused)) { relayoutParams.mShadowRadiusId = taskInfo.isFocused @@ -699,6 +702,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin } /** + * Checks whether the touch event falls inside the customizable caption region. + */ + boolean checkTouchEventInCustomizableRegion(MotionEvent ev) { + return mResult.mCustomizableCaptionRegion.contains((int) ev.getRawX(), (int) ev.getRawY()); + } + + /** * Check a passed MotionEvent if a click has occurred on any button on this caption * Note this should only be called when a regular onClick is not possible * (i.e. the button was clicked through status bar layer) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java index dc65855646ea..32c2d1e9b257 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java @@ -31,6 +31,7 @@ import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; +import android.graphics.Region; import android.os.Binder; import android.view.Display; import android.view.InsetsSource; @@ -311,6 +312,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> if (numOfElements == 0) { boundingRects = null; } else { + // The customizable region can at most be equal to the caption bar. + if (params.mAllowCaptionInputFallthrough) { + outResult.mCustomizableCaptionRegion.set(mCaptionInsetsRect); + } boundingRects = new Rect[numOfElements]; for (int i = 0; i < numOfElements; i++) { final OccludingCaptionElement element = @@ -319,9 +324,14 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> resources.getDimensionPixelSize(element.mWidthResId); boundingRects[i] = calculateBoundingRect(element, elementWidthPx, mCaptionInsetsRect); + // Subtract the regions used by the caption elements, the rest is + // customizable. + if (params.mAllowCaptionInputFallthrough) { + outResult.mCustomizableCaptionRegion.op(boundingRects[i], + Region.Op.DIFFERENCE); + } } } - // Add this caption as an inset source. wct.addInsetsSource(mTaskInfo.token, mOwner, 0 /* index */, WindowInsets.Type.captionBar(), mCaptionInsetsRect, @@ -389,6 +399,11 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT); lp.setTitle("Caption of Task=" + mTaskInfo.taskId); lp.setTrustedOverlay(); + if (params.mAllowCaptionInputFallthrough) { + lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY; + } else { + lp.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY; + } if (mViewHost == null) { mViewHost = mSurfaceControlViewHostFactory.create(mDecorWindowContext, mDisplay, mCaptionWindowManager); @@ -596,6 +611,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> int mCaptionHeightId; int mCaptionWidthId; final List<OccludingCaptionElement> mOccludingCaptionElements = new ArrayList<>(); + boolean mAllowCaptionInputFallthrough; int mShadowRadiusId; int mCornerRadius; @@ -610,6 +626,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mCaptionHeightId = Resources.ID_NULL; mCaptionWidthId = Resources.ID_NULL; mOccludingCaptionElements.clear(); + mAllowCaptionInputFallthrough = false; mShadowRadiusId = Resources.ID_NULL; mCornerRadius = 0; @@ -637,6 +654,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> int mCaptionHeight; int mCaptionWidth; int mCaptionX; + final Region mCustomizableCaptionRegion = Region.obtain(); int mWidth; int mHeight; T mRootView; @@ -647,6 +665,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mCaptionHeight = 0; mCaptionWidth = 0; mCaptionX = 0; + mCustomizableCaptionRegion.setEmpty(); mRootView = null; } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/extension/TaskInfo.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/extension/TaskInfo.kt new file mode 100644 index 000000000000..5dd96aceaec7 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/extension/TaskInfo.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.wm.shell.windowdecor.extension + +import android.app.TaskInfo +import android.view.WindowInsetsController.APPEARANCE_LIGHT_CAPTION_BARS +import android.view.WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND + +val TaskInfo.isTransparentCaptionBarAppearance: Boolean + get() { + val appearance = taskDescription?.statusBarAppearance ?: 0 + return (appearance and APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND) != 0 + } + +val TaskInfo.isLightCaptionBarAppearance: Boolean + get() { + val appearance = taskDescription?.statusBarAppearance ?: 0 + return (appearance and APPEARANCE_LIGHT_CAPTION_BARS) != 0 + } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt index 7e5b9bd649f2..b7dd01faa543 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt @@ -8,8 +8,6 @@ import android.graphics.Bitmap import android.graphics.Color import android.view.View import android.view.View.OnLongClickListener -import android.view.WindowInsetsController.APPEARANCE_LIGHT_CAPTION_BARS -import android.view.WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND import android.widget.ImageButton import android.widget.ImageView import android.widget.TextView @@ -22,6 +20,8 @@ import com.android.internal.R.attr.materialColorSurfaceContainerLow import com.android.internal.R.attr.materialColorSurfaceDim import com.android.wm.shell.R import com.android.wm.shell.windowdecor.MaximizeButtonView +import com.android.wm.shell.windowdecor.extension.isLightCaptionBarAppearance +import com.android.wm.shell.windowdecor.extension.isTransparentCaptionBarAppearance /** * A desktop mode window decoration used when the window is floating (i.e. freeform). It hosts @@ -107,7 +107,7 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder( @ColorInt private fun getCaptionBackgroundColor(taskInfo: RunningTaskInfo): Int { - if (isTransparentBackgroundRequested(taskInfo)) { + if (taskInfo.isTransparentCaptionBarAppearance) { return Color.TRANSPARENT } val materialColorAttr: Int = @@ -133,10 +133,10 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder( @ColorInt private fun getAppNameAndButtonColor(taskInfo: RunningTaskInfo): Int { val materialColorAttr = when { - isTransparentBackgroundRequested(taskInfo) && - isLightCaptionBar(taskInfo) -> materialColorOnSecondaryContainer - isTransparentBackgroundRequested(taskInfo) && - !isLightCaptionBar(taskInfo) -> materialColorOnSurface + taskInfo.isTransparentCaptionBarAppearance && + taskInfo.isLightCaptionBarAppearance -> materialColorOnSecondaryContainer + taskInfo.isTransparentCaptionBarAppearance && + !taskInfo.isLightCaptionBarAppearance -> materialColorOnSurface isDarkMode() -> materialColorOnSurface else -> materialColorOnSecondaryContainer } @@ -167,16 +167,6 @@ internal class DesktopModeAppControlsWindowDecorationViewHolder( Configuration.UI_MODE_NIGHT_YES } - private fun isTransparentBackgroundRequested(taskInfo: RunningTaskInfo): Boolean { - val appearance = taskInfo.taskDescription?.statusBarAppearance ?: 0 - return (appearance and APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND) != 0 - } - - private fun isLightCaptionBar(taskInfo: RunningTaskInfo): Boolean { - val appearance = taskInfo.taskDescription?.statusBarAppearance ?: 0 - return (appearance and APPEARANCE_LIGHT_CAPTION_BARS) != 0 - } - companion object { private const val TAG = "DesktopModeAppControlsWindowDecorationViewHolder" private const val DARK_THEME_UNFOCUSED_OPACITY = 140 // 55% diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java index d4e9ac96d221..e74c804d4f40 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java @@ -36,7 +36,6 @@ import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.graphics.Rect; import android.os.RemoteException; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.Rational; @@ -45,6 +44,8 @@ import android.view.DisplayInfo; import android.view.SurfaceControl; import android.window.WindowContainerToken; +import androidx.test.filters.SmallTest; + import com.android.wm.shell.MockSurfaceControlHelper; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java index 5d968d3360ab..3384509f1da9 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java @@ -42,10 +42,11 @@ import android.graphics.Point; import android.graphics.Rect; import android.os.Bundle; import android.os.RemoteException; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import androidx.test.filters.SmallTest; + import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.WindowManagerShellWrapper; import com.android.wm.shell.common.DisplayController; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java index 45f6c8c7f69f..72db6e091307 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java @@ -23,20 +23,21 @@ import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_EXPAND_COLLAPSE; import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_FULLSCREEN; import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_MOVE; -import static java.util.Collections.EMPTY_LIST; - import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static java.util.Collections.EMPTY_LIST; + import android.app.PendingIntent; import android.app.RemoteAction; import android.graphics.drawable.Icon; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import androidx.test.filters.SmallTest; + import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.common.pip.PipMediaController; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java index 050443914355..fbc0db9c2850 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java @@ -32,7 +32,6 @@ import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.graphics.Rect; import android.os.IBinder; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.SurfaceControl; @@ -40,6 +39,8 @@ import android.window.TransitionInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; +import androidx.test.filters.SmallTest; + import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.transition.Transitions; diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt index f84685a92b57..917fd715f71f 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt @@ -31,6 +31,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.Choreographer import android.view.Display.DEFAULT_DISPLAY +import android.view.IWindowManager import android.view.InputChannel import android.view.InputMonitor import android.view.InsetsSource @@ -96,6 +97,7 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() { @Mock private lateinit var mockShellExecutor: ShellExecutor @Mock private lateinit var mockRootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer @Mock private lateinit var mockShellCommandHandler: ShellCommandHandler + @Mock private lateinit var mockWindowManager: IWindowManager private val transactionFactory = Supplier<SurfaceControl.Transaction> { SurfaceControl.Transaction() @@ -110,10 +112,12 @@ class DesktopModeWindowDecorViewModelTests : ShellTestCase() { shellInit = ShellInit(mockShellExecutor) desktopModeWindowDecorViewModel = DesktopModeWindowDecorViewModel( mContext, + mockShellExecutor, mockMainHandler, mockMainChoreographer, shellInit, mockShellCommandHandler, + mockWindowManager, mockTaskOrganizer, mockDisplayController, mockShellController, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java index 40e61dd95f51..9e62bd254ac5 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java @@ -16,6 +16,10 @@ package com.android.wm.shell.windowdecor; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.view.WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.any; @@ -168,6 +172,57 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { assertThat(relayoutParams.mCornerRadius).isGreaterThan(0); } + @Test + public void updateRelayoutParams_freeformAndTransparent_allowsInputFallthrough() { + final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true); + taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM); + taskInfo.taskDescription.setStatusBarAppearance( + APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND); + final RelayoutParams relayoutParams = new RelayoutParams(); + + DesktopModeWindowDecoration.updateRelayoutParams( + relayoutParams, + mTestableContext, + taskInfo, + /* applyStartTransactionOnDraw= */ true, + /* shouldSetTaskPositionAndCrop */ false); + + assertThat(relayoutParams.mAllowCaptionInputFallthrough).isTrue(); + } + + @Test + public void updateRelayoutParams_freeformButOpaque_disallowsInputFallthrough() { + final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true); + taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM); + taskInfo.taskDescription.setStatusBarAppearance(0); + final RelayoutParams relayoutParams = new RelayoutParams(); + + DesktopModeWindowDecoration.updateRelayoutParams( + relayoutParams, + mTestableContext, + taskInfo, + /* applyStartTransactionOnDraw= */ true, + /* shouldSetTaskPositionAndCrop */ false); + + assertThat(relayoutParams.mAllowCaptionInputFallthrough).isFalse(); + } + + @Test + public void updateRelayoutParams_fullscreen_disallowsInputFallthrough() { + final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true); + taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN); + final RelayoutParams relayoutParams = new RelayoutParams(); + + DesktopModeWindowDecoration.updateRelayoutParams( + relayoutParams, + mTestableContext, + taskInfo, + /* applyStartTransactionOnDraw= */ true, + /* shouldSetTaskPositionAndCrop */ false); + + assertThat(relayoutParams.mAllowCaptionInputFallthrough).isFalse(); + } + private void fillRoundedCornersResources(int fillValue) { when(mMockRoundedCornersRadiusArray.getDimensionPixelSize(anyInt(), anyInt())) .thenReturn(fillValue); diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index f0c639574a9f..49254d1c6f6e 100644 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -81,7 +81,7 @@ ApkAssetsPtr ApkAssets::LoadOverlay(const std::string& idmap_path, package_prope std::string overlay_path(loaded_idmap->OverlayApkPath()); auto fd = unique_fd(base::utf8::open(overlay_path.c_str(), O_RDONLY | O_CLOEXEC)); std::unique_ptr<AssetsProvider> overlay_assets; - if (IsFabricatedOverlay(fd)) { + if (IsFabricatedOverlayName(overlay_path) && IsFabricatedOverlay(fd)) { // Fabricated overlays do not contain resource definitions. All of the overlay resource values // are defined inline in the idmap. overlay_assets = EmptyAssetsProvider::Create(std::move(overlay_path)); @@ -137,8 +137,7 @@ ApkAssetsPtr ApkAssets::LoadImpl(std::unique_ptr<Asset> resources_asset, return {}; } loaded_arsc = LoadedArsc::Load(data, length, loaded_idmap.get(), property_flags); - } else if (loaded_idmap != nullptr && - IsFabricatedOverlay(std::string(loaded_idmap->OverlayApkPath()))) { + } else if (loaded_idmap != nullptr && IsFabricatedOverlay(loaded_idmap->OverlayApkPath())) { loaded_arsc = LoadedArsc::Load(loaded_idmap.get()); } else { loaded_arsc = LoadedArsc::CreateEmpty(); diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp index 5f98b8f8db43..982419059ead 100644 --- a/libs/androidfw/Idmap.cpp +++ b/libs/androidfw/Idmap.cpp @@ -18,8 +18,10 @@ #include "androidfw/Idmap.h" +#include "android-base/file.h" #include "android-base/logging.h" #include "android-base/stringprintf.h" +#include "android-base/utf8.h" #include "androidfw/misc.h" #include "androidfw/ResourceTypes.h" #include "androidfw/Util.h" @@ -250,7 +252,12 @@ std::optional<std::string_view> ReadString(const uint8_t** in_out_data_ptr, size } } // namespace -LoadedIdmap::LoadedIdmap(std::string&& idmap_path, const Idmap_header* header, +// O_PATH is a lightweight way of creating an FD, only exists on Linux +#ifndef O_PATH +#define O_PATH (0) +#endif + +LoadedIdmap::LoadedIdmap(const std::string& idmap_path, const Idmap_header* header, const Idmap_data_header* data_header, const Idmap_target_entry* target_entries, const Idmap_target_entry_inline* target_inline_entries, @@ -267,10 +274,10 @@ LoadedIdmap::LoadedIdmap(std::string&& idmap_path, const Idmap_header* header, configurations_(configs), overlay_entries_(overlay_entries), string_pool_(std::move(string_pool)), - idmap_path_(std::move(idmap_path)), + idmap_fd_(android::base::utf8::open(idmap_path.c_str(), O_RDONLY|O_CLOEXEC|O_BINARY|O_PATH)), overlay_apk_path_(overlay_apk_path), target_apk_path_(target_apk_path), - idmap_last_mod_time_(getFileModDate(idmap_path_.data())) {} + idmap_last_mod_time_(getFileModDate(idmap_fd_.get())) {} std::unique_ptr<LoadedIdmap> LoadedIdmap::Load(StringPiece idmap_path, StringPiece idmap_data) { ATRACE_CALL(); @@ -368,7 +375,7 @@ std::unique_ptr<LoadedIdmap> LoadedIdmap::Load(StringPiece idmap_path, StringPie } bool LoadedIdmap::IsUpToDate() const { - return idmap_last_mod_time_ == getFileModDate(idmap_path_.c_str()); + return idmap_last_mod_time_ == getFileModDate(idmap_fd_.get()); } } // namespace android diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 2c99f1aa3675..a3dd9833219e 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -54,6 +54,8 @@ #define INT32_MAX ((int32_t)(2147483647)) #endif +using namespace std::literals; + namespace android { #if defined(_WIN32) @@ -237,12 +239,24 @@ void Res_png_9patch::serialize(const Res_png_9patch& patch, const int32_t* xDivs fill9patchOffsets(reinterpret_cast<Res_png_9patch*>(outData)); } -bool IsFabricatedOverlay(const std::string& path) { - return IsFabricatedOverlay(path.c_str()); +bool IsFabricatedOverlayName(std::string_view path) { + static constexpr auto suffixFrro = ".frro"sv; + static constexpr auto suffixIdmap = ".frro@idmap"sv; + + return (path.size() > suffixFrro.size() && path.ends_with(suffixFrro)) + || (path.size() > suffixIdmap.size() && path.ends_with(suffixIdmap)); } -bool IsFabricatedOverlay(const char* path) { - auto fd = base::unique_fd(base::utf8::open(path, O_RDONLY|O_CLOEXEC)); +bool IsFabricatedOverlay(std::string_view path) { + if (!IsFabricatedOverlayName(path)) { + return false; + } + std::string path_copy; + if (path[path.size()] != '\0') { + path_copy.assign(path); + path = path_copy; + } + auto fd = base::unique_fd(base::utf8::open(path.data(), O_RDONLY|O_CLOEXEC|O_BINARY)); if (fd < 0) { return false; } @@ -7319,9 +7333,6 @@ class IdmapTypeMapping { public: void add(uint32_t targetResId, uint32_t overlayResId) { uint8_t targetTypeId = Res_GETTYPE(targetResId); - if (mData.find(targetTypeId) == mData.end()) { - mData.emplace(targetTypeId, std::set<std::pair<uint32_t, uint32_t>>()); - } auto& entries = mData[targetTypeId]; entries.insert(std::make_pair(targetResId, overlayResId)); } diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h index d9f7c2a1ac19..c32a38ee9ec2 100644 --- a/libs/androidfw/include/androidfw/Idmap.h +++ b/libs/androidfw/include/androidfw/Idmap.h @@ -23,6 +23,7 @@ #include <variant> #include "android-base/macros.h" +#include "android-base/unique_fd.h" #include "androidfw/ConfigDescription.h" #include "androidfw/StringPiece.h" #include "androidfw/ResourceTypes.h" @@ -159,11 +160,6 @@ class LoadedIdmap { // Loads an IDMAP from a chunk of memory. Returns nullptr if the IDMAP data was malformed. static std::unique_ptr<LoadedIdmap> Load(StringPiece idmap_path, StringPiece idmap_data); - // Returns the path to the IDMAP. - std::string_view IdmapPath() const { - return idmap_path_; - } - // Returns the path to the RRO (Runtime Resource Overlay) APK for which this IDMAP was generated. std::string_view OverlayApkPath() const { return overlay_apk_path_; @@ -203,7 +199,7 @@ class LoadedIdmap { const Idmap_overlay_entry* overlay_entries_; const std::unique_ptr<ResStringPool> string_pool_; - std::string idmap_path_; + android::base::unique_fd idmap_fd_; std::string_view overlay_apk_path_; std::string_view target_apk_path_; time_t idmap_last_mod_time_; @@ -211,7 +207,7 @@ class LoadedIdmap { private: DISALLOW_COPY_AND_ASSIGN(LoadedIdmap); - explicit LoadedIdmap(std::string&& idmap_path, + explicit LoadedIdmap(const std::string& idmap_path, const Idmap_header* header, const Idmap_data_header* data_header, const Idmap_target_entry* target_entries, diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index 3d1403d0e039..c2648909386c 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -59,8 +59,8 @@ constexpr const uint32_t kFabricatedOverlayMagic = 0x4f525246; // FRRO (big endi constexpr const uint32_t kFabricatedOverlayCurrentVersion = 3; // Returns whether or not the path represents a fabricated overlay. -bool IsFabricatedOverlay(const std::string& path); -bool IsFabricatedOverlay(const char* path); +bool IsFabricatedOverlayName(std::string_view path); +bool IsFabricatedOverlay(std::string_view path); bool IsFabricatedOverlay(android::base::borrowed_fd fd); /** diff --git a/libs/androidfw/include/androidfw/misc.h b/libs/androidfw/include/androidfw/misc.h index d40d24ede769..077609d20d55 100644 --- a/libs/androidfw/include/androidfw/misc.h +++ b/libs/androidfw/include/androidfw/misc.h @@ -43,6 +43,8 @@ typedef enum FileType { FileType getFileType(const char* fileName); /* get the file's modification date; returns -1 w/errno set on failure */ time_t getFileModDate(const char* fileName); +/* same, but also returns -1 if the file has already been deleted */ +time_t getFileModDate(int fd); // Check if |path| or |fd| resides on a readonly filesystem. bool isReadonlyFilesystem(const char* path); diff --git a/libs/androidfw/misc.cpp b/libs/androidfw/misc.cpp index d3949e9cf69f..93dcaf549a90 100644 --- a/libs/androidfw/misc.cpp +++ b/libs/androidfw/misc.cpp @@ -76,13 +76,23 @@ FileType getFileType(const char* fileName) /* * Get a file's modification date. */ -time_t getFileModDate(const char* fileName) -{ +time_t getFileModDate(const char* fileName) { struct stat sb; + if (stat(fileName, &sb) < 0) { + return (time_t)-1; + } + return sb.st_mtime; +} - if (stat(fileName, &sb) < 0) - return (time_t) -1; - +time_t getFileModDate(int fd) { + struct stat sb; + if (fstat(fd, &sb) < 0) { + return (time_t)-1; + } + if (sb.st_nlink <= 0) { + errno = ENOENT; + return (time_t)-1; + } return sb.st_mtime; } diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 8f3f82e06cf8..6f7024ae76b4 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -7878,9 +7878,9 @@ public class AudioManager { */ @FlaggedApi(FLAG_SUPPORTED_DEVICE_TYPES_API) public @NonNull Set<Integer> - getSupportedDeviceTypes(int direction) { + getSupportedDeviceTypes(@AudioDeviceRole int direction) { if (direction != GET_DEVICES_OUTPUTS && direction != GET_DEVICES_INPUTS) { - throw new IllegalArgumentException("AudioManager.getSupportedDeviceTypes(" + throw new IllegalArgumentException("AudioManager.getSupportedDeviceTypes(0x" + Integer.toHexString(direction) + ") - Invalid."); } diff --git a/media/lib/tvremote/tests/Android.bp b/media/lib/tvremote/tests/Android.bp index f02cfc393c81..280c515e9a9e 100644 --- a/media/lib/tvremote/tests/Android.bp +++ b/media/lib/tvremote/tests/Android.bp @@ -17,6 +17,7 @@ android_test { ], static_libs: [ "mockito-target-minus-junit4", + "androidx.test.rules", ], platform_apis: true, certificate: "platform", diff --git a/media/lib/tvremote/tests/src/com/android/media/tv/remoteprovider/TvRemoteProviderTest.java b/media/lib/tvremote/tests/src/com/android/media/tv/remoteprovider/TvRemoteProviderTest.java index e6e39390962e..3b38a4621389 100644 --- a/media/lib/tvremote/tests/src/com/android/media/tv/remoteprovider/TvRemoteProviderTest.java +++ b/media/lib/tvremote/tests/src/com/android/media/tv/remoteprovider/TvRemoteProviderTest.java @@ -29,7 +29,8 @@ import android.media.tv.ITvRemoteServiceInput; import android.os.Binder; import android.os.IBinder; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import java.util.ArrayList; diff --git a/media/mca/tests/Android.bp b/media/mca/tests/Android.bp index f02b4c0a4bfb..04f083dee093 100644 --- a/media/mca/tests/Android.bp +++ b/media/mca/tests/Android.bp @@ -13,7 +13,10 @@ android_test { "android.test.runner", "android.test.base", ], - static_libs: ["junit"], + static_libs: [ + "junit", + "androidx.test.rules", + ], // Include all test java files. srcs: ["src/**/*.java"], platform_apis: true, diff --git a/media/mca/tests/src/android/camera/mediaeffects/tests/functional/EffectsVideoCapture.java b/media/mca/tests/src/android/camera/mediaeffects/tests/functional/EffectsVideoCapture.java index 474b00f77a34..44f9805010bb 100644 --- a/media/mca/tests/src/android/camera/mediaeffects/tests/functional/EffectsVideoCapture.java +++ b/media/mca/tests/src/android/camera/mediaeffects/tests/functional/EffectsVideoCapture.java @@ -16,18 +16,19 @@ package android.camera.mediaeffects.tests.functional; -import android.media.filterfw.samples.CameraEffectsRecordingSample; import android.app.Activity; import android.app.Instrumentation; import android.content.Intent; -import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.LargeTest; -import android.view.KeyEvent; -import android.util.Log; -import android.content.Intent; -import android.os.Environment; import android.media.MediaMetadataRetriever; +import android.media.filterfw.samples.CameraEffectsRecordingSample; import android.net.Uri; +import android.os.Environment; +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; +import android.view.KeyEvent; + +import androidx.test.filters.LargeTest; + import java.io.File; public class EffectsVideoCapture extends ActivityInstrumentationTestCase2 diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java index 9b643ad3c086..022f1da5ce5b 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CameraTest.java @@ -16,9 +16,6 @@ package com.android.mediaframeworktest.functional; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; - import android.content.Context; import android.hardware.Camera; import android.hardware.Camera.PictureCallback; @@ -27,10 +24,14 @@ import android.hardware.Camera.ShutterCallback; import android.os.ConditionVariable; import android.os.Looper; import android.test.ActivityInstrumentationTestCase; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import android.view.SurfaceHolder; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; +import com.android.mediaframeworktest.MediaNames; + import java.io.*; /** diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java index da106be78ac0..8f32e91ce5c5 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java @@ -18,9 +18,10 @@ package com.android.mediaframeworktest.functional; import android.media.MediaMetadataRetriever; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; import android.util.Log; +import androidx.test.filters.MediumTest; + import com.android.mediaframeworktest.MediaNames; import com.android.mediaframeworktest.MediaProfileReader; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java index 728e68dd8dd6..83793ee22b0a 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java @@ -16,21 +16,20 @@ package com.android.mediaframeworktest.functional; -import java.io.File; - import android.content.Context; import android.content.Intent; -import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; -import android.util.Log; + +import androidx.test.filters.MediumTest; +import androidx.test.filters.Suppress; + import com.android.mediaframeworktest.MediaFrameworkTest; +import java.io.File; + /* * System tests for the handling of mime type in the media framework. * diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java index 55a1545422fd..d7d1875f95e8 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerInvokeTest.java @@ -16,17 +16,14 @@ package com.android.mediaframeworktest.functional; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; - -import android.test.ActivityInstrumentationTestCase2; -import android.util.Log; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; - import android.media.MediaPlayer; import android.os.Parcel; +import android.test.ActivityInstrumentationTestCase2; + +import androidx.test.filters.MediumTest; +import androidx.test.filters.Suppress; + +import com.android.mediaframeworktest.MediaFrameworkTest; import java.util.Calendar; import java.util.Random; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioEffectTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioEffectTest.java index ab78714cb56e..6b8cbe97f404 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioEffectTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioEffectTest.java @@ -16,28 +16,26 @@ package com.android.mediaframeworktest.functional.audio; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; -import android.content.res.AssetFileDescriptor; -import android.media.audiofx.AudioEffect; import android.media.AudioFormat; import android.media.AudioManager; -import android.media.AudioTrack; import android.media.AudioRecord; -import android.media.audiofx.EnvironmentalReverb; -import android.media.audiofx.Equalizer; +import android.media.AudioTrack; import android.media.MediaPlayer; import android.media.MediaRecorder; - +import android.media.audiofx.AudioEffect; +import android.media.audiofx.EnvironmentalReverb; +import android.media.audiofx.Equalizer; import android.os.Looper; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import java.nio.ByteOrder; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; +import com.android.mediaframeworktest.MediaNames; + import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.UUID; /** diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java index 3a332c67c579..25288e11d153 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java @@ -16,16 +16,16 @@ package com.android.mediaframeworktest.functional.audio; -import com.android.mediaframeworktest.MediaFrameworkTest; import android.content.Context; import android.media.AudioManager; -import android.media.MediaPlayer; import android.media.AudioManager.OnAudioFocusChangeListener; import android.os.Looper; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.LargeTest; -import android.util.Log; + +import androidx.test.filters.LargeTest; +import androidx.test.filters.MediumTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; /** * Junit / Instrumentation test case for the media AudioManager api diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioTrackTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioTrackTest.java index eac5c28853d0..107b51d7a6f2 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioTrackTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioTrackTest.java @@ -16,17 +16,15 @@ package com.android.mediaframeworktest.functional.audio; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; - import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioTrack; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; + +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; /** * Junit / Instrumentation test case for the media AudioTrack api diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaBassBoostTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaBassBoostTest.java index 1fa5c0d33cc9..c2dd246b9ae6 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaBassBoostTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaBassBoostTest.java @@ -16,27 +16,13 @@ package com.android.mediaframeworktest.functional.audio; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; -import com.android.mediaframeworktest.functional.EnergyProbe; -import android.content.Context; -import android.content.res.AssetFileDescriptor; -import android.media.audiofx.AudioEffect; -import android.media.AudioManager; import android.media.audiofx.BassBoost; -import android.media.audiofx.Visualizer; -import android.media.MediaPlayer; - -import android.os.Looper; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import java.nio.ByteOrder; -import java.nio.ByteBuffer; -import java.util.UUID; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; /** * Junit / Instrumentation test case for the media AudioTrack api diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java index e788c17e0c9f..4bbd9130509d 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java @@ -16,26 +16,20 @@ package com.android.mediaframeworktest.functional.audio; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; -import com.android.mediaframeworktest.functional.EnergyProbe; import android.content.Context; -import android.content.res.AssetFileDescriptor; -import android.media.audiofx.AudioEffect; import android.media.AudioManager; -import android.media.audiofx.EnvironmentalReverb; -import android.media.audiofx.Visualizer; import android.media.MediaPlayer; - -import android.os.Looper; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; +import android.media.audiofx.AudioEffect; +import android.media.audiofx.EnvironmentalReverb; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import java.nio.ByteOrder; -import java.nio.ByteBuffer; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; +import com.android.mediaframeworktest.MediaNames; +import com.android.mediaframeworktest.functional.EnergyProbe; + import java.util.UUID; /** diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEqualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEqualizerTest.java index da9089d35369..a43f7616398b 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEqualizerTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEqualizerTest.java @@ -16,27 +16,13 @@ package com.android.mediaframeworktest.functional.audio; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; -import com.android.mediaframeworktest.functional.EnergyProbe; -import android.content.Context; -import android.content.res.AssetFileDescriptor; -import android.media.audiofx.AudioEffect; -import android.media.AudioManager; import android.media.audiofx.Equalizer; -import android.media.audiofx.Visualizer; -import android.media.MediaPlayer; - -import android.os.Looper; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import java.nio.ByteOrder; -import java.nio.ByteBuffer; -import java.util.UUID; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; /** * Junit / Instrumentation test case for the media AudioTrack api diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java index bc9c48d9fd55..9d3cf7956784 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java @@ -16,26 +16,20 @@ package com.android.mediaframeworktest.functional.audio; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; -import com.android.mediaframeworktest.functional.EnergyProbe; import android.content.Context; -import android.content.res.AssetFileDescriptor; -import android.media.audiofx.AudioEffect; import android.media.AudioManager; -import android.media.audiofx.PresetReverb; -import android.media.audiofx.Visualizer; import android.media.MediaPlayer; - -import android.os.Looper; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; +import android.media.audiofx.AudioEffect; +import android.media.audiofx.PresetReverb; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import java.nio.ByteOrder; -import java.nio.ByteBuffer; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; +import com.android.mediaframeworktest.MediaNames; +import com.android.mediaframeworktest.functional.EnergyProbe; + import java.util.UUID; /** diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVirtualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVirtualizerTest.java index 122545f06da6..144656c455e9 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVirtualizerTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVirtualizerTest.java @@ -16,27 +16,13 @@ package com.android.mediaframeworktest.functional.audio; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; -import com.android.mediaframeworktest.functional.EnergyProbe; -import android.content.Context; -import android.content.res.AssetFileDescriptor; -import android.media.audiofx.AudioEffect; -import android.media.AudioManager; import android.media.audiofx.Virtualizer; -import android.media.audiofx.Visualizer; -import android.media.MediaPlayer; - -import android.os.Looper; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import java.nio.ByteOrder; -import java.nio.ByteBuffer; -import java.util.UUID; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; /** * Junit / Instrumentation test case for the media AudioTrack api diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java index abf85d7e47ac..76449542ed49 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java @@ -16,24 +16,20 @@ package com.android.mediaframeworktest.functional.audio; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; import android.content.Context; -import android.content.res.AssetFileDescriptor; -import android.media.audiofx.AudioEffect; import android.media.AudioManager; -import android.media.audiofx.Visualizer; import android.media.MediaPlayer; - +import android.media.audiofx.AudioEffect; +import android.media.audiofx.Visualizer; import android.os.Looper; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import java.nio.ByteOrder; -import java.nio.ByteBuffer; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; +import com.android.mediaframeworktest.MediaNames; + import java.util.UUID; /** diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/SimTonesTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/SimTonesTest.java index aaf992cc07a7..ae4207410502 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/SimTonesTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/SimTonesTest.java @@ -17,12 +17,13 @@ package com.android.mediaframeworktest.functional.audio; // import android.content.Resources; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.functional.TonesAutoTest; - import android.content.Context; import android.test.ActivityInstrumentationTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; +import com.android.mediaframeworktest.functional.TonesAutoTest; /** * Junit / Instrumentation test case for the SIM tone generator diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java index 9c08d480ca3a..bf5e816766e3 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java @@ -16,22 +16,23 @@ package com.android.mediaframeworktest.functional.camera; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.helpers.CameraTestHelper; - -import java.io.Writer; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.List; - import android.hardware.Camera.Parameters; import android.os.Handler; import android.os.Looper; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import android.view.SurfaceHolder; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; +import com.android.mediaframeworktest.helpers.CameraTestHelper; + +import java.io.Writer; +import java.util.List; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + /** * Junit / Instrumentation test case for the following camera APIs: * - flash diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java index f9d49644488b..45c95e0ec2a0 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java @@ -20,17 +20,18 @@ import android.hardware.Camera; import android.os.Handler; import android.os.Looper; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import android.view.SurfaceHolder; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.List; +import androidx.test.filters.LargeTest; import com.android.mediaframeworktest.MediaFrameworkTest; import com.android.mediaframeworktest.helpers.CameraTestHelper; +import java.util.List; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + /** * Junit / Instrumentation test case for camera API pairwise testing * Settings tested against: flash mode, exposure compensation, white balance, diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java index 7be2707cc97c..8739820f4a09 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediaplayback/MediaPlayerApiTest.java @@ -16,19 +16,17 @@ package com.android.mediaframeworktest.functional.mediaplayback; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; -import com.android.mediaframeworktest.MediaProfileReader; -import com.android.mediaframeworktest.functional.CodecTest; - import android.content.Context; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; -import java.io.File; +import androidx.test.filters.LargeTest; +import androidx.test.filters.MediumTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; +import com.android.mediaframeworktest.MediaNames; +import com.android.mediaframeworktest.MediaProfileReader; +import com.android.mediaframeworktest.functional.CodecTest; /** * Junit / Instrumentation test case for the media player api diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java index 35540e358c8b..3c456fb96f37 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java @@ -16,37 +16,32 @@ package com.android.mediaframeworktest.functional.mediarecorder; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaNames; - -import java.io.*; - import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; -import android.graphics.Typeface; import android.hardware.Camera; +import android.media.EncoderCapabilities.AudioEncoderCap; +import android.media.EncoderCapabilities.VideoEncoderCap; import android.media.MediaCodec; import android.media.MediaMetadataRetriever; import android.media.MediaPlayer; import android.media.MediaRecorder; -import android.media.EncoderCapabilities; -import android.media.EncoderCapabilities.VideoEncoderCap; -import android.media.EncoderCapabilities.AudioEncoderCap; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; -import android.view.SurfaceView; -import com.android.mediaframeworktest.MediaProfileReader; + +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; import com.android.mediaframeworktest.MediaFrameworkTestRunner; +import com.android.mediaframeworktest.MediaNames; +import com.android.mediaframeworktest.MediaProfileReader; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.Suppress; +import java.io.*; import java.util.List; - /** * Junit / Instrumentation test case for the media recorder api */ diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java index cc7a7d5bb9dc..e89becdec8ed 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java @@ -31,9 +31,10 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; +import androidx.test.filters.SmallTest; + /** * <p> * Junit / Instrumentation test case for the camera2 api diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java index 9d09dcc5c440..eaa5a856eb0e 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java @@ -46,10 +46,11 @@ import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; import android.view.Surface; +import androidx.test.filters.SmallTest; + import com.android.mediaframeworktest.MediaFrameworkIntegrationTestRunner; import org.mockito.ArgumentCaptor; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java index 8c05725a9ef1..0154d6a0e2e2 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java @@ -16,36 +16,33 @@ package com.android.mediaframeworktest.performance; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaFrameworkPerfTestRunner; -import com.android.mediaframeworktest.MediaNames; -import com.android.mediaframeworktest.MediaTestUtil; - -import android.database.sqlite.SQLiteDatabase; import android.hardware.Camera; import android.hardware.Camera.PreviewCallback; import android.media.CamcorderProfile; import android.media.MediaPlayer; import android.media.MediaRecorder; -import android.media.EncoderCapabilities.VideoEncoderCap; import android.os.ConditionVariable; import android.os.Looper; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import android.view.SurfaceHolder; -import java.util.List; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkPerfTestRunner; +import com.android.mediaframeworktest.MediaFrameworkTest; +import com.android.mediaframeworktest.MediaNames; +import com.android.mediaframeworktest.MediaProfileReader; +import com.android.mediaframeworktest.MediaTestUtil; + import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Writer; -import java.io.File; -import java.io.FileWriter; -import java.io.BufferedWriter; - -import com.android.mediaframeworktest.MediaProfileReader; /** * Junit / Instrumentation - performance measurement for media player and diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java index dc8da4868df3..a47d8bc2f323 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2RecordingTest.java @@ -43,13 +43,13 @@ import android.media.MediaExtractor; import android.media.MediaFormat; import android.media.MediaRecorder; import android.os.SystemClock; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import android.util.Range; import android.util.Size; import android.view.Surface; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.LargeTest; import com.android.ex.camera2.blocking.BlockingSessionCallback; import com.android.mediaframeworktest.Camera2SurfaceViewTestCase; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2SwitchPreviewTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2SwitchPreviewTest.java index a26ee2d1a668..002a143bd8bd 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2SwitchPreviewTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/Camera2SwitchPreviewTest.java @@ -16,71 +16,34 @@ package com.android.mediaframeworktest.stress; -import com.android.ex.camera2.blocking.BlockingSessionCallback; -import com.android.ex.camera2.exceptions.TimeoutRuntimeException; -import com.android.mediaframeworktest.Camera2SurfaceViewTestCase; -import com.android.mediaframeworktest.helpers.Camera2Focuser; -import com.android.mediaframeworktest.helpers.CameraTestUtils; -import com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback; +import static com.android.mediaframeworktest.helpers.CameraTestUtils.MAX_READER_IMAGES; +import static com.android.mediaframeworktest.helpers.CameraTestUtils.SIZE_BOUND_1080P; +import static com.android.mediaframeworktest.helpers.CameraTestUtils.SIZE_BOUND_2160P; +import static com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleImageReaderListener; +import static com.android.mediaframeworktest.helpers.CameraTestUtils.configureCameraSession; +import static com.android.mediaframeworktest.helpers.CameraTestUtils.getSupportedVideoSizes; import android.graphics.ImageFormat; -import android.graphics.Point; -import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraCaptureSession.CaptureCallback; -import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession; import android.hardware.camera2.CameraDevice; -import android.hardware.camera2.CameraAccessException; -import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; -import android.hardware.camera2.DngCreator; -import android.hardware.camera2.params.MeteringRectangle; -import android.media.Image; -import android.media.ImageReader; import android.media.CamcorderProfile; -import android.media.MediaExtractor; -import android.media.MediaFormat; +import android.media.ImageReader; import android.media.MediaRecorder; -import android.os.ConditionVariable; -import android.os.Environment; import android.util.Log; -import android.util.Pair; -import android.util.Rational; +import android.util.Range; import android.util.Size; import android.view.Surface; -import android.hardware.camera2.params.StreamConfigurationMap; -import android.test.suitebuilder.annotation.LargeTest; -import android.util.Log; -import android.util.Range; - -import java.io.ByteArrayOutputStream; -import java.util.ArrayList; -import java.util.List; -import java.io.File; -import java.util.Arrays; -import java.util.HashMap; - -import static com.android.mediaframeworktest.helpers.CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.MAX_READER_IMAGES; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleImageReaderListener; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.basicValidateJpegImage; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.configureCameraSession; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.dumpFile; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.getDataFromImage; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.getValueNotNull; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.makeImageReader; -import static com.android.ex.camera2.blocking.BlockingSessionCallback.SESSION_CLOSED; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.SESSION_CLOSE_TIMEOUT_MS; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.SIZE_BOUND_1080P; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.SIZE_BOUND_2160P; -import static com.android.mediaframeworktest.helpers.CameraTestUtils.getSupportedVideoSizes; import com.android.ex.camera2.blocking.BlockingSessionCallback; import com.android.mediaframeworktest.Camera2SurfaceViewTestCase; -import com.android.mediaframeworktest.helpers.CameraTestUtils; +import com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback; -import junit.framework.AssertionFailedError; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; /** * <p>Tests Back/Front camera switching and Camera/Video modes witching.</p> diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java index 74244b9745f0..9883df2e3b86 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/CameraStressTest.java @@ -16,6 +16,16 @@ package com.android.mediaframeworktest.stress; +import android.hardware.Camera.Parameters; +import android.os.Handler; +import android.os.Looper; +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; +import android.view.SurfaceHolder; + +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.LargeTest; + import com.android.mediaframeworktest.MediaFrameworkTest; import com.android.mediaframeworktest.helpers.CameraTestHelper; @@ -23,19 +33,9 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.Writer; +import java.util.List; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; -import java.util.List; - -import android.hardware.Camera.Parameters; -import android.os.Handler; -import android.os.Looper; -import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.LargeTest; -import android.util.Log; -import android.view.SurfaceHolder; - -import androidx.test.InstrumentationRegistry; /** * Junit / Instrumentation test case for the following camera APIs: diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java index 6a820ecf3b30..cb69e1b461d1 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java @@ -16,16 +16,16 @@ package com.android.mediaframeworktest.stress; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaPlayerStressTestRunner; - import android.os.Bundle; import android.os.Environment; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; import com.android.mediaframeworktest.MediaNames; +import com.android.mediaframeworktest.MediaPlayerStressTestRunner; import com.android.mediaframeworktest.functional.CodecTest; import java.io.BufferedReader; @@ -34,7 +34,6 @@ import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.Writer; - import java.util.ArrayList; import java.util.List; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java index 4221f1bad30c..221881a9ecb9 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java @@ -16,16 +16,16 @@ package com.android.mediaframeworktest.stress; -import com.android.mediaframeworktest.MediaFrameworkTest; -import com.android.mediaframeworktest.MediaPlayerStressTestRunner; - import android.os.Bundle; import android.os.Environment; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; import com.android.mediaframeworktest.MediaNames; +import com.android.mediaframeworktest.MediaPlayerStressTestRunner; import com.android.mediaframeworktest.functional.CodecTest; import java.io.BufferedWriter; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java index 199f17970890..47bd63397448 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java @@ -17,16 +17,6 @@ package com.android.mediaframeworktest.stress; -import com.android.mediaframeworktest.MediaFrameworkTest; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - import android.hardware.Camera; import android.media.CamcorderProfile; import android.media.MediaPlayer; @@ -35,11 +25,22 @@ import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import android.view.SurfaceHolder; + +import androidx.test.filters.LargeTest; + +import com.android.mediaframeworktest.MediaFrameworkTest; import com.android.mediaframeworktest.MediaRecorderStressTestRunner; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + /** * Junit / Instrumentation test case for the media player api */ diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/template/AudioTestHarnessTemplateAndroidTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/template/AudioTestHarnessTemplateAndroidTest.java index 6c2a3f72edc8..fec108f9a20b 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/template/AudioTestHarnessTemplateAndroidTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/template/AudioTestHarnessTemplateAndroidTest.java @@ -20,9 +20,10 @@ import android.media.AudioAttributes; import android.media.MediaPlayer; import android.os.Bundle; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; +import androidx.test.filters.LargeTest; + import com.android.mediaframeworktest.AudioTestHarnessTemplateRunner; import com.android.mediaframeworktest.MediaFrameworkTest; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java index c814eba7d187..964da4527917 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java @@ -16,12 +16,10 @@ package com.android.mediaframeworktest.unit; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Log; -import android.util.Pair; -import android.util.Range; -import android.util.Rational; -import android.util.SizeF; +import static android.hardware.camera2.impl.CameraMetadataNative.*; + +import static com.android.mediaframeworktest.unit.ByteArrayHelpers.*; + import android.graphics.ImageFormat; import android.graphics.Point; import android.graphics.PointF; @@ -31,7 +29,6 @@ import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraMetadata; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; -import android.util.Size; import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.marshal.impl.MarshalQueryableEnum; import android.hardware.camera2.params.ColorSpaceTransform; @@ -45,9 +42,14 @@ import android.hardware.camera2.params.StreamConfigurationDuration; import android.hardware.camera2.params.StreamConfigurationMap; import android.hardware.camera2.params.TonemapCurve; import android.hardware.camera2.utils.TypeReference; +import android.util.Log; +import android.util.Pair; +import android.util.Range; +import android.util.Rational; +import android.util.Size; +import android.util.SizeF; -import static android.hardware.camera2.impl.CameraMetadataNative.*; -import static com.android.mediaframeworktest.unit.ByteArrayHelpers.*; +import androidx.test.filters.SmallTest; import java.lang.reflect.Array; import java.nio.ByteBuffer; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsTypeReferenceTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsTypeReferenceTest.java index 1b765eabd1c8..924ad476bb35 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsTypeReferenceTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsTypeReferenceTest.java @@ -20,8 +20,7 @@ import static android.hardware.camera2.utils.TypeReference.*; import android.hardware.camera2.utils.TypeReference; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Log; +import androidx.test.filters.SmallTest; import java.lang.reflect.Type; import java.util.List; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java index b648763db9e9..6cb8b54617e5 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraUtilsUncheckedThrowTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.utils.UncheckedThrow; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import junit.framework.Assert; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java index 2cb5704f5c2d..d9fc88de3f8a 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ImageReaderTest.java @@ -24,7 +24,8 @@ import android.media.Image.Plane; import android.media.ImageReader; import android.media.ImageReader.OnImageAvailableListener; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; public class ImageReaderTest extends AndroidTestCase { diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java index ea0494f2a8f1..65264d30f04f 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java @@ -36,7 +36,8 @@ import android.provider.MediaStore.Files; import android.provider.MediaStore.Images; import android.provider.MediaStore.Video; import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import org.mockito.ArgumentMatcher; import org.mockito.Mock; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java index e3d389737bb0..80edf8a4bd0a 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java @@ -26,10 +26,10 @@ import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; import android.util.Log; +import androidx.test.filters.LargeTest; +import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; import com.android.media.playback.flags.Flags; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java index 37dd4b5330c5..06c527d3e584 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetCurrentPositionStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java index 48fd16c3f4b2..5a3604401e3b 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetDurationStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoHeightStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoHeightStateUnitTest.java index 6d3c0831418e..f86f77e26187 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoHeightStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoHeightStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoWidthStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoWidthStateUnitTest.java index 198439cd921c..fb31edb3b720 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoWidthStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerGetVideoWidthStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerIsPlayingStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerIsPlayingStateUnitTest.java index b9c63fd5a4c2..e1c992ebda98 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerIsPlayingStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerIsPlayingStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java index bfa3976f5867..7aed3b7a53c6 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java @@ -18,10 +18,9 @@ package com.android.mediaframeworktest.unit; import android.media.Metadata; import android.os.Parcel; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Log; -import java.util.Calendar; +import androidx.test.filters.SmallTest; + import java.util.Date; /* diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java index 7a967927202a..aa4bfe67e941 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerPauseStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerResetStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerResetStateUnitTest.java index 2497cd7dec3e..d8651f5681b8 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerResetStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerResetStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java index 991fe9cc5041..3bcde7f2bd3e 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSeekToStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java index b984514452d4..36e93c0fb40e 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetAudioStreamTypeStateUnitTest.java @@ -16,10 +16,11 @@ package com.android.mediaframeworktest.unit; -import android.media.MediaPlayer; import android.media.AudioManager; +import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetLoopingStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetLoopingStateUnitTest.java index 17c9d8c1979f..adb56d0f8335 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetLoopingStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetLoopingStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetVolumeStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetVolumeStateUnitTest.java index a149565039f4..84691da19ea8 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetVolumeStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerSetVolumeStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java index 68c8e42a1a21..a0999d894a2c 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStartStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java index ab8519a760b9..b0673a87dd71 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStopStateUnitTest.java @@ -18,7 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaPlayer; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java index 134144d005b9..8299a7e6dd0f 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java @@ -18,8 +18,9 @@ package com.android.mediaframeworktest.unit; import android.media.MediaRecorder; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; + +import androidx.test.filters.MediumTest; + import java.io.IOException; /** diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java index cae9e31c3cad..1e4c06025b8b 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java @@ -18,8 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaRecorder; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; + +import androidx.test.filters.MediumTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java index 4b5a8183087b..b3e9009dbdd4 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java @@ -18,8 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaRecorder; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; + +import androidx.test.filters.MediumTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java index f8ab48cf178e..3b56e6f21484 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java @@ -18,8 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaRecorder; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; + +import androidx.test.filters.MediumTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java index 712a7586f53f..0980802c868c 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java @@ -18,8 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaRecorder; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; + +import androidx.test.filters.MediumTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java index cacdd87557c0..3a4a7c732be3 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java @@ -18,8 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaRecorder; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; + +import androidx.test.filters.MediumTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java index d1232fcfba40..192c8966310e 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java @@ -18,8 +18,8 @@ package com.android.mediaframeworktest.unit; import android.media.MediaRecorder; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; + +import androidx.test.filters.MediumTest; /** * Unit test class to test the set of valid and invalid states that diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java index 91100aef07bf..093ed88f4b9c 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java @@ -18,10 +18,10 @@ package com.android.mediaframeworktest.unit; import android.media.MediaRecorder; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; import android.util.Log; +import androidx.test.filters.MediumTest; + /** * Unit test class to test the set of valid and invalid states that * MediaRecorder.stop() method can be called. diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java index 9dd2732cb0f3..f54f06dae291 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java @@ -16,10 +16,11 @@ package com.android.mediaframeworktest.unit; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Range; import android.util.Rational; +import androidx.test.filters.SmallTest; + /** * <pre> * adb shell am instrument \ diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java index 1bb7db9034f3..a94b5af527cf 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java @@ -16,9 +16,12 @@ package com.android.mediaframeworktest.unit; -import android.test.suitebuilder.annotation.SmallTest; +import static android.util.Rational.*; + import android.util.Rational; +import androidx.test.filters.SmallTest; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -28,8 +31,6 @@ import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Field; -import static android.util.Rational.*; - /** * <pre> * adb shell am instrument \ diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/SurfaceUtilsTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/SurfaceUtilsTest.java index f578e46ea4f1..cd564b2d1fd3 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/SurfaceUtilsTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/SurfaceUtilsTest.java @@ -19,9 +19,10 @@ package com.android.mediaframeworktest.unit; import android.graphics.ImageFormat; import android.hardware.camera2.utils.SurfaceUtils; import android.media.ImageReader; -import android.test.suitebuilder.annotation.SmallTest; import android.view.Surface; +import androidx.test.filters.SmallTest; + import junit.framework.Assert; public class SurfaceUtilsTest extends junit.framework.TestCase { diff --git a/media/tests/projection/Android.bp b/media/tests/projection/Android.bp index c9a886415c6d..fd5f19535537 100644 --- a/media/tests/projection/Android.bp +++ b/media/tests/projection/Android.bp @@ -3,6 +3,7 @@ //######################################################################## package { + default_team: "trendy_team_lse_desktop_os_experience", // See: http://go/android-license-faq // A large-scale-change added 'default_applicable_licenses' to import // all of the 'license_kinds' from "frameworks_base_license" diff --git a/nfc/java/android/nfc/cardemulation/PollingFrame.java b/nfc/java/android/nfc/cardemulation/PollingFrame.java index 3383f3bd4e7a..994f4ae1c2e3 100644 --- a/nfc/java/android/nfc/cardemulation/PollingFrame.java +++ b/nfc/java/android/nfc/cardemulation/PollingFrame.java @@ -201,7 +201,7 @@ public final class PollingFrame implements Parcelable{ /** * Returns the timestamp of when the polling loop frame was observed in milliseconds. These - * timestamps are relative and not absolute and should only be used fro comparing the timing of + * timestamps are relative and not absolute and should only be used for comparing the timing of * frames relative to each other. * @return the timestamp in milliseconds */ diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml index bc3ad0615ada..d910f2fc9904 100644 --- a/packages/CompanionDeviceManager/res/values-nb/strings.xml +++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml @@ -72,6 +72,6 @@ <string name="permission_storage_summary" msgid="3918240895519506417"></string> <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Strøm apper og andre systemfunksjoner fra telefonen"</string> <string name="permission_media_routing_control_summary" msgid="2714631092321412250">"Se en liste over tilgjengelige enheter, og kontroller hvilken enhet som strømmer eller caster lyd eller video fra andre apper"</string> - <string name="device_type" product="default" msgid="8268703872070046263">"telefonen"</string> - <string name="device_type" product="tablet" msgid="5038791954983067774">"nettbrettet"</string> + <string name="device_type" product="default" msgid="8268703872070046263">"telefon"</string> + <string name="device_type" product="tablet" msgid="5038791954983067774">"nettbrett"</string> </resources> diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java index 66282dc209ed..4c1f6313c3a0 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java @@ -27,13 +27,13 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DiscoveryState; import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DiscoveryState.FINISHED_TIMEOUT; -import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_PERMISSIONS; -import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_NAMES; import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_ICONS; +import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_NAMES; +import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_PERMISSIONS; import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_SUMMARIES; +import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_TITLES; import static com.android.companiondevicemanager.CompanionDeviceResources.SUPPORTED_PROFILES; import static com.android.companiondevicemanager.CompanionDeviceResources.SUPPORTED_SELF_MANAGED_PROFILES; -import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_TITLES; import static com.android.companiondevicemanager.Utils.getApplicationLabel; import static com.android.companiondevicemanager.Utils.getHtmlFromResources; import static com.android.companiondevicemanager.Utils.getIcon; @@ -68,6 +68,7 @@ import android.text.Spanned; import android.util.Log; import android.view.View; import android.view.ViewTreeObserver; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; @@ -697,14 +698,15 @@ public class CompanionDeviceActivity extends FragmentActivity implements disableButtons(); + LinearLayoutManager permissionListLayoutManager = + (LinearLayoutManager) mPermissionListRecyclerView + .getLayoutManager(); + // Enable buttons once users scroll down to the bottom of the permission list. mPermissionListRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override - public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - super.onScrollStateChanged(recyclerView, newState); - if (!recyclerView.canScrollVertically(1)) { - enableButtons(); - } + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + enableAllowButtonIfNeeded(permissionListLayoutManager); } }); // Enable buttons if last item in the permission list is visible to the users when @@ -713,26 +715,36 @@ public class CompanionDeviceActivity extends FragmentActivity implements new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { - LinearLayoutManager layoutManager = - (LinearLayoutManager) mPermissionListRecyclerView - .getLayoutManager(); - int lastVisibleItemPosition = - layoutManager.findLastCompletelyVisibleItemPosition(); - int numItems = mPermissionListRecyclerView.getAdapter().getItemCount(); - - if (lastVisibleItemPosition >= numItems - 1) { - enableButtons(); - } - + enableAllowButtonIfNeeded(permissionListLayoutManager); mPermissionListRecyclerView.getViewTreeObserver() .removeOnGlobalLayoutListener(this); } }); + // Set accessibility for the recyclerView that to be able scroll up/down for voice access. + mPermissionListRecyclerView.setAccessibilityDelegate(new View.AccessibilityDelegate() { + public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(host, info); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_DOWN); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP); + } + }); + mConstraintList.setVisibility(View.VISIBLE); mPermissionListRecyclerView.setVisibility(View.VISIBLE); } + // Enable the Allow button if the last element in the PermissionListRecyclerView is reached. + private void enableAllowButtonIfNeeded(LinearLayoutManager layoutManager) { + int lastVisibleItemPosition = + layoutManager.findLastCompletelyVisibleItemPosition(); + int numItems = mPermissionListRecyclerView.getAdapter().getItemCount(); + + if (lastVisibleItemPosition >= numItems - 1) { + enableButtons(); + } + } + // Disable and grey out the Allow and Don't allow buttons if the last permission in the // permission list is not visible to the users. private void disableButtons() { diff --git a/packages/CredentialManager/res/values-af/strings.xml b/packages/CredentialManager/res/values-af/strings.xml index 6c46ffca6aec..b9ed4a2564de 100644 --- a/packages/CredentialManager/res/values-af/strings.xml +++ b/packages/CredentialManager/res/values-af/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Wagwoorde sal steeds saam met toegangsleutels beskikbaar wees terwyl ons na ’n wagwoordlose toekoms beweeg."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Kies waar om jou <xliff:g id="CREATETYPES">%1$s</xliff:g> te stoor"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Kies ’n wagwoordbestuurder om jou inligting te stoor en volgende keer vinniger aan te meld"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Skep toegangsleutel vir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Stoor wagwoord vir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Stoor aanmeldinligting vir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"toegangsleutel"</string> <string name="password" msgid="6738570945182936667">"wagwoord"</string> diff --git a/packages/CredentialManager/res/values-am/strings.xml b/packages/CredentialManager/res/values-am/strings.xml index 6d65fe11fd05..e1ded6ac39a7 100644 --- a/packages/CredentialManager/res/values-am/strings.xml +++ b/packages/CredentialManager/res/values-am/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ወደ የይለፍ ቃል የሌለው ወደፊት ስንሄድ የይለፍ ቃላት ከይለፍ ቁልፎች ጎን ለጎን ይገኛሉ።"</string> <string name="choose_provider_title" msgid="8870795677024868108">"የእርስዎን <xliff:g id="CREATETYPES">%1$s</xliff:g> የት እንደሚያስቀምጡ ይምረጡ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"መረጃዎን ለማስቀመጥ እና በቀጣይ ጊዜ በፍጥነት በመለያ ለመግባት የሚስጥር ቁልፍ አስተዳዳሪን ይምረጡ"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ለ<xliff:g id="APPNAME">%1$s</xliff:g> የይለፍ ቁልፍ ይፈጠር?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"ለ<xliff:g id="APPNAME">%1$s</xliff:g> የይለፍ ቃል ይቀመጥ?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"ለ<xliff:g id="APPNAME">%1$s</xliff:g> የመግቢያ መረጃ ይቀመጥ?"</string> <string name="passkey" msgid="632353688396759522">"የይለፍ ቁልፍ"</string> <string name="password" msgid="6738570945182936667">"የይለፍ ቃል"</string> diff --git a/packages/CredentialManager/res/values-ar/strings.xml b/packages/CredentialManager/res/values-ar/strings.xml index 654d5b6917aa..be55469be98d 100644 --- a/packages/CredentialManager/res/values-ar/strings.xml +++ b/packages/CredentialManager/res/values-ar/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"بينما ننطلق نحو مستقبل بدون كلمات مرور، ستظل كلمات المرور متوفّرة إلى جانب مفاتيح المرور."</string> <string name="choose_provider_title" msgid="8870795677024868108">"اختيار المكان الذي تريد حفظ <xliff:g id="CREATETYPES">%1$s</xliff:g> فيه"</string> <string name="choose_provider_body" msgid="4967074531845147434">"اختَر مدير كلمات مرور لحفظ معلوماتك وتسجيل الدخول بشكل أسرع في المرة القادمة."</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"هل تريد إنشاء مفتاح مرور لتطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\"؟"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"هل تريد حفظ كلمة المرور لتطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\"؟"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"هل تريد حفظ معلومات تسجيل الدخول لتطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\"؟"</string> <string name="passkey" msgid="632353688396759522">"مفتاح المرور"</string> <string name="password" msgid="6738570945182936667">"كلمة المرور"</string> diff --git a/packages/CredentialManager/res/values-as/strings.xml b/packages/CredentialManager/res/values-as/strings.xml index 9ab41ddb214c..6b02ea71dedc 100644 --- a/packages/CredentialManager/res/values-as/strings.xml +++ b/packages/CredentialManager/res/values-as/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"আমি পাছৱৰ্ডবিহীন ভৱিষ্যতৰ দিশে আগবঢ়াৰ লগে লগে পাছকীৰ লগতে পাছৱৰ্ডসমূহো উপলব্ধ হ’ব।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"আপোনাৰ <xliff:g id="CREATETYPES">%1$s</xliff:g> ক’ত ছেভ কৰিব লাগে সেয়া বাছনি কৰক"</string> <string name="choose_provider_body" msgid="4967074531845147434">"আপোনাৰ তথ্য ছেভ কৰি পৰৱৰ্তী সময়ত দ্ৰুতভাৱে ছাইন ইন কৰিবলৈ এটা পাছৱৰ্ড পৰিচালক বাছনি কৰক"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>ৰ বাবে পাছকী সৃষ্টি কৰিবনে?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g>ৰ বাবে পাছৱৰ্ড ছেভ কৰিবনে?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g>ৰ বাবে ছাইন ইনৰ তথ্য ছেভ কৰিবনে?"</string> <string name="passkey" msgid="632353688396759522">"পাছকী"</string> <string name="password" msgid="6738570945182936667">"পাছৱৰ্ড"</string> diff --git a/packages/CredentialManager/res/values-az/strings.xml b/packages/CredentialManager/res/values-az/strings.xml index 67efc8bdde48..caef7270860e 100644 --- a/packages/CredentialManager/res/values-az/strings.xml +++ b/packages/CredentialManager/res/values-az/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsuz gələcəyə doğru irəlilədikcə parollar hələ də açarlar ilə yanaşı əlçatan olacaq."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> elementinin saxlanacağı yeri seçin"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Məlumatlarınızı yadda saxlamaq və növbəti dəfə daha sürətli daxil olmaq üçün parol meneceri seçin"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> üçün giriş açarı yaradılsın?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> üçün parol yadda saxlanılsın?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> üçün giriş məlumatları yadda saxlansın?"</string> <string name="passkey" msgid="632353688396759522">"açar"</string> <string name="password" msgid="6738570945182936667">"parol"</string> diff --git a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml index e01e8a3613c9..0248a08e2a7b 100644 --- a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml +++ b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako se krećemo ka budućnosti bez lozinki, lozinke će i dalje biti dostupne uz pristupne kodove."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gde ćete sačuvati: <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Izaberite menadžera lozinki da biste sačuvali podatke i brže se prijavili sledeći put"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Želite da napravite pristupni kôd za: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Želite da sačuvate lozinku za: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Želite da sačuvate podatke za prijavljivanje za: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"pristupni kôd"</string> <string name="password" msgid="6738570945182936667">"lozinka"</string> diff --git a/packages/CredentialManager/res/values-be/strings.xml b/packages/CredentialManager/res/values-be/strings.xml index e7fe62242a92..cc841d19adbd 100644 --- a/packages/CredentialManager/res/values-be/strings.xml +++ b/packages/CredentialManager/res/values-be/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Хоць мы ўжо рухаемся ў бок будучыні без выкарыстання пароляў, яны па-ранейшаму застануцца даступнымі нароўні з ключамі доступу."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Выберыце, куды захаваць <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Выберыце менеджар пароляў, каб захаваць свае даныя і забяспечыць хуткі ўваход у наступныя разы"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Стварыце ключ доступу да праграмы \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Захаваць пароль для праграмы \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Захаваць інфармацыю пра спосаб уваходу ў праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> <string name="passkey" msgid="632353688396759522">"ключ доступу"</string> <string name="password" msgid="6738570945182936667">"пароль"</string> diff --git a/packages/CredentialManager/res/values-bg/strings.xml b/packages/CredentialManager/res/values-bg/strings.xml index 9b5255efaf73..e7027c1d45da 100644 --- a/packages/CredentialManager/res/values-bg/strings.xml +++ b/packages/CredentialManager/res/values-bg/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Паролите ще продължат да са налице заедно с ключовете за достъп по пътя ни към бъдеще без пароли."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Изберете къде да запазите своите <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Изберете мениджър на пароли, в който да се запазят данните ви, така че следващия път да влезете по-бързо в профила си"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Да се създаде ли код за достъп за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Да се запази ли паролата за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Да се запазят ли данните за вход за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"код за достъп"</string> <string name="password" msgid="6738570945182936667">"парола"</string> diff --git a/packages/CredentialManager/res/values-bn/strings.xml b/packages/CredentialManager/res/values-bn/strings.xml index 981431c57593..49eb68c8216a 100644 --- a/packages/CredentialManager/res/values-bn/strings.xml +++ b/packages/CredentialManager/res/values-bn/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"আমরা পাসওয়ার্ডবিহীন ভবিষ্যতের দিকে এগিয়ে গেলেও, এখনও \'পাসকী\'-এর পাশাপাশি পাসওয়ার্ড ব্যবহার করা যাবে।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"আপনার <xliff:g id="CREATETYPES">%1$s</xliff:g> কোথায় সেভ করবেন তা বেছে নিন"</string> <string name="choose_provider_body" msgid="4967074531845147434">"আপনার তথ্য সেভ করতে একটি Password Manager বেছে নিন এবং পরের বার আরও দ্রুত সাইন-ইন করুন"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>-এর জন্য \'পাসকী\' তৈরি করবেন?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g>-এর জন্য পাসওয়ার্ড সেভ করবেন?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g>-এর জন্য সাইন-ইন সংক্রান্ত তথ্য সেভ করবেন?"</string> <string name="passkey" msgid="632353688396759522">"পাসকী"</string> <string name="password" msgid="6738570945182936667">"পাসওয়ার্ড"</string> diff --git a/packages/CredentialManager/res/values-bs/strings.xml b/packages/CredentialManager/res/values-bs/strings.xml index 2e516250ee6a..afa4882a292e 100644 --- a/packages/CredentialManager/res/values-bs/strings.xml +++ b/packages/CredentialManager/res/values-bs/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako se krećemo prema budućnosti bez lozinki, lozinke će i dalje biti dostupne uz pristupne ključeve."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gdje će se pohranjivati <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Odaberite upravitelja lozinki da sačuvate svoje informacije i brže se prijavite sljedeći put"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Kreirati pristupni ključ za aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Sačuvati lozinku za aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Sačuvati informacije o prijavi za aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"pristupni ključ"</string> <string name="password" msgid="6738570945182936667">"lozinka"</string> diff --git a/packages/CredentialManager/res/values-ca/strings.xml b/packages/CredentialManager/res/values-ca/strings.xml index 97d758cc47bf..c937c09cd442 100644 --- a/packages/CredentialManager/res/values-ca/strings.xml +++ b/packages/CredentialManager/res/values-ca/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Tot i que avancem cap a un futur sense contrasenyes, continuaran estant disponibles juntament amb les claus d\'accés."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Tria on vols desar les <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un gestor de contrasenyes per desar la teva informació i iniciar la sessió més ràpidament la pròxima vegada"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vols crear la clau d\'accés per a <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Vols desar la contrasenya per a <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vols desar la informació d\'inici de sessió per a <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"clau d\'accés"</string> <string name="password" msgid="6738570945182936667">"contrasenya"</string> diff --git a/packages/CredentialManager/res/values-cs/strings.xml b/packages/CredentialManager/res/values-cs/strings.xml index c317c9228a65..06a81b02f7da 100644 --- a/packages/CredentialManager/res/values-cs/strings.xml +++ b/packages/CredentialManager/res/values-cs/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Ačkoliv směřujeme k budoucnosti bez hesel, vedle přístupových klíčů budou stále k dispozici i hesla."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Určete, kam ukládat <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Vyberte správce hesel k uložení svých údajů, abyste se příště mohli přihlásit rychleji"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vytvořit přístupový klíč pro aplikaci <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Uložit heslo pro aplikaci <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Uložit přihlašovací údaje pro aplikaci <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"přístupový klíč"</string> <string name="password" msgid="6738570945182936667">"heslo"</string> diff --git a/packages/CredentialManager/res/values-da/strings.xml b/packages/CredentialManager/res/values-da/strings.xml index cc6b12a0653d..207c33c7a6be 100644 --- a/packages/CredentialManager/res/values-da/strings.xml +++ b/packages/CredentialManager/res/values-da/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Selvom vi nærmer os en fremtid, hvor adgangskoder er mindre fremtrædende, kan de stadig bruges i samspil med adgangsnøgler."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Vælg, hvor du vil gemme dine <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Vælg en adgangskodeadministrator for at gemme dine oplysninger, så du kan logge ind hurtigere næste gang"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vil du oprette en adgangsnøgle til <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Vil du gemme adgangskoden til <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vil du gemme loginoplysningerne til <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"adgangsnøgle"</string> <string name="password" msgid="6738570945182936667">"adgangskode"</string> diff --git a/packages/CredentialManager/res/values-de/strings.xml b/packages/CredentialManager/res/values-de/strings.xml index 0dbde65becc6..38fa3e9a4faa 100644 --- a/packages/CredentialManager/res/values-de/strings.xml +++ b/packages/CredentialManager/res/values-de/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Auch wenn wir uns auf eine passwortlose Zukunft zubewegen, werden neben Passkeys weiter Passwörter verfügbar sein."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Wähle aus, wo deine <xliff:g id="CREATETYPES">%1$s</xliff:g> gespeichert werden sollen"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Du kannst einen Passwortmanager auswählen, um deine Anmeldedaten zu speichern, damit du dich nächstes Mal schneller anmelden kannst"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Passkey für <xliff:g id="APPNAME">%1$s</xliff:g> erstellen?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Passwort für <xliff:g id="APPNAME">%1$s</xliff:g> speichern?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Anmeldedaten für <xliff:g id="APPNAME">%1$s</xliff:g> speichern?"</string> <string name="passkey" msgid="632353688396759522">"Passkey"</string> <string name="password" msgid="6738570945182936667">"Passwort"</string> diff --git a/packages/CredentialManager/res/values-el/strings.xml b/packages/CredentialManager/res/values-el/strings.xml index c2a28631a7dc..509cfe6d34f3 100644 --- a/packages/CredentialManager/res/values-el/strings.xml +++ b/packages/CredentialManager/res/values-el/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Καθώς κινούμαστε προς ένα μέλλον χωρίς κωδικούς πρόσβασης, οι κωδικοί πρόσβασης θα εξακολουθούν να είναι διαθέσιμοι μαζί με τα κλειδιά πρόσβασης."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Επιλέξτε πού θα αποθηκεύονται τα <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Επιλέξτε ένα πρόγραμμα διαχείρισης κωδικών πρόσβασης για να αποθηκεύσετε τα στοιχεία σας και να συνδεθείτε πιο γρήγορα την επόμενη φορά."</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Δημιουργία κλειδιού πρόσβασης για <xliff:g id="APPNAME">%1$s</xliff:g>;"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Αποθήκευση κωδικού πρόσβασης για <xliff:g id="APPNAME">%1$s</xliff:g>;"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Αποθήκευση στοιχείων σύνδεσης για <xliff:g id="APPNAME">%1$s</xliff:g>;"</string> <string name="passkey" msgid="632353688396759522">"κλειδί πρόσβασης"</string> <string name="password" msgid="6738570945182936667">"κωδικός πρόσβασης"</string> diff --git a/packages/CredentialManager/res/values-en-rAU/strings.xml b/packages/CredentialManager/res/values-en-rAU/strings.xml index 7ae0583bcb45..cd63b41bc331 100644 --- a/packages/CredentialManager/res/values-en-rAU/strings.xml +++ b/packages/CredentialManager/res/values-en-rAU/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Create passkey for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Save password for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Save sign-in info for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-en-rCA/strings.xml b/packages/CredentialManager/res/values-en-rCA/strings.xml index 195f12f8ee4c..ff1de20583bd 100644 --- a/packages/CredentialManager/res/values-en-rCA/strings.xml +++ b/packages/CredentialManager/res/values-en-rCA/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Create passkey for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Save password for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Save sign-in info for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-en-rGB/strings.xml b/packages/CredentialManager/res/values-en-rGB/strings.xml index 7ae0583bcb45..cd63b41bc331 100644 --- a/packages/CredentialManager/res/values-en-rGB/strings.xml +++ b/packages/CredentialManager/res/values-en-rGB/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Create passkey for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Save password for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Save sign-in info for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-en-rIN/strings.xml b/packages/CredentialManager/res/values-en-rIN/strings.xml index 7ae0583bcb45..cd63b41bc331 100644 --- a/packages/CredentialManager/res/values-en-rIN/strings.xml +++ b/packages/CredentialManager/res/values-en-rIN/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Create passkey for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Save password for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Save sign-in info for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-en-rXC/strings.xml b/packages/CredentialManager/res/values-en-rXC/strings.xml index 5949607c318b..8ffe0016fa23 100644 --- a/packages/CredentialManager/res/values-en-rXC/strings.xml +++ b/packages/CredentialManager/res/values-en-rXC/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Create passkey for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Save password for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Save sign-in info for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-es-rUS/strings.xml b/packages/CredentialManager/res/values-es-rUS/strings.xml index f42693edcc73..29fb64db2ed2 100644 --- a/packages/CredentialManager/res/values-es-rUS/strings.xml +++ b/packages/CredentialManager/res/values-es-rUS/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"A medida que avanzamos hacia un futuro sin contraseñas, estas seguirán estando disponibles junto a las llaves de acceso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Elige dónde guardar tus <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un administrador de contraseñas para guardar tu información y acceder más rápido la próxima vez"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"¿Quieres crear una llave de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"¿Quieres guardar la contraseña para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"¿Quieres guardar la información de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"llave de acceso"</string> <string name="password" msgid="6738570945182936667">"contraseña"</string> diff --git a/packages/CredentialManager/res/values-es/strings.xml b/packages/CredentialManager/res/values-es/strings.xml index 7e16e208a045..077ea99ab0df 100644 --- a/packages/CredentialManager/res/values-es/strings.xml +++ b/packages/CredentialManager/res/values-es/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Aunque nos dirigimos hacia un mundo sin contraseñas, estas seguirán estando disponibles junto con las llaves de acceso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Elige dónde guardar tus <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un gestor de contraseñas para guardar tu información e iniciar sesión más rápido la próxima vez"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"¿Crear llave de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"¿Guardar la contraseña de <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"¿Guardar la información de inicio de sesión de <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"llave de acceso"</string> <string name="password" msgid="6738570945182936667">"contraseña"</string> diff --git a/packages/CredentialManager/res/values-et/strings.xml b/packages/CredentialManager/res/values-et/strings.xml index 0ae48b47c92a..6de564b9ed99 100644 --- a/packages/CredentialManager/res/values-et/strings.xml +++ b/packages/CredentialManager/res/values-et/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Liikudes paroolivaba tuleviku poole, jäävad paroolid pääsuvõtmete kõrval siiski kättesaadavaks."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Valige, kuhu soovite oma <xliff:g id="CREATETYPES">%1$s</xliff:g> salvestada"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Valige paroolihaldur, et salvestada oma teave ja järgmisel korral kiiremini sisse logida"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Kas luua rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> jaoks pääsuvõti?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Kas salvestada rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> jaoks parool?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Kas salvestada rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> jaoks sisselogimisandmed?"</string> <string name="passkey" msgid="632353688396759522">"pääsuvõti"</string> <string name="password" msgid="6738570945182936667">"parool"</string> diff --git a/packages/CredentialManager/res/values-eu/strings.xml b/packages/CredentialManager/res/values-eu/strings.xml index 8775c8782101..018968cf6d70 100644 --- a/packages/CredentialManager/res/values-eu/strings.xml +++ b/packages/CredentialManager/res/values-eu/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Pasahitzik gabeko etorkizun baterantz goazen arren, pasahitzek sarbide-gakoen bizikide izaten jarraituko dute."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Aukeratu non gorde <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Hautatu informazioa gordetzeko pasahitz-kudeatzaile bat eta hasi saioa bizkorrago hurrengoan"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> atzitzeko sarbide-gako bat sortu nahi duzu?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioko pasahitza gorde nahi duzu?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioko saioa hasteko informazioa gorde nahi duzu?"</string> <string name="passkey" msgid="632353688396759522">"sarbide-gakoa"</string> <string name="password" msgid="6738570945182936667">"pasahitza"</string> diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml index 381c61e8c01a..55a79d86a3f8 100644 --- a/packages/CredentialManager/res/values-fa/strings.xml +++ b/packages/CredentialManager/res/values-fa/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"درحالیکه بهسوی آیندهای بیگذرواژه حرکت میکنیم، گذرواژهها همچنان در کنار گذرکلیدها دردسترس خواهند بود"</string> <string name="choose_provider_title" msgid="8870795677024868108">"جایی را برای ذخیره کردن <xliff:g id="CREATETYPES">%1$s</xliff:g> انتخاب کنید"</string> <string name="choose_provider_body" msgid="4967074531845147434">"مدیر گذرواژهای انتخاب کنید تا اطلاعاتتان را ذخیره کنید و دفعه بعد سریعتر به سیستم وارد شوید"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"برای <xliff:g id="APPNAME">%1$s</xliff:g> گذرکلید ایجاد شود؟"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"گذرواژه <xliff:g id="APPNAME">%1$s</xliff:g> ذخیره شود؟"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"اطلاعات ورود به سیستم <xliff:g id="APPNAME">%1$s</xliff:g> ذخیره شود؟"</string> <string name="passkey" msgid="632353688396759522">"گذرکلید"</string> <string name="password" msgid="6738570945182936667">"گذرواژه"</string> diff --git a/packages/CredentialManager/res/values-fi/strings.xml b/packages/CredentialManager/res/values-fi/strings.xml index 3c1c5968e433..9f95720a22b4 100644 --- a/packages/CredentialManager/res/values-fi/strings.xml +++ b/packages/CredentialManager/res/values-fi/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kehitys kulkee kohti salasanatonta tulevaisuutta, mutta salasanat ovat edelleen käytettävissä avainkoodien ohella."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Valitse, minne <xliff:g id="CREATETYPES">%1$s</xliff:g> tallennetaan"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Valitse salasanojen ylläpitotyökalu, niin voit tallentaa tietosi ja kirjautua ensi kerralla nopeammin sisään"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Luodaanko avainkoodi (<xliff:g id="APPNAME">%1$s</xliff:g>)?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Tallennetaanko salasana (<xliff:g id="APPNAME">%1$s</xliff:g>)?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Tallennetaanko kirjautumistiedot (<xliff:g id="APPNAME">%1$s</xliff:g>)?"</string> <string name="passkey" msgid="632353688396759522">"avainkoodi"</string> <string name="password" msgid="6738570945182936667">"salasana"</string> diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml index ff95af239622..481fac9b1da6 100644 --- a/packages/CredentialManager/res/values-fr-rCA/strings.xml +++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"À mesure que nous nous dirigeons vers un avenir sans mot de passe, ils resteront toujours utilisés parallèlement aux clés d\'accès."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choisir où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Sélectionnez un gestionnaire de mots de passe pour enregistrer vos renseignements et vous connecter plus rapidement la prochaine fois"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Créer une clé d\'accès pour <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Enregistrer le mot de passe pour <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Enregistrer les renseignements de connexion pour <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"clé d\'accès"</string> <string name="password" msgid="6738570945182936667">"mot de passe"</string> diff --git a/packages/CredentialManager/res/values-fr/strings.xml b/packages/CredentialManager/res/values-fr/strings.xml index d39391221713..37df7fb1e83d 100644 --- a/packages/CredentialManager/res/values-fr/strings.xml +++ b/packages/CredentialManager/res/values-fr/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Nous nous dirigeons vers un futur sans mots de passe, mais ceux-ci resteront disponibles en plus des clés d\'accès."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Choisissez où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Sélectionnez un gestionnaire de mots de passe pour enregistrer vos informations et vous connecter plus rapidement la prochaine fois"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Créer une clé d\'accès pour <xliff:g id="APPNAME">%1$s</xliff:g> ?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Enregistrer le mot de passe pour <xliff:g id="APPNAME">%1$s</xliff:g> ?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Enregistrer les informations de connexion pour <xliff:g id="APPNAME">%1$s</xliff:g> ?"</string> <string name="passkey" msgid="632353688396759522">"clé d\'accès"</string> <string name="password" msgid="6738570945182936667">"mot de passe"</string> diff --git a/packages/CredentialManager/res/values-gl/strings.xml b/packages/CredentialManager/res/values-gl/strings.xml index d3c822233c17..8770465aecd6 100644 --- a/packages/CredentialManager/res/values-gl/strings.xml +++ b/packages/CredentialManager/res/values-gl/strings.xml @@ -17,7 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="app_name" msgid="4539824758261855508">"Xestor de credenciais"</string> + <string name="app_name" msgid="4539824758261855508">"Credential Manager"</string> <string name="string_cancel" msgid="6369133483981306063">"Cancelar"</string> <string name="string_continue" msgid="1346732695941131882">"Continuar"</string> <string name="string_more_options" msgid="2763852250269945472">"Gardar doutro xeito"</string> @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Durante este percorrido cara a un futuro sen contrasinais, estes seguirán estando dispoñibles a canda as claves de acceso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Escolle onde queres gardar: <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un xestor de contrasinais para gardar a túa información e iniciar sesión máis rápido a próxima vez"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Queres crear unha clave de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Queres gardar o contrasinal de <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Queres gardar a información de inicio de sesión de <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"clave de acceso"</string> <string name="password" msgid="6738570945182936667">"contrasinal"</string> diff --git a/packages/CredentialManager/res/values-gu/strings.xml b/packages/CredentialManager/res/values-gu/strings.xml index 3d4da84df23b..efc88c13a3eb 100644 --- a/packages/CredentialManager/res/values-gu/strings.xml +++ b/packages/CredentialManager/res/values-gu/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"આપણે પાસવર્ડ રહિત ભવિષ્ય તરફ આગળ વધી રહ્યાં છીએ, છતાં પાસકીની સાથોસાથ હજી પણ પાસવર્ડ ઉપલબ્ધ રહેશે."</string> <string name="choose_provider_title" msgid="8870795677024868108">"તમારી <xliff:g id="CREATETYPES">%1$s</xliff:g> ક્યાં સાચવવી તે પસંદ કરો"</string> <string name="choose_provider_body" msgid="4967074531845147434">"તમારી માહિતી સાચવવા માટે પાસવર્ડ મેનેજર પસંદ કરો અને આગલી વખતે વધુ ઝડપથી સાઇન ઇન કરો"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> માટે પાસકી બનાવીએ?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> માટે પાસવર્ડ સાચવીએ?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> માટે સાઇન-ઇન કરવાની માહિતી સાચવીએ?"</string> <string name="passkey" msgid="632353688396759522">"પાસકી"</string> <string name="password" msgid="6738570945182936667">"પાસવર્ડ"</string> diff --git a/packages/CredentialManager/res/values-hi/strings.xml b/packages/CredentialManager/res/values-hi/strings.xml index 672a8523d9ed..661a4a227916 100644 --- a/packages/CredentialManager/res/values-hi/strings.xml +++ b/packages/CredentialManager/res/values-hi/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"आने वाले समय में बिना पासवर्ड वाली टेक्नोलॉजी यानी पासकी का इस्तेमाल बढ़ेगा, हालांकि इसके साथ-साथ पासवर्ड भी इस्तेमाल किए जा सकेंगे."</string> <string name="choose_provider_title" msgid="8870795677024868108">"चुनें कि अपनी <xliff:g id="CREATETYPES">%1$s</xliff:g> कहां सेव करनी हैं"</string> <string name="choose_provider_body" msgid="4967074531845147434">"अपनी जानकारी सेव करने के लिए, पासवर्ड मैनेजर चुनें और अगली बार ज़्यादा तेज़ी से साइन इन करें"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"क्या आपको <xliff:g id="APPNAME">%1$s</xliff:g> के लिए पासकी बनानी है?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"क्या आपको <xliff:g id="APPNAME">%1$s</xliff:g> के लिए पासवर्ड सेव करना है?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"क्या आपको <xliff:g id="APPNAME">%1$s</xliff:g> के लिए साइन-इन की जानकारी सेव करनी है?"</string> <string name="passkey" msgid="632353688396759522">"पासकी"</string> <string name="password" msgid="6738570945182936667">"पासवर्ड"</string> diff --git a/packages/CredentialManager/res/values-hr/strings.xml b/packages/CredentialManager/res/values-hr/strings.xml index 525ade3642d4..eceb1b54c247 100644 --- a/packages/CredentialManager/res/values-hr/strings.xml +++ b/packages/CredentialManager/res/values-hr/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako idemo u smjeru budućnosti bez zaporki, one će i dalje biti dostupne uz pristupne ključeve."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gdje će se spremati <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Odaberite upravitelja zaporki kako biste spremili svoje informacije i drugi se put brže prijavili"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Želite li izraditi pristupni ključ za <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Spremiti zaporku za <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Spremiti informacije o prijavi za <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"pristupni ključ"</string> <string name="password" msgid="6738570945182936667">"zaporka"</string> diff --git a/packages/CredentialManager/res/values-hu/strings.xml b/packages/CredentialManager/res/values-hu/strings.xml index 1a67ecb02859..3415eea3f06c 100644 --- a/packages/CredentialManager/res/values-hu/strings.xml +++ b/packages/CredentialManager/res/values-hu/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Miközben a jelszó nélküli jövő felé haladunk, a jelszavak továbbra is rendelkezésre állnak majd az azonosítókulcsok mellett."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Válassza ki, hogy hova szeretné menteni <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Válasszon jelszókezelőt, hogy menthesse az adatait, és gyorsabban jelentkezhessen be a következő alkalommal."</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Létrehoz azonosítókulcsot a következőhöz: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Szeretné elmenteni a(z) <xliff:g id="APPNAME">%1$s</xliff:g> jelszavát?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Menti a bejelentkezési adatokat a következőhöz: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"azonosítókulcs"</string> <string name="password" msgid="6738570945182936667">"jelszó"</string> diff --git a/packages/CredentialManager/res/values-hy/strings.xml b/packages/CredentialManager/res/values-hy/strings.xml index aeb39909ef9c..af803b4e7594 100644 --- a/packages/CredentialManager/res/values-hy/strings.xml +++ b/packages/CredentialManager/res/values-hy/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Թեև մենք առանց գաղտնաբառերի ապագայի ճանապարհին ենք, դրանք դեռ հասանելի կլինեն անցաբառերի հետ մեկտեղ։"</string> <string name="choose_provider_title" msgid="8870795677024868108">"Նշեք, թե որտեղ եք ուզում պահել ձեր <xliff:g id="CREATETYPES">%1$s</xliff:g>ը"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Ընտրեք գաղտնաբառերի կառավարիչ՝ ձեր տեղեկությունները պահելու և հաջորդ անգամ ավելի արագ մուտք գործելու համար"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Ստեղծե՞լ անցաբառ <xliff:g id="APPNAME">%1$s</xliff:g> հավելվածի համար"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Պահե՞լ «<xliff:g id="APPNAME">%1$s</xliff:g>» հավելվածի գաղտնաբառը"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Պահե՞լ «<xliff:g id="APPNAME">%1$s</xliff:g>» հավելվածի մուտքի տվյալները"</string> <string name="passkey" msgid="632353688396759522">"անցաբառ"</string> <string name="password" msgid="6738570945182936667">"գաղտնաբառ"</string> diff --git a/packages/CredentialManager/res/values-in/strings.xml b/packages/CredentialManager/res/values-in/strings.xml index 8bc868617430..180c869a8430 100644 --- a/packages/CredentialManager/res/values-in/strings.xml +++ b/packages/CredentialManager/res/values-in/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Sandi akan tetap tersedia bersama kunci sandi seiring perjalanan menuju era di mana sandi tidak diperlukan lagi."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Pilih tempat penyimpanan <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Pilih pengelola sandi untuk menyimpan info Anda dan login lebih cepat lain kali"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Buat kunci sandi untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Simpan sandi untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Simpan info login untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"kunci sandi"</string> <string name="password" msgid="6738570945182936667">"sandi"</string> diff --git a/packages/CredentialManager/res/values-is/strings.xml b/packages/CredentialManager/res/values-is/strings.xml index e75746317889..332d15e4f888 100644 --- a/packages/CredentialManager/res/values-is/strings.xml +++ b/packages/CredentialManager/res/values-is/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Við stefnum að framtíð án aðgangsorða en aðgangsorð verða áfram í boði samhliða aðgangslyklum."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Veldu hvar þú vilt vista <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Veldu aðgangsorðastjórnun til að vista upplýsingarnar og vera fljótari að skrá þig inn næst"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Viltu búa til aðgangslykil fyrir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Viltu vista aðgangsorð fyrir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Viltu vista innskráningarupplýsingar fyrir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"aðgangslykill"</string> <string name="password" msgid="6738570945182936667">"aðgangsorð"</string> diff --git a/packages/CredentialManager/res/values-it/strings.xml b/packages/CredentialManager/res/values-it/strings.xml index 724137bfe962..5c8333693033 100644 --- a/packages/CredentialManager/res/values-it/strings.xml +++ b/packages/CredentialManager/res/values-it/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Il futuro sarà senza password, ma per ora saranno ancora disponibili insieme alle passkey."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Scegli dove salvare le <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Seleziona un gestore delle password per salvare i tuoi dati e accedere più velocemente la prossima volta"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vuoi creare una passkey per <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Vuoi salvare la password di <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vuoi salvare i dati di accesso di <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-iw/strings.xml b/packages/CredentialManager/res/values-iw/strings.xml index a3adedf89e82..55fb9f2912b2 100644 --- a/packages/CredentialManager/res/values-iw/strings.xml +++ b/packages/CredentialManager/res/values-iw/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"אנחנו מתקדמים לעבר עתיד ללא סיסמאות, אבל עדיין אפשר יהיה להשתמש בסיסמאות וגם במפתחות גישה."</string> <string name="choose_provider_title" msgid="8870795677024868108">"בחירת המקום לשמירה של <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"אפשר לבחור באחד משירותי ניהול הסיסמאות כדי לשמור את הפרטים ולהיכנס לחשבון מהר יותר בפעם הבאה"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ליצור מפתח גישה ל-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"לשמור את הסיסמה של <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"לשמור את פרטי הכניסה של <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"מפתח גישה"</string> <string name="password" msgid="6738570945182936667">"סיסמה"</string> diff --git a/packages/CredentialManager/res/values-ja/strings.xml b/packages/CredentialManager/res/values-ja/strings.xml index 2269f7ee2eee..1ffc7dbe931c 100644 --- a/packages/CredentialManager/res/values-ja/strings.xml +++ b/packages/CredentialManager/res/values-ja/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"将来的にパスワードレスに移行するにあたり、パスワードもパスキーと並行して引き続きご利用いただけます。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g>の保存先を選択"</string> <string name="choose_provider_body" msgid="4967074531845147434">"パスワード マネージャーを選択して情報を保存しておくと、次回からすばやくログインできます"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> のパスキーを作成しますか?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> のパスワードを保存しますか?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> のログイン情報を保存しますか?"</string> <string name="passkey" msgid="632353688396759522">"パスキー"</string> <string name="password" msgid="6738570945182936667">"パスワード"</string> diff --git a/packages/CredentialManager/res/values-ka/strings.xml b/packages/CredentialManager/res/values-ka/strings.xml index f58e4336b8fa..fdf079715181 100644 --- a/packages/CredentialManager/res/values-ka/strings.xml +++ b/packages/CredentialManager/res/values-ka/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"უპაროლო მომავალში პაროლები კვლავ ხელმისაწვდომი იქნება, წვდომის გასაღებებთან ერთად."</string> <string name="choose_provider_title" msgid="8870795677024868108">"აირჩიეთ სად შეინახოთ თქვენი <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"აირჩიეთ პაროლების მმართველი თქვენი ინფორმაციის შესანახად, რომ მომავალში უფრო სწრაფად შეხვიდეთ."</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"შექმნით წვდომის გასაღებს <xliff:g id="APPNAME">%1$s</xliff:g> აპისთვის?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"შეინახავთ <xliff:g id="APPNAME">%1$s</xliff:g> აპის პაროლს?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"შეინახავთ <xliff:g id="APPNAME">%1$s</xliff:g> აპში შესვლის ინფორმაციას?"</string> <string name="passkey" msgid="632353688396759522">"წვდომის გასაღები"</string> <string name="password" msgid="6738570945182936667">"პაროლი"</string> diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml index 79fe5ce096a6..1c1b186f88d8 100644 --- a/packages/CredentialManager/res/values-kk/strings.xml +++ b/packages/CredentialManager/res/values-kk/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Құпия сөзсіз болашақ жақын болғанына қарамастан, келешекте құпия сөздерді кіру кілттерімен қатар қолдана беруге болады."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> қайда сақталатынын таңдаңыз"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Мәліметіңізді сақтап, келесіде жылдам кіру үшін құпия сөз менеджерін таңдаңыз."</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> үшін кіру кілтін жасау керек пе?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> үшін құпия сөзді сақтау керек пе?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> үшін кіру мәліметін сақтау керек пе?"</string> <string name="passkey" msgid="632353688396759522">"Кіру кілті"</string> <string name="password" msgid="6738570945182936667">"құпия сөз"</string> diff --git a/packages/CredentialManager/res/values-km/strings.xml b/packages/CredentialManager/res/values-km/strings.xml index feba45e9b525..084087986f55 100644 --- a/packages/CredentialManager/res/values-km/strings.xml +++ b/packages/CredentialManager/res/values-km/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"នៅពេលដែលយើងឈានទៅរកអនាគតដែលគ្មានពាក្យសម្ងាត់ ពាក្យសម្ងាត់នៅតែអាចប្រើបានរួមជាមួយកូដសម្ងាត់។"</string> <string name="choose_provider_title" msgid="8870795677024868108">"ជ្រើសរើសកន្លែងដែលត្រូវរក្សាទុក<xliff:g id="CREATETYPES">%1$s</xliff:g>របស់អ្នក"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ជ្រើសរើសកម្មវិធីគ្រប់គ្រងពាក្យសម្ងាត់ ដើម្បីរក្សាទុកព័ត៌មានរបស់អ្នក និងចូលគណនីបានកាន់តែរហ័សនៅពេលលើកក្រោយ"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"បង្កើតកូដសម្ងាត់សម្រាប់ <xliff:g id="APPNAME">%1$s</xliff:g> ឬ?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"រក្សាទុកពាក្យសម្ងាត់សម្រាប់ <xliff:g id="APPNAME">%1$s</xliff:g> ឬ?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"រក្សាទុកព័ត៌មានអំពីការចូលគណនីសម្រាប់ <xliff:g id="APPNAME">%1$s</xliff:g> ឬ?"</string> <string name="passkey" msgid="632353688396759522">"កូដសម្ងាត់"</string> <string name="password" msgid="6738570945182936667">"ពាក្យសម្ងាត់"</string> diff --git a/packages/CredentialManager/res/values-kn/strings.xml b/packages/CredentialManager/res/values-kn/strings.xml index 17d49505386f..84549d1af0bc 100644 --- a/packages/CredentialManager/res/values-kn/strings.xml +++ b/packages/CredentialManager/res/values-kn/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ನಾವು ಪಾಸ್ವರ್ಡ್ ರಹಿತ ತಂತ್ರಜ್ಞಾನದ ಕಡೆಗೆ ಸಾಗುತ್ತಿರುವಾಗ, ಪಾಸ್ಕೀಗಳ ಜೊತೆಗೆ ಪಾಸ್ವರ್ಡ್ಗಳು ಇನ್ನೂ ಲಭ್ಯವಿರುತ್ತವೆ."</string> <string name="choose_provider_title" msgid="8870795677024868108">"ನಿಮ್ಮ <xliff:g id="CREATETYPES">%1$s</xliff:g> ಎಲ್ಲಿ ಸೇವ್ ಆಗಬೇಕು ಎಂಬುದನ್ನು ಆರಿಸಿ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ನಿಮ್ಮ ಮಾಹಿತಿಯನ್ನು ಉಳಿಸಲು ಪಾಸ್ವರ್ಡ್ ನಿರ್ವಾಹಕವನ್ನು ಆಯ್ಕೆಮಾಡಿ ಹಾಗೂ ಮುಂದಿನ ಬಾರಿ ವೇಗವಾಗಿ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> ಗಾಗಿ ಪಾಸ್ಕೀ ಅನ್ನು ರಚಿಸುವುದೇ?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> ಗಾಗಿ ಪಾಸ್ವರ್ಡ್ ಉಳಿಸುವುದೇ?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> ಗಾಗಿ ಸೈನ್-ಇನ್ ಮಾಹಿತಿಯನ್ನು ಉಳಿಸುವುದೇ?"</string> <string name="passkey" msgid="632353688396759522">"ಪಾಸ್ಕೀ"</string> <string name="password" msgid="6738570945182936667">"ಪಾಸ್ವರ್ಡ್"</string> diff --git a/packages/CredentialManager/res/values-ko/strings.xml b/packages/CredentialManager/res/values-ko/strings.xml index c6bec2e5bff0..0c970dd3cae4 100644 --- a/packages/CredentialManager/res/values-ko/strings.xml +++ b/packages/CredentialManager/res/values-ko/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"비밀번호 없는 미래로 나아가는 과정에서 비밀번호는 여전히 패스키와 함께 사용될 것입니다."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> 저장 위치 선택"</string> <string name="choose_provider_body" msgid="4967074531845147434">"정보를 저장해서 다음에 더 빠르게 로그인하려면 비밀번호 관리자를 선택하세요."</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>의 패스키를 만드시겠습니까?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g>의 비밀번호를 저장하시겠습니까?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g>의 로그인 정보를 저장하시겠습니까?"</string> <string name="passkey" msgid="632353688396759522">"패스키"</string> <string name="password" msgid="6738570945182936667">"비밀번호"</string> diff --git a/packages/CredentialManager/res/values-ky/strings.xml b/packages/CredentialManager/res/values-ky/strings.xml index effa3759d2d9..3937ff5afc31 100644 --- a/packages/CredentialManager/res/values-ky/strings.xml +++ b/packages/CredentialManager/res/values-ky/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Сырсөзсүз келечекти көздөй баратсак да, аларды киргизүүчү ачкычтар менен бирге колдоно берүүгө болот."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> кайда сакталарын тандаңыз"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Маалыматыңызды сактоо жана кийинки жолу тезирээк кирүү үчүн сырсөздөрдү башкаргычты тандаңыз"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> колдонмосуна киргизүүчү ачкыч түзөсүзбү?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> үчүн сырсөз сакталсынбы?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> үчүн кирүү маалыматы сакталсынбы?"</string> <string name="passkey" msgid="632353688396759522">"киргизүүчү ачкыч"</string> <string name="password" msgid="6738570945182936667">"сырсөз"</string> diff --git a/packages/CredentialManager/res/values-lo/strings.xml b/packages/CredentialManager/res/values-lo/strings.xml index d921f561c96b..79a31e8b1e8b 100644 --- a/packages/CredentialManager/res/values-lo/strings.xml +++ b/packages/CredentialManager/res/values-lo/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ໃນຂະນະທີ່ພວກເຮົາກ້າວໄປສູ່ອະນາຄົດທີ່ບໍ່ຕ້ອງໃຊ້ລະຫັດຜ່ານ, ລະຫັດຜ່ານຈະຍັງຄົງໃຊ້ໄດ້ຄວບຄູ່ໄປກັບກະແຈຜ່ານ."</string> <string name="choose_provider_title" msgid="8870795677024868108">"ເລືອກບ່ອນທີ່ຈະບັນທຶກ <xliff:g id="CREATETYPES">%1$s</xliff:g> ຂອງທ່ານ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ເລືອກຕົວຈັດການລະຫັດຜ່ານເພື່ອບັນທຶກຂໍ້ມູນຂອງທ່ານ ແລະ ເຂົ້າສູ່ລະບົບໄວຂຶ້ນໃນເທື່ອຕໍ່ໄປ"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ສ້າງກະແຈຜ່ານສຳລັບ <xliff:g id="APPNAME">%1$s</xliff:g> ບໍ?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"ບັນທຶກລະຫັດຜ່ານສຳລັບ <xliff:g id="APPNAME">%1$s</xliff:g> ບໍ?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"ບັນທຶກຂໍ້ມູນການເຂົ້າສູ່ລະບົບສຳລັບ <xliff:g id="APPNAME">%1$s</xliff:g> ບໍ?"</string> <string name="passkey" msgid="632353688396759522">"ກະແຈຜ່ານ"</string> <string name="password" msgid="6738570945182936667">"ລະຫັດຜ່ານ"</string> diff --git a/packages/CredentialManager/res/values-lt/strings.xml b/packages/CredentialManager/res/values-lt/strings.xml index f4fc6d45866f..e6bcd0685dca 100644 --- a/packages/CredentialManager/res/values-lt/strings.xml +++ b/packages/CredentialManager/res/values-lt/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Kol stengiamės padaryti, kad ateityje nereikėtų naudoti slaptažodžių, jie vis dar bus pasiekiami kartu su prieigos raktais."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Pasirinkite, kur išsaugoti „<xliff:g id="CREATETYPES">%1$s</xliff:g>“"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Pasirinkite slaptažodžių tvarkyklę, kurią naudodami galėsite išsaugoti informaciją ir kitą kartą prisijungti greičiau"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Sukurti „passkey“, skirtą „<xliff:g id="APPNAME">%1$s</xliff:g>“?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Išsaugoti „<xliff:g id="APPNAME">%1$s</xliff:g>“ slaptažodį?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Išsaugoti prisijungimo prie „<xliff:g id="APPNAME">%1$s</xliff:g>“ informaciją?"</string> <string name="passkey" msgid="632353688396759522">"„passkey“"</string> <string name="password" msgid="6738570945182936667">"slaptažodis"</string> diff --git a/packages/CredentialManager/res/values-lv/strings.xml b/packages/CredentialManager/res/values-lv/strings.xml index e43b5a0b1dca..a62bf28223e8 100644 --- a/packages/CredentialManager/res/values-lv/strings.xml +++ b/packages/CredentialManager/res/values-lv/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Lai arī pamazām notiek pāreja uz darbu bez parolēm, tās joprojām būs pieejamas līdzās piekļuves atslēgām."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Izvēlieties, kur saglabāt savas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Lai saglabātu informāciju un nākamreiz varētu pierakstīties ātrāk, atlasiet paroļu pārvaldnieku."</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vai izveidot piekļuves atslēgu lietotnei <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Vai saglabāt paroli lietotnei <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vai saglabāt pierakstīšanās informāciju lietotnei <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"piekļuves atslēga"</string> <string name="password" msgid="6738570945182936667">"parole"</string> diff --git a/packages/CredentialManager/res/values-mk/strings.xml b/packages/CredentialManager/res/values-mk/strings.xml index 320664023832..b5d59969c7a4 100644 --- a/packages/CredentialManager/res/values-mk/strings.xml +++ b/packages/CredentialManager/res/values-mk/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Како што се движиме кон иднина без лозинки, лозинките сепак ќе бидат достапни покрај криптографските клучеви."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Изберете каде да ги зачувате вашите <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Изберете управник со лозинки за да ги зачувате вашите податоци и да се најавите побрзо следниот пат"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Да се создаде криптографски клуч за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Дали да се зачува лозинката за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Да се зачуваат податоците за најавување за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"криптографски клуч"</string> <string name="password" msgid="6738570945182936667">"лозинка"</string> diff --git a/packages/CredentialManager/res/values-ml/strings.xml b/packages/CredentialManager/res/values-ml/strings.xml index 60d0af247c1c..fcbd12b20cb0 100644 --- a/packages/CredentialManager/res/values-ml/strings.xml +++ b/packages/CredentialManager/res/values-ml/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"നമ്മൾ പാസ്വേഡ് രഹിത ഭാവിയിലേക്ക് ചുവടുവെച്ചുകൊണ്ടിരിക്കുകയാണ് എങ്കിലും, പാസ്കീകൾക്കൊപ്പം പാസ്വേഡുകൾ തുടർന്നും ലഭ്യമായിരിക്കും."</string> <string name="choose_provider_title" msgid="8870795677024868108">"നിങ്ങളുടെ <xliff:g id="CREATETYPES">%1$s</xliff:g> എവിടെയാണ് സംരക്ഷിക്കേണ്ടതെന്ന് തിരഞ്ഞെടുക്കുക"</string> <string name="choose_provider_body" msgid="4967074531845147434">"നിങ്ങളുടെ വിവരങ്ങൾ സംരക്ഷിക്കാനും അടുത്ത തവണ വേഗത്തിൽ സൈൻ ഇൻ ചെയ്യാനും ഒരു പാസ്വേഡ് മാനേജർ തിരഞ്ഞെടുക്കുക"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്നതിനായി പാസ്കീ സൃഷ്ടിക്കണോ?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്നതിനായി പാസ്വേഡ് സംരക്ഷിക്കണോ?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്നതിനായി സൈൻ ഇൻ വിവരങ്ങൾ സംരക്ഷിക്കണോ?"</string> <string name="passkey" msgid="632353688396759522">"പാസ്കീ"</string> <string name="password" msgid="6738570945182936667">"പാസ്വേഡ്"</string> diff --git a/packages/CredentialManager/res/values-mn/strings.xml b/packages/CredentialManager/res/values-mn/strings.xml index 1050fc789756..b0d4ca6bea2d 100644 --- a/packages/CredentialManager/res/values-mn/strings.xml +++ b/packages/CredentialManager/res/values-mn/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Бид нууц үггүй ирээдүй рүү урагшлахын хэрээр нууц үг нь нэвтрэх түлхүүрийн хамтаар боломжтой хэвээр байх болно."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g>-г хаана хадгалахаа сонгоно уу"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Мэдээллээ хадгалж, дараагийн удаа илүү хурдан нэвтрэхийн тулд нууц үгний менежерийг сонгоно уу"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>-д passkey үүсгэх үү?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g>-н нууц үгийг хадгалах уу?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g>-н нэвтрэх мэдээллийг хадгалах уу?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"нууц үг"</string> diff --git a/packages/CredentialManager/res/values-mr/strings.xml b/packages/CredentialManager/res/values-mr/strings.xml index 11fee3beb1de..5747afd88996 100644 --- a/packages/CredentialManager/res/values-mr/strings.xml +++ b/packages/CredentialManager/res/values-mr/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"पासवर्ड न वापरणाऱ्या भविष्यात पुढे जाताना, पासवर्ड तरीही पासकीच्या बरोबरीने उपलब्ध असतील."</string> <string name="choose_provider_title" msgid="8870795677024868108">"तुमची <xliff:g id="CREATETYPES">%1$s</xliff:g> कुठे सेव्ह करायची ते निवडा"</string> <string name="choose_provider_body" msgid="4967074531845147434">"तुमची माहिती सेव्ह करण्यासाठी आणि पुढच्या वेळी जलद साइन इन करण्याकरिता Password Manager निवडा"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> साठी पासकी तयार करायची का?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> साठी पासवर्ड सेव्ह करायचा का?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> साठी साइन-इन माहिती सेव्ह करायची का?"</string> <string name="passkey" msgid="632353688396759522">"पासकी"</string> <string name="password" msgid="6738570945182936667">"पासवर्ड"</string> diff --git a/packages/CredentialManager/res/values-ms/strings.xml b/packages/CredentialManager/res/values-ms/strings.xml index 8198707373d7..a6bc11d615f7 100644 --- a/packages/CredentialManager/res/values-ms/strings.xml +++ b/packages/CredentialManager/res/values-ms/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Meskipun masa depan kita nanti tidak memerlukan kata laluan, kata laluan masih akan tersedia bersama dengan kunci laluan."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Pilih tempat untuk menyimpan <xliff:g id="CREATETYPES">%1$s</xliff:g> anda"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Pilih Password Manager untuk menyimpan maklumat anda dan log masuk lebih pantas pada kali seterusnya"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Cipta kunci laluan untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Simpan kata laluan untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Simpan maklumat log masuk untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"kunci laluan"</string> <string name="password" msgid="6738570945182936667">"kata laluan"</string> diff --git a/packages/CredentialManager/res/values-my/strings.xml b/packages/CredentialManager/res/values-my/strings.xml index 02b80cf2e386..55eed78176b4 100644 --- a/packages/CredentialManager/res/values-my/strings.xml +++ b/packages/CredentialManager/res/values-my/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"စကားဝှက်မသုံးခြင်း အနာဂတ်ဆီသို့ ရှေ့ဆက်ရာတွင် လျှို့ဝှက်ကီးများနှင့်အတူ စကားဝှက်များကို ဆက်လက်အသုံးပြုနိုင်ပါမည်။"</string> <string name="choose_provider_title" msgid="8870795677024868108">"သင်၏ <xliff:g id="CREATETYPES">%1$s</xliff:g> သိမ်းရန်နေရာ ရွေးခြင်း"</string> <string name="choose_provider_body" msgid="4967074531845147434">"သင့်အချက်အလက်သိမ်းပြီး နောက်တစ်ကြိမ်၌ ပိုမိုမြန်ဆန်စွာ လက်မှတ်ထိုးဝင်ရန် စကားဝှက်မန်နေဂျာကို ရွေးပါ"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> အတွက် လျှို့ဝှက်ကီးပြုလုပ်မလား။"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> အတွက် စကားဝှက်ကို သိမ်းမလား။"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> အတွက် လက်မှတ်ထိုးဝင်သည့်အချက်အလက်ကို သိမ်းမလား။"</string> <string name="passkey" msgid="632353688396759522">"လျှို့ဝှက်ကီး"</string> <string name="password" msgid="6738570945182936667">"စကားဝှက်"</string> diff --git a/packages/CredentialManager/res/values-nb/strings.xml b/packages/CredentialManager/res/values-nb/strings.xml index 4ec8524c1daa..f7c5762c0598 100644 --- a/packages/CredentialManager/res/values-nb/strings.xml +++ b/packages/CredentialManager/res/values-nb/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Vi går mot en fremtid uten passord, men passord fortsetter å være tilgjengelige ved siden av passnøkler."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Velg hvor du vil lagre <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Velg et verktøy for passordlagring for å lagre informasjonen din og logge på raskere neste gang"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vil du opprette en passnøkkel for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Vil du lagre passord for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vil du lagre påloggingsinformasjon for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passnøkkel"</string> <string name="password" msgid="6738570945182936667">"passord"</string> diff --git a/packages/CredentialManager/res/values-ne/strings.xml b/packages/CredentialManager/res/values-ne/strings.xml index 28223ddc4403..bc3fc0ef1f09 100644 --- a/packages/CredentialManager/res/values-ne/strings.xml +++ b/packages/CredentialManager/res/values-ne/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"हामी पासवर्डरहित भविष्यतर्फ बढ्दै गर्दा पासकीका साथसाथै पासवर्ड पनि उपलब्ध हुने छ।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"तपाईं आफ्ना <xliff:g id="CREATETYPES">%1$s</xliff:g> कहाँ सेभ गर्न चाहनुहुन्छ भन्ने कुरा छनौट गर्नुहोस्"</string> <string name="choose_provider_body" msgid="4967074531845147434">"कुनै पासवर्ड म्यानेजरमा आफ्नो जानकारी सेभ गरी अर्को पटक अझ छिटो साइन इन गर्नुहोस्"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> को पासकी बनाउने हो?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> को पासवर्ड सेभ गर्ने हो?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> मा साइन गर्न प्रयोग गरिनु पर्ने जानकारी सेभ गर्ने हो?"</string> <string name="passkey" msgid="632353688396759522">"पासकी"</string> <string name="password" msgid="6738570945182936667">"पासवर्ड"</string> diff --git a/packages/CredentialManager/res/values-nl/strings.xml b/packages/CredentialManager/res/values-nl/strings.xml index b82382c5b899..d4ce16b9d023 100644 --- a/packages/CredentialManager/res/values-nl/strings.xml +++ b/packages/CredentialManager/res/values-nl/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"We zijn op weg naar een wachtwoordloze toekomst, maar naast toegangssleutels kun je nog steeds gebruikmaken van wachtwoorden."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Kiezen waar je je <xliff:g id="CREATETYPES">%1$s</xliff:g> wilt opslaan"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecteer een wachtwoordmanager om je informatie op te slaan en de volgende keer sneller in te loggen"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Toegangssleutel maken voor <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Wachtwoord opslaan voor <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Inloggegevens opslaan voor <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"Toegangssleutel"</string> <string name="password" msgid="6738570945182936667">"wachtwoord"</string> diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml index 57853f01bf2f..4ca9c396c94d 100644 --- a/packages/CredentialManager/res/values-or/strings.xml +++ b/packages/CredentialManager/res/values-or/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ଆମେ ଏକ ପାସୱାର୍ଡବିହୀନ ଭବିଷ୍ୟତ ଆଡ଼କୁ ମୁଭ କରୁଥିବା ଯୋଗୁଁ ଏବେ ବି ପାସକୀଗୁଡ଼ିକ ସହିତ ପାସୱାର୍ଡ ଉପଲବ୍ଧ ହେବ।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"ଆପଣଙ୍କ <xliff:g id="CREATETYPES">%1$s</xliff:g> କେଉଁଠାରେ ସେଭ କରିବେ ତାହା ବାଛନ୍ତୁ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ଆପଣଙ୍କ ସୂଚନା ସେଭ କରି ପରବର୍ତ୍ତୀ ସମୟରେ ଶୀଘ୍ର ସାଇନ ଇନ କରିବା ପାଇଁ ଏକ Password Manager ଚୟନ କରନ୍ତୁ"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> ପାଇଁ ପାସକୀ ତିଆରି କରିବେ?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> ପାଇଁ ପାସୱାର୍ଡ ସେଭ କରିବେ?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> ପାଇଁ ସାଇନ-ଇନର ସୂଚନା ସେଭ କରିବେ?"</string> <string name="passkey" msgid="632353688396759522">"ପାସକୀ"</string> <string name="password" msgid="6738570945182936667">"ପାସୱାର୍ଡ"</string> diff --git a/packages/CredentialManager/res/values-pa/strings.xml b/packages/CredentialManager/res/values-pa/strings.xml index 25e1f0a59e6a..414a4cebf87c 100644 --- a/packages/CredentialManager/res/values-pa/strings.xml +++ b/packages/CredentialManager/res/values-pa/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ਹਾਲਾਂਕਿ, ਅਸੀਂ ਪਾਸਵਰਡ ਰਹਿਤ ਭਵਿੱਖ ਵੱਲ ਵਧ ਰਹੇ ਹਾਂ, ਪਰ ਪਾਸਕੀਆਂ ਦੇ ਨਾਲ ਪਾਸਵਰਡ ਹਾਲੇ ਵੀ ਉਪਲਬਧ ਹੋਣਗੇ।"</string> <string name="choose_provider_title" msgid="8870795677024868108">"ਚੁਣੋ ਕਿ ਆਪਣੀਆਂ <xliff:g id="CREATETYPES">%1$s</xliff:g> ਨੂੰ ਕਿੱਥੇ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ਆਪਣੀ ਜਾਣਕਾਰੀ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਅਤੇ ਅਗਲੀ ਵਾਰ ਤੇਜ਼ੀ ਨਾਲ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ ਚੁਣੋ"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ਕੀ <xliff:g id="APPNAME">%1$s</xliff:g> ਲਈ ਪਾਸਕੀ ਬਣਾਉਣੀ ਹੈ?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"ਕੀ <xliff:g id="APPNAME">%1$s</xliff:g> ਲਈ ਪਾਸਵਰਡ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"ਕੀ <xliff:g id="APPNAME">%1$s</xliff:g> ਲਈ ਸਾਈਨ-ਇਨ ਜਾਣਕਾਰੀ ਰੱਖਿਅਤ ਕਰਨੀ ਹੈ?"</string> <string name="passkey" msgid="632353688396759522">"ਪਾਸਕੀ"</string> <string name="password" msgid="6738570945182936667">"ਪਾਸਵਰਡ"</string> diff --git a/packages/CredentialManager/res/values-pl/strings.xml b/packages/CredentialManager/res/values-pl/strings.xml index e581ff2f6358..91e227653eaf 100644 --- a/packages/CredentialManager/res/values-pl/strings.xml +++ b/packages/CredentialManager/res/values-pl/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"W czasie przechodzenia na technologie niewymagające haseł możliwość stosowania haseł – niezależnie od kluczy dostępu – wciąż będzie dostępna."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Wybierz, gdzie zapisywać <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Wybierz menedżera haseł, aby zapisywać informacje i logować się szybciej"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Utworzyć klucz dla aplikacji <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Zapisać hasło do aplikacji <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Zapisać dane logowania do aplikacji <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"klucz"</string> <string name="password" msgid="6738570945182936667">"hasło"</string> diff --git a/packages/CredentialManager/res/values-pt-rBR/strings.xml b/packages/CredentialManager/res/values-pt-rBR/strings.xml index f6d03dfd51f3..105441f25267 100644 --- a/packages/CredentialManager/res/values-pt-rBR/strings.xml +++ b/packages/CredentialManager/res/values-pt-rBR/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Estamos avançando em direção a um futuro sem senhas, mas elas ainda vão estar disponíveis junto às chaves de acesso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde salvar suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gerenciador de senhas para salvar suas informações e fazer login mais rapidamente na próxima vez"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Criar uma chave de acesso para o app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Salvar senha do app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Salvar informações de login do app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"chave de acesso"</string> <string name="password" msgid="6738570945182936667">"senha"</string> diff --git a/packages/CredentialManager/res/values-pt-rPT/strings.xml b/packages/CredentialManager/res/values-pt-rPT/strings.xml index 0007fad11cc3..f7259d8f9711 100644 --- a/packages/CredentialManager/res/values-pt-rPT/strings.xml +++ b/packages/CredentialManager/res/values-pt-rPT/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"À medida que avançamos para um futuro sem palavras-passe, as palavras-passe continuam disponíveis juntamente com as chaves de acesso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde guardar as suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gestor de palavras-passe para guardar as suas informações e iniciar sessão mais rapidamente da próxima vez"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Criar uma chave de acesso para a app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Guardar a palavra-passe da app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Guardar as informações de início de sessão da app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"chave de acesso"</string> <string name="password" msgid="6738570945182936667">"palavra-passe"</string> diff --git a/packages/CredentialManager/res/values-pt/strings.xml b/packages/CredentialManager/res/values-pt/strings.xml index f6d03dfd51f3..105441f25267 100644 --- a/packages/CredentialManager/res/values-pt/strings.xml +++ b/packages/CredentialManager/res/values-pt/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Estamos avançando em direção a um futuro sem senhas, mas elas ainda vão estar disponíveis junto às chaves de acesso."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde salvar suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gerenciador de senhas para salvar suas informações e fazer login mais rapidamente na próxima vez"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Criar uma chave de acesso para o app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Salvar senha do app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Salvar informações de login do app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"chave de acesso"</string> <string name="password" msgid="6738570945182936667">"senha"</string> diff --git a/packages/CredentialManager/res/values-ro/strings.xml b/packages/CredentialManager/res/values-ro/strings.xml index 32d0056af72c..cfe61a96a382 100644 --- a/packages/CredentialManager/res/values-ro/strings.xml +++ b/packages/CredentialManager/res/values-ro/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Ne îndreptăm spre un viitor fără parole, însă acestea sunt încă disponibile, alături de cheile de acces."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Alege unde dorești să salvezi <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Selectează un manager de parole pentru a salva informațiile și a te conecta mai rapid data viitoare"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Creezi o cheie de acces pentru <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Salvezi parola pentru <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Salvezi informațiile de conectare pentru <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"cheia de acces"</string> <string name="password" msgid="6738570945182936667">"parolă"</string> diff --git a/packages/CredentialManager/res/values-ru/strings.xml b/packages/CredentialManager/res/values-ru/strings.xml index a48b0f2ca1e2..ba7d34ae7bd6 100644 --- a/packages/CredentialManager/res/values-ru/strings.xml +++ b/packages/CredentialManager/res/values-ru/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Хотя движение к будущему без паролей уже началось, их по-прежнему можно будет использовать наряду с ключами доступа."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Укажите, куда нужно сохранить <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Выберите менеджер паролей, чтобы сохранять учетные данные и быстро выполнять вход."</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Создать ключ доступа для приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Сохранить пароль для приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Сохранить учетные данные для приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string> <string name="passkey" msgid="632353688396759522">"ключ доступа"</string> <string name="password" msgid="6738570945182936667">"пароль"</string> diff --git a/packages/CredentialManager/res/values-si/strings.xml b/packages/CredentialManager/res/values-si/strings.xml index d6113b371c9e..03ada97da904 100644 --- a/packages/CredentialManager/res/values-si/strings.xml +++ b/packages/CredentialManager/res/values-si/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"අපි මුරපද රහිත අනාගතයක් කරා ගමන් කරන විට, මුරයතුරු සමග මුරපද තවමත් පවතී."</string> <string name="choose_provider_title" msgid="8870795677024868108">"ඔබේ <xliff:g id="CREATETYPES">%1$s</xliff:g> සුරැකිය යුතු ස්ථානය තෝරා ගන්න"</string> <string name="choose_provider_body" msgid="4967074531845147434">"ඔබේ තතු සුරැකීමට සහ මීළඟ වතාවේ වේගයෙන් පුරනය වීමට මුරපද කළමනාකරුවෙකු තෝරන්න"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> සඳහා මුරයතුර තනන්න ද?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> සඳහා මුරපදය සුරකින්න ද?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> සඳහා පුරනය වීමේ තතු සුරකින්න ද?"</string> <string name="passkey" msgid="632353688396759522">"මුරයතුර"</string> <string name="password" msgid="6738570945182936667">"මුරපදය"</string> diff --git a/packages/CredentialManager/res/values-sk/strings.xml b/packages/CredentialManager/res/values-sk/strings.xml index 62d8f190aa83..7198625818e1 100644 --- a/packages/CredentialManager/res/values-sk/strings.xml +++ b/packages/CredentialManager/res/values-sk/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Blížime sa k budúcnosti bez hesiel, ale heslá budú popri prístupových kľúčoch stále k dispozícii."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Vyberte, kam sa majú ukladať <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Vyberte správcu hesiel, do ktorého sa budú ukladať vaše údaje, aby ste sa nabudúce mohli rýchlejšie prihlásiť"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Chcete vytvoriť prístupový kľúč pre aplikáciu <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Chcete uložiť heslo pre aplikáciu <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Chcete uložiť prihlasovacie údaje pre aplikáciu <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"prístupový kľúč"</string> <string name="password" msgid="6738570945182936667">"heslo"</string> diff --git a/packages/CredentialManager/res/values-sl/strings.xml b/packages/CredentialManager/res/values-sl/strings.xml index 846d27d4219d..3ff85f0e41fb 100644 --- a/packages/CredentialManager/res/values-sl/strings.xml +++ b/packages/CredentialManager/res/values-sl/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Na poti v prihodnost brez gesel bodo poleg ključev za dostop še vedno v uporabi tudi gesla."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Izbira mesta za shranjevanje <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Izberite upravitelja gesel za shranjevanje podatkov za prijavo, da se boste naslednjič lahko hitreje prijavili."</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Želite ustvariti ključ za dostop do aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Želite shraniti geslo za aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Želite shraniti podatke za prijavo za aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"ključ za dostop"</string> <string name="password" msgid="6738570945182936667">"geslo"</string> diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml index 7678125e16a2..41f63915771f 100644 --- a/packages/CredentialManager/res/values-sq/strings.xml +++ b/packages/CredentialManager/res/values-sq/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Teksa shkojmë drejt një të ardhmeje pa fjalëkalime, këto të fundit do të ofrohen ende së bashku me çelësat e kalimit."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Zgjidh se ku t\'i ruash <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Zgjidh një menaxher fjalëkalimesh për të ruajtur informacionet e tua dhe për t\'u identifikuar më shpejt herën tjetër"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Të krijohet çelësi i kalimit për <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Të ruhet fjalëkalimi për <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Të ruhen informacionet e identifikimit për <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"çelësin e kalimit"</string> <string name="password" msgid="6738570945182936667">"fjalëkalimi"</string> diff --git a/packages/CredentialManager/res/values-sr/strings.xml b/packages/CredentialManager/res/values-sr/strings.xml index 8c71e71ae683..1a5567fe4c46 100644 --- a/packages/CredentialManager/res/values-sr/strings.xml +++ b/packages/CredentialManager/res/values-sr/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Како се крећемо ка будућности без лозинки, лозинке ће и даље бити доступне уз приступне кодове."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Одаберите где ћете сачувати: <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Изаберите менаџера лозинки да бисте сачували податке и брже се пријавили следећи пут"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Желите да направите приступни кôд за: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Желите да сачувате лозинку за: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Желите да сачувате податке за пријављивање за: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"приступни кôд"</string> <string name="password" msgid="6738570945182936667">"лозинка"</string> diff --git a/packages/CredentialManager/res/values-sv/strings.xml b/packages/CredentialManager/res/values-sv/strings.xml index 9aa11653a5fa..8937b019ffc0 100644 --- a/packages/CredentialManager/res/values-sv/strings.xml +++ b/packages/CredentialManager/res/values-sv/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Medan vi beger oss mot en lösenordslös framtid kommer lösenord fortfarande att vara tillgängliga utöver nycklar."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Välj var du vill spara <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Välj en lösenordshanterare för att spara dina uppgifter och logga in snabbare nästa gång"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vill du skapa en nyckel för <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Vill du spara lösenordet för <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Vill du spara inloggningsuppgifterna för <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"nyckel"</string> <string name="password" msgid="6738570945182936667">"lösenord"</string> diff --git a/packages/CredentialManager/res/values-sw/strings.xml b/packages/CredentialManager/res/values-sw/strings.xml index adf659ead166..051122f4ab71 100644 --- a/packages/CredentialManager/res/values-sw/strings.xml +++ b/packages/CredentialManager/res/values-sw/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Tunavyoelekea katika enzi isiyo ya manenosiri, manenosiri yataendelea kupatikana pamoja na funguo za siri."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Chagua ambako unahifadhi <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Chagua kidhibiti cha manenosiri ili uhifadhi taarifa zako na uingie kwenye akaunti kwa urahisi wakati mwingine"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Ungependa kuunda ufunguo wa siri kwa ajili ya <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Ungependa kuhifadhi nenosiri kwa ajili ya <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Ungependa kuhifadhi maelezo ya kuingia katika akaunti kwa ajili ya <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"ufunguo wa siri"</string> <string name="password" msgid="6738570945182936667">"nenosiri"</string> diff --git a/packages/CredentialManager/res/values-ta/strings.xml b/packages/CredentialManager/res/values-ta/strings.xml index c43776ea6d59..64d4a2458cd0 100644 --- a/packages/CredentialManager/res/values-ta/strings.xml +++ b/packages/CredentialManager/res/values-ta/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"கடவுச்சொல்லற்ற எதிர்காலத்தை நோக்கி நாம் பயணிக்கிறோம். கடவுச்சாவிகளைப் பயன்படுத்தும் இதே வேளையில் கடவுச்சொற்களையும் பயன்படுத்த முடியும்."</string> <string name="choose_provider_title" msgid="8870795677024868108">"உங்கள் <xliff:g id="CREATETYPES">%1$s</xliff:g> எங்கே சேமிக்கப்பட வேண்டும் என்பதைத் தேர்வுசெய்யுங்கள்"</string> <string name="choose_provider_body" msgid="4967074531845147434">"உங்கள் தகவல்களைச் சேமித்து அடுத்த முறை விரைவாக உள்நுழைய ஒரு கடவுச்சொல் நிர்வாகியைத் தேர்வுசெய்யுங்கள்"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸுக்கான கடவுச்சாவியை உருவாக்கவா?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸுக்கான கடவுச்சொல்லைச் சேமிக்கவா?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸுக்கான உள்நுழைவு விவரங்களைச் சேமிக்கவா?"</string> <string name="passkey" msgid="632353688396759522">"கடவுச்சாவி"</string> <string name="password" msgid="6738570945182936667">"கடவுச்சொல்"</string> diff --git a/packages/CredentialManager/res/values-te/strings.xml b/packages/CredentialManager/res/values-te/strings.xml index 980fb152c5ff..066f785282b1 100644 --- a/packages/CredentialManager/res/values-te/strings.xml +++ b/packages/CredentialManager/res/values-te/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"మనం భవిష్యత్తులో పాస్వర్డ్ రహిత టెక్నాలజీని ఉపయోగించినా, పాస్కీలతో పాటు పాస్వర్డ్లు కూడా అందుబాటులో ఉంటాయి."</string> <string name="choose_provider_title" msgid="8870795677024868108">"మీ <xliff:g id="CREATETYPES">%1$s</xliff:g> ఎక్కడ సేవ్ చేయాలో ఎంచుకోండి"</string> <string name="choose_provider_body" msgid="4967074531845147434">"తర్వాతిసారి మరింత వేగంగా సైన్ ఇన్ చేసేందుకు వీలుగా మీ సమాచారాన్ని సేవ్ చేయడం కోసం ఒక పాస్వర్డ్ మేనేజర్ను ఎంచుకోండి"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> కోసం పాస్-కీని క్రియేట్ చేయాలా?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> కోసం పాస్వర్డ్ను సేవ్ చేయాలా?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> కోసం సైన్ ఇన్ సమాచారాన్ని సేవ్ చేయాలా?"</string> <string name="passkey" msgid="632353688396759522">"పాస్-కీ"</string> <string name="password" msgid="6738570945182936667">"పాస్వర్డ్"</string> diff --git a/packages/CredentialManager/res/values-th/strings.xml b/packages/CredentialManager/res/values-th/strings.xml index e222d6b7a5b5..783d05769b20 100644 --- a/packages/CredentialManager/res/values-th/strings.xml +++ b/packages/CredentialManager/res/values-th/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"ในขณะที่เราก้าวไปสู่อนาคตที่ไม่ต้องใช้รหัสผ่านนั้น รหัสผ่านจะยังคงใช้ได้อยู่ควบคู่ไปกับการเปลี่ยนไปใช้พาสคีย์"</string> <string name="choose_provider_title" msgid="8870795677024868108">"เลือกว่าต้องการบันทึก<xliff:g id="CREATETYPES">%1$s</xliff:g>ไว้ที่ใด"</string> <string name="choose_provider_body" msgid="4967074531845147434">"เลือกเครื่องมือจัดการรหัสผ่านเพื่อบันทึกข้อมูลและลงชื่อเข้าใช้เร็วขึ้นในครั้งถัดไป"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"สร้างพาสคีย์สำหรับ <xliff:g id="APPNAME">%1$s</xliff:g> ไหม"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"บันทึกรหัสผ่านสำหรับ <xliff:g id="APPNAME">%1$s</xliff:g> ไหม"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"บันทึกข้อมูลการลงชื่อเข้าใช้สำหรับ <xliff:g id="APPNAME">%1$s</xliff:g> ไหม"</string> <string name="passkey" msgid="632353688396759522">"พาสคีย์"</string> <string name="password" msgid="6738570945182936667">"รหัสผ่าน"</string> diff --git a/packages/CredentialManager/res/values-tl/strings.xml b/packages/CredentialManager/res/values-tl/strings.xml index 5487df1be7d0..18283eacdba0 100644 --- a/packages/CredentialManager/res/values-tl/strings.xml +++ b/packages/CredentialManager/res/values-tl/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Habang lumalayo tayo sa mga password, magiging available pa rin ang mga password kasama ng mga passkey."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Piliin kung saan mo ise-save ang iyong <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Pumili ng password manager para ma-save ang iyong impormasyon at makapag-sign in nang mas mabilis sa susunod na pagkakataon"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Gumawa ng passkey para sa <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"I-save ang password para sa <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"I-save ang impormasyon sa pag-sign in para sa <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"passkey"</string> <string name="password" msgid="6738570945182936667">"password"</string> diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml index 5dda8aa316f0..8778797d5968 100644 --- a/packages/CredentialManager/res/values-tr/strings.xml +++ b/packages/CredentialManager/res/values-tr/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Şifresiz bir geleceğe doğru ilerlerken şifreler, geçiş anahtarlarıyla birlikte kullanılmaya devam edecektir."</string> <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> kaydedileceği yeri seçin"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Bilgilerinizi kaydedip bir dahaki sefere daha hızlı oturum açmak için bir şifre yöneticisi seçin"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> için geçiş anahtarı oluşturulsun mu?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> için şifre kaydedilsin mi?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> için oturum açma bilgileri kaydedilsin mi?"</string> <string name="passkey" msgid="632353688396759522">"Geçiş anahtarı"</string> <string name="password" msgid="6738570945182936667">"Şifre"</string> diff --git a/packages/CredentialManager/res/values-uk/strings.xml b/packages/CredentialManager/res/values-uk/strings.xml index 1cda5d4fc4dc..53de1b313c34 100644 --- a/packages/CredentialManager/res/values-uk/strings.xml +++ b/packages/CredentialManager/res/values-uk/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"На шляху до безпарольного майбутнього паролі й надалі будуть використовуватися паралельно з ключами доступу."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Виберіть, де зберігати <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Виберіть менеджер паролів, щоб зберігати свої дані й надалі входити в облікові записи швидше"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Створити ключ доступу для додатка <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Зберегти пароль для додатка <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Зберегти дані для входу для додатка <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"ключ доступу"</string> <string name="password" msgid="6738570945182936667">"пароль"</string> diff --git a/packages/CredentialManager/res/values-ur/strings.xml b/packages/CredentialManager/res/values-ur/strings.xml index 105045c6fb14..47e33fb5aeaf 100644 --- a/packages/CredentialManager/res/values-ur/strings.xml +++ b/packages/CredentialManager/res/values-ur/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"چونکہ ہم بغیر پاس ورڈ والے مستقبل کی طرف جا رہے ہیں اس کے باوجود پاس ورڈز پاس کیز کے ساتھ ہی دستیاب ہوں گے۔"</string> <string name="choose_provider_title" msgid="8870795677024868108">"منتخب کریں کہ آپ کی <xliff:g id="CREATETYPES">%1$s</xliff:g> کو کہاں محفوظ کرنا ہے"</string> <string name="choose_provider_body" msgid="4967074531845147434">"اپنی معلومات کو محفوظ کرنے اور اگلی بار تیزی سے سائن ان کرنے کے لیے پاس ورڈ مینیجر منتخب کریں"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> کے لیے پاس کی تخلیق کریں؟"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> کے لیے پاس ورڈ کو محفوظ کریں؟"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> کے لیے سائن ان کی معلومات محفوظ کریں؟"</string> <string name="passkey" msgid="632353688396759522">"پاس کی"</string> <string name="password" msgid="6738570945182936667">"پاس ورڈ"</string> diff --git a/packages/CredentialManager/res/values-uz/strings.xml b/packages/CredentialManager/res/values-uz/strings.xml index ec42f07d6a6b..6025cae04b6c 100644 --- a/packages/CredentialManager/res/values-uz/strings.xml +++ b/packages/CredentialManager/res/values-uz/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsiz kelajak sari harakatlanar ekanmiz, parollar kalitlar bilan birga ishlatilishda davom etadi."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Bu <xliff:g id="CREATETYPES">%1$s</xliff:g> qayerga saqlanishini tanlang"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Maʼlumotlaringizni saqlash va keyingi safar tez kirish uchun parollar menejerini tanlang"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> uchun kod yaratilsinmi?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"<xliff:g id="APPNAME">%1$s</xliff:g> uchun parol saqlansinmi?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"<xliff:g id="APPNAME">%1$s</xliff:g> uchun kirish maʼlumoti saqlansinmi?"</string> <string name="passkey" msgid="632353688396759522">"kalit"</string> <string name="password" msgid="6738570945182936667">"parol"</string> diff --git a/packages/CredentialManager/res/values-vi/strings.xml b/packages/CredentialManager/res/values-vi/strings.xml index dbee6589b5fd..141103630ee3 100644 --- a/packages/CredentialManager/res/values-vi/strings.xml +++ b/packages/CredentialManager/res/values-vi/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Trong quá trình chúng tôi hướng đến tương lai không dùng mật khẩu, bạn vẫn sẽ dùng được mật khẩu cùng với khoá truy cập."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Chọn vị trí lưu <xliff:g id="CREATETYPES">%1$s</xliff:g> của bạn"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Hãy chọn một trình quản lý mật khẩu để lưu thông tin của bạn và đăng nhập nhanh hơn vào lần tới"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Tạo khoá đăng nhập cho <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Lưu mật khẩu cho <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Lưu thông tin đăng nhập cho <xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"khoá đăng nhập"</string> <string name="password" msgid="6738570945182936667">"mật khẩu"</string> diff --git a/packages/CredentialManager/res/values-zh-rCN/strings.xml b/packages/CredentialManager/res/values-zh-rCN/strings.xml index c82f2f8bb49d..dcc226986d23 100644 --- a/packages/CredentialManager/res/values-zh-rCN/strings.xml +++ b/packages/CredentialManager/res/values-zh-rCN/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"在我们向无密码未来迈进的过程中,密码仍会与通行密钥并行使用。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"选择保存<xliff:g id="CREATETYPES">%1$s</xliff:g>的位置"</string> <string name="choose_provider_body" msgid="4967074531845147434">"请选择一款密码管理工具来保存您的信息,以便下次更快地登录"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"要为“<xliff:g id="APPNAME">%1$s</xliff:g>”创建通行密钥吗?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"要保存“<xliff:g id="APPNAME">%1$s</xliff:g>”的密码吗?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"要保存“<xliff:g id="APPNAME">%1$s</xliff:g>”的登录信息吗?"</string> <string name="passkey" msgid="632353688396759522">"通行密钥"</string> <string name="password" msgid="6738570945182936667">"密码"</string> diff --git a/packages/CredentialManager/res/values-zh-rHK/strings.xml b/packages/CredentialManager/res/values-zh-rHK/strings.xml index 1d3e5aabd797..5e893f6d8d4c 100644 --- a/packages/CredentialManager/res/values-zh-rHK/strings.xml +++ b/packages/CredentialManager/res/values-zh-rHK/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"我們將會改用無密碼技術,而密碼仍可與密鑰並行使用。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"選擇儲存<xliff:g id="CREATETYPES">%1$s</xliff:g>的位置"</string> <string name="choose_provider_body" msgid="4967074531845147434">"選取密碼管理工具即可儲存自己的資料,縮短下次登入的時間"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"要為「<xliff:g id="APPNAME">%1$s</xliff:g>」建立密鑰嗎?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"要儲存「<xliff:g id="APPNAME">%1$s</xliff:g>」的密碼嗎?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"要儲存「<xliff:g id="APPNAME">%1$s</xliff:g>」的登入資料嗎?"</string> <string name="passkey" msgid="632353688396759522">"密鑰"</string> <string name="password" msgid="6738570945182936667">"密碼"</string> diff --git a/packages/CredentialManager/res/values-zh-rTW/strings.xml b/packages/CredentialManager/res/values-zh-rTW/strings.xml index 184505a05ba6..1e1dca491961 100644 --- a/packages/CredentialManager/res/values-zh-rTW/strings.xml +++ b/packages/CredentialManager/res/values-zh-rTW/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"我們日後將改採無密碼技術,密碼仍可與密碼金鑰並行使用。"</string> <string name="choose_provider_title" msgid="8870795677024868108">"選擇要將<xliff:g id="CREATETYPES">%1$s</xliff:g>存在哪裡"</string> <string name="choose_provider_body" msgid="4967074531845147434">"選取密碼管理工具並儲存資訊,下次就能更快登入"</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"要為「<xliff:g id="APPNAME">%1$s</xliff:g>」建立密碼金鑰嗎?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"要儲存「<xliff:g id="APPNAME">%1$s</xliff:g>」的密碼嗎?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"要儲存「<xliff:g id="APPNAME">%1$s</xliff:g>」的登入資訊嗎?"</string> <string name="passkey" msgid="632353688396759522">"密碼金鑰"</string> <string name="password" msgid="6738570945182936667">"密碼"</string> diff --git a/packages/CredentialManager/res/values-zu/strings.xml b/packages/CredentialManager/res/values-zu/strings.xml index 8feeb17d7e3e..72a1e8f43a0a 100644 --- a/packages/CredentialManager/res/values-zu/strings.xml +++ b/packages/CredentialManager/res/values-zu/strings.xml @@ -39,8 +39,10 @@ <string name="seamless_transition_detail" msgid="4475509237171739843">"Njengoba sibhekela kwikusasa elingenaphasiwedi, amagama ayimfihlo asazotholakala eceleni kokhiye bokudlula."</string> <string name="choose_provider_title" msgid="8870795677024868108">"Khetha lapho ongagcina khona i-<xliff:g id="CREATETYPES">%1$s</xliff:g> yakho"</string> <string name="choose_provider_body" msgid="4967074531845147434">"Khetha isiphathi sephasiwedi ukuze ulondoloze ulwazi lwakho futhi ungene ngemvume ngokushesha ngesikhathi esizayo."</string> - <string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Sungula ukhiye wokudlula we-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> - <string name="choose_create_option_password_title" msgid="7097275038523578687">"Londolozela amaphasiwedi ye-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> + <!-- no translation found for choose_create_option_passkey_title (7980430650778623135) --> + <skip /> + <!-- no translation found for choose_create_option_password_title (6238446571944651980) --> + <skip /> <string name="choose_create_option_sign_in_title" msgid="4124872317613421249">"Londoloza ulwazi lokungena lwe-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string> <string name="passkey" msgid="632353688396759522">"ukhiye wokudlula"</string> <string name="password" msgid="6738570945182936667">"iphasiwedi"</string> diff --git a/packages/CredentialManager/res/values/dimens.xml b/packages/CredentialManager/res/values/dimens.xml index 350920b23c69..82dee5c22736 100644 --- a/packages/CredentialManager/res/values/dimens.xml +++ b/packages/CredentialManager/res/values/dimens.xml @@ -26,7 +26,7 @@ <dimen name="autofill_dropdown_textview_min_width">112dp</dimen> <dimen name="autofill_dropdown_textview_max_width">230dp</dimen> <dimen name="dropdown_layout_horizontal_margin">24dp</dimen> - <integer name="autofill_max_visible_datasets">5</integer> + <integer name="autofill_max_visible_datasets">4</integer> <dimen name="dropdown_touch_target_min_height">48dp</dimen> <dimen name="horizontal_chip_padding">8dp</dimen> <dimen name="vertical_chip_padding">6dp</dimen> diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt index 39d3f42e8bf4..e2857f96cdf2 100644 --- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ktx/CredentialKtx.kt @@ -47,8 +47,9 @@ import com.android.credentialmanager.model.CredentialType import com.android.credentialmanager.model.get.ProviderInfo import com.android.credentialmanager.model.get.RemoteEntryInfo import com.android.credentialmanager.TAG +import com.android.credentialmanager.model.EntryInfo -fun CredentialEntryInfo.getIntentSenderRequest( +fun EntryInfo.getIntentSenderRequest( isAutoSelected: Boolean = false ): IntentSenderRequest? { val entryIntent = fillInIntent?.putExtra(IS_AUTO_SELECTED_KEY, isAutoSelected) @@ -132,6 +133,7 @@ private fun getCredentialOptionInfoList( lastUsedTimeMillis = credentialEntry.lastUsedTime, isAutoSelectable = credentialEntry.isAutoSelectAllowed && credentialEntry.isAutoSelectAllowedFromOption, + entryGroupId = credentialEntry.entryGroupId.toString(), ) ) } @@ -155,6 +157,7 @@ private fun getCredentialOptionInfoList( lastUsedTimeMillis = credentialEntry.lastUsedTime, isAutoSelectable = credentialEntry.isAutoSelectAllowed && credentialEntry.isAutoSelectAllowedFromOption, + entryGroupId = credentialEntry.entryGroupId.toString(), ) ) } @@ -177,6 +180,7 @@ private fun getCredentialOptionInfoList( lastUsedTimeMillis = credentialEntry.lastUsedTime, isAutoSelectable = credentialEntry.isAutoSelectAllowed && credentialEntry.isAutoSelectAllowedFromOption, + entryGroupId = credentialEntry.entryGroupId.toString(), ) ) } diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt index 9725881e1c97..a5d4730967a3 100644 --- a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/get/CredentialEntryInfo.kt @@ -40,6 +40,8 @@ class CredentialEntryInfo( val shouldTintIcon: Boolean, val lastUsedTimeMillis: Instant?, val isAutoSelectable: Boolean, + val entryGroupId: String, // Used for deduplication, and displayed as the grouping title + // "For <value-of-entryGroupId>" on the more-option screen. ) : EntryInfo( providerId, entryKey, diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt index 13260231038d..293e1112636e 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt @@ -237,23 +237,14 @@ class CredentialAutofillService : AutofillService() { if (providerList.isEmpty()) { return false } - var totalEntryCount = 0 - providerList.forEach { provider -> - totalEntryCount += provider.credentialEntryList.size - } val providerDisplayInfo: ProviderDisplayInfo = toProviderDisplayInfo(providerList) + var totalEntryCount = providerDisplayInfo.sortedUserNameToCredentialEntryList.size val inlineSuggestionsRequest = filLRequest.inlineSuggestionsRequest - val inlineMaxSuggestedCount = inlineSuggestionsRequest?.maxSuggestionCount ?: 0 val inlinePresentationSpecs = inlineSuggestionsRequest?.inlinePresentationSpecs val inlinePresentationSpecsCount = inlinePresentationSpecs?.size ?: 0 - val maxDropdownDisplayLimit = this.resources.getInteger( + val maxDatasetDisplayLimit = this.resources.getInteger( com.android.credentialmanager.R.integer.autofill_max_visible_datasets) - var maxInlineItemCount = totalEntryCount - maxInlineItemCount = maxInlineItemCount.coerceAtMost(inlineMaxSuggestedCount) - val lastDropdownDatasetIndex = Settings.Global.getInt(this.contentResolver, - Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, - (maxDropdownDisplayLimit - 1)).coerceAtMost(totalEntryCount) - + .coerceAtMost(totalEntryCount) var i = 0 var datasetAdded = false @@ -278,7 +269,7 @@ class CredentialAutofillService : AutofillService() { Log.e(TAG, "PendingIntent was missing from the entry.") return@usernameLoop } - if (i >= maxInlineItemCount && i >= lastDropdownDatasetIndex) { + if (i >= maxDatasetDisplayLimit) { return@usernameLoop } val icon: Icon = if (primaryEntry.icon == null) { @@ -291,7 +282,7 @@ class CredentialAutofillService : AutofillService() { } // Create inline presentation var inlinePresentation: InlinePresentation? = null - if (inlinePresentationSpecs != null && i < maxInlineItemCount) { + if (inlinePresentationSpecs != null && i < maxDatasetDisplayLimit) { val spec: InlinePresentationSpec? = if (i < inlinePresentationSpecsCount) { inlinePresentationSpecs[i] } else { @@ -305,7 +296,7 @@ class CredentialAutofillService : AutofillService() { } } var dropdownPresentation: RemoteViews? = null - if (i < lastDropdownDatasetIndex) { + if (i < maxDatasetDisplayLimit) { dropdownPresentation = RemoteViewsFactory .createDropdownPresentation(this, icon, primaryEntry) } @@ -331,17 +322,15 @@ class CredentialAutofillService : AutofillService() { .build()) datasetAdded = true i++ - - if (i == lastDropdownDatasetIndex) { - addDropdownMoreOptionsPresentation(bottomSheetIntent, autofillId, - fillResponseBuilder) - } } val pinnedSpec = getLastInlinePresentationSpec(inlinePresentationSpecs, inlinePresentationSpecsCount) - if (datasetAdded && pinnedSpec != null) { - addPinnedInlineSuggestion(pinnedSpec, autofillId, - fillResponseBuilder, bottomSheetIntent) + if (datasetAdded) { + addDropdownMoreOptionsPresentation(bottomSheetIntent, autofillId, fillResponseBuilder) + if (pinnedSpec != null) { + addPinnedInlineSuggestion(pinnedSpec, autofillId, + fillResponseBuilder, bottomSheetIntent) + } } return datasetAdded } diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt index d24adb567bc4..4ef776099119 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt @@ -16,6 +16,7 @@ package com.android.credentialmanager.createflow +import android.credentials.flags.Flags.selectorUiImprovementsEnabled import android.text.TextUtils import androidx.activity.compose.ManagedActivityResultLauncher import androidx.activity.result.ActivityResult @@ -329,6 +330,18 @@ fun CreationSelectionCard( ) } item { Divider(thickness = 24.dp, color = Color.Transparent) } + + val footerDescription = createOptionInfo.footerDescription + if (selectorUiImprovementsEnabled()) { + if (!footerDescription.isNullOrBlank()) { + item { + Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) { + BodySmallText(text = footerDescription) + } + } + item { Divider(thickness = 24.dp, color = Color.Transparent) } + } + } item { CredentialContainerCard { PrimaryCreateOptionRow( @@ -366,18 +379,19 @@ fun CreationSelectionCard( }, ) } - val footerDescription = createOptionInfo.footerDescription - if (footerDescription != null && footerDescription.length > 0) { - item { - Divider( - thickness = 1.dp, - color = LocalAndroidColorScheme.current.outlineVariant, - modifier = Modifier.padding(vertical = 16.dp) - ) - } - item { - Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) { - BodySmallText(text = footerDescription) + if (!selectorUiImprovementsEnabled()) { + if (footerDescription != null && footerDescription.length > 0) { + item { + Divider( + thickness = 1.dp, + color = LocalAndroidColorScheme.current.outlineVariant, + modifier = Modifier.padding(vertical = 16.dp) + ) + } + item { + Row(modifier = Modifier.fillMaxWidth().wrapContentHeight()) { + BodySmallText(text = footerDescription) + } } } } diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt index ccc46604ff98..660db7007224 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt @@ -16,6 +16,7 @@ package com.android.credentialmanager.getflow +import android.credentials.flags.Flags.selectorUiImprovementsEnabled import android.graphics.drawable.Drawable import android.text.TextUtils import androidx.activity.compose.ManagedActivityResultLauncher @@ -75,6 +76,7 @@ import com.android.credentialmanager.model.get.CredentialEntryInfo import com.android.credentialmanager.model.get.RemoteEntryInfo import com.android.credentialmanager.userAndDisplayNameForPasskey import com.android.internal.logging.UiEventLogger.UiEventEnum +import kotlin.math.max @Composable fun GetCredentialScreen( @@ -110,16 +112,29 @@ fun GetCredentialScreen( ProviderActivityState.NOT_APPLICABLE -> { if (getCredentialUiState.currentScreenState == GetScreenState.PRIMARY_SELECTION) { - PrimarySelectionCard( - requestDisplayInfo = getCredentialUiState.requestDisplayInfo, - providerDisplayInfo = getCredentialUiState.providerDisplayInfo, - providerInfoList = getCredentialUiState.providerInfoList, - activeEntry = getCredentialUiState.activeEntry, - onEntrySelected = viewModel::getFlowOnEntrySelected, - onConfirm = viewModel::getFlowOnConfirmEntrySelected, - onMoreOptionSelected = viewModel::getFlowOnMoreOptionSelected, - onLog = { viewModel.logUiEvent(it) }, - ) + if (selectorUiImprovementsEnabled()) { + PrimarySelectionCardVImpl( + requestDisplayInfo = getCredentialUiState.requestDisplayInfo, + providerDisplayInfo = getCredentialUiState.providerDisplayInfo, + providerInfoList = getCredentialUiState.providerInfoList, + activeEntry = getCredentialUiState.activeEntry, + onEntrySelected = viewModel::getFlowOnEntrySelected, + onConfirm = viewModel::getFlowOnConfirmEntrySelected, + onMoreOptionSelected = viewModel::getFlowOnMoreOptionSelected, + onLog = { viewModel.logUiEvent(it) }, + ) + } else { + PrimarySelectionCard( + requestDisplayInfo = getCredentialUiState.requestDisplayInfo, + providerDisplayInfo = getCredentialUiState.providerDisplayInfo, + providerInfoList = getCredentialUiState.providerInfoList, + activeEntry = getCredentialUiState.activeEntry, + onEntrySelected = viewModel::getFlowOnEntrySelected, + onConfirm = viewModel::getFlowOnConfirmEntrySelected, + onMoreOptionSelected = viewModel::getFlowOnMoreOptionSelected, + onLog = { viewModel.logUiEvent(it) }, + ) + } viewModel.uiMetrics.log(GetCredentialEvent .CREDMAN_GET_CRED_SCREEN_PRIMARY_SELECTION) } else { @@ -174,7 +189,8 @@ fun GetCredentialScreen( } } -/** Draws the primary credential selection page. */ +/** Draws the primary credential selection page, used in Android U. */ +// TODO(b/327518384) - remove after flag selectorUiImprovementsEnabled is enabled. @Composable fun PrimarySelectionCard( requestDisplayInfo: RequestDisplayInfo, @@ -358,6 +374,198 @@ fun PrimarySelectionCard( onLog(GetCredentialEvent.CREDMAN_GET_CRED_PRIMARY_SELECTION_CARD) } +internal const val MAX_ENTRY_FOR_PRIMARY_PAGE = 4 +/** Draws the primary credential selection page, used starting from android V. */ +@Composable +fun PrimarySelectionCardVImpl( + requestDisplayInfo: RequestDisplayInfo, + providerDisplayInfo: ProviderDisplayInfo, + providerInfoList: List<ProviderInfo>, + activeEntry: EntryInfo?, + onEntrySelected: (EntryInfo) -> Unit, + onConfirm: () -> Unit, + onMoreOptionSelected: () -> Unit, + onLog: @Composable (UiEventEnum) -> Unit, +) { + val showMoreForTruncatedEntry = remember { mutableStateOf(false) } + val sortedUserNameToCredentialEntryList = + providerDisplayInfo.sortedUserNameToCredentialEntryList + val authenticationEntryList = providerDisplayInfo.authenticationEntryList + // Show at most 4 entries (credential type or locked type) in this primary page + val primaryPageCredentialEntryList = + sortedUserNameToCredentialEntryList.take(MAX_ENTRY_FOR_PRIMARY_PAGE) + val primaryPageLockedEntryList = authenticationEntryList.take( + max(0, MAX_ENTRY_FOR_PRIMARY_PAGE - primaryPageCredentialEntryList.size) + ) + SheetContainerCard { + val preferTopBrandingContent = requestDisplayInfo.preferTopBrandingContent + if (preferTopBrandingContent != null) { + item { + HeadlineProviderIconAndName( + preferTopBrandingContent.icon, + preferTopBrandingContent.displayName + ) + } + } else { + // When only one provider's entries will be displayed on the primary page, display that + // provider's icon + name up top. + val singleProviderId = findSingleProviderIdForPrimaryPage( + primaryPageCredentialEntryList, + primaryPageLockedEntryList + ) + if (singleProviderId != null) { + // First should always work but just to be safe. + val providerInfo = providerInfoList.firstOrNull { it.id == singleProviderId } + if (providerInfo != null) { + item { + HeadlineProviderIconAndName( + providerInfo.icon, + providerInfo.displayName + ) + } + } + } + } + + val hasSingleEntry = primaryPageCredentialEntryList.size + + primaryPageLockedEntryList.size == 1 + item { + if (requestDisplayInfo.preferIdentityDocUi) { + HeadlineText( + text = stringResource( + if (hasSingleEntry) { + R.string.get_dialog_title_use_info_on + } else { + R.string.get_dialog_title_choose_option_for + }, + requestDisplayInfo.appName + ), + ) + } else { + HeadlineText( + text = stringResource( + if (hasSingleEntry) { + val singleEntryType = primaryPageCredentialEntryList.firstOrNull() + ?.sortedCredentialEntryList?.firstOrNull()?.credentialType + if (singleEntryType == CredentialType.PASSKEY) + R.string.get_dialog_title_use_passkey_for + else if (singleEntryType == CredentialType.PASSWORD) + R.string.get_dialog_title_use_password_for + else if (authenticationEntryList.isNotEmpty()) + R.string.get_dialog_title_unlock_options_for + else R.string.get_dialog_title_use_sign_in_for + } else { + if (authenticationEntryList.isNotEmpty() || + sortedUserNameToCredentialEntryList.any { perNameEntryList -> + perNameEntryList.sortedCredentialEntryList.any { entry -> + entry.credentialType != CredentialType.PASSWORD && + entry.credentialType != CredentialType.PASSKEY + } + } + ) // For an unknown / locked entry, it's not true that it is + // already saved, strictly speaking. Hence use a different title + // without the mention of "saved" + R.string.get_dialog_title_choose_sign_in_for + else + R.string.get_dialog_title_choose_saved_sign_in_for + }, + requestDisplayInfo.appName + ), + ) + } + } + item { Divider(thickness = 24.dp, color = Color.Transparent) } + item { + CredentialContainerCard { + Column(verticalArrangement = Arrangement.spacedBy(2.dp)) { + primaryPageCredentialEntryList.forEach { + CredentialEntryRow( + credentialEntryInfo = it.sortedCredentialEntryList.first(), + onEntrySelected = onEntrySelected, + enforceOneLine = true, + onTextLayout = { + showMoreForTruncatedEntry.value = it.hasVisualOverflow + }, + hasSingleEntry = hasSingleEntry, + ) + } + primaryPageLockedEntryList.forEach { + AuthenticationEntryRow( + authenticationEntryInfo = it, + onEntrySelected = onEntrySelected, + enforceOneLine = true, + ) + } + } + } + } + item { Divider(thickness = 24.dp, color = Color.Transparent) } + var totalEntriesCount = sortedUserNameToCredentialEntryList + .flatMap { it.sortedCredentialEntryList }.size + authenticationEntryList + .size + providerInfoList.flatMap { it.actionEntryList }.size + if (providerDisplayInfo.remoteEntry != null) totalEntriesCount += 1 + // Row horizontalArrangement differs on only one actionButton(should place on most + // left)/only one confirmButton(should place on most right)/two buttons exist the same + // time(should be one on the left, one on the right) + item { + CtaButtonRow( + leftButton = if (totalEntriesCount > 1) { + { + ActionButton( + stringResource(R.string.get_dialog_title_sign_in_options), + onMoreOptionSelected + ) + } + } else if (showMoreForTruncatedEntry.value) { + { + ActionButton( + stringResource(R.string.button_label_view_more), + onMoreOptionSelected + ) + } + } else null, + rightButton = if (activeEntry != null) { // Only one sign-in options exist + { + ConfirmButton( + stringResource(R.string.string_continue), + onClick = onConfirm + ) + } + } else null, + ) + } + } + onLog(GetCredentialEvent.CREDMAN_GET_CRED_PRIMARY_SELECTION_CARD) +} + +/** + * Attempt to find a single provider id, if it has supplied all the entries to be displayed on the + * front page; otherwise if multiple providers are found, return null. + */ +private fun findSingleProviderIdForPrimaryPage( + primaryPageCredentialEntryList: List<PerUserNameCredentialEntryList>, + primaryPageLockedEntryList: List<AuthenticationEntryInfo> +): String? { + var providerId: String? = null + primaryPageCredentialEntryList.forEach { + val currProviderId = it.sortedCredentialEntryList.first().providerId + if (providerId == null) { + providerId = currProviderId + } else if (providerId != currProviderId) { + return null + } + } + primaryPageLockedEntryList.forEach { + val currProviderId = it.providerId + if (providerId == null) { + providerId = currProviderId + } else if (providerId != currProviderId) { + return null + } + } + return providerId +} + /** Draws the secondary credential selection page, where all sign-in options are listed. */ @Composable fun AllSignInOptionCard( @@ -540,6 +748,8 @@ fun CredentialEntryRow( onEntrySelected: (EntryInfo) -> Unit, enforceOneLine: Boolean = false, onTextLayout: (TextLayoutResult) -> Unit = {}, + // Make optional since the secondary page doesn't care about this value. + hasSingleEntry: Boolean? = null, ) { val (username, displayName) = if (credentialEntryInfo.credentialType == CredentialType.PASSKEY) userAndDisplayNameForPasskey( @@ -554,11 +764,19 @@ fun CredentialEntryRow( if (credentialEntryInfo.icon == null) painterResource(R.drawable.ic_other_sign_in_24) else null, entryHeadlineText = username, - entrySecondLineText = listOf( + entrySecondLineText = + (if (hasSingleEntry != null && hasSingleEntry) + if (credentialEntryInfo.credentialType == CredentialType.PASSKEY || + credentialEntryInfo.credentialType == CredentialType.PASSWORD) + listOf(displayName) + // Still show the type display name for all non-password/passkey types since it won't be + // mentioned in the bottom sheet heading. + else listOf(displayName, credentialEntryInfo.credentialTypeDisplayName) + else listOf( displayName, credentialEntryInfo.credentialTypeDisplayName, credentialEntryInfo.providerDisplayName - ).filterNot(TextUtils::isEmpty).let { itemsToDisplay -> + )).filterNot(TextUtils::isEmpty).let { itemsToDisplay -> if (itemsToDisplay.isEmpty()) null else itemsToDisplay.joinToString( separator = stringResource(R.string.get_dialog_sign_in_type_username_separator) diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt index 458a99a8cd2f..e7f11a15a06c 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt @@ -16,6 +16,7 @@ package com.android.credentialmanager.getflow +import android.credentials.flags.Flags.selectorUiImprovementsEnabled import android.graphics.drawable.Drawable import com.android.credentialmanager.model.get.ProviderInfo import com.android.credentialmanager.model.EntryInfo @@ -133,7 +134,7 @@ fun toProviderDisplayInfo( providerInfo.credentialEntryList.forEach { userNameToCredentialEntryMap.compute( - it.userName + if (selectorUiImprovementsEnabled()) it.entryGroupId else it.userName ) { _, v -> if (v == null) { mutableListOf(it) diff --git a/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt b/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt index e609d0c5c008..d9ba36e1cdfc 100644 --- a/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt +++ b/packages/CredentialManager/tests/robotests/screenshot/src/com/android/credentialmanager/GetCredScreenshotTest.kt @@ -146,7 +146,8 @@ class GetCredScreenshotTest(emulationSpec: DeviceEmulationSpec) { icon = null, shouldTintIcon = true, lastUsedTimeMillis = null, - isAutoSelectable = false + isAutoSelectable = false, + entryGroupId = "username", ) ), authenticationEntryList = emptyList(), diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt index 463c4d1b063e..66be7ba5e079 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt @@ -29,10 +29,14 @@ import com.android.credentialmanager.model.get.AuthenticationEntryInfo import com.android.credentialmanager.model.get.CredentialEntryInfo import com.android.credentialmanager.ui.mappers.toGet import android.util.Log +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.compose.runtime.Composable import com.android.credentialmanager.CredentialSelectorUiState.Cancel import com.android.credentialmanager.CredentialSelectorUiState.Close import com.android.credentialmanager.CredentialSelectorUiState.Create import com.android.credentialmanager.CredentialSelectorUiState.Idle +import com.android.credentialmanager.activity.StartBalIntentSenderForResultContract +import com.android.credentialmanager.ktx.getIntentSenderRequest import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted @@ -47,6 +51,8 @@ class CredentialSelectorViewModel @Inject constructor( ) : FlowEngine, ViewModel() { private val isPrimaryScreen = MutableStateFlow(true) private val shouldClose = MutableStateFlow(false) + private lateinit var selectedEntry: EntryInfo + private var isAutoSelected: Boolean = false val uiState: StateFlow<CredentialSelectorUiState> = combine( credentialManagerClient.requests, @@ -108,6 +114,25 @@ class CredentialSelectorViewModel @Inject constructor( ) shouldClose.value = result } + + @Composable + override fun getEntrySelector(): (entry: EntryInfo, isAutoSelected: Boolean) -> Unit { + val launcher = rememberLauncherForActivityResult( + StartBalIntentSenderForResultContract() + ) { + sendSelectionResult(entryInfo = selectedEntry, + resultCode = it.resultCode, + resultData = it.data, + isAutoSelected = isAutoSelected) + } + return { selected, autoSelect -> + selectedEntry = selected + isAutoSelected = autoSelect + selected.getIntentSenderRequest()?.let { + launcher.launch(it) + } ?: Log.w(TAG, "Cannot parse IntentSenderRequest") + } + } } sealed class CredentialSelectorUiState { diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt index e4216446772b..2e80a7c672f4 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/FlowEngine.kt @@ -17,6 +17,8 @@ package com.android.credentialmanager import android.content.Intent +import androidx.activity.result.IntentSenderRequest +import androidx.compose.runtime.Composable import com.android.credentialmanager.model.EntryInfo /** Engine of the credential selecting flow. */ @@ -42,4 +44,14 @@ interface FlowEngine { resultData: Intent? = null, isAutoSelected: Boolean = false, ) + + /** + * Helper function to get an entry selector. + * + * @return selector fun consumes selected [EntryInfo]. Once invoked, [IntentSenderRequest] would + * be launched and invocation of [sendSelectionResult] would happen right after launching result + * coming back. + */ + @Composable + fun getEntrySelector(): (entry: EntryInfo, isAutoSelected: Boolean) -> Unit }
\ No newline at end of file diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt index f9a5887158eb..405de1d3acc6 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/WearApp.kt @@ -43,6 +43,7 @@ import com.google.android.horologist.compose.navscaffold.WearNavScaffold import com.google.android.horologist.compose.navscaffold.composable import com.google.android.horologist.compose.navscaffold.scrollable import com.android.credentialmanager.model.CredentialType +import com.android.credentialmanager.model.EntryInfo import com.android.credentialmanager.ui.screens.multiple.MultiCredentialsFoldScreen @OptIn(ExperimentalHorologistApi::class) @@ -56,6 +57,7 @@ fun WearApp( val swipeToDismissBoxState = rememberSwipeToDismissBoxState() val navHostState = rememberSwipeDismissableNavHostState(swipeToDismissBoxState = swipeToDismissBoxState) + val selectEntry = flowEngine.getEntrySelector() val uiState by viewModel.uiState.collectAsStateWithLifecycle() WearNavScaffold( @@ -111,6 +113,7 @@ fun WearApp( navController = navController, state = state, onCloseApp = onCloseApp, + selectEntry = selectEntry ) } @@ -133,9 +136,14 @@ private fun handleGetNavigation( navController: NavController, state: CredentialSelectorUiState.Get, onCloseApp: () -> Unit, + selectEntry: (entry: EntryInfo, isAutoSelected: Boolean) -> Unit, ) { when (state) { is SingleEntry -> { + if (state.entry.isAutoSelectable) { + selectEntry(state.entry, true) + return + } when (state.entry.credentialType) { CredentialType.UNKNOWN -> { navController.navigateToSignInWithProviderScreen() diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt index 1f1a296dca9b..2ca8ef13c0cf 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreen.kt @@ -18,8 +18,6 @@ package com.android.credentialmanager.ui.screens.single.password -import android.util.Log -import androidx.activity.compose.rememberLauncherForActivityResult import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable @@ -28,9 +26,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.android.credentialmanager.FlowEngine import com.android.credentialmanager.R -import com.android.credentialmanager.TAG -import com.android.credentialmanager.activity.StartBalIntentSenderForResultContract -import com.android.credentialmanager.ktx.getIntentSenderRequest import com.android.credentialmanager.ui.components.PasswordRow import com.android.credentialmanager.ui.components.ContinueChip import com.android.credentialmanager.ui.components.DismissChip @@ -57,11 +52,7 @@ fun SinglePasswordScreen( modifier: Modifier = Modifier, flowEngine: FlowEngine, ) { - val launcher = rememberLauncherForActivityResult( - StartBalIntentSenderForResultContract() - ) { - flowEngine.sendSelectionResult(entry, it.resultCode, it.data) - } + val selectEntry = flowEngine.getEntrySelector() SingleAccountScreen( headerContent = { SignInHeader( @@ -80,11 +71,7 @@ fun SinglePasswordScreen( ) { item { Column { - ContinueChip { - entry.getIntentSenderRequest()?.let { - launcher.launch(it) - } ?: Log.w(TAG, "Cannot parse IntentSenderRequest") - } + ContinueChip { selectEntry(entry, false) } SignInOptionsChip{ flowEngine.openSecondaryScreen() } DismissChip { flowEngine.cancel() } } diff --git a/packages/EasterEgg/Android.bp b/packages/EasterEgg/Android.bp index 0caf505c2177..6f4f9ca2e8e1 100644 --- a/packages/EasterEgg/Android.bp +++ b/packages/EasterEgg/Android.bp @@ -48,6 +48,8 @@ android_app { }, static_libs: [ + "easter_egg_flags_lib", + "androidx.core_core", "androidx.annotation_annotation", "androidx.recyclerview_recyclerview", @@ -72,3 +74,16 @@ android_app { kotlincflags: ["-Xjvm-default=all"], } + +java_aconfig_library { + name: "easter_egg_flags_lib", + aconfig_declarations: "easter_egg_flags", +} + +aconfig_declarations { + name: "easter_egg_flags", + package: "com.android.egg.flags", + srcs: [ + "easter_egg_flags.aconfig", + ], +} diff --git a/packages/EasterEgg/easter_egg_flags.aconfig b/packages/EasterEgg/easter_egg_flags.aconfig new file mode 100644 index 000000000000..3268a4f5728c --- /dev/null +++ b/packages/EasterEgg/easter_egg_flags.aconfig @@ -0,0 +1,8 @@ +package: "com.android.egg.flags" + +flag { + name: "flag_flag" + namespace: "systemui" + description: "Flags are planted on planets when you land. Yes, it's a flag for flags." + bug: "320150798" +} diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt b/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt index fec3ab3877ea..11dce613b0fb 100644 --- a/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt +++ b/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt @@ -174,7 +174,9 @@ open class Universe(val namer: Namer, randomSeed: Long) : Simulator(randomSeed) ship = Spacecraft() - ship.pos = star.pos + Vec2.makeWithAngleMag(PIf / 4, PLANET_ORBIT_RANGE.start) + // in the test universe, start the ship near the outermost planet + ship.pos = planets.last().pos + Vec2(planets.first().radius * 1.5f, 0f) + ship.angle = 0f add(ship) diff --git a/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt b/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt index 24b9c6a283c2..6baf36ee3c8a 100644 --- a/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt +++ b/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt @@ -31,6 +31,8 @@ import androidx.core.math.MathUtils.clamp import java.lang.Float.max import kotlin.math.sqrt +import com.android.egg.flags.Flags.flagFlag + const val DRAW_ORBITS = true const val DRAW_GRAVITATIONAL_FIELDS = true const val DRAW_STAR_GRAVITATIONAL_FIELDS = true @@ -279,8 +281,23 @@ fun ZoomedDrawScope.drawSpacecraft(ship: Spacecraft) { fun ZoomedDrawScope.drawLanding(landing: Landing) { val v = landing.planet.pos + Vec2.makeWithAngleMag(landing.angle, landing.planet.radius) - drawLine(Color.Red, v + Vec2(-5f, -5f), v + Vec2(5f, 5f), strokeWidth = 1f / zoom) - drawLine(Color.Red, v + Vec2(5f, -5f), v + Vec2(-5f, 5f), strokeWidth = 1f / zoom) + + if (flagFlag()) { + val strokeWidth = 2f / zoom + val height = 80f + rotateRad(landing.angle, pivot = v) { + translate(v.x, v.y) { + drawPath( + Path().apply { + moveTo(0f, 0f) + lineTo(height, 0f) + lineTo(height * 0.875f, height * 0.25f) + lineTo(height * 0.75f, 0f) + close() + }, Color.Yellow, style = Stroke(width = strokeWidth)) + } + } + } } fun ZoomedDrawScope.drawSpark(spark: Spark) { diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml index 531190327165..ee0c752c54b0 100644 --- a/packages/PackageInstaller/res/values-fr/strings.xml +++ b/packages/PackageInstaller/res/values-fr/strings.xml @@ -98,9 +98,9 @@ <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"Pour votre sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur actuellement. Vous pouvez modifier cette option dans les paramètres."</string> <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"Pour votre sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur cette montre actuellement. Vous pouvez modifier cette option dans les paramètres."</string> <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"Pour votre sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur ce téléphone actuellement. Vous pouvez modifier cette option dans les paramètres."</string> - <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Votre téléphone et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de son utilisation."</string> - <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Votre tablette et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de son utilisation."</string> - <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Votre téléviseur et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string> + <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Votre téléphone et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être l\'unique responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de son utilisation."</string> + <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Votre tablette et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être l\'unique responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de son utilisation."</string> + <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Votre téléviseur et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être l\'unique responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string> <string name="cloned_app_label" msgid="7503612829833756160">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string> <string name="archiving_app_label" msgid="1127085259724124725">"Archiver <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ?"</string> <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuer"</string> diff --git a/packages/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS index 5f5f1d59ac1c..5966c9f759fb 100644 --- a/packages/SettingsLib/OWNERS +++ b/packages/SettingsLib/OWNERS @@ -5,6 +5,7 @@ cipson@google.com dsandler@android.com edgarwang@google.com evanlaird@google.com +jiannan@google.com juliacr@google.com ykhung@google.com diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt index bb7e8575ba1b..3acf075d8900 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/Preference.kt @@ -18,7 +18,6 @@ package com.android.settingslib.spa.widget.preference import androidx.compose.foundation.clickable import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import com.android.settingslib.spa.framework.common.EntryMacro @@ -107,14 +106,9 @@ fun Preference( ) { val onClickWithLog = wrapOnClickWithLog(model.onClick) val enabled = model.enabled() - val modifier = remember(enabled) { - if (onClickWithLog != null) { - Modifier.clickable( - enabled = enabled, - onClick = onClickWithLog - ) - } else Modifier - } + val modifier = if (onClickWithLog != null) { + Modifier.clickable(enabled = enabled, onClick = onClickWithLog) + } else Modifier EntryHighlight { BasePreference( title = model.title, diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 8d3582a736fe..7245099c4ff2 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laaiproses is onderbreek om battery te beskerm"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Kontroleer tans laaibykomstigheid"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor gegrond op jou gebruik"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> oor tot vol"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> oor tot vol"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laaiproses word geoptimeer"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laai tans"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Onbekend"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Laai"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laai tans vinnig"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index f6931ad30353..dc91df021347 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ባትሪን ለመጠበቅ ኃይል መሙላት በይቆይ ላይ"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - የኃይል መሙያ መለዋወጫዎችን በመፈተሽ ላይ"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ገደማ ቀርቷል"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>) ገደማ ቀርቷል"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"በአጠቃቀምዎ መሠረት <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ገደማ ቀርቷል"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"እስኪሞላ ድረስ <xliff:g id="TIME">%1$s</xliff:g> ይቀራል"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - እስኪሞላ ድረስ <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ኃይል መሙላት እንዲተባ ተደርጓል"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - ኃይል በመሙላት ላይ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"ያልታወቀ"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ኃይል በመሙላት ላይ"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ኃይል በፍጥነት በመሙላት ላይ"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 92dc69ca54fe..87c4d7fb99a7 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - الشحن معلَّق لحماية البطارية"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - يجب فحص ملحق الشحن"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا."</string> <string name="power_discharging_duration" msgid="1076561255466053220">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا، بناءً على استخدامك"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"يتبقّى <xliff:g id="TIME">%1$s</xliff:g> حتى اكتمال شحن البطارية."</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقّى <xliff:g id="TIME">%2$s</xliff:g> حتى اكتمال شحن البطارية."</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - تم تحسين الشحن"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g>: جارٍ الشحن"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"غير معروف"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"جارٍ الشحن"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"جارٍ الشحن سريعًا"</string> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index 48d3df4621f3..bcf9f5d25980 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g>ৰ দ্বাৰা অগ্ৰাহ্য কৰা হৈছে"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - বেটাৰী সুৰক্ষিত কৰিবলৈ চাৰ্জিং স্থগিত ৰখা হৈছে"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - চাৰ্জিঙৰ আনুষংগিক বস্তু পৰীক্ষা কৰি থকা হৈছে"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"প্রায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"প্রায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি প্ৰায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"সম্পূৰ্ণ হ’বলৈ <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string> <string name="power_charging_duration" msgid="6127154952524919719">"সম্পূৰ্ণ হ’বলৈ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - চাৰ্জিং অপ্টিমাইজ কৰা হৈছে"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ চাৰ্জ হৈ আছে"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"অজ্ঞাত"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"চাৰ্জ কৰি থকা হৈছে"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"দ্ৰুততাৰে চাৰ্জ হৈছে"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index e27a40cdf7b1..22dbff2036bb 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Batareyanı qorumaq üçün şarj gözlədilir"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj aksesuarı yoxlanır"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Təxminən <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Təxminən <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"İstifadəyə əsasən təxminən <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Tam şarj edilənədək <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - tam şarj edilənədək <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj optimallaşdırılıb"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj edilir"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Naməlum"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Enerji doldurma"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Sürətlə doldurulur"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index dd48b70bd8ed..ee58e8ef5e04 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>–<xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je na čekanju da bi se zaštitila baterija"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – provera dodatne opreme za punjenje"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> na osnovu korišćenja"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do kraja punjenja"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do kraja punjenja"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je optimizovano"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Punjenje"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Puni se"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo se puni"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index 48247a01034f..079a8f3aaa11 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Перавызначаны <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарадка прыпынена, каб абараніць акумулятар"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – правяраецца зарадная прылада"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Зараду хопіць прыблізна на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Зараду (<xliff:g id="LEVEL">%2$s</xliff:g>) хопіць прыблізна на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Зараду пры такім выкарыстанні хопіць прыблізна на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Да поўнай зарадкі засталося <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – да поўнай зарадкі засталося: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зарадка аптымізавана"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – зараджаецца"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Невядома"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Зарадка"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Хуткая зарадка"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index 035b1dd19c5a..5a0c0b779f55 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зареждането е поставено на пауза с цел запазване на батерията"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Аксесоарът за зареждане се проверява"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Още около <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Още около <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Още около <xliff:g id="TIME_REMAINING">%1$s</xliff:g> въз основа на използването"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Оставащо време до пълно зареждане: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – Оставащо време до пълно зареждане: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зареждането е оптимизирано"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарежда се"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Неизвестно"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Зарежда се"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Зарежда се бързо"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index 9a2f88c1eb1f..6fb6fb3dc6cd 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ব্যাটারিকে সুরক্ষিত রাখতে চার্জিং হোল্ড করা হয়েছে"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - চার্জিংয়ের সরঞ্জাম চেক করা হচ্ছে"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"আর আনুমানিক <xliff:g id="TIME_REMAINING">%1$s</xliff:g> চলবে"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"আর আনুমানিক <xliff:g id="TIME_REMAINING">%1$s</xliff:g> চলবে (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ব্যবহারের উপর ভিত্তি করে আর আনুমানিক <xliff:g id="TIME_REMAINING">%1$s</xliff:g> চলবে"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>-এ ব্যাটারি পুরো চার্জ হয়ে যাবে"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>-এ ব্যাটারি পুরো চার্জ হয়ে যাবে"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - চার্জিং অপ্টিমাইজ করা হয়েছে"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - চার্জ করা হচ্ছে"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"অজানা"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"চার্জ হচ্ছে"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"দ্রুত চার্জ হচ্ছে"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index 01662dd8bed6..a430848e79f3 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je na čekanju radi zaštite baterije"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – provjera opreme za punjenje"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Preostalo je još oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Preostalo je još oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Preostalo je još oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g> na osnovu vaše potrošnje"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do potpune napunjenosti"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do potpune napunjenosti"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je optimizirano"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Punjenje"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 61898881baac..0bbb97960a76 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>: <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>: la càrrega s\'ha posat en espera per protegir la bateria"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g>: s\'està comprovant l\'accessori de càrrega"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Temps restant aproximat: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Temps restant aproximat: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Temps restant aproximat segons l\'ús que en fas: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> per completar la càrrega"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g>: càrrega optimitzada"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g>: s\'està carregant"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconegut"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"S\'està carregant"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregant ràpidament"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index ec104b4a95e4..97d0d15bfedf 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Nabíjení je pozastaveno za účelem ochrany baterie"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Kontrola nabíjecího příslušenství"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Zbývá asi <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Zbývá asi <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Při vašem obvyklém využití zbývá asi <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do úplného nabití"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – optimalizované nabíjení"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Nabíjení"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Neznámé"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Nabíjí se"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rychlé nabíjení"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index b92fc040cd30..096042246e01 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Opladningen er sat på pause for at beskytte batteriet"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Tjekker opladningstilbehøret"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Fuldt opladet om <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – fuldt opladet om <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – opladning er optimeret"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – oplades"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Ukendt"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Oplader"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Oplader hurtigt"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index debdb1e6b361..cb36cca64ff4 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladevorgang zum Schutz des Akkus angehalten"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladezubehör wird geprüft"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Bei deinem Nutzungsmuster hast du noch ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Voll in <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – voll in <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Laden wird optimiert"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Wird geladen"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Unbekannt"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Wird aufgeladen"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Schnelles Aufladen"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 6cf05597feb2..4953884b0d74 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Η φόρτιση τέθηκε σε αναμονή για προστασία της μπαταρίας"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Έλεγχος αξεσουάρ φόρτισης"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Απομένει/ουν περίπου <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Απομένει/ουν περίπου <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Απομένει/ουν περίπου <xliff:g id="TIME_REMAINING">%1$s</xliff:g>, βάσει της χρήσης σας"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Απομένουν <xliff:g id="TIME">%1$s</xliff:g> για πλήρη φόρτιση"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - Απομένουν <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Η φόρτιση βελτιστοποιήθηκε"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ Φόρτιση"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Άγνωστο"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Φόρτιση"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ταχεία φόρτιση"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index b2c5718c999f..d730fb7951e1 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Charging on hold to protect battery"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Checking charging accessory"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> left until full"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimised"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – charging"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 21fff5e1e3be..36dfd2fb0c28 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -457,7 +457,7 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging on hold to protect battery"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Checking charging accessory"</string> + <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Check charging accessory"</string> <string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index b2c5718c999f..d730fb7951e1 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Charging on hold to protect battery"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Checking charging accessory"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> left until full"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimised"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – charging"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index b2c5718c999f..d730fb7951e1 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Charging on hold to protect battery"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Checking charging accessory"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> left until full"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> left until full"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging optimised"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – charging"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Unknown"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Charging"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charging rapidly"</string> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index 25e2779c4f5c..8b05e12f2ee4 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -457,7 +457,7 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Charging on hold to protect battery"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Checking charging accessory"</string> + <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> - Check charging accessory"</string> <string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left based on your usage"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index d0ba34c4c8f4..775f23c14eac 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Se detuvo la carga para proteger la batería"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Verificando el accesorio de carga"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tiempo restante: aproximadamente <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Tiempo restante: aproximadamente <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tiempo restante: aproximadamente <xliff:g id="TIME_REMAINING">%1$s</xliff:g> en función de tu uso"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> para completar"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga optimizada"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Cargando"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rápidamente"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 77049e0c6837..70b85029a2b0 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>: <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga pausada para proteger la batería"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Comprobando accesorio de carga"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tiempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Tiempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tiempo restante aproximado según tu uso: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> hasta la carga completa"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hasta la carga completa"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga optimizada"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ Cargar"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carga rápida"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index 6a3c208efa59..daae2147ce7b 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – laadimine on aku kaitsmiseks ootele pandud"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – laadimistarviku kontrollimine"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Ligikaudu <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Ligikaudu <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Teie kasutuse põhjal on jäänud ligikaudu <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Täislaadimiseks kulub <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – täislaadimiseks kulub <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – laadimine on optimeeritud"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – laadimine"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Tundmatu"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Laadimine"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Kiirlaadimine"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index 64e372ac182a..2fd01f3ab848 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>: kargatze-prozesua zain dago bateria babesteko"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g>: kargatzeko osagarria egiaztatzen"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> inguru gelditzen dira"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> inguru gelditzen dira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Erabilera kontuan izanda, <xliff:g id="TIME_REMAINING">%1$s</xliff:g> inguru gelditzen dira"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kargatzeko modu optimizatua"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ Kargatzen"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Ezezaguna"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Kargatzen"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Bizkor kargatzen"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 01d4618a319e..9a1e1076eae9 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - برای محافظت از باتری، شارژ موقتاً متوقف شده است"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - بررسی لوازم شارژ"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"براساس مصرفتان، تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> تا شارژ کامل باقی مانده است"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل باقی مانده است"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - شارژ بهینه شده است"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - درحال شارژ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"ناشناس"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"در حال شارژ شدن"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"درحال شارژ شدن سریع"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 529bed536f1f..0faa32c54442 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Lataus on keskeytetty akun suojaamiseksi"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Tarkistetaan latauslisävarustetta"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Noin <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Noin <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Noin <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä käyttösi perusteella"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> kunnes täynnä"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Lataus optimoitu"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladataan"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Tuntematon"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Ladataan"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Nopea lataus"</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index ea2383425dc9..24de4cd07a80 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> : <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – La recharge a été mise en pause pour protéger la pile"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Vérification de l\'accessoire de recharge en cours…"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Il reste environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Il reste environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Il reste environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> en fonction de votre usage"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> jusqu\'à la recharge complète"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> jusqu\'à la recharge complète)"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Recharge optimisée"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Recharge en cours…"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Inconnu"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Charge en cours…"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Recharge rapide"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index dbf107acf46e..8f61c8d604fa 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Recharge en pause pour protéger la batterie"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Vérification de l\'accessoire de recharge"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Temps restant : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Temps restant : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Chargée à 100 %% dans <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Recharge optimisée"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - En charge"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Inconnu"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Batterie en charge"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Charge rapide"</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index 233c9d4d6a1b..4cd9e2ca86b7 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>. A carga púxose en pausa para protexer a batería"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g>. Comprobando accesorio de carga"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Tempo restante aproximado (<xliff:g id="LEVEL">%2$s</xliff:g>): <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tempo restante aproximado en función do uso: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> para completar a carga"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> (<xliff:g id="TIME">%2$s</xliff:g> para completar a carga)"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> (carga optimizada)"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> (cargando)"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Descoñecido"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Cargando"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Cargando rapidamente"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index 762ed28a4317..15f92875e22d 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - બૅટરીને સુરક્ષિત રાખવા માટે, ચાર્જિંગ હોલ્ડ પર રાખવામાં આવ્યું છે"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જિંગ ઍક્સેસરી ચેક કરી રહ્યાં છીએ"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"લગભગ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> બાકી છે"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"લગભગ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> બાકી છે (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"તમારા વપરાશના આધારે લગભગ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> બાકી છે"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"પૂર્ણ ચાર્જ થવામાં <xliff:g id="TIME">%1$s</xliff:g> બાકી છે"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - પૂર્ણ ચાર્જ થવામાં <xliff:g id="TIME">%2$s</xliff:g> બાકી છે"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જિંગ ઑપ્ટિમાઇઝ કરવામાં આવ્યું છે"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - ચાર્જિંગ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"અજાણ્યું"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ચાર્જ થઈ રહ્યું છે"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ઝડપથી ચાર્જ થાય છે"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 6a0e3e0f706f..5c94489f8f77 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - बैटरी को सुरक्षित रखने के लिए, फ़ोन को चार्ज होने से रोक दिया गया है"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंग ऐक्सेसरी की जांच की जा रही है"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"बैटरी करीब <xliff:g id="TIME_REMAINING">%1$s</xliff:g> में खत्म हो जाएगी"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"बैटरी करीब <xliff:g id="TIME_REMAINING">%1$s</xliff:g> में खत्म हो जाएगी (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"आपके इस्तेमाल के हिसाब से बैटरी करीब <xliff:g id="TIME_REMAINING">%1$s</xliff:g> में खत्म हो जाएगी"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> में बैटरी पूरी चार्ज हो जाएगी"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> में बैटरी पूरी चार्ज हो जाएगी"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंग को ऑप्टिमाइज़ किया गया"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्ज हो रही है"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हो रही है"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"तेज़ चार्ज हो रही है"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index f019936ed9c4..cc7b327e9d4f 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje je pauzirano radi zaštite baterije"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – provjera dodatka za punjenje"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Još oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Još otprilike <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Još otprilike <xliff:g id="TIME_REMAINING">%1$s</xliff:g> na temelju vaše upotrebe"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do napunjenosti"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje se optimizira"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – punjenje"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Nepoznato"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Punjenje"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Brzo punjenje"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index d3d2960b22b9..e9fd9dbd54e9 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Az akkumulátor védelme érdekében a töltés szünetel"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Akkumulátortartozék ellenőrzése…"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Körülbelül <xliff:g id="TIME_REMAINING">%1$s</xliff:g> maradt hátra"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Körülbelül <xliff:g id="TIME_REMAINING">%1$s</xliff:g> maradt hátra (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Körülbelül <xliff:g id="TIME_REMAINING">%1$s</xliff:g> maradt hátra az eszköz használata alapján"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> a teljes töltöttségig"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes töltöttségig"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Optimalizált töltés"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Töltés…"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Ismeretlen"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Töltés"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Gyorstöltés"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index 4c14ae12fbb1..d6b356005ac6 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Լիցքավորումը դադարեցվել է՝ մարտկոցը պաշտպանելու համար"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Լիցքավորման սարքը ստուգվում է"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Լիցքը կբավարարի մոտ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Լիցքը (<xliff:g id="LEVEL">%2$s</xliff:g>) կբավարարի մոտ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Լիցքը կբավարարի մոտ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>՝ կախված օգտագործման եղանակից"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> մինչև լրիվ լիցքավորումը"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Լիցքավորումն օպտիմալացված է"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> — Լիցքավորում"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Անհայտ"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Լիցքավորում"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Արագ լիցքավորում"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 1379ecfc99b7..398853aa5b02 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengisian daya dihentikan sementara untuk melindungi baterai"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Memeriksa aksesori pengisi daya"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Sekitar <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Sekitar <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Sekitar <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi berdasarkan penggunaan Anda"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> lagi sampai penuh"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi sampai penuh"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengisian daya dioptimalkan"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Mengisi daya"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Tidak diketahui"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Mengisi daya"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengisi daya cepat"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index e48d063d9d3c..2be92e5dff33 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Hleðsla í bið til að vernda rafhlöðuna"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Athugar hleðslutæki"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Um það bil <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Um það bil <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Um það bil <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir miðað við notkun þína"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> fram að fullri hleðslu"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> fram að fullri hleðslu"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Hleðsla fínstillt"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ Í hleðslu"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Óþekkt"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Í hleðslu"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hröð hleðsla"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index b33551440684..3dc69e8ace46 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ricarica in sospeso per proteggere la batteria"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Controllo dell\'accessorio di ricarica"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo rimanente: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> circa"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Tempo rimanente: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> circa (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> circa"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> alla ricarica completa"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla ricarica completa"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ricarica ottimizzata"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ In carica"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Sconosciuta"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"In carica"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ricarica veloce"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index a559cc616105..e3c1f65b4a4d 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – הטעינה הושהתה כדי להגן על הסוללה"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – מתבצעת בדיקה של אביזר הטעינה"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"הזמן הנותר: בערך <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"הזמן הנותר: בערך <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"הזמן הנותר על סמך השימוש שלך: בערך <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"הזמן הנותר לטעינה מלאה: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – הזמן הנותר לטעינה מלאה: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – הטעינה עברה אופטימיזציה"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – בטעינה"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"לא ידוע"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"בטעינה"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"הסוללה נטענת מהר"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index a7be818b3f85..9ef9cf1bc043 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - バッテリーを保護するため、充電を一時停止しています"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電用アクセサリを確認しています"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"残り時間: 約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"残り時間: 約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"残り時間: 約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>(使用状況に基づく)"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"完了まであと <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - 完了まであと <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電が最適化されています"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電中"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"不明"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"急速充電中"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index eb06df31e676..4ddb0054c329 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – დატენვა შეჩერებულია ბატარეის დასაცავად"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – მიმდინარეობს დამტენი აქსესუარის შემოწმება"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"დარჩა დაახლოებით <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"დარჩა დაახლოებით <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"დარჩა დაახლოებით <xliff:g id="TIME_REMAINING">%1$s</xliff:g>, ბატარეის მოხმარების გათვალისწინებით"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"სრულ დატენვამდე დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> — სრულ დატენვამდე დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - დატენვა ოპტიმიზირებულია"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – იტენება"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"უცნობი"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"იტენება"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"სწრაფად იტენება"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index 86da0a4c0179..fa46e8e93db6 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>: батареяны қорғау үшін зарядтау кідіртіледі."</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g>: зарядтау құрылғысы тексеріледі."</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Шамамен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Шамамен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Пайдалану деректеріңізге сәйкес енді шамамен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Толық зарядталғанға дейін <xliff:g id="TIME">%1$s</xliff:g> қалды."</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: толық зарядталуға <xliff:g id="TIME">%2$s</xliff:g> қалды"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядтау оңтайландырылды"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Зарядталып жатыр"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Белгісіз"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Зарядталуда"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Жылдам зарядтау"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 848e9049df33..cd2a6c41ef5a 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"បដិសេធដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - កំពុងផ្អាកការសាកថ្ម ដើម្បីការពារថ្ម"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - កំពុងពិនិត្យមើលគ្រឿងសាកថ្ម"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"នៅសល់ប្រហែល <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ទៀត"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"នៅសល់ប្រហែល <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ទៀត (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"នៅសល់ប្រហែល <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ទៀត ផ្អែកលើការប្រើប្រាស់របស់អ្នក"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបពេញ"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើបពេញ"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - បានបង្កើនប្រសិទ្ធភាពនៃការសាក"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - កំពុងសាកថ្ម"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"មិនស្គាល់"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"កំពុងសាកថ្ម"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"កំពុងសាកថ្មយ៉ាងឆាប់រហ័ស"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index d13019c28fe5..a01a4bd1c37d 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಬ್ಯಾಟರಿಯನ್ನು ರಕ್ಷಿಸಲು ಚಾರ್ಜಿಂಗ್ ಅನ್ನು ಹೋಲ್ಡ್ ಮಾಡಲಾಗಿದೆ"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಚಾರ್ಜಿಂಗ್ ಪರಿಕರವನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"(<xliff:g id="LEVEL">%2$s</xliff:g>) ತಲುಪಲು <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ ಸುಮಾರು <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> - ಸಮಯದಲ್ಲಿ ಪೂರ್ತಿ ಚಾರ್ಜ್ ಆಗುತ್ತದೆ"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಸಮಯದಲ್ಲಿ ಪೂರ್ತಿ ಚಾರ್ಜ್ ಆಗುತ್ತದೆ"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಚಾರ್ಜಿಂಗ್ ಅನ್ನು ಆಪ್ಟಿಮೈಸ್ ಮಾಡಲಾಗಿದೆ"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - ಚಾರ್ಜಿಂಗ್ ಆಗುತ್ತಿದೆ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"ಅಪರಿಚಿತ"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ವೇಗದ ಚಾರ್ಜಿಂಗ್"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 3c8ad01f0f02..c9c92e5894f7 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>, <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - 배터리 보호를 위해 충전 일시중지"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 액세서리 확인 중"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"남은 시간: 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"남은 시간 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>(<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"내 사용량을 기준으로 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> 남음"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> 후 충전 완료"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 충전 최적화됨"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ 충전 중"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"알 수 없음"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"충전 중"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"고속 충전 중"</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index cec61bbdf764..44b01472b232 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Батареяны коргоо үчүн кубаттоо тындырылды"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Кубаттоо шайманы текшерилүүдө"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Болжол менен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> калды"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Болжол менен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> калды (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Колдонгонуңузга караганда болжол менен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> калды"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> кийин толук кубатталат"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> кийин толук кубатталат"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> — Кубаттоо жакшыртылды"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Кубатталууда"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Белгисиз"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Кубатталууда"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ыкчам кубатталууда"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 420925920982..70e9b68551c3 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ຢຸດການສາກຊົ່ວຄາວເພື່ອປົກປ້ອງແບັດເຕີຣີ"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - ກຳລັງກວດສອບອຸປະກອນເສີມສຳລັບການສາກ"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"ເຫຼືອອີກປະມານ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"ເຫຼືອອີກປະມານ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ເຫຼືອອີກປະມານ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"ຍັງເຫຼືອອີກ <xliff:g id="TIME">%1$s</xliff:g> ຈຶ່ງຈະສາກເຕັມ"</string> <string name="power_charging_duration" msgid="6127154952524919719">"ຍັງເຫຼືອອີກ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະສາກເຕັມ"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ການສາກຖືກປັບໃຫ້ເໝາະສົມແລ້ວ"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - ກຳລັງສາກໄຟ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"ບໍ່ຮູ້ຈັກ"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ກຳລັງສາກໄຟ"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ກຳລັງສາກໄຟດ່ວນ"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index cb0069d66e42..bc66a806375f 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -457,7 +457,7 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – įkrovimas pristabdytas, siekiant apsaugoti akumuliatorių"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – tikrinamas įkrovimo priedas"</string> + <string name="power_incompatible_charging_settings_home_page" msgid="1322050766135126880">"<xliff:g id="LEVEL">%1$s</xliff:g> – patikrinkite įkrovimo priedą"</string> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Liko maždaug <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Liko maždaug <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Liko maždaug <xliff:g id="TIME_REMAINING">%1$s</xliff:g>, atsižvelgiant į naudojimą"</string> @@ -478,8 +478,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Liko <xliff:g id="TIME">%1$s</xliff:g>, kol bus visiškai įkrauta"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko <xliff:g id="TIME">%2$s</xliff:g>, kol bus visiškai įkrauta"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – įkrovimas optimizuotas"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – įkraunama"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Nežinomas"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Kraunasi..."</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Greitai įkraunama"</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index db566881f016..8aac7f1e9609 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> — <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> — uzlāde apturēta, lai aizsargātu akumulatoru"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> — notiek uzlādes piederuma pārbaude"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Aptuvenais atlikušais laiks: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Aptuvenais atlikušais laiks: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Ņemot vērā lietojumu, atlikušais laiks: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> līdz pilnai uzlādei"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai uzlādei"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> — uzlāde optimizēta"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> — notiek uzlāde"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Nezināms"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Uzlāde"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Notiek ātrā uzlāde"</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 6738e2068ae1..d50634c1ead1 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - полнењето е паузирано за да се заштити батеријата"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - се проверува додатокот за полнење"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Уште околу <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Уште околу <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Уште околу <xliff:g id="TIME_REMAINING">%1$s</xliff:g> според вашето користење"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до полна батерија"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полна батерија"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Полнењето е оптимизирано"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ се полни"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Непознато"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Се полни"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо полнење"</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index a5c38bc22d1f..085b7c16180c 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ബാറ്ററി പരിരക്ഷിക്കാൻ ചാർജിംഗ് ഹോൾഡിലാണ്"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - ചാർജിംഗ് ആക്സസറി പരിശോധിക്കുന്നു"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"ഏതാണ്ട് <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ശേഷിക്കുന്നു"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"ഏതാണ്ട് <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ശേഷിക്കുന്നു (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"നിങ്ങളുടെ ഉപയോഗത്തെ അടിസ്ഥാനമാക്കി ഏതാണ്ട് <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ശേഷിക്കുന്നു"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"പൂർണ്ണമാകാൻ <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമാകാൻ <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ചാർജിംഗ് ഒപ്റ്റിമൈസ് ചെയ്തു"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ ചാർജ് ചെയ്യുന്നു"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"അജ്ഞാതം"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ചാർജ് ചെയ്യുന്നു"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"അതിവേഗ ചാർജിംഗ്"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index c03c89f68b18..60a31e8e3c3b 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Батарейг хамгаалахын тулд цэнэглэхийг хүлээлгэсэн"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Цэнэглэх нэмэлт хэрэгслийг шалгаж байна"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Ойролцоогоор <xliff:g id="TIME_REMAINING">%1$s</xliff:g> үлдсэн"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Ойролцоогоор <xliff:g id="TIME_REMAINING">%1$s</xliff:g> үлдсэн (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Таны хэрэглээнд үндэслэн ойролцоогоор <xliff:g id="TIME_REMAINING">%1$s</xliff:g> үлдсэн"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Дүүрэх хүртэл <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - дүүрэх хүртэл <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Цэнэглэх явцыг оновчилсон"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Цэнэглэж байна"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Тодорхойгүй"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Цэнэглэж байна"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Хурдан цэнэглэж байна"</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index bbe782da8f85..32de0e5f5daa 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - बॅटरीचे संरक्षण करण्यासाठी चार्जिंग थांबवले आहे"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंगसंबंधित ॲक्सेसरी तपासत आहे"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"अंदाजे <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाकी आहे"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"अंदाजे <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाकी आहे (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"तुमच्या वापरावर आधारित अंदाजे <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाकी आहे"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"पूर्ण चार्ज होण्यासाठी <xliff:g id="TIME">%1$s</xliff:g> शिल्लक आहेत"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूर्ण चार्ज होण्यासाठी <xliff:g id="TIME">%2$s</xliff:g> शिल्लक आहे"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिंग ऑप्टिमाइझ केले"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ चार्ज होत आहे"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज होत आहे"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"वेगाने चार्ज होत आहे"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index 3da4f08be11b..f0abd94dd9d1 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengecasan ditunda untuk melindungi bateri"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Memeriksa aksesori pengecasan"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Kira-kira <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Kira-kira <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Kira-kira <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi berdasarkan penggunaan anda"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> lagi sebelum penuh"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lagi sebelum penuh"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pengecasan dioptimumkan"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Mengecas"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Tidak diketahui"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Mengecas"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengecas dgn cepat"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index f4b669773aeb..3d942855e00e 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ဘက်ထရီကာကွယ်ရန် အားသွင်းခြင်းကို ခဏရပ်ထားသည်"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းပစ္စည်း စစ်ဆေးနေသည်"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ခန့် ကျန်သည်"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ခန့် ကျန်သည် (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"သင်၏ အသုံးပြုမှု အပေါ် မူတည်၍ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ခန့် ကျန်သည်"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"အားပြည့်ရန် <xliff:g id="TIME">%1$s</xliff:g> လိုသည်"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားပြည့်ရန် <xliff:g id="TIME">%2$s</xliff:g> လိုသည်"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းခြင်းကို အကောင်းဆုံးပြင်ဆင်ထားသည်"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - အားသွင်းနေသည်"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"မသိ"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"အားသွင်းနေပါသည်"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"အမြန် အားသွင်းနေသည်"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index fbdc9e33f576..d286da13d8f1 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladingen er satt på vent for å beskytte batteriet"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Sjekker ladetilbehøret"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen basert på bruken din"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Fulladet om <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – Fulladet om <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Ladingen er optimalisert"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – lader"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Ukjent"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Lader"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Lader raskt"</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index 245a31f9fcae..146418c83e69 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ब्याट्री जोगाउन चार्जिङ होल्ड गरिएको छ"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्जिङ एक्सेसरीको जाँच गरिँदै छ"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"लगभग <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाँकी छ"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"लगभग <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाँकी छ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"तपाईंको प्रयोगको आधारमा लगभग <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाँकी छ"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"पूरा चार्ज हुन <xliff:g id="TIME">%1$s</xliff:g> लाग्ने छ"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - पूरा चार्ज हुन <xliff:g id="TIME">%2$s</xliff:g> लाग्ने छ"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्ज गर्ने प्रक्रिया अप्टिमाइज गरिएको छ"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - चार्ज गरिँदै छ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"अज्ञात"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"चार्ज हुँदै छ"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"द्रुत गतिमा चार्ज गरिँदै छ"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 4eafb5740e05..f5ae2540d7ae 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>: opladen is in de wacht gezet om de batterij te beschermen"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g>: oplaadaccessoire checken"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Nog ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Nog ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Nog ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> op basis van je gebruik"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Vol over <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - vol over <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Opladen geoptimaliseerd"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ Opladen"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Onbekend"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Opladen"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Snel opladen"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index 5a8bed43faf7..b71cf0ebd125 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ଦ୍ୱାରା ଓଭର୍ରାଇଡ୍ କରାଯାଇଛି"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ବେଟେରୀକୁ ସୁରକ୍ଷିତ ରଖିବା ପାଇଁ ଚାର୍ଜିଂ ହୋଲ୍ଡରେ ଅଛି"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - ଚାର୍ଜିଂ ଆକସେସୋରୀକୁ ଯାଞ୍ଚ କରାଯାଉଛି"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"ପାଖାପାଖି <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ବଳକା ଅଛି"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"ପାଖାପାଖି <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ପାଇଁ (<xliff:g id="LEVEL">%2$s</xliff:g>) ବଳକା ଅଛି"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ଆପଣଙ୍କ ବ୍ୟବହାରକୁ ଆଧାର କରି ପାଖାପାଖି <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ବଳକା ଅଛି"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"ପୂର୍ଣ୍ଣ ହେବାକୁ ଆଉ <xliff:g id="TIME">%1$s</xliff:g> ବାକି ଅଛି"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - ପୂର୍ଣ୍ଣ ହେବାକୁ ଆଉ <xliff:g id="TIME">%2$s</xliff:g> ବାକି ଅଛି"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ଚାର୍ଜିଂକୁ ଅପ୍ଟିମାଇଜ କରାଯାଇଛି"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ ଚାର୍ଜିଂ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"ଅଜ୍ଞାତ"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ଚାର୍ଜ ହେଉଛି"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ଶୀଘ୍ର ଚାର୍ଜ ହେଉଛି"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index df1fea17f645..76d49214761d 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਬੈਟਰੀ ਦੀ ਸੁਰੱਖਿਆ ਲਈ ਚਾਰਜਿੰਗ ਨੂੰ ਰੋਕਿਆ ਗਿਆ ਹੈ"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਚਾਰਜਿੰਗ ਐਕਸੈਸਰੀ ਦੀ ਜਾਂਚ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"ਲਗਭਗ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਬਾਕੀ"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"ਲਗਭਗ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਬਾਕੀ (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਬਾਕੀ"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"ਬੈਟਰੀ ਪੂਰੀ ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਬੈਟਰੀ ਪੂਰੀ ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਚਾਰਜਿੰਗ ਨੂੰ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"ਅਗਿਆਤ"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ਤੇਜ਼ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index e9f9da8e095b..1b76b6f0fd03 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – wstrzymano ładowanie, aby chronić baterię"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – sprawdzam akcesoria do ładowania"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Jeszcze około <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Jeszcze około <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Jeszcze około <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (na podstawie Twojego sposobu korzystania)"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do pełnego naładowania"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – ładowanie zoptymalizowane"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – ładowanie"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Nieznane"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Ładowanie"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Szybkie ładowanie"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 4ee1cbd417ef..bdfff4aa93c7 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento suspenso para proteger a bateria"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Verificando o acessório de carregamento"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tempo restante aproximado, com base no seu uso: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> até a conclusão"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> até a conclusão"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento otimizado"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> (carregando)"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconhecido"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Carregando"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregando rápido"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index eae5cc965f7f..6fb851b7a32e 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento em espera para proteger a bateria"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – A verificar o acessório de carregamento"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Resta(m) cerca de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Resta(m) cerca de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Resta(m) cerca de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> com base na sua utilização"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> até à carga máxima"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até à carga máxima"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g>: carregamento otimizado"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – A carregar"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconhecido"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"A carregar"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregamento rápido"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 4ee1cbd417ef..bdfff4aa93c7 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento suspenso para proteger a bateria"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Verificando o acessório de carregamento"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Tempo restante aproximado, com base no seu uso: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> até a conclusão"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> até a conclusão"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carregamento otimizado"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> (carregando)"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconhecido"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Carregando"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregando rápido"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index 91261d49f15e..e8d68520b5c4 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Încărcarea s-a întrerupt pentru a proteja bateria"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Se verifică accesoriul de încărcare"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Timp aproximativ rămas: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Timp aproximativ rămas: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"În baza utilizării, timpul rămas este de aproximativ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> până la finalizare"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> până la finalizare"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Încărcare optimizată"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Se încarcă"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Necunoscut"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Se încarcă"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Se încarcă rapid"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 87b2a938fa31..ef1e817614d7 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"Уровень заряда – <xliff:g id="PERCENTAGE">%1$s</xliff:g>. <xliff:g id="TIME_STRING">%2$s</xliff:g>."</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g>, зарядка приостановлена для защиты батареи"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g>, проверяется зарядное устройство"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Заряда хватит примерно на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Заряда (<xliff:g id="LEVEL">%2$s</xliff:g>) хватит примерно на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Заряда хватит примерно на <xliff:g id="TIME_REMAINING">%1$s</xliff:g> при текущем уровне расхода"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до полной зарядки"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядка оптимизирована"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – заряжается"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Неизвестно"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Идет зарядка"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Быстрая зарядка"</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index 72bd507a5175..cf83ee8cc27f 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - බැටරිය ආරක්ෂා කිරීම සඳහා ආරෝපණය රඳවා තබා ඇත"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආරෝපණ ආයිත්තම පරීක්ෂා කිරීම"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ක් පමණ ඉතිරියි"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ක් පමණ ඉතිරියි (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"ඔබේ භාවිතය මත පදනම්ව <xliff:g id="TIME_REMAINING">%1$s</xliff:g> පමණ ඉතිරිව ඇත"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"සම්පූර්ණ වීමට <xliff:g id="TIME">%1$s</xliff:g>ක් ඉතිරියි"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - සම්පූර්ණ වීමට <xliff:g id="TIME">%2$s</xliff:g>ක් ඉතිරියි"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආරෝපණය ප්රශස්ත කර ඇත"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආරෝපණය වේ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"නොදනී"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ආරෝපණය වෙමින්"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"ශීඝ්ර ආරෝපණය"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index dd8be3a1d7a0..577a6c1ff15c 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – nabíjanie je pozastavené, aby sa chránila batéria"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – kontroluje sa nabíjacie príslušenstvo"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Ešte približne <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Zostáva približne <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Zostáva približne <xliff:g id="TIME_REMAINING">%1$s</xliff:g> – závisí to od intenzity využitia"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> do úplného nabitia"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Nabíjanie je optimalizované"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – nabíja sa"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Neznáme"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Nabíja sa"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rýchle nabíjanie"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index eefb119eca02..7acd64d1ab4e 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Zaradi zaščite baterije je polnjenje na čakanju"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Preverjanje pripomočka za polnjenje"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Še približno <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Še približno <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Glede na način uporabe še približno <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Še <xliff:g id="TIME">%1$s</xliff:g> do napolnjenosti"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – še <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – polnjenje je optimizirano"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – polnjenje"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Neznano"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Polnjenje"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hitro polnjenje"</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index e847c515bb7e..a2b2042db952 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Karikimi është vendosur në pritje për të mbrojtur baterinë"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Po kontrollohet aksesori i karikimit"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Rreth <xliff:g id="TIME_REMAINING">%1$s</xliff:g> të mbetura"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Rreth <xliff:g id="TIME_REMAINING">%1$s</xliff:g> të mbetura (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Rreth <xliff:g id="TIME_REMAINING">%1$s</xliff:g> të mbetura bazuar në përdorimin tënd"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> derisa të mbushet"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të mbushet"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Karikimi u optimizua"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Po karikohet"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"I panjohur"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Po karikohet"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Karikim i shpejtë"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index ed0e9a6ea975..14dd7720ce79 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>–<xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – пуњење је на чекању да би се заштитила батерија"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – провера додатне опреме за пуњење"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g> на основу коришћења"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до краја пуњења"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до краја пуњења"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – пуњење је оптимизовано"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Пуњење"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Непознато"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Пуни се"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Брзо се пуни"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index b4de50408daa..c9262e9d2494 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Laddningen har pausats för att skydda batteriet"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kontrollerar laddningstillbehöret"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Cirka <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kvar"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Cirka <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kvar (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Cirka <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kvar utifrån din användning"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> kvar tills fulladdat"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kvar tills fulladdat"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Laddningen har optimerats"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – laddas"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Okänd"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Laddar"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Laddas snabbt"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 40725c92d6ea..92c9c7c573cd 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Imesitisha kuchaji ili kulinda betri yako"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Inakagua kifaa cha kuchaji"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Zimesalia takribani <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Zimesalia takribani <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Zimesalia takribani <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kulingana na jinsi unavyoitumia"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Zimesalia <xliff:g id="TIME">%1$s</xliff:g> ijae chaji"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> zimesalia ijae chaji"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Hali ya kuchaji imeboreshwa"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Inachaji"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Haijulikani"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Inachaji"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Inachaji kwa kasi"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 2fe243aee324..ec73fbed7264 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - பேட்டரியைப் பாதுகாப்பதற்காகச் சார்ஜிங் இடைநிறுத்தப்பட்டுள்ளது"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - சார்ஜிங் துணைக்கருவியைச் சரிபார்க்கிறது"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"கிட்டத்தட்ட <xliff:g id="TIME_REMAINING">%1$s</xliff:g> மீதமுள்ளது"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"கிட்டத்தட்ட <xliff:g id="TIME_REMAINING">%1$s</xliff:g> மீதமுள்ளது (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"உபயோகத்தின் அடிப்படையில் கிட்டத்தட்ட <xliff:g id="TIME_REMAINING">%1$s</xliff:g> மீதமுள்ளது"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"முழுவதும் சார்ஜாக <xliff:g id="TIME">%1$s</xliff:g> ஆகும்"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - முழுவதும் சார்ஜாக <xliff:g id="TIME">%2$s</xliff:g> ஆகும்"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - சார்ஜிங் மேம்படுத்தப்பட்டது"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ சார்ஜாகிறது"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"அறியப்படாத"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"சார்ஜ் ஆகிறது"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"வேகமாக சார்ஜாகிறது"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index 43f2b835bc44..0ffdf6a680ae 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - బ్యాటరీని రక్షించడానికి ఛార్జింగ్ హోల్డ్లో ఉంచబడింది"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - ఛార్జ్ చేసే పరికరాన్ని చెక్ చేయండి"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"దాదాపు <xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"మీ వినియోగం ఆధారంగా దాదాపు <xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>లో పూర్తిగా ఛార్జ్ అవుతుంది"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ఛార్జింగ్ ఆప్టిమైజ్ చేయబడింది"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - ఛార్జ్ అవుతోంది"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"తెలియదు"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"ఛార్జ్ అవుతోంది"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"వేగవంతమైన ఛార్జింగ్"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 8395a5185363..7bccc25c65dd 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - หยุดการชาร์จชั่วคราวเพื่อถนอมแบตเตอรี่"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - กำลังตรวจสอบอุปกรณ์เสริมสำหรับการชาร์จ"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"เหลืออีกประมาณ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"เหลืออีกประมาณ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"เหลืออีกประมาณ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ขึ้นอยู่กับการใช้งานของคุณ"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"อีก <xliff:g id="TIME">%1$s</xliff:g>จึงจะเต็ม"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - อีก <xliff:g id="TIME">%2$s</xliff:g> จึงจะเต็ม"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - ปรับการชาร์จให้เหมาะสมแล้ว"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ กำลังชาร์จ"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"ไม่ทราบ"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"กำลังชาร์จ"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"กำลังชาร์จอย่างเร็ว"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index a337bd8a69f2..19ba24fcbda4 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Naka-hold ang pag-charge para protektahan ang baterya"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Sinusuri ang accessory sa pag-charge"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Humigit-kumulang <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ang natitira"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Humigit-kumulang <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ang natitira (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Humigit-kumulang <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ang natitira batay sa iyong paggamit"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> na lang bago mapuno"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> na lang bago mapuno"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Naka-optimize ang pag-charge"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Nagcha-charge"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Hindi Kilala"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Nagcha-charge"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mabilis na charge"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 43e18edca594..80d2fe294ea3 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Pili korumak için şarj beklemede"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj aksesuarı kontrol ediliyor"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Yaklaşık <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kaldı"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Yaklaşık <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kaldı (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Kullanımınıza dayalı olarak yaklaşık <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kaldı"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Tamamen şarj olmasına <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tamamen şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Şarj işlemi optimize edildi"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ Şarj ediliyor"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Bilinmiyor"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Şarj oluyor"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hızlı şarj oluyor"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 984bb7978294..b1c64f8222b3 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – заряджання призупинено, щоб захистити акумулятор"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – перевірка зарядного пристрою"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Залишилося приблизно <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Залишилося приблизно <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Згідно з даними про використання залишилося приблизно <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> до повного заряду"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного заряду"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – заряджання оптимізовано"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – заряджається"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Невідомо"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Заряджається"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Швидке заряджання"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index bc8a46748d8b..f71f4a2174b1 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - بیٹری کی حفاظت کرنے کے لیے چارجنگ ہولڈ پر ہے"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - چارجنگ ایکسیسری کی جانچ کی جا رہی ہے"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> باقی ہے"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> باقی ہے (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"آپ کے استعمال کی بنیاد پر تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> باقی ہے"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"مکمل چارج ہونے میں <xliff:g id="TIME">%1$s</xliff:g> باقی ہے"</string> <string name="power_charging_duration" msgid="6127154952524919719">"مکمل چارج ہونے میں <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - چارجنگ کو بہتر بنایا گیا"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - چارج ہو رہی ہے"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"نامعلوم"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"چارج ہو رہا ہے"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"تیزی سے چارج ہو رہا ہے"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index a655dc0f0304..a3ef6b64d9f9 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Batareyani himoyalash uchun quvvatlash toʻxtatildi"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Quvvatlash aksessuari tekshirilmoqda"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Quvvati tugashiga taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Toʻlishiga <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – Toʻlishiga <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Quvvatlash optimallashtirildi"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Quvvatlanmoqda"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Noma’lum"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Quvvat olmoqda"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Tezkor quvvat olmoqda"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 643f8ca85499..3ac91fac6cc0 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> – Đang tạm ngưng sạc để bảo vệ pin"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> – Đang kiểm tra phụ kiện sạc"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Còn khoảng <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Còn khoảng <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Còn khoảng <xliff:g id="TIME_REMAINING">%1$s</xliff:g> dựa trên mức sử dụng của bạn"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> nữa là pin đầy"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> nữa là pin đầy"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – Quá trình sạc được tối ưu hoá"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> – Đang sạc"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Không xác định"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Đang sạc"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Đang sạc nhanh"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 3b08e1f27bd6..7ff6ceec5fa1 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - 为保护电池,已暂停充电"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - 正在检查充电配件"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"根据您的使用情况,大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"还需<xliff:g id="TIME">%1$s</xliff:g>充满"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充电方式已优化"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - 正在充电"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"正在充电"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"正在快速充电"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index eba782e54e48..53b55bba0bd0 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - 為保護電池,目前暫停充電"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - 正在檢查充電配件"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"根據你的使用情況,還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>後充滿電"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充滿電"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 已優化充電"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> ‑ 充電中"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"未知"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 099ad0364b0e..f9ee07d07fd0 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - 為保護電池,目前暫停充電"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - 正在檢查充電配件"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"還能使用約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"目前電量為 <xliff:g id="LEVEL">%2$s</xliff:g>,還能使用約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"根據你的使用情形,還能使用約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g>後充飽"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電效能已最佳化"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電中"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"不明"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 4d652f819ff3..8ff64d141b94 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -457,7 +457,8 @@ <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string> <string name="power_charging_on_hold_settings_home_page" msgid="7690464049464805856">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ukushaja kumisiwe ukuze kuvikelwe ibhethri"</string> - <string name="power_incompatible_charging_settings_home_page" msgid="1261756225093962684">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kuhlolwa okokushaja"</string> + <!-- no translation found for power_incompatible_charging_settings_home_page (1322050766135126880) --> + <skip /> <string name="power_remaining_duration_only" msgid="8264199158671531431">"Cishe u-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> osele"</string> <string name="power_discharging_duration" msgid="1076561255466053220">"Cishe u-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> osele (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_duration_only_enhanced" msgid="2527842780666073218">"Cishe u-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> osele ngokususelwe ekusebenziseni wakho"</string> @@ -478,8 +479,7 @@ <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> okusele kuze kugcwale"</string> <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> okusele kuze kugcwale"</string> <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Ukushaja kuthuthukisiwe"</string> - <!-- no translation found for power_charging_future_paused (1809543660923642799) --> - <skip /> + <string name="power_charging_future_paused" msgid="1809543660923642799">"Iku-<xliff:g id="LEVEL">%1$s</xliff:g> ‑ Iyashaja"</string> <string name="battery_info_status_unknown" msgid="268625384868401114">"Akwaziwa"</string> <string name="battery_info_status_charging" msgid="4279958015430387405">"Iyashaja"</string> <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Ishaja ngokushesha"</string> diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppCopyingHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppCopyingHelperTest.java index 2a5c43cae289..9ab17c49bbec 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppCopyingHelperTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppCopyingHelperTest.java @@ -37,9 +37,10 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.UserHandle; -import android.test.suitebuilder.annotation.SmallTest; import android.util.ArraySet; +import androidx.test.filters.SmallTest; + import com.android.settingslib.BaseTest; import org.mockito.ArgumentMatcher; diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java index 2522e956a25e..ab28d061419c 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java @@ -41,9 +41,10 @@ import android.content.pm.UserInfo; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; -import android.test.suitebuilder.annotation.SmallTest; import android.view.inputmethod.InputMethodInfo; +import androidx.test.filters.SmallTest; + import com.android.settingslib.BaseTest; import org.mockito.ArgumentMatcher; diff --git a/packages/SettingsProvider/res/xml/bookmarks.xml b/packages/SettingsProvider/res/xml/bookmarks.xml index 4b97b4779e1b..22d02262c388 100644 --- a/packages/SettingsProvider/res/xml/bookmarks.xml +++ b/packages/SettingsProvider/res/xml/bookmarks.xml @@ -23,7 +23,7 @@ 'c': Contacts 'e': Email 'g': GMail - 'l': Calendar + 'k': Calendar 'm': Maps 'p': Music 's': SMS @@ -33,7 +33,7 @@ --> <bookmarks> <bookmark - category="android.intent.category.APP_BROWSER" + role="android.app.role.BROWSER" shortcut="b" /> <bookmark category="android.intent.category.APP_CONTACTS" @@ -51,7 +51,7 @@ category="android.intent.category.APP_MUSIC" shortcut="p" /> <bookmark - category="android.intent.category.APP_MESSAGING" + role="android.app.role.SMS" shortcut="s" /> <bookmark category="android.intent.category.APP_CALCULATOR" diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 53f2caf0b793..0c02f56ab294 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -210,6 +210,7 @@ <uses-permission android:name="android.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS" /> <uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" /> <uses-permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS" /> + <uses-permission android:name="android.permission.EMERGENCY_INSTALL_PACKAGES" /> <!-- Permission required for processes that don't own the focused window to switch touch mode state --> <uses-permission android:name="android.permission.MODIFY_TOUCH_MODE_STATE" /> diff --git a/packages/Shell/tests/src/com/android/shell/UtilitiesTest.java b/packages/Shell/tests/src/com/android/shell/UtilitiesTest.java index 51b7ba8529a8..ad9eec7f3303 100644 --- a/packages/Shell/tests/src/com/android/shell/UtilitiesTest.java +++ b/packages/Shell/tests/src/com/android/shell/UtilitiesTest.java @@ -15,10 +15,12 @@ */ package com.android.shell; -import android.test.suitebuilder.annotation.SmallTest; -import junit.framework.TestCase; import static com.android.shell.BugreportProgressService.isValid; +import androidx.test.filters.SmallTest; + +import junit.framework.TestCase; + @SmallTest public class UtilitiesTest extends TestCase { diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index e63232a87499..cc2e84c5a995 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -32,55 +32,6 @@ license { ], } -// Opt-in configuration for code depending on Jetpack Compose. -soong_config_module_type { - name: "systemui_compose_java_defaults", - module_type: "java_defaults", - config_namespace: "ANDROID", - bool_variables: ["SYSTEMUI_USE_COMPOSE"], - properties: [ - "srcs", - "static_libs", - ], -} - -systemui_compose_java_defaults { - name: "SystemUI_compose_defaults", - soong_config_variables: { - SYSTEMUI_USE_COMPOSE: { - // Because files in compose/features/ depend on SystemUI - // code, we compile those files when compiling SystemUI-core. - // We also compile the ComposeFacade in - // compose/facade/enabled/. - srcs: [ - "compose/features/src/**/*.kt", - "compose/facade/enabled/src/**/*.kt", - ], - - // The dependencies needed by SystemUIComposeFeatures, - // except for SystemUI-core. - // Copied from compose/features/Android.bp. - static_libs: [ - "PlatformComposeCore", - "PlatformComposeSceneTransitionLayout", - - "androidx.compose.runtime_runtime", - "androidx.compose.material3_material3", - "androidx.compose.material_material-icons-extended", - "androidx.activity_activity-compose", - "androidx.compose.animation_animation-graphics", - ], - - // By default, Compose is disabled and we compile the ComposeFacade - // in compose/facade/disabled/. - conditions_default: { - srcs: ["compose/facade/disabled/src/**/*.kt"], - static_libs: [], - }, - }, - }, -} - java_library { name: "SystemUI-proto", @@ -138,14 +89,13 @@ android_library { android_library { name: "SystemUI-core", - defaults: [ - "SystemUI_compose_defaults", - ], srcs: [ "src/**/*.kt", "src/**/*.java", "src/**/I*.aidl", ":ReleaseJavaFiles", + "compose/features/src/**/*.kt", + "compose/facade/enabled/src/**/*.kt", ], product_variables: { debuggable: { @@ -207,6 +157,13 @@ android_library { "LowLightDreamLib", "motion_tool_lib", "notification_flags_lib", + "PlatformComposeCore", + "PlatformComposeSceneTransitionLayout", + "androidx.compose.runtime_runtime", + "androidx.compose.material3_material3", + "androidx.compose.material_material-icons-extended", + "androidx.activity_activity-compose", + "androidx.compose.animation_animation-graphics", ], libs: [ "keepanno-annotations", @@ -337,15 +294,19 @@ android_library { "ravenwood-junit", "platform-test-annotations", "notification_flags_lib", + "PlatformComposeCore", + "PlatformComposeSceneTransitionLayout", + "androidx.compose.runtime_runtime", + "androidx.compose.material3_material3", + "androidx.compose.material_material-icons-extended", + "androidx.activity_activity-compose", + "androidx.compose.animation_animation-graphics", ], } android_library { name: "SystemUI-tests", use_resource_processor: true, - defaults: [ - "SystemUI_compose_defaults", - ], manifest: "tests/AndroidManifest-base.xml", additional_manifests: ["tests/AndroidManifest.xml"], srcs: [ @@ -357,6 +318,8 @@ android_library { ":ReleaseJavaFiles", ":SystemUI-tests-multivalent", ":SystemUI-tests-utils", + "compose/features/src/**/*.kt", + "compose/facade/enabled/src/**/*.kt", ], static_libs: [ "SystemUI-tests-base", @@ -367,6 +330,7 @@ android_library { "androidx.test.ext.truth", "kotlin-test", "SystemUICustomizationTestUtils", + "androidx.compose.runtime_runtime", ], libs: [ "android.test.runner", @@ -396,7 +360,6 @@ android_app { defaults: [ "platform_app_defaults", "SystemUI_optimized_defaults", - "SystemUI_compose_defaults", ], manifest: "tests/AndroidManifest-base.xml", @@ -405,9 +368,12 @@ android_app { "src/**/*.java", "src/**/I*.aidl", ":ReleaseJavaFiles", + "compose/features/src/**/*.kt", + "compose/facade/enabled/src/**/*.kt", ], static_libs: [ "SystemUI-tests-base", + "androidx.compose.runtime_runtime", ], libs: [ "keepanno-annotations", diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index ba7738005de2..8c8975fdbdd5 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -76,6 +76,16 @@ flag { } flag { + name: "notification_content_alpha_optimization" + namespace: "systemui" + description: "Only reset alpha values of needed content views" + bug: "292024656" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "notifications_live_data_store_refactor" namespace: "systemui" description: "Replaces NotifLiveDataStore with ActiveNotificationListRepository, and updates consumers. " @@ -84,6 +94,17 @@ flag { } flag { + name: "pss_app_selector_abrupt_exit_fix" + namespace: "systemui" + description: "Fixes the app selector abruptly disappearing without an animation, when the" + "selected task is the foreground task." + bug: "314385883" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "notifications_background_media_icons" namespace: "systemui" description: "Updates icons for media notifications in the background." @@ -447,6 +468,13 @@ flag { } flag { + name: "hearing_aids_qs_tile_dialog" + namespace: "systemui" + description: "Show a dialog when clicking on hearing aids quick settings tile." + bug: "291423171" +} + +flag { name: "notification_row_user_context" namespace: "systemui" description: "Create a user-specific Context for the ImageResolver in ExpandableNotificationRow" @@ -542,6 +570,9 @@ flag { namespace: "systemui" description: "Binds Keyguard Media Controller Visibility to MediaContainerView" bug: "298213983" + metadata { + purpose: PURPOSE_BUGFIX + } } flag { @@ -563,3 +594,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "media_controls_refactor" + namespace: "systemui" + description: "Refactors media code to follow the recommended architecture" + bug: "326408371" +} diff --git a/packages/SystemUI/compose/core/TEST_MAPPING b/packages/SystemUI/compose/core/TEST_MAPPING index ee95f737c113..b71c5fb29fd7 100644 --- a/packages/SystemUI/compose/core/TEST_MAPPING +++ b/packages/SystemUI/compose/core/TEST_MAPPING @@ -12,17 +12,6 @@ ] }, { - "name": "SystemUIComposeFeaturesTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] - }, - { "name": "SystemUIComposeGalleryTests", "options": [ { diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt deleted file mode 100644 index 4398b2541f65..000000000000 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package com.android.systemui.compose - -import android.content.Context -import android.view.View -import android.view.WindowInsets -import androidx.activity.ComponentActivity -import androidx.lifecycle.LifecycleOwner -import com.android.systemui.bouncer.ui.BouncerDialogFactory -import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel -import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel -import com.android.systemui.communal.ui.viewmodel.CommunalViewModel -import com.android.systemui.communal.widgets.WidgetConfigurator -import com.android.systemui.keyboard.stickykeys.ui.viewmodel.StickyKeysIndicatorViewModel -import com.android.systemui.keyguard.shared.model.LockscreenSceneBlueprint -import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel -import com.android.systemui.people.ui.viewmodel.PeopleViewModel -import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel -import com.android.systemui.scene.shared.model.Scene -import com.android.systemui.scene.shared.model.SceneDataSourceDelegator -import com.android.systemui.scene.shared.model.SceneKey -import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel -import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.StateFlow - -/** The Compose facade, when Compose is *not* available. */ -object ComposeFacade : BaseComposeFacade { - override fun isComposeAvailable(): Boolean = false - - override fun composeInitializer(): ComposeInitializer { - throwComposeUnavailableError() - } - - override fun setPeopleSpaceActivityContent( - activity: ComponentActivity, - viewModel: PeopleViewModel, - onResult: (PeopleViewModel.Result) -> Unit, - ) { - throwComposeUnavailableError() - } - - override fun setCommunalEditWidgetActivityContent( - activity: ComponentActivity, - viewModel: BaseCommunalViewModel, - widgetConfigurator: WidgetConfigurator, - onOpenWidgetPicker: () -> Unit, - onEditDone: () -> Unit, - ) { - throwComposeUnavailableError() - } - - override fun setVolumePanelActivityContent( - activity: ComponentActivity, - viewModel: VolumePanelViewModel, - onDismiss: () -> Unit, - ) { - throwComposeUnavailableError() - } - - override fun createFooterActionsView( - context: Context, - viewModel: FooterActionsViewModel, - qsVisibilityLifecycleOwner: LifecycleOwner - ): View { - throwComposeUnavailableError() - } - - override fun createSceneContainerView( - scope: CoroutineScope, - context: Context, - viewModel: SceneContainerViewModel, - windowInsets: StateFlow<WindowInsets?>, - sceneByKey: Map<SceneKey, Scene>, - dataSourceDelegator: SceneDataSourceDelegator, - ): View { - throwComposeUnavailableError() - } - - override fun createStickyKeysIndicatorContent( - context: Context, - viewModel: StickyKeysIndicatorViewModel - ): View { - throwComposeUnavailableError() - } - - override fun createCommunalView( - context: Context, - viewModel: BaseCommunalViewModel, - ): View { - throwComposeUnavailableError() - } - - override fun createCommunalContainer(context: Context, viewModel: CommunalViewModel): View { - throwComposeUnavailableError() - } - - override fun createBouncer( - context: Context, - viewModel: BouncerViewModel, - dialogFactory: BouncerDialogFactory, - ): View = throwComposeUnavailableError() - - override fun createLockscreen( - context: Context, - viewModel: LockscreenContentViewModel, - blueprints: Set<@JvmSuppressWildcards LockscreenSceneBlueprint>, - ): View = throwComposeUnavailableError() - - private fun throwComposeUnavailableError(): Nothing { - error( - "Compose is not available. Make sure to check isComposeAvailable() before calling any" + - " other function on ComposeFacade." - ) - } -} diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/BouncerSceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/BouncerSceneModule.kt deleted file mode 100644 index 1a5e22b2c5ee..000000000000 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/BouncerSceneModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.scene - -import dagger.Module - -@Module interface BouncerSceneModule diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/CommunalSceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/CommunalSceneModule.kt deleted file mode 100644 index f80a90659545..000000000000 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/CommunalSceneModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.scene - -import dagger.Module - -@Module interface CommunalSceneModule diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/GoneSceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/GoneSceneModule.kt deleted file mode 100644 index 5cc3b75df787..000000000000 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/GoneSceneModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.scene - -import dagger.Module - -@Module interface GoneSceneModule diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/QuickSettingsSceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/QuickSettingsSceneModule.kt deleted file mode 100644 index 387b05644f14..000000000000 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/QuickSettingsSceneModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.scene - -import dagger.Module - -@Module interface QuickSettingsSceneModule diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ShadeSceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ShadeSceneModule.kt deleted file mode 100644 index 232c4211c7c1..000000000000 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ShadeSceneModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.scene - -import dagger.Module - -@Module interface ShadeSceneModule diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/anc/AncModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/anc/AncModule.kt deleted file mode 100644 index a4fb05d3b5b9..000000000000 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/anc/AncModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.volume.panel.component.anc - -import dagger.Module - -@Module interface AncModule diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/bottombar/BottomBarModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/bottombar/BottomBarModule.kt deleted file mode 100644 index c8dae76f9f1a..000000000000 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/bottombar/BottomBarModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.volume.panel.component.bottombar - -import dagger.Module - -@Module interface BottomBarModule diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/volume/VolumeSlidersModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/volume/VolumeSlidersModule.kt deleted file mode 100644 index b4cb0983f213..000000000000 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/volume/VolumeSlidersModule.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.volume.panel.component.volume - -import dagger.Module - -@Module interface VolumeSlidersModule diff --git a/packages/SystemUI/compose/features/Android.bp b/packages/SystemUI/compose/features/Android.bp deleted file mode 100644 index dfb3a55b0966..000000000000 --- a/packages/SystemUI/compose/features/Android.bp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2022 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT 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 { - default_team: "trendy_team_system_ui_please_use_a_more_specific_subteam_if_possible_", - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"], -} - -android_library { - name: "SystemUIComposeFeatures", - use_resource_processor: true, - manifest: "AndroidManifest.xml", - - srcs: [ - "src/**/*.kt", - ], - - static_libs: [ - "SystemUI-core", - "PlatformComposeCore", - "PlatformComposeSceneTransitionLayout", - - "androidx.compose.runtime_runtime", - "androidx.compose.animation_animation-graphics", - "androidx.compose.material3_material3", - "androidx.compose.material_material-icons-extended", - "androidx.activity_activity-compose", - ], - - kotlincflags: ["-Xjvm-default=all"], - skip_jarjar_repackage: true, -} diff --git a/packages/SystemUI/compose/features/AndroidManifest.xml b/packages/SystemUI/compose/features/AndroidManifest.xml deleted file mode 100644 index c1a9ec55c227..000000000000 --- a/packages/SystemUI/compose/features/AndroidManifest.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.systemui.compose.features"> - -</manifest> diff --git a/packages/SystemUI/compose/features/TEST_MAPPING b/packages/SystemUI/compose/features/TEST_MAPPING deleted file mode 100644 index 7430acb2e900..000000000000 --- a/packages/SystemUI/compose/features/TEST_MAPPING +++ /dev/null @@ -1,26 +0,0 @@ -{ - "presubmit": [ - { - "name": "SystemUIComposeFeaturesTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] - }, - { - "name": "SystemUIComposeGalleryTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] - } - ] -}
\ No newline at end of file diff --git a/packages/SystemUI/compose/features/tests/Android.bp b/packages/SystemUI/compose/features/tests/Android.bp deleted file mode 100644 index 69b18c45aed6..000000000000 --- a/packages/SystemUI/compose/features/tests/Android.bp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2022 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT 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 { - default_team: "trendy_team_system_ui_please_use_a_more_specific_subteam_if_possible_", - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_packages_SystemUI_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_packages_SystemUI_license"], -} - -// TODO(b/230606318): Make those host tests instead of device tests. -android_test { - name: "SystemUIComposeFeaturesTests", - use_resource_processor: true, - manifest: "AndroidManifest.xml", - test_suites: ["device-tests"], - sdk_version: "current", - certificate: "platform", - - srcs: [ - "src/**/*.kt", - ], - - static_libs: [ - "SystemUIComposeFeatures", - - "androidx.test.runner", - "androidx.test.ext.junit", - - "androidx.compose.runtime_runtime", - "androidx.compose.ui_ui-test-junit4", - "androidx.compose.ui_ui-test-manifest", - ], - - kotlincflags: ["-Xjvm-default=all"], -} diff --git a/packages/SystemUI/compose/features/tests/AndroidManifest.xml b/packages/SystemUI/compose/features/tests/AndroidManifest.xml deleted file mode 100644 index fc337fb19f43..000000000000 --- a/packages/SystemUI/compose/features/tests/AndroidManifest.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2022 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - package="com.android.systemui.compose.features.tests" > - - <application - android:name="android.app.Application" - android:appComponentFactory="androidx.core.app.AppComponentFactory" - tools:replace="android:name,android:appComponentFactory"> - <uses-library android:name="android.test.runner" /> - - <!-- Disable providers from SystemUI --> - <provider android:name="com.android.systemui.keyguard.KeyguardSliceProvider" - android:authorities="com.android.systemui.test.keyguard.disabled" - android:enabled="false" - tools:replace="android:authorities" - tools:node="remove" /> - <provider android:name="com.android.systemui.keyguard.CustomizationProvider" - android:authorities="com.android.systemui.test.keyguard.quickaffordance.disabled" - android:enabled="false" - tools:replace="android:authorities" - tools:node="remove" /> - <provider android:name="com.android.systemui.people.PeopleProvider" - android:authorities="com.android.systemui.test.people.disabled" - android:enabled="false" - tools:replace="android:authorities" - tools:node="remove" /> - <provider android:name="androidx.core.content.FileProvider" - android:authorities="com.android.systemui.test.fileprovider.disabled" - android:enabled="false" - tools:replace="android:authorities" - tools:node="remove"/> - </application> - - <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.systemui.compose.features.tests" - android:label="Tests for SystemUIComposeFeatures"/> - -</manifest>
\ No newline at end of file diff --git a/packages/SystemUI/compose/scene/TEST_MAPPING b/packages/SystemUI/compose/scene/TEST_MAPPING index f644a23ba0a3..f9424ed62d78 100644 --- a/packages/SystemUI/compose/scene/TEST_MAPPING +++ b/packages/SystemUI/compose/scene/TEST_MAPPING @@ -23,17 +23,6 @@ ] }, { - "name": "SystemUIComposeFeaturesTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] - }, - { "name": "SystemUIComposeGalleryTests", "options": [ { diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt index c3857889a134..7707a600c691 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt @@ -17,6 +17,8 @@ package com.android.keyguard import android.testing.TestableLooper +import android.view.KeyEvent +import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager import android.widget.EditText @@ -25,8 +27,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils +import com.android.internal.widget.LockscreenCredential import com.android.keyguard.domain.interactor.KeyguardKeyboardInteractor -import com.android.systemui.Flags as AconfigFlags import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.flags.FakeFeatureFlags @@ -36,12 +38,17 @@ import com.android.systemui.res.R import com.android.systemui.statusbar.policy.DevicePostureController import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.util.concurrency.DelayableExecutor +import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever +import junit.framework.Assert.assertFalse +import junit.framework.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.ArgumentMatchers.anyString +import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.mock @@ -49,6 +56,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations +import com.android.systemui.Flags as AconfigFlags @SmallTest @RunWith(AndroidJUnit4::class) @@ -77,6 +85,7 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() { private lateinit var mKeyguardMessageAreaController: KeyguardMessageAreaController<BouncerKeyguardMessageArea> @Mock private lateinit var postureController: DevicePostureController + @Captor private lateinit var keyListenerArgumentCaptor: ArgumentCaptor<View.OnKeyListener> private lateinit var keyguardPasswordViewController: KeyguardPasswordViewController @@ -171,4 +180,34 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() { keyguardPasswordViewController.resetState() verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_password) } + + @Test + fun testSpaceKeyDoesNotSubmitPassword() { + keyguardPasswordViewController.onViewAttached() + verify(passwordEntry).setOnKeyListener(keyListenerArgumentCaptor.capture()) + + val eventHandled = + keyListenerArgumentCaptor.value.onKey(keyguardPasswordView, + KeyEvent.KEYCODE_SPACE, + KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SPACE)) + + assertFalse("Unlock attempted.", eventHandled) + } + + @Test + fun testEnterKeySubmitsPassword() { + val password = mock<LockscreenCredential>() + `when`(keyguardPasswordView.enteredCredential).thenReturn(password) + `when`(password.size()).thenReturn(4) + `when`(password.duplicate()).thenReturn(password) + keyguardPasswordViewController.onViewAttached() + verify(passwordEntry).setOnKeyListener(keyListenerArgumentCaptor.capture()) + + val eventHandled = + keyListenerArgumentCaptor.value.onKey(keyguardPasswordView, + KeyEvent.KEYCODE_ENTER, + KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER)) + + assertTrue("Unlock not attempted.", eventHandled) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt index b611e0aafa2f..36919d0c74a4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepositoryTest.kt @@ -1052,32 +1052,6 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { biometricSettingsRepository.setIsFaceAuthCurrentlyAllowed(true) faceAuthenticateIsCalled() } - @Test - fun authFailedCallAfterAuthLockedOutErrorShouldBeIgnored() = - testScope.runTest { - initCollectors() - allPreconditionsToRunFaceAuthAreTrue() - runCurrent() - assertThat(canFaceAuthRun()).isTrue() - - underTest.requestAuthenticate(FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED, false) - runCurrent() - - faceAuthenticateIsCalled() - authenticationCallback.value.onAuthenticationError( - FACE_ERROR_LOCKOUT_PERMANENT, - "Too many attempts, face not available" - ) - - val lockoutError = authStatus() as ErrorFaceAuthenticationStatus - assertThat(lockedOut()).isTrue() - assertThat(lockoutError.isLockoutError()).isTrue() - - authenticationCallback.value.onAuthenticationFailed() - runCurrent() - - assertThat(authStatus()).isEqualTo(lockoutError) - } private suspend fun TestScope.testGatingCheckForFaceAuth( gatingCheckModifier: suspend () -> Unit diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt index 128b46533a8b..19b80da62dc7 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt @@ -25,7 +25,6 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository -import com.android.systemui.common.shared.model.Position import com.android.systemui.coroutines.collectLastValue import com.android.systemui.doze.DozeMachine import com.android.systemui.doze.DozeTransitionCallback @@ -152,24 +151,6 @@ class KeyguardRepositoryImplTest : SysuiTestCase() { } @Test - fun clockPosition() = - testScope.runTest { - assertThat(underTest.clockPosition.value).isEqualTo(Position(0, 0)) - - underTest.setClockPosition(0, 1) - assertThat(underTest.clockPosition.value).isEqualTo(Position(0, 1)) - - underTest.setClockPosition(1, 9) - assertThat(underTest.clockPosition.value).isEqualTo(Position(1, 9)) - - underTest.setClockPosition(1, 0) - assertThat(underTest.clockPosition.value).isEqualTo(Position(1, 0)) - - underTest.setClockPosition(3, 1) - assertThat(underTest.clockPosition.value).isEqualTo(Position(3, 1)) - } - - @Test fun dozeTimeTick() = testScope.runTest { val lastDozeTimeTick by collectLastValue(underTest.dozeTimeTick) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt index b0f59fe68f11..225b5b1408e3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt @@ -71,7 +71,7 @@ class AodBurnInViewModelTest : SysuiTestCase() { mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) MockitoAnnotations.initMocks(this) - whenever(burnInInteractor.keyguardBurnIn).thenReturn(burnInFlow) + whenever(burnInInteractor.burnIn(anyInt(), anyInt())).thenReturn(burnInFlow) kosmos.burnInInteractor = burnInInteractor whenever(goneToAodTransitionViewModel.enterFromTopTranslationY(anyInt())) .thenReturn(emptyFlow()) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt index 864acfb1ddb9..ce089b1b723a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt @@ -16,6 +16,7 @@ package com.android.systemui.keyguard.ui.viewmodel +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.Flags as AConfigFlags import com.android.systemui.SysuiTestCase @@ -24,9 +25,13 @@ import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.coroutines.collectLastValue import com.android.systemui.doze.util.BurnInHelperWrapper import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory +import com.android.systemui.keyguard.shared.model.BurnInModel import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever @@ -36,18 +41,23 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.junit.runners.JUnit4 import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.MockitoAnnotations @SmallTest -@RunWith(JUnit4::class) +@RunWith(AndroidJUnit4::class) class KeyguardIndicationAreaViewModelTest : SysuiTestCase() { + private val kosmos = testKosmos() + private val testScope = kosmos.testScope @Mock private lateinit var burnInHelperWrapper: BurnInHelperWrapper @Mock private lateinit var shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel + @Mock private lateinit var burnInInteractor: BurnInInteractor + private val burnInFlow = MutableStateFlow(BurnInModel()) + + private lateinit var bottomAreaInteractor: KeyguardBottomAreaInteractor private lateinit var underTest: KeyguardIndicationAreaViewModel private lateinit var repository: FakeKeyguardRepository @@ -70,9 +80,11 @@ class KeyguardIndicationAreaViewModelTest : SysuiTestCase() { MockitoAnnotations.initMocks(this) mSetFlagsRule.disableFlags(AConfigFlags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR) + mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT) whenever(burnInHelperWrapper.burnInOffset(anyInt(), any())) .thenReturn(RETURNED_BURN_IN_OFFSET) + whenever(burnInInteractor.burnIn(anyInt(), anyInt())).thenReturn(burnInFlow) val withDeps = KeyguardInteractorFactory.create() val keyguardInteractor = withDeps.keyguardInteractor @@ -82,78 +94,85 @@ class KeyguardIndicationAreaViewModelTest : SysuiTestCase() { whenever(bottomAreaViewModel.startButton).thenReturn(startButtonFlow) whenever(bottomAreaViewModel.endButton).thenReturn(endButtonFlow) whenever(bottomAreaViewModel.alpha).thenReturn(alphaFlow) + bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository) underTest = KeyguardIndicationAreaViewModel( keyguardInteractor = keyguardInteractor, - bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository), + bottomAreaInteractor = bottomAreaInteractor, keyguardBottomAreaViewModel = bottomAreaViewModel, burnInHelperWrapper = burnInHelperWrapper, + burnInInteractor = burnInInteractor, shortcutsCombinedViewModel = shortcutsCombinedViewModel, configurationInteractor = ConfigurationInteractor(FakeConfigurationRepository()), ) } @Test - fun alpha() = runTest { - val value = collectLastValue(underTest.alpha) - - assertThat(value()).isEqualTo(1f) - alphaFlow.value = 0.1f - assertThat(value()).isEqualTo(0.1f) - alphaFlow.value = 0.5f - assertThat(value()).isEqualTo(0.5f) - alphaFlow.value = 0.2f - assertThat(value()).isEqualTo(0.2f) - alphaFlow.value = 0f - assertThat(value()).isEqualTo(0f) - } + fun alpha() = + testScope.runTest { + val value = collectLastValue(underTest.alpha) + + assertThat(value()).isEqualTo(1f) + alphaFlow.value = 0.1f + assertThat(value()).isEqualTo(0.1f) + alphaFlow.value = 0.5f + assertThat(value()).isEqualTo(0.5f) + alphaFlow.value = 0.2f + assertThat(value()).isEqualTo(0.2f) + alphaFlow.value = 0f + assertThat(value()).isEqualTo(0f) + } @Test - fun isIndicationAreaPadded() = runTest { - repository.setKeyguardShowing(true) - val value = collectLastValue(underTest.isIndicationAreaPadded) - - assertThat(value()).isFalse() - startButtonFlow.value = startButtonFlow.value.copy(isVisible = true) - assertThat(value()).isTrue() - endButtonFlow.value = endButtonFlow.value.copy(isVisible = true) - assertThat(value()).isTrue() - startButtonFlow.value = startButtonFlow.value.copy(isVisible = false) - assertThat(value()).isTrue() - endButtonFlow.value = endButtonFlow.value.copy(isVisible = false) - assertThat(value()).isFalse() - } + fun isIndicationAreaPadded() = + testScope.runTest { + repository.setKeyguardShowing(true) + val value = collectLastValue(underTest.isIndicationAreaPadded) + + assertThat(value()).isFalse() + startButtonFlow.value = startButtonFlow.value.copy(isVisible = true) + assertThat(value()).isTrue() + endButtonFlow.value = endButtonFlow.value.copy(isVisible = true) + assertThat(value()).isTrue() + startButtonFlow.value = startButtonFlow.value.copy(isVisible = false) + assertThat(value()).isTrue() + endButtonFlow.value = endButtonFlow.value.copy(isVisible = false) + assertThat(value()).isFalse() + } @Test - fun indicationAreaTranslationX() = runTest { - val value = collectLastValue(underTest.indicationAreaTranslationX) - - assertThat(value()).isEqualTo(0f) - repository.setClockPosition(100, 100) - assertThat(value()).isEqualTo(100f) - repository.setClockPosition(200, 100) - assertThat(value()).isEqualTo(200f) - repository.setClockPosition(200, 200) - assertThat(value()).isEqualTo(200f) - repository.setClockPosition(300, 100) - assertThat(value()).isEqualTo(300f) - } + fun indicationAreaTranslationX() = + testScope.runTest { + val value = collectLastValue(underTest.indicationAreaTranslationX) + + assertThat(value()).isEqualTo(0f) + bottomAreaInteractor.setClockPosition(100, 100) + assertThat(value()).isEqualTo(100f) + bottomAreaInteractor.setClockPosition(200, 100) + assertThat(value()).isEqualTo(200f) + bottomAreaInteractor.setClockPosition(200, 200) + assertThat(value()).isEqualTo(200f) + bottomAreaInteractor.setClockPosition(300, 100) + assertThat(value()).isEqualTo(300f) + } @Test - fun indicationAreaTranslationY() = runTest { - val value = collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET)) - - // Negative 0 - apparently there's a difference in floating point arithmetic - FML - assertThat(value()).isEqualTo(-0f) - val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f) - assertThat(value()).isEqualTo(expected1) - val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f) - assertThat(value()).isEqualTo(expected2) - val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f) - assertThat(value()).isEqualTo(expected3) - val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f) - assertThat(value()).isEqualTo(expected4) - } + fun indicationAreaTranslationY() = + testScope.runTest { + val value = + collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET)) + + // Negative 0 - apparently there's a difference in floating point arithmetic - FML + assertThat(value()).isEqualTo(-0f) + val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f) + assertThat(value()).isEqualTo(expected1) + val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f) + assertThat(value()).isEqualTo(expected2) + val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f) + assertThat(value()).isEqualTo(expected3) + val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f) + assertThat(value()).isEqualTo(expected4) + } private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float { repository.setDozeAmount(dozeAmount) diff --git a/packages/SystemUI/res/layout-land/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout-land/biometric_prompt_constraint_layout.xml new file mode 100644 index 000000000000..5fe74aa6817f --- /dev/null +++ b/packages/SystemUI/res/layout-land/biometric_prompt_constraint_layout.xml @@ -0,0 +1,322 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" +xmlns:app="http://schemas.android.com/apk/res-auto" +xmlns:tools="http://schemas.android.com/tools" +android:layout_width="match_parent" +android:layout_height="match_parent"> + + <ImageView + android:id="@+id/background" + android:layout_width="0dp" + android:layout_height="0dp" + android:contentDescription="@string/biometric_dialog_empty_space_description" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <View + android:id="@+id/panel" + android:layout_width="0dp" + android:layout_height="0dp" + android:background="?android:attr/colorBackgroundFloating" + android:clickable="true" + android:clipToOutline="true" + android:importantForAccessibility="no" + android:paddingHorizontal="16dp" + android:paddingVertical="16dp" + android:visibility="visible" + app:layout_constraintBottom_toTopOf="@+id/bottomGuideline" + app:layout_constraintEnd_toStartOf="@+id/rightGuideline" + app:layout_constraintStart_toStartOf="@+id/leftGuideline" + app:layout_constraintTop_toTopOf="@+id/topGuideline" /> + + <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper + android:id="@+id/biometric_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.8" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:srcCompat="@tools:sample/avatars" /> + + <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper + android:id="@+id/biometric_icon_overlay" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_gravity="center" + android:contentDescription="@null" + android:scaleType="fitXY" + app:layout_constraintBottom_toBottomOf="@+id/biometric_icon" + app:layout_constraintEnd_toEndOf="@+id/biometric_icon" + app:layout_constraintStart_toStartOf="@+id/biometric_icon" + app:layout_constraintTop_toTopOf="@+id/biometric_icon" /> + + <ScrollView + android:id="@+id/scrollView" + android:layout_width="0dp" + android:layout_height="0dp" + android:fillViewport="true" + android:padding="16dp" + app:layout_constrainedHeight="true" + app:layout_constrainedWidth="true" + app:layout_constraintBottom_toTopOf="@+id/buttonBarrier" + app:layout_constraintEnd_toStartOf="@+id/midGuideline" + app:layout_constraintStart_toStartOf="@id/leftGuideline" + app:layout_constraintTop_toTopOf="@+id/topGuideline"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/innerConstraint" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <ImageView + android:id="@+id/logo" + android:layout_width="@dimen/biometric_auth_icon_size" + android:layout_height="@dimen/biometric_auth_icon_size" + android:layout_gravity="center" + android:scaleType="fitXY" + android:visibility="visible" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <LinearLayout + android:id="@+id/customized_view_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:orientation="vertical" + android:paddingHorizontal="0dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/subtitle" + app:layout_constraintVertical_bias="0.0" /> + + <Space + android:id="@+id/space_above_content" + android:layout_width="match_parent" + android:layout_height="@dimen/biometric_prompt_space_above_content" + android:visibility="gone" /> + + <TextView + android:id="@+id/title" + style="@style/TextAppearance.AuthCredential.Title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + android:paddingHorizontal="0dp" + android:textAlignment="viewStart" + app:layout_constraintBottom_toTopOf="@+id/subtitle" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/logo" + app:layout_constraintVertical_bias="0.0" + app:layout_constraintVertical_chainStyle="packed" /> + + <TextView + android:id="@+id/subtitle" + style="@style/TextAppearance.AuthCredential.Subtitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + android:paddingHorizontal="0dp" + android:textAlignment="viewStart" + app:layout_constraintBottom_toTopOf="@+id/contentBarrier" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/title" /> + + <TextView + android:id="@+id/description" + style="@style/TextAppearance.AuthCredential.Description" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + android:paddingHorizontal="0dp" + android:textAlignment="viewStart" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/subtitle" + app:layout_constraintVertical_bias="0.0" /> + + <TextView + android:id="@+id/logo_description" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:gravity="@integer/biometric_dialog_text_gravity" + android:marqueeRepeatLimit="1" + android:singleLine="true" + android:textAlignment="viewStart" + android:paddingLeft="8dp" + app:layout_constraintBottom_toBottomOf="@+id/logo" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/logo" + app:layout_constraintTop_toTopOf="@+id/logo" /> + + <androidx.constraintlayout.widget.Barrier + android:id="@+id/contentBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="top" + app:constraint_referenced_ids="description, customized_view_container" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + </ScrollView> + + <TextView + android:id="@+id/indicator" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:accessibilityLiveRegion="polite" + android:fadingEdge="horizontal" + android:gravity="center_horizontal" + android:marqueeRepeatLimit="marquee_forever" + android:scrollHorizontally="true" + android:textColor="@color/biometric_dialog_gray" + android:textSize="12sp" + app:layout_constraintBottom_toTopOf="@+id/buttonBarrier" + app:layout_constraintEnd_toEndOf="@+id/biometric_icon" + app:layout_constraintStart_toStartOf="@+id/biometric_icon" + app:layout_constraintTop_toBottomOf="@+id/biometric_icon" + app:layout_constraintVertical_bias="0.0" /> + + <!-- Negative Button, reserved for app --> + <Button + android:id="@+id/button_negative" + style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginLeft="8dp" + android:ellipsize="end" + android:maxLines="2" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/bottomGuideline" + app:layout_constraintStart_toStartOf="@+id/scrollView" /> + + <!-- Cancel Button, replaces negative button when biometric is accepted --> + <Button + android:id="@+id/button_cancel" + style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginLeft="8dp" + android:text="@string/cancel" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/bottomGuideline" + app:layout_constraintStart_toStartOf="@+id/scrollView" /> + + <!-- "Use Credential" Button, replaces if device credential is allowed --> + <Button + android:id="@+id/button_use_credential" + style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginLeft="8dp" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/bottomGuideline" + app:layout_constraintStart_toStartOf="@+id/scrollView" /> + + <!-- Positive Button --> + <Button + android:id="@+id/button_confirm" + style="@*android:style/Widget.DeviceDefault.Button.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginRight="8dp" + android:ellipsize="end" + android:maxLines="2" + android:text="@string/biometric_dialog_confirm" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/bottomGuideline" + app:layout_constraintEnd_toEndOf="@+id/scrollView" + tools:visibility="invisible" /> + + <!-- Try Again Button --> + <Button + android:id="@+id/button_try_again" + style="@*android:style/Widget.DeviceDefault.Button.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginRight="8dp" + android:ellipsize="end" + android:maxLines="2" + android:text="@string/biometric_dialog_try_again" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/bottomGuideline" + app:layout_constraintEnd_toEndOf="@+id/scrollView" /> + + <!-- Guidelines for setting panel border --> + <androidx.constraintlayout.widget.Barrier + android:id="@+id/topBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="top" + app:constraint_referenced_ids="scrollView" /> + + <androidx.constraintlayout.widget.Barrier + android:id="@+id/buttonBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="top" + app:constraint_referenced_ids="button_negative, button_cancel, button_use_credential, button_confirm, button_try_again" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/leftGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_begin="@dimen/biometric_dialog_border_padding" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/rightGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/midGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_begin="406dp" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/bottomGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/topGuideline" + android:layout_width="0dp" + android:layout_height="0dp" + android:orientation="horizontal" + app:layout_constraintGuide_begin="@dimen/biometric_dialog_border_padding" /> + +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml new file mode 100644 index 000000000000..5b30dfb77342 --- /dev/null +++ b/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml @@ -0,0 +1,304 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ImageView + android:id="@+id/background" + android:layout_width="0dp" + android:layout_height="0dp" + android:contentDescription="@string/biometric_dialog_empty_space_description" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <View + android:id="@+id/panel" + android:layout_width="0dp" + android:layout_height="0dp" + android:background="?android:attr/colorBackgroundFloating" + android:clickable="true" + android:clipToOutline="true" + android:importantForAccessibility="no" + android:paddingHorizontal="16dp" + android:paddingVertical="16dp" + android:visibility="visible" + app:layout_constraintBottom_toTopOf="@+id/bottomGuideline" + app:layout_constraintEnd_toStartOf="@+id/rightGuideline" + app:layout_constraintStart_toStartOf="@+id/leftGuideline" + app:layout_constraintTop_toTopOf="@+id/topBarrier" /> + + <Button + android:id="@+id/button_negative" + style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginLeft="8dp" + android:ellipsize="end" + android:maxLines="2" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel" /> + + <Button + android:id="@+id/button_cancel" + style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginLeft="8dp" + android:text="@string/cancel" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel" /> + + <Button + android:id="@+id/button_use_credential" + style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginLeft="8dp" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel" /> + + <Button + android:id="@+id/button_confirm" + style="@*android:style/Widget.DeviceDefault.Button.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginRight="8dp" + android:ellipsize="end" + android:maxLines="2" + android:text="@string/biometric_dialog_confirm" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/panel" + app:layout_constraintEnd_toEndOf="@+id/panel" + tools:visibility="invisible" /> + + <Button + android:id="@+id/button_try_again" + style="@*android:style/Widget.DeviceDefault.Button.Colored" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginBottom="8dp" + android:layout_marginRight="8dp" + android:ellipsize="end" + android:maxLines="2" + android:text="@string/biometric_dialog_try_again" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="@+id/panel" + app:layout_constraintEnd_toEndOf="@+id/panel" /> + + <!-- Negative Button, reserved for app --> + + <ScrollView + android:id="@+id/scrollView" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:fillViewport="true" + android:padding="16dp" + app:layout_constrainedHeight="true" + app:layout_constrainedWidth="true" + app:layout_constraintBottom_toTopOf="@+id/biometric_icon" + app:layout_constraintEnd_toEndOf="@id/panel" + app:layout_constraintStart_toStartOf="@id/panel" + app:layout_constraintTop_toTopOf="@+id/topGuideline" + app:layout_constraintVertical_bias="1.0"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/innerConstraint" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <ImageView + android:id="@+id/logo" + android:layout_width="@dimen/biometric_auth_icon_size" + android:layout_height="@dimen/biometric_auth_icon_size" + android:layout_gravity="center" + android:scaleType="fitXY" + android:visibility="visible" + app:layout_constraintBottom_toTopOf="@+id/logo_description" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <LinearLayout + android:id="@+id/customized_view_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:orientation="vertical" + android:paddingHorizontal="@dimen/biometric_prompt_content_container_padding_horizontal" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/subtitle" /> + + <Space + android:id="@+id/space_above_content" + android:layout_width="match_parent" + android:layout_height="@dimen/biometric_prompt_space_above_content" + android:visibility="gone" /> + + <TextView + android:id="@+id/title" + style="@style/TextAppearance.AuthCredential.Title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + app:layout_constraintBottom_toTopOf="@+id/subtitle" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/logo_description" /> + + <TextView + android:id="@+id/subtitle" + style="@style/TextAppearance.AuthCredential.Subtitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + app:layout_constraintBottom_toTopOf="@+id/contentBarrier" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/title" /> + + <TextView + android:id="@+id/logo_description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:gravity="@integer/biometric_dialog_text_gravity" + android:marqueeRepeatLimit="1" + android:singleLine="true" + app:layout_constraintBottom_toTopOf="@+id/title" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/logo" /> + + <TextView + android:id="@+id/description" + style="@style/TextAppearance.AuthCredential.Description" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/subtitle" /> + + <androidx.constraintlayout.widget.Barrier + android:id="@+id/contentBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="top" + app:constraint_referenced_ids="description, customized_view_container" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + </ScrollView> + + <!-- Cancel Button, replaces negative button when biometric is accepted --> + <TextView + android:id="@+id/indicator" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:accessibilityLiveRegion="polite" + android:fadingEdge="horizontal" + android:gravity="center_horizontal" + android:marqueeRepeatLimit="marquee_forever" + android:scrollHorizontally="true" + android:textColor="@color/biometric_dialog_gray" + android:textSize="12sp" + app:layout_constraintBottom_toTopOf="@+id/buttonBarrier" + app:layout_constraintEnd_toEndOf="@+id/panel" + app:layout_constraintStart_toStartOf="@+id/panel" + app:layout_constraintTop_toBottomOf="@+id/biometric_icon" + app:layout_constraintVertical_bias="0.0" /> + + <!-- "Use Credential" Button, replaces if device credential is allowed --> + + <!-- Positive Button --> + <androidx.constraintlayout.widget.Barrier + android:id="@+id/topBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="top" + app:constraint_referenced_ids="scrollView" /> + + <!-- Try Again Button --> + <androidx.constraintlayout.widget.Barrier + android:id="@+id/buttonBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="top" + app:constraint_referenced_ids="button_negative, button_cancel, button_use_credential, button_confirm, button_try_again" /> + + <!-- Guidelines for setting panel border --> + <androidx.constraintlayout.widget.Guideline + android:id="@+id/leftGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_begin="@dimen/biometric_dialog_border_padding" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/rightGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/bottomGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/topGuideline" + android:layout_width="0dp" + android:layout_height="0dp" + android:orientation="horizontal" + app:layout_constraintGuide_percent="0.25171" /> + + <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper + android:id="@+id/biometric_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.8" + tools:srcCompat="@tools:sample/avatars" /> + + <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper + android:id="@+id/biometric_icon_overlay" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_gravity="center" + android:contentDescription="@null" + android:scaleType="fitXY" + app:layout_constraintBottom_toBottomOf="@+id/biometric_icon" + app:layout_constraintEnd_toEndOf="@+id/biometric_icon" + app:layout_constraintStart_toStartOf="@+id/biometric_icon" + app:layout_constraintTop_toTopOf="@+id/biometric_icon" /> + +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml index 0ecdcfcbdd83..74292b4edf0a 100644 --- a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml +++ b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml @@ -1,27 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" -xmlns:app="http://schemas.android.com/apk/res-auto" -xmlns:tools="http://schemas.android.com/tools" -android:layout_width="match_parent" -android:layout_height="match_parent"> - - <ImageView - android:id="@+id/logo" - android:layout_width="@dimen/biometric_auth_icon_size" - android:layout_height="@dimen/biometric_auth_icon_size" - android:layout_gravity="center" - android:scaleType="fitXY" - android:visibility="gone" /> - - <TextView - android:id="@+id/logo_description" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="@integer/biometric_dialog_text_gravity" - android:singleLine="true" - android:marqueeRepeatLimit="1" - android:ellipsize="marquee" - android:visibility="gone"/> + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> <ImageView android:id="@+id/background" @@ -47,7 +29,7 @@ android:layout_height="match_parent"> app:layout_constraintBottom_toTopOf="@+id/bottomGuideline" app:layout_constraintEnd_toStartOf="@+id/rightGuideline" app:layout_constraintStart_toStartOf="@+id/leftGuideline" - app:layout_constraintTop_toTopOf="@+id/title" /> + app:layout_constraintTop_toTopOf="@+id/topBarrier" /> <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper android:id="@+id/biometric_icon" @@ -69,90 +51,133 @@ android:layout_height="match_parent"> android:scaleType="fitXY" app:layout_constraintBottom_toBottomOf="@+id/biometric_icon" app:layout_constraintEnd_toEndOf="@+id/biometric_icon" - app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="@+id/biometric_icon" - app:layout_constraintTop_toTopOf="@+id/biometric_icon" - app:layout_constraintVertical_bias="0.0" /> + app:layout_constraintTop_toTopOf="@+id/biometric_icon" /> - <TextView - android:id="@+id/title" - android:layout_width="wrap_content" + <ScrollView + android:id="@+id/scrollView" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:gravity="@integer/biometric_dialog_text_gravity" - android:singleLine="true" - android:marqueeRepeatLimit="1" - android:ellipsize="marquee" - style="@style/TextAppearance.AuthCredential.Title" - app:layout_constraintBottom_toTopOf="@+id/subtitle" - app:layout_constraintEnd_toEndOf="@+id/panel" - app:layout_constraintStart_toStartOf="@+id/panel" /> + android:fillViewport="true" + android:padding="16dp" + app:layout_constrainedHeight="true" + app:layout_constrainedWidth="true" + app:layout_constraintBottom_toTopOf="@+id/biometric_icon" + app:layout_constraintEnd_toEndOf="@id/rightGuideline" + app:layout_constraintStart_toStartOf="@id/leftGuideline" + app:layout_constraintTop_toTopOf="@+id/topGuideline" + app:layout_constraintVertical_bias="1.0"> - <TextView - android:id="@+id/subtitle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:gravity="@integer/biometric_dialog_text_gravity" - android:singleLine="true" - android:marqueeRepeatLimit="1" - android:ellipsize="marquee" - style="@style/TextAppearance.AuthCredential.Subtitle" - app:layout_constraintBottom_toTopOf="@+id/description" - app:layout_constraintEnd_toEndOf="@+id/panel" - app:layout_constraintStart_toStartOf="@+id/panel" /> + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/innerConstraint" + android:layout_width="match_parent" + android:layout_height="wrap_content"> - <Space - android:id="@+id/space_above_content" - android:layout_width="match_parent" - android:layout_height="@dimen/biometric_prompt_space_above_content" - android:visibility="gone" - app:layout_constraintTop_toBottomOf="@+id/subtitle" - app:layout_constraintEnd_toEndOf="@+id/panel" - app:layout_constraintStart_toStartOf="@+id/panel"/> + <ImageView + android:id="@+id/logo" + android:layout_width="@dimen/biometric_auth_icon_size" + android:layout_height="@dimen/biometric_auth_icon_size" + android:layout_gravity="center" + android:scaleType="fitXY" + android:visibility="visible" + app:layout_constraintBottom_toTopOf="@+id/logo_description" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> - <ScrollView - android:id="@+id/customized_view_container" - android:layout_width="0dp" - android:layout_height="0dp" - android:fillViewport="true" - android:fadeScrollbars="false" - android:gravity="center_vertical" - android:orientation="vertical" - android:paddingHorizontal="@dimen/biometric_prompt_content_container_padding_horizontal" - android:scrollbars="vertical" - android:visibility="gone" - app:layout_constraintTop_toBottomOf="@+id/space_above_content" - app:layout_constraintBottom_toTopOf="@+id/biometric_icon" - app:layout_constraintEnd_toEndOf="@+id/panel" - app:layout_constraintStart_toStartOf="@+id/panel"/> + <LinearLayout + android:id="@+id/customized_view_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:orientation="vertical" + android:paddingHorizontal="@dimen/biometric_prompt_content_container_padding_horizontal" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/subtitle" /> - <TextView - android:id="@+id/description" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginBottom="24dp" - android:scrollbars="vertical" - android:gravity="@integer/biometric_dialog_text_gravity" - style="@style/TextAppearance.AuthCredential.Description" - app:layout_constraintBottom_toTopOf="@+id/biometric_icon" - app:layout_constraintEnd_toEndOf="@+id/panel" - app:layout_constraintStart_toStartOf="@+id/panel" /> + <Space + android:id="@+id/space_above_content" + android:layout_width="match_parent" + android:layout_height="@dimen/biometric_prompt_space_above_content" + android:visibility="gone" /> + + <TextView + android:id="@+id/title" + style="@style/TextAppearance.AuthCredential.Title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + app:layout_constraintBottom_toTopOf="@+id/subtitle" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/logo_description" /> + + <TextView + android:id="@+id/subtitle" + style="@style/TextAppearance.AuthCredential.Subtitle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + app:layout_constraintBottom_toTopOf="@+id/contentBarrier" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/title" /> + + <TextView + android:id="@+id/logo_description" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:gravity="@integer/biometric_dialog_text_gravity" + android:marqueeRepeatLimit="1" + android:singleLine="true" + app:layout_constraintBottom_toTopOf="@+id/title" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/logo" /> + + <TextView + android:id="@+id/description" + style="@style/TextAppearance.AuthCredential.Description" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="@integer/biometric_dialog_text_gravity" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/subtitle" /> + + <androidx.constraintlayout.widget.Barrier + android:id="@+id/contentBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="top" + app:constraint_referenced_ids="description, customized_view_container" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + </ScrollView> <TextView android:id="@+id/indicator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" - android:gravity="center_horizontal" - android:textColor="@color/biometric_dialog_gray" - android:textSize="12sp" android:accessibilityLiveRegion="polite" + android:fadingEdge="horizontal" + android:gravity="center_horizontal" android:marqueeRepeatLimit="marquee_forever" android:scrollHorizontally="true" - android:fadingEdge="horizontal" + android:textColor="@color/biometric_dialog_gray" + android:textSize="12sp" + app:layout_constraintBottom_toTopOf="@+id/buttonBarrier" app:layout_constraintEnd_toEndOf="@+id/panel" - app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/panel" - app:layout_constraintTop_toBottomOf="@+id/biometric_icon" /> + app:layout_constraintTop_toBottomOf="@+id/biometric_icon" + app:layout_constraintVertical_bias="0.0" /> <!-- Negative Button, reserved for app --> <Button @@ -230,6 +255,22 @@ android:layout_height="match_parent"> app:layout_constraintEnd_toEndOf="@+id/panel" /> <!-- Guidelines for setting panel border --> + <androidx.constraintlayout.widget.Barrier + android:id="@+id/topBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="top" + app:constraint_referenced_ids="scrollView" /> + + <androidx.constraintlayout.widget.Barrier + android:id="@+id/buttonBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="top" + app:constraint_referenced_ids="button_negative, button_cancel, button_use_credential, button_confirm, button_try_again" /> + <androidx.constraintlayout.widget.Guideline android:id="@+id/leftGuideline" android:layout_width="wrap_content" @@ -251,4 +292,11 @@ android:layout_height="match_parent"> android:orientation="horizontal" app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" /> + <androidx.constraintlayout.widget.Guideline + android:id="@+id/topGuideline" + android:layout_width="0dp" + android:layout_height="0dp" + android:orientation="horizontal" + app:layout_constraintGuide_percent="0.25171" /> + </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/packages/SystemUI/res/layout/biometric_prompt_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_layout.xml index e7590746207d..984210906e68 100644 --- a/packages/SystemUI/res/layout/biometric_prompt_layout.xml +++ b/packages/SystemUI/res/layout/biometric_prompt_layout.xml @@ -70,7 +70,7 @@ android:layout_height="@dimen/biometric_prompt_space_above_content" android:visibility="gone" /> - <ScrollView + <LinearLayout android:id="@+id/customized_view_container" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 4002517b2cd4..c4d7f8bbb349 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Voeg meer legstukke by"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Langdruk om legstukke te pasmaak"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pasmaak legstukke"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Wysig legstuk"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Verwyder"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Voeg legstuk by"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Lui"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibreer"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Demp"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tik om te ontdemp."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tik om op vibreer te stel. Toeganklikheidsdienste kan dalk gedemp wees."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tik om te demp. Toeganklikheidsdienste kan dalk gedemp wees."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tik om op vibreer te stel."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tik om te demp."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Geraasbeheer"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tik om luiermodus te verander"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"demp"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ontdemp"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aan/af-kieslys"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Bladsy <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Sluitskerm"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Sien versorgingstappe"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Sien versorgingstappe"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Prop jou toestel uit"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Maak notas"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Maak notas, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Deel tans oudio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitsaai"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hou op om <xliff:g id="APP_NAME">%1$s</xliff:g> uit te saai?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"As jy <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitsaai of die uitvoer verander, sal jou huidige uitsending stop"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index ebc20027209f..37ba3c182422 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ተጨማሪ ምግብሮችን ያክሉ"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ምግብሮችን ለማበጀት በረጅሙ ይጫኑ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ምግብሮችን አብጅ"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ምግብርን አርትዕ"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"አስወግድ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ምግብር አክል"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"ጥሪ"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ንዘር"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"ድምጸ-ከል አድርግ"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s። ወደ ንዝረት ለማቀናበር መታ ያድርጉ። የተደራሽነት አገልግሎቶች ድምጸ-ከል ሊደረግባቸው ይችላል።"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ። የተደራሽነት አገልግሎቶች ድምጸ-ከል ሊደረግባቸው ይችላል።"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s። ወደ ንዝረት ለማቀናበር መታ ያድርጉ።"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ።"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"የጫጫታ መቆጣጠሪያ"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"የደዋይ ሁነታን ለመቀየር መታ ያድርጉ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ድምጸ-ከል አድርግ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ድምጸ-ከልን አንሳ"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"የኃይል ምናሌ"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ገፅ <xliff:g id="ID_1">%1$d</xliff:g> ከ <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ማያ ገፅ ቁልፍ"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"የእንክብካቤ ደረጃዎችን ይመልከቱ"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"የእንክብካቤ ደረጃዎችን ይመልከቱ"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"መሣሪያዎን ይንቀሉ"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>፣ <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"የማስታወሻ አያያዝ"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"የማስታወሻ አያያዝ፣ <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ኦዲዮ በማጋራት ላይ"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"በማሰራጨት ላይ"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን ማሰራጨት ይቁም?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>ን ካሰራጩ ወይም ውፅዓትን ከቀየሩ የአሁኑ ስርጭትዎ ይቆማል"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index ec72578f9fc3..1de96aea2210 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"إضافة المزيد من التطبيقات المصغّرة"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"اضغط مع الاستمرار لتخصيص التطبيقات المصغّرة."</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"تخصيص التطبيقات المصغَّرة"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"تعديل التطبيق المصغَّر"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"إزالة"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"إضافة تطبيق مصغّر"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"استصدار رنين"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"اهتزاز"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"كتم الصوت"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. انقر لإلغاء التجاهل."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. انقر للتعيين على الاهتزاز. قد يتم تجاهل خدمات \"سهولة الاستخدام\"."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. انقر للتجاهل. قد يتم تجاهل خدمات \"سهولة الاستخدام\"."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. انقر للتعيين على الاهتزاز."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. انقر لكتم الصوت."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"التحكُّم في مستوى الضجيج"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"انقر لتغيير وضع الرنين."</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"كتم الصوت"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"إعادة الصوت"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"قائمة زر التشغيل"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"الصفحة <xliff:g id="ID_1">%1$d</xliff:g> من <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"شاشة القفل"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"الاطّلاع على خطوات العناية"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"الاطّلاع على خطوات العناية"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"افصِل جهازك"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>، <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"تدوين الملاحظات"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"تدوين الملاحظات في \"<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>\""</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"تتم مشاركة الصوت"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"البث"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"هل تريد إيقاف بث تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>؟"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"إذا أجريت بث تطبيق <xliff:g id="SWITCHAPP">%1$s</xliff:g> أو غيَّرت جهاز الإخراج، سيتوقَف البث الحالي."</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index f66650b41451..da69f77836a1 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"অধিক ৱিজেট যোগ দিয়ক"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ৱিজেট কাষ্টমাইজ কৰিবলৈ দীঘলীয়াকৈ টিপক"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ৱিজেট কাষ্টমাইজ কৰক"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ৱিজেট সম্পাদনা কৰক"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"আঁতৰাওক"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ৱিজেট যোগ দিয়ক"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"ৰিং"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"কম্পন"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"মিউট"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s। আনমিউট কৰিবৰ বাবে টিপক।"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s। কম্পনৰ বাবে টিপক। দিব্য়াংগসকলৰ বাবে থকা সেৱা মিউট হৈ থাকিব পাৰে।"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। মিউট কৰিবলৈ টিপক। দিব্য়াংগসকলৰ বাবে থকা সেৱা মিউট হৈ থাকিব পাৰে।"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। কম্পন অৱস্থাত ছেট কৰিবলৈ টিপক।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। মিউট কৰিবলৈ টিপক।"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"কোলাহল নিয়ন্ত্ৰণ"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"ৰিংগাৰ ম’ড সলনি কৰিবলৈ টিপক"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট কৰক"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট কৰক"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"পাৱাৰ মেনু"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>ৰ পৃষ্ঠা <xliff:g id="ID_1">%1$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"লক স্ক্ৰীন"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"যত্ন লোৱাৰ পদক্ষেপসমূহ চাওক"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"যত্ন লোৱাৰ পদক্ষেপসমূহ চাওক"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"আপোনাৰ ডিভাইচটো আনপ্লাগ কৰক"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"টোকা গ্ৰহণ কৰা"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"টোকা গ্ৰহণ কৰা, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"অডিঅ’ শ্বেয়াৰ কৰি থকা হৈছে"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"সম্প্ৰচাৰণ"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰা বন্ধ কৰিবনে?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"যদি আপুনি <xliff:g id="SWITCHAPP">%1$s</xliff:g>ৰ সম্প্ৰচাৰ কৰে অথবা আউটপুট সলনি কৰে, তেন্তে, আপোনাৰ বৰ্তমানৰ সম্প্ৰচাৰ বন্ধ হৈ যাব"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 70484414a4cb..8857ddb72b47 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Vidcetlər əlavə edin"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Basıb saxlayaraq vidcetləri fərdiləşdirin"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Vidcetləri fərdiləşdirin"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Vidceti redaktə edin"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Silin"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Vidcet əlavə edin"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zəng"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrasiya"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Susdurun"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Səsli etmək üçün tıklayın."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Vibrasiyanı ayarlamaq üçün tıklayın. Əlçatımlılıq xidmətləri səssiz edilmiş ola bilər."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Səssiz etmək üçün tıklayın. Əlçatımlılıq xidmətləri səssiz edilmiş ola bilər."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Vibrasiyanı ayarlamaq üçün klikləyin."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Səssiz etmək üçün klikləyin."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Səs-küy idarəsi"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Zəng rejimini dəyişmək üçün toxunun"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"susdurun"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"səssiz rejimdən çıxarın"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Qidalanma düyməsi menyusu"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> səhifədən <xliff:g id="ID_1">%1$d</xliff:g> səhifə"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran kilidi"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ehtiyat tədbiri mərhələlərinə baxın"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ehtiyat tədbiri mərhələlərinə baxın"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Cihazınızı ayırın"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Qeydgötürmə"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Qeydgötürmə, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Audio paylaşılır"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayım"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinin yayımlanması dayandırılsın?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> tətbiqini yayımlasanız və ya nəticəni dəyişsəniz, cari yayımınız dayandırılacaq"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index a598d8f3733b..677f169f8bc4 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte još vidžeta"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dugi pritisak za prilagođavanje vidžeta"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodi vidžete"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Izmeni vidžet"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Ukloni"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodaj vidžet"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Aktiviraj zvono"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibriraj"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Isključi zvuk"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Dodirnite da biste uključili zvuk."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Dodirnite da biste podesili na vibraciju. Zvuk usluga pristupačnosti će možda biti isključen."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da biste isključili zvuk. Zvuk usluga pristupačnosti će možda biti isključen."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da biste podesili na vibraciju."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da biste isključili zvuk."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrola šuma"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promenili režim zvona"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni dugmeta za uključivanje"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. strana od <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključan ekran"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Pogledajte upozorenja"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Pogledajte upozorenja"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Isključite uređaj"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Pravljenje beležaka"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Pravljenje beležaka, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Deli se zvuk"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitovanje"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite da zaustavite emitovanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitujete aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promenite izlaz, aktuelno emitovanje će se zaustaviti"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 2b137fb63258..7feb1607be22 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Дадаць іншыя віджэты"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Доўга націскайце, каб наладзіць віджэты"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Наладзіць віджэты"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Змяніць віджэт"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Выдаліць"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Дадаць віджэт"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Званок"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вібрацыя"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Гук выключаны"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Дакраніцеся, каб уключыць гук."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Дакраніцеся, каб уключыць вібрацыю. Можа быць адключаны гук службаў спецыяльных магчымасцей."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Дакраніцеся, каб адключыць гук. Можа быць адключаны гук службаў спецыяльных магчымасцей."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Дакраніцеся, каб уключыць вібрацыю."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Дакраніцеся, каб адключыць гук"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Кантроль шуму"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Націсніце, каб змяніць рэжым званка"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"выключыць гук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"уключыць гук"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопкі сілкавання"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Старонка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Экран блакіроўкі"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Глядзець паэтапную дапамогу"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Глядзець паэтапную дапамогу"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Адключыце прыладу"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Стварэнне нататак"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Стварэнне нататак, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Ідзе абагульванне аўдыя"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Перадача даных"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Спыніць трансляцыю праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Пры пераключэнні на праграму \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" ці змяненні вываду бягучая трансляцыя спыняецца"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index aa3da9caa6f9..d684d650af94 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Добавете още приспособления"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Натиснете продължително за персонализ. на приспос."</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Персонализиране на приспособленията"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Редактиране на приспособлението"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Премахване"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Добавяне на приспособление"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Позвъняване"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибриране"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Без звук"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Докоснете, за да включите отново звука."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Докоснете, за да зададете вибриране. Възможно е звукът на услугите за достъпност да бъде заглушен."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Докоснете, за да заглушите звука. Възможно е звукът на услугите за достъпност да бъде заглушен."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Докоснете, за да зададете вибриране."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Докоснете, за да заглушите звука."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Управление на шума"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Докоснете, за да промените режима на звънене"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"спиране"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"пускане"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню за включване/изключване"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> от <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Заключен екран"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Вижте стъпките, които да предприемете"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Вижте стъпките, които да предприемете"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Изключете устройството си"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Водене на бележки"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Водене на бележки, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Споделя аудио"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Излъчване"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се спре ли предаването на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако предавате <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените изхода, текущото ви предаване ще бъде прекратено"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 12e24c0a3bd3..db52b2ea1621 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"আরও উইজেট যোগ করুন"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"উইজেট কাস্টমাইজ করতে বেশিক্ষণ প্রেস করুন"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"উইজেট কাস্টমাইজ করুন"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"উইজেট এডিট করুন"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"সরান"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"উইজেট যোগ করুন"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"রিং"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ভাইব্রেট"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"মিউট"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s। সশব্দ করতে আলতো চাপুন।"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s। কম্পন এ সেট করতে আলতো চাপুন। অ্যাক্সেসযোগ্যতার পরিষেবাগুলিকে মিউট করা হতে পারে।"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। মিউট করতে আলতো চাপুন। অ্যাক্সেসযোগ্যতার পরিষেবাগুলিকে মিউট করা হতে পারে।"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। ভাইব্রেট করতে ট্যাপ করুন।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। মিউট করতে ট্যাপ করুন।"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"আশপাশের আওয়াজ কন্ট্রোল করা"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"রিঙ্গার মোড পরিবর্তন করতে ট্যাপ করুন"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"মিউট করুন"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"আনমিউট করুন"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"পাওয়ার মেনু"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>টির মধ্যে <xliff:g id="ID_1">%1$d</xliff:g> নং পৃষ্ঠা"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"লক স্ক্রিন"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ডিভাইস রক্ষণাবেক্ষণের ধাপগুলি দেখুন"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ডিভাইস রক্ষণাবেক্ষণের ধাপগুলি দেখুন"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"আপনার ডিভাইস আনপ্লাগ করা"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"নোট নেওয়া"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"নোট নেওয়া, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"অডিও শেয়ার করা হচ্ছে"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ব্রডকাস্ট করা হচ্ছে"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> সম্প্রচার বন্ধ করবেন?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"আপনি <xliff:g id="SWITCHAPP">%1$s</xliff:g> সম্প্রচার করলে বা আউটপুট পরিবর্তন করলে, আপনার বর্তমান সম্প্রচার বন্ধ হয়ে যাবে"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index f79e2d915451..3d54f6cfb747 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte još vidžeta"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pritisnite i zadržite da prilagodite vidžete"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodite vidžete"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Uredite vidžet"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Uklanjanje"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodajte vidžet"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zvono"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibriranje"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Isključi zvuk"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Dodirnite da uključite zvukove."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Dodirnite za postavljanje vibracije. Zvukovi usluga pristupačnosti mogu biti isključeni."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da isključite zvuk. Zvukovi usluga pristupačnosti mogu biti isključeni."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da postavite vibraciju."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da isključite zvuk."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Upravljanje bukom"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da promijenite način rada zvuka zvona"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključite zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključite zvuk"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni napajanja"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključani ekran"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Pogledajte korake za zaštitu"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Pogledajte korake za zaštitu"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Iskopčajte uređaj"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Pisanje bilješki"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Pisanje bilješki, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Dijeljenje zvuka"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, trenutno emitiranje će se zaustaviti"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 583275f366b3..bcc451b60e16 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Afegeix més widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén premut per personalitzar els widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalitza els widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edita el widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Suprimeix"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Afegeix un widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Fes sonar"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibra"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silencia"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toca per activar el so."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toca per activar la vibració. Pot ser que els serveis d\'accessibilitat se silenciïn."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toca per silenciar el so. Pot ser que els serveis d\'accessibilitat se silenciïn."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toca per activar la vibració."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toca per silenciar."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Control de soroll"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Toca per canviar el mode de timbre"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"deixar de silenciar"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú d\'engegada"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pàgina <xliff:g id="ID_1">%1$d</xliff:g> (<xliff:g id="ID_2">%2$d</xliff:g> en total)"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueig"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Mostra els passos de manteniment"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Mostra els passos de manteniment"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desconnecta el dispositiu"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Presa de notes"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Presa de notes, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"S\'està compartint l\'àudio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"S\'està emetent"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vols deixar d\'emetre <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emets <xliff:g id="SWITCHAPP">%1$s</xliff:g> o canvies la sortida, l\'emissió actual s\'aturarà"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 6cdb3d8af2a1..bf7566a803ee 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Přidat další widgety"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dlouhým stisknutím můžete přizpůsobit widgety"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Přizpůsobit widgety"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Upravit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Odstranit"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Přidat widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Vyzvánění"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrace"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Ztlumení"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Klepnutím zapnete zvuk."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Klepnutím aktivujete režim vibrací. Služby přístupnosti mohou být ztlumeny."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Klepnutím vypnete zvuk. Služby přístupnosti mohou být ztlumeny."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Klepnutím nastavíte vibrace."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Klepnutím vypnete zvuk."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Omezení hluku"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Klepnutím změníte režim vyzvánění"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnout zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnout zvuk"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Nabídka vypínače"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stránka <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Obrazovka uzamčení"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Zobrazit pokyny, co dělat"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Zobrazit pokyny, co dělat"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Odpojte zařízení"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g> <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Psaní poznámek"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Psaní poznámek, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Sdílení zvuku"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysílání"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zastavit vysílání v aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Pokud budete vysílat v aplikaci <xliff:g id="SWITCHAPP">%1$s</xliff:g> nebo změníte výstup, aktuální vysílání se zastaví"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 79b01a84b3bb..60cf76a2d5e7 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tilføj flere widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Hold fingeren nede for at tilpasse widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tilpas widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Rediger widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Fjern"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Tilføj widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibration"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Slå lyden fra"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tryk for at slå lyden til."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tryk for at konfigurere til at vibrere. Tilgængelighedstjenester kan blive deaktiveret."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tryk for at slå lyden fra. Lyden i tilgængelighedstjenester kan blive slået fra."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tryk for at aktivere vibration."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tryk for at slå lyden fra."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Støjstyring"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tryk for at ændre ringetilstand"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"slå lyden fra"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå lyden til"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu for afbryderknappen"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Side <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Låseskærm"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Se håndteringsvejledning"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Se håndteringsvejledning"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Træk stikket ud af din enhed"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Notetagning"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Notetagning, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Deler lyd"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Udsender"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop udsendelsen <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du udsender <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller skifter output, stopper din aktuelle udsendelse"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 43f799bd1b68..60165d24a260 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Weitere Widgets hinzufügen"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Lange drücken, um Widgets anzupassen"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widgets anpassen"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Widget bearbeiten"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Entfernen"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Widget hinzufügen"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Klingeln lassen"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrieren"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Stummschalten"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Zum Aufheben der Stummschaltung tippen."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tippen, um Vibrieren festzulegen. Bedienungshilfen werden unter Umständen stummgeschaltet."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Zum Stummschalten tippen. Bedienungshilfen werden unter Umständen stummgeschaltet."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Zum Aktivieren der Vibration tippen."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Zum Stummschalten tippen."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Geräuschunterdrückung"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Zum Ändern des Klingeltonmodus tippen"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Stummschalten"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"Aufheben der Stummschaltung"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Ein-/Aus-Menü"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Seite <xliff:g id="ID_1">%1$d</xliff:g> von <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Sperrbildschirm"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Schritte zur Abkühlung des Geräts ansehen"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Schritte zur Abkühlung des Geräts ansehen"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Gerät vom Stromnetz trennen"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Notizen"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Notizen, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Audio wird geteilt"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Übertragung läuft"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> nicht mehr streamen?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Wenn du <xliff:g id="SWITCHAPP">%1$s</xliff:g> streamst oder die Ausgabe änderst, wird dein aktueller Stream beendet"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 43ab777aa1de..6c45adfbda4b 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Προσθήκη περισσότερων γραφικών στοιχείων"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Παρατεταμένο πάτημα για προσαρμογή γραφ. στοιχείων"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Προσαρμογή γραφικών στοιχείων"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Επεξεργασία γραφικού στοιχείου"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Κατάργηση"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Προσθήκη γραφικού στοιχείου"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Κουδούνισμα"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Δόνηση"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Σίγαση"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Πατήστε για κατάργηση σίγασης."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Πατήστε για ενεργοποιήσετε τη δόνηση. Οι υπηρεσίες προσβασιμότητας ενδέχεται να τεθούν σε σίγαση."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Πατήστε για σίγαση. Οι υπηρεσίες προσβασιμότητας ενδέχεται να τεθούν σε σίγαση."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Πατήστε για να ενεργοποιήσετε τη δόνηση."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Πατήστε για σίγαση."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Έλεγχος θορύβου"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Πατήστε για να αλλάξετε τη λειτουργία ειδοποίησης ήχου"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"σίγαση"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"κατάργηση σίγασης"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Μενού λειτουργίας"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Σελίδα <xliff:g id="ID_1">%1$d</xliff:g> από <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Οθόνη κλειδώματος"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Δείτε βήματα αντιμετώπισης."</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Δείτε βήματα αντιμετώπισης."</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Αποσυνδέστε τη συσκευή"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Δημιουργία σημειώσεων"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Δημιουργία σημειώσεων, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Κοινοποίηση ήχου"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Μετάδοση"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Διακοπή μετάδοσης με την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Εάν κάνετε μετάδοση με την εφαρμογή <xliff:g id="SWITCHAPP">%1$s</xliff:g> ή αλλάξετε την έξοδο, η τρέχουσα μετάδοση θα σταματήσει"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 9d2742a2b9fe..3dbe2dc013f5 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrate"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Mute"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tap to unmute."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Noise control"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Note-taking"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Note-taking, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Sharing audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index f77f66028397..14cb7a0e0f36 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -429,6 +429,7 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customize widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customize widgets"</string> + <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string> @@ -573,11 +574,14 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrate"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Mute"</string> + <string name="media_device_cast" msgid="4786241789687569892">"Cast"</string> + <string name="stream_notification_unavailable" msgid="4313854556205836435">"Unavailable because ring is muted"</string> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tap to unmute."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Noise Control"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> @@ -832,6 +836,8 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string> + <string name="finder_active" msgid="7907846989716941952">"You can locate this phone with Find My Device even when powered off"</string> + <string name="shutdown_progress" msgid="5464239146561542178">"Shutting down…"</string> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string> @@ -1186,6 +1192,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Note-taking"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Note-taking, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Sharing audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 9d2742a2b9fe..3dbe2dc013f5 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrate"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Mute"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tap to unmute."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Noise control"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Note-taking"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Note-taking, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Sharing audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 9d2742a2b9fe..3dbe2dc013f5 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrate"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Mute"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tap to unmute."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Noise control"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Note-taking"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Note-taking, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Sharing audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 6f5c13362405..af690e475b75 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -429,6 +429,7 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customize widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customize widgets"</string> + <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string> @@ -573,11 +574,14 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrate"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Mute"</string> + <string name="media_device_cast" msgid="4786241789687569892">"Cast"</string> + <string name="stream_notification_unavailable" msgid="4313854556205836435">"Unavailable because ring is muted"</string> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tap to unmute."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tap to mute. Accessibility services may be muted."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tap to set to vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tap to mute."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Noise Control"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tap to change ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"unmute"</string> @@ -832,6 +836,8 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string> + <string name="finder_active" msgid="7907846989716941952">"You can locate this phone with Find My Device even when powered off"</string> + <string name="shutdown_progress" msgid="5464239146561542178">"Shutting down…"</string> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"See care steps"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"See care steps"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Unplug your device"</string> @@ -1186,6 +1192,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Note-taking"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Note-taking, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Sharing audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Broadcasting"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Stop broadcasting <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"If you broadcast <xliff:g id="SWITCHAPP">%1$s</xliff:g> or change the output, your current broadcast will stop"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 8c64a0767cfd..15de0d5bacaf 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Agregar más widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén presionado para personalizar los widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modificar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Quitar"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Agregar widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Timbre"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silenciar"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Presiona para dejar de silenciar."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Presiona para establecer el modo vibración. Es posible que los servicios de accesibilidad estén silenciados."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Presiona para silenciar. Es posible que los servicios de accesibilidad estén silenciados."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Presiona para establecer el modo vibración."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Presiona para silenciar."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Control de ruido"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Presiona para cambiar el modo de timbre"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de encendido"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver pasos de mantenimiento"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver pasos de mantenimiento"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desenchufa el dispositivo"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Tomar notas"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Tomar notas, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Compartiendo audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitiendo"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Quieres dejar de transmitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si transmites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu transmisión actual se detendrá"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 692bb26fb190..3edc603034f1 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Añade más widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén pulsado para personalizar los widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Quitar"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Añadir widget"</string> @@ -530,7 +532,7 @@ <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Tu padre o madre gestionan este dispositivo y pueden ver y controlar cierta información, como las aplicaciones que utilizas, tu ubicación y tu tiempo de pantalla."</string> <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string> <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Desbloqueado por TrustAgent"</string> - <string name="kg_prompt_after_adaptive_auth_lock" msgid="1265107698772588299">"Protección antirrobo\nDispositivo bloqueado; demasiados intentos"</string> + <string name="kg_prompt_after_adaptive_auth_lock" msgid="1265107698772588299">"Protección antirrobo\nDispositivo bloqueado por nº de intentos"</string> <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> <string name="accessibility_volume_settings" msgid="1458961116951564784">"Ajustes de sonido"</string> <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Subtitular automáticamente"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Hacer sonar"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silenciar"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toca para activar el sonido."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toca para poner el dispositivo en vibración. Los servicios de accesibilidad pueden silenciarse."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toca para silenciar. Los servicios de accesibilidad pueden silenciarse."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toca para activar la vibración."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toca para silenciar."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Control de ruido"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Toca para cambiar el modo de timbre"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"dejar de silenciar"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de encendido"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver pasos de mantenimiento"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver pasos de mantenimiento"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desenchufa tu dispositivo"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Toma de notas"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Toma de notas, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Compartiendo audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiendo"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"¿Dejar de emitir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si emites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu emisión actual se detendrá"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 070f200f2d74..7ae5219795a9 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lisage rohkem vidinaid"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vajutage pikalt vidinate kohandamiseks"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Kohanda vidinaid"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Muuda vidinat"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Eemalda"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Lisa vidin"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Helisemine"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibreerimine"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Vaigistatud"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Puudutage vaigistuse tühistamiseks."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Puudutage värinarežiimi määramiseks. Juurdepääsetavuse teenused võidakse vaigistada."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Puudutage vaigistamiseks. Juurdepääsetavuse teenused võidakse vaigistada."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Puudutage vibreerimise määramiseks."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Puudutage vaigistamiseks."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Mürasummutus"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Puudutage telefonihelina režiimi muutmiseks"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vaigistamine"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vaigistuse tühistamine"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Toitemenüü"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Leht <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Lukustuskuva"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Vaadake hooldusjuhiseid"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Vaadake hooldusjuhiseid"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Eemaldage seade"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Märkmete tegemine"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Märkmete tegemine <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Jagab heli"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Edastamine"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Kas peatada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> ülekandmine?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kui kannate rakendust <xliff:g id="SWITCHAPP">%1$s</xliff:g> üle või muudate väljundit, peatatakse teie praegune ülekanne"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 36eac0ce42b9..d0b10a0db21d 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -346,7 +346,7 @@ <string name="qs_record_issue_stop" msgid="3531747965741982657">"Gelditu"</string> <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Gailuaren erabileraren zer alderdiri eragin dio?"</string> <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Hautatu arazo mota"</string> - <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Pantaila-grabagailua"</string> + <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Pantaila-grabaketa"</string> <string-array name="qs_record_issue_types"> <item msgid="2947988124014085798">"Errendimendua"</item> <item msgid="1627504621139124393">"Erabiltzaile-interfazea"</item> @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Gehitu widget gehiago"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widgetak pertsonalizatzeko, sakatu luze"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pertsonalizatu widgetak"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editatu widgeta"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Kendu"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Gehitu widget bat"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Jo tonua"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Dardara"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Ez jo tonua"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Sakatu audioa aktibatzeko."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Sakatu dardara ezartzeko. Baliteke erabilerraztasun-eginbideen audioa desaktibatzea."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Sakatu audioa desaktibatzeko. Baliteke erabilerraztasun-eginbideen audioa desaktibatzea."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Sakatu hau dardara ezartzeko."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Sakatu hau audioa desaktibatzeko."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Zarata-murrizketa"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Sakatu tonu-jotzailearen modua aldatzeko"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desaktibatu audioa"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktibatu audioa"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Itzaltzeko menua"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g> orria"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantaila blokeatua"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ikusi zaintzeko urratsak"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ikusi zaintzeko urratsak"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Deskonektatu gailua"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Oharrak idaztea"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Oharrak idaztea, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Audioa partekatzen"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Igortzen"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren audioa igortzeari utzi nahi diozu?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> aplikazioaren audioa igortzen baduzu, edo audio-irteera aldatzen baduzu, une hartako igorpena eten egingo da"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index b3a5e36327db..0f937814e55d 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"افزودن ابزارکهای بیشتر"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"برای سفارشیسازی ابزارکها، فشار طولانی دهید"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"سفارشیسازی ابزارکها"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ویرایش ابزارک"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"برداشتن"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"افزودن ابزارک"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"زنگ زدن"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"لرزش"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"صامت"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. برای باصدا کردن ضربه بزنید."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. برای تنظیم روی لرزش ضربه بزنید. ممکن است سرویسهای دسترسپذیری بیصدا شوند."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. برای صامت کردن ضربه بزنید. ممکن است سرویسهای دسترسپذیری صامت شود."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. برای تنظیم روی لرزش، ضربه بزنید."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. برای صامت کردن ضربه بزنید."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"کنترل صدای محیط"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"برای تغییر حالت زنگ، ضربه بزنید"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"صامت کردن"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"باصدا کردن"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"منوی روشن/خاموش"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"صفحه <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"صفحه قفل"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"دیدن اقدامات محافظتی"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"دیدن اقدامات محافظتی"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"دستگاه را جدا کنید"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>، <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"یادداشتبرداری"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"یادداشتبرداری، <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"همرسانی صدا"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"همهفرستی"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"همهفرستی <xliff:g id="APP_NAME">%1$s</xliff:g> متوقف شود؟"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر <xliff:g id="SWITCHAPP">%1$s</xliff:g> را همهفرستی کنید یا خروجی را تغییر دهید، همهفرستی کنونی متوقف خواهد شد"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 47e7f2d7dd2d..5d3959d92b68 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lisää widgetejä"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Yksilöi widgetit pitkällä painalluksella"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Muokkaa widgettejä"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Muokkaa widgetiä"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Poista"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Lisää widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Soittoääni"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Värinä"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Äänetön"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Poista mykistys koskettamalla."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Siirry värinätilaan koskettamalla. Myös esteettömyyspalvelut saattavat mykistyä."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Mykistä koskettamalla. Myös esteettömyyspalvelut saattavat mykistyä."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Siirry värinätilaan napauttamalla."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Mykistä napauttamalla."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Melunvaimennus"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Vaihda soittoäänen tilaa napauttamalla"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"mykistä"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"poista mykistys"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Virtavalikko"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sivu <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Lukitusnäyttö"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Katso huoltovaiheet"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Katso huoltovaiheet"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Irrota laite"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Muistiinpanojen tekeminen"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Muistiinpanot, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Audiota jaetaan"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Lähettää"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Lopetetaanko <xliff:g id="APP_NAME">%1$s</xliff:g>-sovelluksen lähettäminen?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jos lähetät <xliff:g id="SWITCHAPP">%1$s</xliff:g>-sovellusta tai muutat ulostuloa, nykyinen lähetyksesi loppuu"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 1bb8147b9cdf..e02c75ceae3b 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ajouter plus de widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Maintenez le doigt pour personnaliser les widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personnaliser les widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modifier le widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Retirer"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ajouter un widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Sonnerie"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibration"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Sonnerie désactivée"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Touchez pour réactiver le son."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Touchez pour activer les vibrations. Il est possible de couper le son des services d\'accessibilité."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Touchez pour couper le son. Il est possible de couper le son des services d\'accessibilité."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Touchez pour activer les vibrations."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Touchez pour couper le son."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Contrôle du bruit"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Touchez pour modifier le mode de sonnerie"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"désactiver le son"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu de l\'interrupteur"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Écran de verrouillage"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Afficher les étapes d\'entretien"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Afficher les étapes d\'entretien"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Débranchez votre appareil"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Prise de note"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Prise de note, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Audio partagé"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion en cours…"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou changez la sortie, votre diffusion actuelle s\'arrêtera"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 84160af98955..2621a904fa33 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -385,8 +385,8 @@ <string name="sensor_privacy_dialog_open_settings" msgid="5635865896053011859">"Ouvrir les paramètres"</string> <string name="media_seamless_other_device" msgid="4654849800789196737">"Autre appareil"</string> <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"Activer/Désactiver l\'écran Récents"</string> - <string name="zen_priority_introduction" msgid="3159291973383796646">"Vous ne serez dérangé par aucun son ni aucune vibration, hormis ceux des alarmes, des rappels, des événements et des appels des contacts de votre choix. Le son continuera de fonctionner notamment pour la musique, les vidéos et les jeux."</string> - <string name="zen_alarms_introduction" msgid="3987266042682300470">"Vous ne serez dérangé par aucun son ni aucune vibration, hormis ceux des alarmes. Le son continuera de fonctionner notamment pour la musique, les vidéos et les jeux."</string> + <string name="zen_priority_introduction" msgid="3159291973383796646">"Vous ne serez pas dérangé par des sons ou des vibrations, hormis ceux des alarmes, des rappels, des événements et des appelants de votre choix. Vous entendrez encore les sons que vous choisirez de jouer, notamment la musique, les vidéos et les jeux."</string> + <string name="zen_alarms_introduction" msgid="3987266042682300470">"Vous ne serez pas dérangé par des sons ou des vibrations, hormis ceux des alarmes. Vous entendrez encore les sons que vous choisirez de jouer, notamment la musique, les vidéos et les jeux."</string> <string name="zen_priority_customize_button" msgid="4119213187257195047">"Personnaliser"</string> <string name="zen_silence_introduction_voice" msgid="853573681302712348">"Cette option permet de bloquer TOUS les sons et les vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux. Vous pourrez encore passer des appels téléphoniques."</string> <string name="zen_silence_introduction" msgid="6117517737057344014">"Cette option permet de bloquer TOUS les sons et les vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux."</string> @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ajouter des widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Appuyez de manière prolongée pour personnaliser les widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personnaliser les widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modifier le widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Supprimer"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ajouter un widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Sonnerie"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibreur"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Couper le son"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Appuyez pour ne plus ignorer."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Appuyez pour mettre en mode vibreur. Vous pouvez ignorer les services d\'accessibilité."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Appuyez pour ignorer. Vous pouvez ignorer les services d\'accessibilité."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Appuyez pour mettre en mode vibreur."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Appuyez pour ignorer."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Contrôle du bruit"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Appuyez pour changer le mode de la sonnerie"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"couper le son"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu Marche/Arrêt"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Écran de verrouillage"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Afficher les étapes d\'entretien"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Afficher les étapes d\'entretien"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Débrancher votre appareil"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Prise de notes"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Prise de notes, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Audio partagé"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Diffusion…"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Arrêter la diffusion de <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Si vous diffusez <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou que vous modifiez le résultat, votre annonce actuelle s\'arrêtera"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index b78199a149cf..1955c040990f 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Engadir máis widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pulsación longa para personalizar os widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Quitar"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Engadir widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Facer soar"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silenciar"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toca para activar o son."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toca para establecer a vibración. Pódense silenciar os servizos de accesibilidade."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toca para silenciar. Pódense silenciar os servizos de accesibilidade."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toca para establecer a vibración."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toca para silenciar."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Control de ruído"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Toca para cambiar o modo de timbre"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenciar"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activar o son"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menú de acendido"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Páxina <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Pantalla de bloqueo"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver pasos de mantemento"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver pasos de mantemento"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desconectar o dispositivo"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Toma de notas"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Toma de notas (<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>)"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Compartindo audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Difusión"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Queres deixar de emitir contido a través de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se emites contido a través de <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou cambias de saída, a emisión en curso deterase"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index d84b1f553f8b..5a1cf421da54 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"વધુ વિજેટ ઉમેરો"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"વિજેટ કસ્ટમાઇઝ કરવા માટે થોડીવાર દબાવી રાખો"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"વિજેટ કસ્ટમાઇઝ કરો"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"વિજેટમાં ફેરફાર કરો"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"કાઢી નાખો"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"વિજેટ ઉમેરો"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"રિંગ કરો"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"વાઇબ્રેટ"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"મ્યૂટ કરો"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. અનમ્યૂટ કરવા માટે ટૅપ કરો."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. વાઇબ્રેટ પર સેટ કરવા માટે ટૅપ કરો. ઍક્સેસિબિલિટી સેવાઓ મ્યૂટ કરવામાં આવી શકે છે."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. મ્યૂટ કરવા માટે ટૅપ કરો. ઍક્સેસિબિલિટી સેવાઓ મ્યૂટ કરવામાં આવી શકે છે."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. કંપન પર સેટ કરવા માટે ટૅપ કરો."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. મ્યૂટ કરવા માટે ટૅપ કરો."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"અવાજનું નિયંત્રણ"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"રિંગર મોડ બદલવા માટે ટૅપ કરો"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"મ્યૂટ કરો"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"અનમ્યૂટ કરો"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"પાવર મેનૂ"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> માંથી <xliff:g id="ID_1">%1$d</xliff:g> પૃષ્ઠ"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"લૉક સ્ક્રીન"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"સારસંભાળના પગલાં જુઓ"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"સારસંભાળના પગલાં જુઓ"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"તમારા ડિવાઇસને અનપ્લગ કરો"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"નોંધ લેવી"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"નોંધ લેવી, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ઑડિયો શેર કરી રહ્યાં છીએ"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"બ્રૉડકાસ્ટ કરી રહ્યાં છે"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> બ્રોડકાસ્ટ કરવાનું રોકીએ?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"જો તમે <xliff:g id="SWITCHAPP">%1$s</xliff:g> બ્રોડકાસ્ટ કરો અથવા આઉટપુટ બદલો, તો તમારું હાલનું બ્રોડકાસ્ટ બંધ થઈ જશે"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 8d1ac11b933f..4b8c959064af 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ज़्यादा विजेट जोड़ें"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेट पसंद के मुताबिक बनाने के लिए उसे दबाकर रखें"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेट अपनी पसंद के मुताबिक बनाएं"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"विजेट में बदलाव करें"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"हटाएं"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"विजेट जोड़ें"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"आवाज़ चालू है"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"वाइब्रेशन"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"आवाज़ बंद है"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. अनम्यूट करने के लिए टैप करें."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. कंपन पर सेट करने के लिए टैप करें. सुलभता सेवाएं म्यूट हो सकती हैं."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. म्यूट करने के लिए टैप करें. सुलभता सेवाएं म्यूट हो सकती हैं."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. कंपन (वाइब्रेशन) पर सेट करने के लिए छूएं."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. म्यूट करने के लिए टैप करें."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"शोर को कंट्रोल करने की सुविधा"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलने के लिए टैप करें"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करें"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्यूट करें"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पावर मेन्यू"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"पेज <xliff:g id="ID_2">%2$d</xliff:g> में से <xliff:g id="ID_1">%1$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"लॉक स्क्रीन"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"डिवाइस के रखरखाव के तरीके देखें"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"डिवाइस के रखरखाव के तरीके देखें"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"डिवाइस को अनप्लग करें"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"नोट बनाएं"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"नोट लेने के लिए, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ऑडियो शेयर किया जा रहा है"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट ऐप्लिकेशन"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> पर ब्रॉडकास्ट करना रोकें?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> पर ब्रॉडकास्ट शुरू करने पर या आउटपुट बदलने पर, आपका मौजूदा ब्रॉडकास्ट बंद हो जाएगा"</string> @@ -1236,9 +1248,9 @@ <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिंग में जाकर, नोट लेने की सुविधा देने वाले ऐप्लिकेशन को डिफ़ॉल्ट के तौर पर सेट करें"</string> <string name="install_app" msgid="5066668100199613936">"ऐप्लिकेशन इंस्टॉल करें"</string> <string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"जारी रखने के लिए, ऊपर की ओर स्वाइप करें"</string> - <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"क्या आपको किसी बाहरी डिवाइस पर डिसप्ले करना है?"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"क्या आपको किसी बाहरी डिवाइस पर स्क्रीन शेयर करनी है?"</string> <string name="connected_display_dialog_dual_display_stop_warning" msgid="4174707498892447947">"आपके फ़ोन के इनर डिसप्ले की स्क्रीन शेयर की जाएगी. फ़्रंट डिसप्ले को बंद कर दिया जाएगा."</string> - <string name="mirror_display" msgid="2515262008898122928">"डिसप्ले करें"</string> + <string name="mirror_display" msgid="2515262008898122928">"स्क्रीन शेयर करें"</string> <string name="dismiss_dialog" msgid="2195508495854675882">"खारिज करें"</string> <string name="connected_display_icon_desc" msgid="6373560639989971997">"डिसप्ले कनेक्ट किया गया"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"माइक्रोफ़ोन और कैमरा"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index d4e460ddf9ca..45666c07aa21 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodavanje još widgeta"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dugo pritisnite za prilagodbu widgeta"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodi widgete"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Uredi widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Ukloni"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodaj widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zvonjenje"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibriranje"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Zvuk je isključen"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Dodirnite da biste uključili zvuk."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Dodirnite da biste postavili na vibraciju. Usluge pristupačnosti možda neće imati zvuk."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da biste isključili zvuk. Usluge pristupačnosti možda neće imati zvuk."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da biste postavili na vibraciju."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da biste isključili zvuk."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrola buke"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promijenili način softvera zvona"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključivanje zvuka"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"uključivanje zvuka"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Izbornik tipke za uključivanje/isključivanje"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaključani zaslon"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Pročitajte upute za održavanje"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Pročitajte upute za održavanje"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Iskopčajte uređaj"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Pisanje bilježaka"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Pisanje bilježaka, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Dijeljenje zvuka"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Emitiranje"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zaustaviti emitiranje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ako emitirate aplikaciju <xliff:g id="SWITCHAPP">%1$s</xliff:g> ili promijenite izlaz, vaše će se trenutačno emitiranje zaustaviti"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 7c62c7a813e8..3606d7486737 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"További modulok hozzáadása"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nyomja meg hosszan a modulok személyre szabásához"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Modulok személyre szabása"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modul szerkesztése"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Eltávolítás"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Modul hozzáadása"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Csörgés"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Rezgés"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Néma"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Koppintson a némítás megszüntetéséhez."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Koppintson a rezgés beállításához. Előfordulhat, hogy a kisegítő lehetőségek szolgáltatásai le vannak némítva."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Koppintson a némításhoz. Előfordulhat, hogy a kisegítő lehetőségek szolgáltatásai le vannak némítva."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Koppintson a rezgés beállításához."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Koppintson a némításhoz."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Zajszabályozás"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Koppintson a csengés módjának módosításához"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"némítás"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"némítás feloldása"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Bekapcsológombhoz tartozó menü"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. oldal, összesen: <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Lezárási képernyő"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Olvassa el a kímélő használat lépéseit"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Olvassa el a kímélő használat lépéseit"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Húzza ki az eszközt"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Jegyzetelés"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Jegyzetelés, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Hang megosztása…"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sugárzás"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Leállítja a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> közvetítését?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"A(z) <xliff:g id="SWITCHAPP">%1$s</xliff:g> közvetítése vagy a kimenet módosítása esetén a jelenlegi közvetítés leáll"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 8427fc3b683f..1510291e00f2 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ավելացնել վիջեթներ"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Երկար սեղմեք՝ վիջեթները հարմարեցնելու համար"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Հարմարեցնել վիջեթները"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Փոփոխել վիջեթը"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Հեռացնել"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ավելացնել վիջեթ"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Սովորական"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Թրթռոց"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Անձայն"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s: Հպեք՝ ձայնը միացնելու համար:"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s: Հպեք՝ թրթռումը միացնելու համար: Մատչելիության ծառայությունների ձայնը կարող է անջատվել:"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s: Հպեք՝ ձայնն անջատելու համար: Մատչելիության ծառայությունների ձայնը կարող է անջատվել:"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s։ Հպեք՝ թրթռոցը միացնելու համար։"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s։ Հպեք՝ ձայնը անջատելու համար։"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Աղմուկի կառավարում"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Հպեք՝ զանգակի ռեժիմը փոխելու համար"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"անջատել ձայնը"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"միացնել ձայնը"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Սնուցման կոճակի ընտրացանկ"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Էջ <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Կողպէկրան"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Քայլեր գերտաքացման ահազանգի դեպքում"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Քայլեր գերտաքացման ահազանգի դեպքում"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Անջատեք սարքը"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Նշումների ստեղծում"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Նշումների ստեղծում, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Փոխանցում է ձայնը"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Հեռարձակում"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Կանգնեցնել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի հեռարձակումը"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Եթե հեռարձակեք <xliff:g id="SWITCHAPP">%1$s</xliff:g> հավելվածը կամ փոխեք աուդիո ելքը, ձեր ընթացիկ հեռարձակումը կկանգնեցվի։"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index a2f05b95026f..09a9938b5abb 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tambahkan widget lainnya"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Hapus"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Tambahkan widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Dering"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Getar"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Nonaktifkan"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Ketuk untuk menyuarakan."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Ketuk untuk menyetel agar bergetar. Layanan aksesibilitas mungkin dibisukan."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ketuk untuk membisukan. Layanan aksesibilitas mungkin dibisukan."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Ketuk untuk menyetel agar bergetar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ketuk untuk menonaktifkan."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrol Bising"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Ketuk untuk mengubah mode pendering"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Tanpa suara"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktifkan"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu daya"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> dari <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Layar kunci"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Lihat langkah-langkah perawatan"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Lihat langkah-langkah perawatan"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Cabut perangkat"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Pembuatan catatan"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Pembuatan catatan, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Berbagi audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika Anda menyiarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau mengubah output, siaran saat ini akan dihentikan"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 9c9a29f513fc..bbc8eab4f9da 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Bæta við fleiri græjum"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Haltu inni til að sérsníða græjur"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sérsníða græjur"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Breyta græju"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Fjarlægja"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Bæta græju við"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Hringing"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Titringur"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Hljóð af"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Ýttu til að hætta að þagga."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Ýttu til að stilla á titring. Hugsanlega verður slökkt á hljóði aðgengisþjónustu."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ýttu til að þagga. Hugsanlega verður slökkt á hljóði aðgengisþjónustu."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Ýttu til að stilla á titring."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ýttu til að þagga."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Hávaðavörn"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Ýta til að skipta um hringjarastillingu"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"þagga"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"hætta að þagga"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aflrofavalmynd"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Blaðsíða <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Lásskjár"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Sjá varúðarskref"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Sjá varúðarskref"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Taktu tækið úr sambandi"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Glósugerð"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Glósugerð, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Deilir hljóði"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Útsending í gangi"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hætta að senda út <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ef þú sendir út <xliff:g id="SWITCHAPP">%1$s</xliff:g> eða skiptir um úttak lýkur yfirstandandi útsendingu"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index ec58af8fe1af..7c09c597f2a5 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -99,7 +99,7 @@ <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e altre app aperte hanno rilevato questo screenshot."</string> <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Aggiungi alla nota"</string> <string name="screenrecord_title" msgid="4257171601439507792">"Registrazione dello schermo"</string> - <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaboraz. registraz. schermo"</string> + <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaborazione registrazione…"</string> <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string> <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Iniziare a registrare?"</string> <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Quando registri, Android ha accesso a qualsiasi elemento visibile sul tuo schermo o in riproduzione sul tuo dispositivo. Presta quindi attenzione a password, dettagli sui pagamenti, messaggi, foto, audio e video."</string> @@ -111,7 +111,7 @@ <string name="screenrecord_mic_label" msgid="2111264835791332350">"Microfono"</string> <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Audio del dispositivo e microfono"</string> <string name="screenrecord_continue" msgid="4055347133700593164">"Inizia"</string> - <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Registrazione schermo"</string> + <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Registrazione schermo in corso…"</string> <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Registrazione schermo e audio"</string> <string name="screenrecord_taps_label" msgid="1595690528298857649">"Mostra tocchi sullo schermo"</string> <string name="screenrecord_stop_label" msgid="72699670052087989">"Interrompi"</string> @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Aggiungi altri widget"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Premi a lungo per personalizzare i widget"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizza widget"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modifica widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Rimuovi"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Aggiungi widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Attiva suoneria"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Attiva vibrazione"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silenzia"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tocca per riattivare l\'audio."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tocca per attivare la vibrazione. L\'audio dei servizi di accessibilità può essere disattivato."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tocca per disattivare l\'audio. L\'audio dei servizi di accessibilità può essere disattivato."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tocca per attivare la vibrazione."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tocca per disattivare l\'audio."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Controllo del rumore"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tocca per cambiare la modalità della suoneria"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"silenzia"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"riattiva l\'audio"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu del tasto di accensione"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> di <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Schermata di blocco"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Leggi le misure da adottare"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Leggi le misure da adottare"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Scollega il dispositivo"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Aggiunta di note"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Aggiunta di note, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Condivisione di audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Trasmissione in corso…"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vuoi interrompere la trasmissione dell\'app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se trasmetti l\'app <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambi l\'uscita, la trasmissione attuale viene interrotta"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index c9a71c71867b..644b599268ec 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"הוספת ווידג\'טים"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"לוחצים לחיצה ארוכה כדי להתאים אישית את הווידג\'טים"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"התאמה אישית של ווידג\'טים"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"עריכת הווידג\'ט"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"הסרה"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"הוספת ווידג\'ט"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"צלצול"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"רטט"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"השתקה"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. יש להקיש כדי לבטל את ההשתקה."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. צריך להקיש כדי להגדיר רטט. ייתכן ששירותי הנגישות מושתקים."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. יש להקיש כדי להשתיק. ייתכן ששירותי הנגישות יושתקו."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. יש להקיש כדי להעביר למצב רטט."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. יש להקיש כדי להשתיק."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"בקרת הרעש"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"יש להקיש כדי לשנות את מצב תוכנת הצלצול"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"השתקה"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ביטול ההשתקה"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"תפריט הפעלה"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"דף <xliff:g id="ID_1">%1$d</xliff:g> מתוך <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"מסך נעילה"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"לצפייה בשלבי הטיפול"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"לצפייה בשלבי הטיפול"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"ניתוק המכשיר"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"כתיבת הערות"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"כתיבת הערות, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"שיתוף האודיו"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"שידור"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"האם להפסיק לשדר את התוכן מאפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"אם משדרים את התוכן מאפליקציית <xliff:g id="SWITCHAPP">%1$s</xliff:g> או משנים את הפלט, השידור הנוכחי יפסיק לפעול"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index dc33b0ddc15d..3e0d24586686 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ウィジェットの追加"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長押ししてウィジェットをカスタマイズ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ウィジェットのカスタマイズ"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ウィジェットを編集"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"削除"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ウィジェットを追加"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"着信音"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"バイブレーション"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"ミュート"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s。タップしてミュートを解除します。"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s。タップしてバイブレーションに設定します。ユーザー補助機能サービスがミュートされる場合があります。"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。タップしてミュートします。ユーザー補助機能サービスがミュートされる場合があります。"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。タップしてバイブレーションに設定します。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。タップしてミュートします。"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ノイズ コントロール"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"タップすると、着信音のモードを変更できます"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ミュート"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ミュートを解除"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源ボタン メニュー"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ページ <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ロック画面"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"取り扱いに関する手順をご覧ください"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"取り扱いに関する手順をご覧ください"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"デバイスを電源から外します"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>、<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"メモ"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"メモ、<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"音声を共有中"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ブロードキャスト"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> のブロードキャストを停止しますか?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> をブロードキャストしたり、出力を変更したりすると、現在のブロードキャストが停止します。"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index d78bc2072734..973af6fa5361 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ვიჯეტების დამატება"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ხანგრძლივად დააჭირეთ ვიჯეტების მოსარგებად"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ვიჯეტების მორგება"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ვიჯეტის რედაქტირება"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ამოშლა"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ვიჯეტის დამატება"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"დარეკვა"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ვიბრაცია"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"დადუმება"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. შეეხეთ დადუმების გასაუქმებლად."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. შეეხეთ ვიბრაციაზე დასაყენებლად. შეიძლება დადუმდეს მარტივი წვდომის სერვისებიც."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. შეეხეთ დასადუმებლად. შეიძლება დადუმდეს მარტივი წვდომის სერვისებიც."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. შეეხეთ ვიბრაციაზე დასაყენებლად."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. შეეხეთ დასადუმებლად."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ხმაურის კონტროლი"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"შეეხეთ მრეკავის რეჟიმის შესაცვლელად"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"დადუმება"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"დადუმების მოხსნა"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ჩართვის მენიუ"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"გვერდი <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>-დან"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ჩაკეტილი ეკრანი"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"მისაღები ზომების გაცნობა"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"მისაღები ზომების გაცნობა"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"გამოაერᲗეᲗ Თქვენი მოწყობილობა"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"ჩანიშვნა"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"ჩანიშვნა, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"აუდიოს გაზიარება"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"იწყებთ მაუწყებლობას"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"გსურთ <xliff:g id="APP_NAME">%1$s</xliff:g>-ის ტრანსლაციის შეჩერება?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g>-ის ტრანსლაციის შემთხვევაში ან აუდიოს გამოსასვლელის შეცვლისას, მიმდინარე ტრანსლაცია შეჩერდება"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 407da0b9b8fa..d5ae0ac6419f 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Басқа виджеттер қосыңыз."</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерді бейімдеу үшін ұзақ басып тұрыңыз."</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерді реттеу"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Виджетті өзгерту"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Өшіру"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Виджет қосу"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Шылдырлау"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Діріл"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Дыбысын өшіру"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Дыбысын қосу үшін түртіңіз."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Діріл режимін орнату үшін түртіңіз. Арнайы мүмкіндік қызметтерінің дыбысы өшуі мүмкін."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Дыбысын өшіру үшін түртіңіз. Арнайы мүмкіндік қызметтерінің дыбысы өшуі мүмкін."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Діріл режимін орнату үшін түртіңіз."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Дыбысын өшіру үшін түртіңіз."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Шуды реттеу"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Қоңырау режимін өзгерту үшін түртіңіз."</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дыбысын өшіру"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дыбысын қосу"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Қуат мәзірі"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ішінен <xliff:g id="ID_1">%1$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Құлыптаулы экран"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Пайдалану нұсқаулығын қараңыз"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Пайдалану нұсқаулығын қараңыз"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Құрылғыны ажыратыңыз"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Ескертпе жазу"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Ескертпе жазу, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Аудио бөлісу"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Таратуда"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын таратуды тоқтатасыз ба?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> қолданбасын таратсаңыз немесе аудио шығысын өзгертсеңіз, қазіргі тарату сеансы тоқтайды."</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index eaca65732975..11a284d2d9f4 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"បញ្ចូលធាតុក្រាហ្វិកច្រើនទៀត"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ចុចឱ្យយូរ ដើម្បីប្ដូរធាតុក្រាហ្វិកតាមបំណង"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ប្ដូរធាតុក្រាហ្វិកតាមបំណង"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"កែធាតុក្រាហ្វិក"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ដកចេញ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"បញ្ចូលធាតុក្រាហ្វិក"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"រោទ៍"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ញ័រ"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"បិទសំឡេង"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s។ ប៉ះដើម្បីបើកសំឡេង។"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s។ ប៉ះដើម្បីកំណត់ឲ្យញ័រ។ សេវាកម្មលទ្ធភាពប្រើប្រាស់អាចនឹងត្រូវបានបិទសំឡេង។"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s។ ប៉ះដើម្បីបិទសំឡេង។ សេវាកម្មលទ្ធភាពប្រើប្រាស់អាចនឹងត្រូវបានបិទសំឡេង។"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s ។ ចុចដើម្បីកំណត់ឲ្យញ័រ។"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s ។ ចុចដើម្បីបិទសំឡេង។"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ការគ្រប់គ្រងសំឡេងរំខាន"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"ចុចដើម្បីប្ដូរមុខងាររោទ៍"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"បិទសំឡេង"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"បើកសំឡេង"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ម៉ឺនុយថាមពល"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ទំព័រ <xliff:g id="ID_1">%1$d</xliff:g> នៃ <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"អេក្រង់ចាក់សោ"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"មើលជំហានថែទាំ"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"មើលជំហានថែទាំ"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"ដកឧបករណ៍របស់អ្នក"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"ការកត់ត្រា"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"ការកត់ត្រា, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"កំពុងចែករំលែកសំឡេង"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ការផ្សាយ"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"បញ្ឈប់ការផ្សាយ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ប្រសិនបើអ្នកផ្សាយ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ឬប្ដូរឧបករណ៍បញ្ចេញសំឡេង ការផ្សាយបច្ចុប្បន្នរបស់អ្នកនឹងបញ្ឈប់"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 64179ba03a3a..a311a8621af3 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ಹೆಚ್ಚಿನ ವಿಜೆಟ್ಗಳನ್ನು ಸೇರಿಸಿ"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ವಿಜೆಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ದೀರ್ಘಕಾಲ ಒತ್ತಿರಿ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ವಿಜೆಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ವಿಜೆಟ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ತೆಗೆದುಹಾಕಿ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ವಿಜೆಟ್ ಅನ್ನು ಸೇರಿಸಿ"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"ರಿಂಗ್"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ವೈಬ್ರೇಟ್"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"ಮ್ಯೂಟ್"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. ಅನ್ಮ್ಯೂಟ್ ಮಾಡುವುದಕ್ಕಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. ಕಂಪನಕ್ಕೆ ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಬಹುದು."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಬಹುದು."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. ವೈಬ್ರೇಟ್ ಮಾಡಲು ಹೊಂದಿಸುವುದಕ್ಕಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ಗದ್ದಲ ನಿಯಂತ್ರಣ"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"ರಿಂಗರ್ ಮೋಡ್ ಬದಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ಮ್ಯೂಟ್ ಮಾಡಿ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ಅನ್ಮ್ಯೂಟ್ ಮಾಡಿ"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ಪವರ್ ಮೆನು"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="ID_1">%1$d</xliff:g> ಪುಟ"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ಲಾಕ್ ಪರದೆ"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ಕಾಳಜಿಯ ಹಂತಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ಕಾಳಜಿಯ ಹಂತಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್ಪ್ಲಗ್ ಮಾಡಿ"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"ಟಿಪ್ಪಣಿ ಮಾಡಿಕೊಳ್ಳುವಿಕೆ"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"ಟಿಪ್ಪಣಿ ಮಾಡಿಕೊಳ್ಳುವಿಕೆ, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ಆಡಿಯೊವನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ಪ್ರಸಾರ ಮಾಡಲಾಗುತ್ತಿದೆ"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನ ಪ್ರಸಾರವನ್ನು ನಿಲ್ಲಿಸಬೇಕೆ?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ನೀವು <xliff:g id="SWITCHAPP">%1$s</xliff:g> ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಿದರೆ ಅಥವಾ ಔಟ್ಪುಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿದರೆ, ನಿಮ್ಮ ಪ್ರಸ್ತುತ ಪ್ರಸಾರವು ಸ್ಥಗಿತಗೊಳ್ಳುತ್ತದೆ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 26825e0286e3..1fe5f90fd78f 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"더 많은 위젯 추가"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"위젯을 맞춤설정하려면 길게 누르기"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"위젯 맞춤설정"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"위젯 수정"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"삭제"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"위젯 추가"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"벨소리"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"진동"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"음소거"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. 탭하여 음소거를 해제하세요."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. 탭하여 진동으로 설정하세요. 접근성 서비스가 음소거될 수 있습니다."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. 탭하여 음소거로 설정하세요. 접근성 서비스가 음소거될 수 있습니다."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. 탭하여 진동으로 설정하세요."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. 탭하여 음소거로 설정하세요."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"소음 제어"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"탭하여 벨소리 장치 모드 변경"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"음소거"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"음소거 해제"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"전원 메뉴"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>페이지 중 <xliff:g id="ID_1">%1$d</xliff:g>페이지"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"잠금 화면"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"해결 방법 확인하기"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"해결 방법 확인하기"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"기기 분리하기"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"메모"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"메모, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"오디오 공유 중"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"방송 중"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> 방송을 중지하시겠습니까?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> 앱을 방송하거나 출력을 변경하면 기존 방송이 중단됩니다"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 79546862454b..789f7d806548 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Көбүрөөк виджеттерди кошуу"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерди ыңгайлаштыруу үчүн кое бербей басып туруңуз"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерди ыңгайлаштыруу"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Виджетти түзөтүү"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Өчүрүү"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Виджет кошуу"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Шыңгыратуу"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Дирилдөө"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Үнсүз"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Үнүн чыгаруу үчүн таптап коюңуз."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Дирилдөөгө коюу үчүн таптап коюңуз. Атайын мүмкүнчүлүктөр кызматынын үнүн өчүрүп койсо болот."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Үнүн өчүрүү үчүн таптап коюңуз. Атайын мүмкүнчүлүктөр кызматынын үнүн өчүрүп койсо болот."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Дирилдөөгө коюу үчүн басыңыз."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Үнүн өчүрүү үчүн басыңыз."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Ызы-чууну көзөмөлдөө"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Коңгуроо режимин өзгөртүү үчүн басыңыз"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"үнсүз"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"үнүн чыгаруу"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Кубат баскычынын менюсу"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ичинен <xliff:g id="ID_1">%1$d</xliff:g>-бет"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Кулпуланган экран"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Тейлөө кадамдарын көрүңүз"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Тейлөө кадамдарын көрүңүз"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Түзмөктү сууруп коюңуз"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Эскертме жазуу"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Эскертме жазуу (<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>)"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Аудиону бөлүшүү"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Кеңири таратуу"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда кабарлоо токтотулсунбу?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Эгер <xliff:g id="SWITCHAPP">%1$s</xliff:g> колдонмосунда кабарласаңыз же аудионун чыгуусун өзгөртсөңүз, учурдагы кабарлоо токтотулат"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 4c1bd4eb0d14..1ca3b2fee9bc 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ເພີ່ມວິດເຈັດເພີ່ມເຕີມ"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ກົດຄ້າງໄວ້ເພື່ອປັບແຕ່ງວິດເຈັດ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ປັບແຕ່ງວິດເຈັດ"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ແກ້ໄຂວິດເຈັດ"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ລຶບອອກ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ເພີ່ມວິດເຈັດ"</string> @@ -573,11 +575,14 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"ເຕືອນດ້ວຍສຽງ"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ສັ່ນເຕືອນ"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"ປິດ"</string> + <string name="media_device_cast" msgid="4786241789687569892">"ສົ່ງສັນຍານ"</string> + <string name="stream_notification_unavailable" msgid="4313854556205836435">"ບໍ່ມີໃຫ້ໃຊ້ເນື່ອງຈາກມີການປິດສຽງໂທເຂົ້າ"</string> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. ແຕະເພື່ອເຊົາປິດສຽງ."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. ແຕະເພື່ອຕັ້ງເປັນສັ່ນ. ບໍລິການຊ່ວຍເຂົ້າເຖິງອາດຖືກປິດສຽງໄວ້."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. ແຕະເພື່ອປິດສຽງ. ບໍລິການຊ່ວຍເຂົ້າເຖິງອາດຖືກປິດສຽງໄວ້."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. ແຕະເພື່ອຕັ້ງເປັນສັ່ນເຕືອນ."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. ແຕະເພື່ອປິດສຽງ."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ການຄວບຄຸມສຽງລົບກວນ"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"ແຕະເພື່ອປ່ຽນໂໝດຣິງເກີ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ປິດສຽງ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ເຊົາປິດສຽງ"</string> @@ -832,6 +837,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ເມນູເປີດປິດ"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ໜ້າຈໍລັອກ"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ເບິ່ງຂັ້ນຕອນການເບິ່ງແຍງ"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ເບິ່ງຂັ້ນຕອນການເບິ່ງແຍງ"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"ຖອດອຸປະກອນຂອງທ່ານອອກ"</string> @@ -1186,6 +1195,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"ການຈົດບັນທຶກ"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"ການຈົດບັນທຶກ <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ກຳລັງແບ່ງປັນສຽງ"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ກຳລັງອອກອາກາດ"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ຢຸດການອອກອາກາດ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ຫາກທ່ານອອກອາກາດ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ຫຼື ປ່ຽນເອົ້າພຸດ, ການອອກອາກາດປັດຈຸບັນຂອງທ່ານຈະຢຸດ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 9a261e05f709..eac5ee48ead1 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pridėkite daugiau valdiklių"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Ilgai paspauskite, kad tinkintumėte valdiklius"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tinkinti valdiklius"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Redaguoti valdiklį"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Pašalinti"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Pridėti valdiklį"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Skambinti"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibruoti"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Nutildyti"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Palieskite, kad įjungtumėte garsą."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Palieskite, kad nustatytumėte vibravimą. Gali būti nutildytos pritaikymo neįgaliesiems paslaugos."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Palieskite, kad nutildytumėte. Gali būti nutildytos pritaikymo neįgaliesiems paslaugos."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Palieskite, kad nustatytumėte vibravimą."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Palieskite, kad nutildytumėte."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Triukšmo valdymas"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Palieskite, kad pakeistumėte skambučio režimą"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"nutildyti"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"įjungti garsą"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Įjungimo meniu"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g> psl. iš <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Užrakinimo ekranas"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Žr. priežiūros veiksmus"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Žr. priežiūros veiksmus"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Atjunkite įrenginį"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Užrašų kūrimas"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Užrašų kūrimas, „<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>“"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Bendrinamas garsas"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transliavimas"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Sustabdyti „<xliff:g id="APP_NAME">%1$s</xliff:g>“ transliaciją?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jei transliuosite „<xliff:g id="SWITCHAPP">%1$s</xliff:g>“ arba pakeisite išvestį, dabartinė transliacija bus sustabdyta"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index a9a1a3c366a4..f69afb93a854 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pievienot citus logrīkus"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nospiediet un turiet, lai pielāgotu logrīkus."</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pielāgot logrīkus"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Rediģēt logrīku"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Noņemt"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Pievienot logrīku"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zvanīt"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrēt"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Izslēgt skaņu"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Pieskarieties, lai ieslēgtu skaņu."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Pieskarieties, lai iestatītu uz vibrozvanu. Var tikt izslēgti pieejamības pakalpojumu signāli."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Pieskarieties, lai izslēgtu skaņu. Var tikt izslēgti pieejamības pakalpojumu signāli."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Pieskarieties, lai iestatītu vibrozvanu."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Pieskarieties, lai izslēgtu skaņu."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Trokšņu kontrole"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Pieskarieties, lai mainītu zvanītāja režīmu."</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izslēgt skaņu"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ieslēgt skaņu"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Barošanas izvēlne"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. lpp. no <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Bloķēšanas ekrāns"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Skatīt apkopes norādījumus"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Skatīt apkopes norādījumus"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Atvienojiet savu ierīci"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Piezīmju pierakstīšana"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Piezīmju pierakstīšana, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Notiek audio kopīgošana"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Notiek apraidīšana"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vai apturēt lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> apraidīšanu?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ja sāksiet lietotnes <xliff:g id="SWITCHAPP">%1$s</xliff:g> apraidīšanu vai mainīsiet izvadi, pašreizējā apraide tiks apturēta"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 20a93f7df6cf..b244fe9343bb 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додајте повеќе виџети"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Притиснете долго за да ги приспособите виџетите"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Приспособете ги виџетите"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Изменување виџети"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Отстранува"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Додајте виџет"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ѕвони"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрации"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Исклучи звук"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Допрете за да вклучите звук."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Допрете за да поставите на вибрации. Можеби ќе се исклучи звукот на услугите за достапност."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Допрете за да исклучите звук. Можеби ќе се исклучи звукот на услугите за достапност."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Допрете за да се постави на вибрации."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Допрете за да се исклучи звукот."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контрола на бучавата"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Допрете за да го промените режимот на ѕвончето"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"исклучен звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"вклучен звук"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Мени на копчето за вклучување"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> од <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Заклучен екран"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Прикажи ги чекорите за грижа за уредот"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Прикажи ги чекорите за грижа за уредот"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Исклучете го уредот од кабел"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Фаќање белешки"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Фаќање белешки, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Се споделува аудио"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитување"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Да се прекине емитувањето на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитувате на <xliff:g id="SWITCHAPP">%1$s</xliff:g> или го промените излезот, тековното емитување ќе запре"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index fc2bc47b64dc..8678b663a089 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"കൂടുതൽ വിജറ്റുകൾ ചേർക്കുക"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കാൻ ദീർഘനേരം അമർത്തുക"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കുക"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"വിജറ്റ് എഡിറ്റ് ചെയ്യുക"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"നീക്കം ചെയ്യുക"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"വിജറ്റ് ചേർക്കുക"</string> @@ -573,11 +575,14 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"റിംഗ് ചെയ്യുക"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"വൈബ്രേറ്റ് ചെയ്യുക"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"മ്യൂട്ട് ചെയ്യുക"</string> + <string name="media_device_cast" msgid="4786241789687569892">"കാസ്റ്റ് ചെയ്യുക"</string> + <string name="stream_notification_unavailable" msgid="4313854556205836435">"റിംഗ് മ്യൂട്ട് ചെയ്തതിനാൽ ലഭ്യമല്ല"</string> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. അൺമ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. വൈബ്രേറ്റിലേക്ക് സജ്ജമാക്കുന്നതിന് ടാപ്പുചെയ്യുക. ഉപയോഗസഹായി സേവനങ്ങൾ മ്യൂട്ടുചെയ്യപ്പെട്ടേക്കാം."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. മ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക. ഉപയോഗസഹായി സേവനങ്ങൾ മ്യൂട്ടുചെയ്യപ്പെട്ടേക്കാം."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s വൈബ്രേറ്റിലേക്ക് സജ്ജമാക്കുന്നതിന് ടാപ്പുചെയ്യുക."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s മ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"നോയ്സ് നിയന്ത്രണം"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"റിംഗർ മോഡ് മാറ്റാൻ ടാപ്പ് ചെയ്യുക"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"മ്യൂട്ട് ചെയ്യുക"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"അൺമ്യൂട്ട് ചെയ്യുക"</string> @@ -832,6 +837,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"പവർ മെനു"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"പേജ് <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ലോക്ക് സ്ക്രീൻ"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"പരിപാലന നിർദ്ദേശങ്ങൾ കാണുക"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"പരിപാലന നിർദ്ദേശങ്ങൾ കാണുക"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"ഉപകരണം അൺപ്ലഗ് ചെയ്യുക"</string> @@ -1186,6 +1195,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"കുറിപ്പ് രേഖപ്പെടുത്തൽ"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"കുറിപ്പ് രേഖപ്പെടുത്തൽ, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ഓഡിയോ പങ്കിടുന്നു"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"പ്രക്ഷേപണം ചെയ്യുന്നു"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബ്രോഡ്കാസ്റ്റ് ചെയ്യുന്നത് അവസാനിപ്പിക്കണോ?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"നിങ്ങൾ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ബ്രോഡ്കാസ്റ്റ് ചെയ്യുകയോ ഔട്ട്പുട്ട് മാറ്റുകയോ ചെയ്താൽ നിങ്ങളുടെ നിലവിലുള്ള ബ്രോഡ്കാസ്റ്റ് അവസാനിക്കും"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index f5bf05a4d671..8aafee3341de 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Илүү олон виджет нэмэх"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджетүүдийг өөрчлөхийн тулд удаан дарна уу"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджетүүдийг өөрчлөх"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Виджетийг засах"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Хасах"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Виджет нэмэх"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Хонх дуугаргах"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Чичиргэх"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Хаах"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Дууг нь нээхийн тулд товшино уу."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Чичиргээнд тохируулахын тулд товшино уу. Хүртээмжийн үйлчилгээний дууг хаасан."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Дууг нь хаахын тулд товшино уу. Хүртээмжийн үйлчилгээний дууг хаасан."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Чичиргээнд тохируулахын тулд товшино уу."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Дууг хаахын тулд товшино уу."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Шуугианы хяналт"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Хонхны горимыг өөрчлөхийн тулд товшино уу"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"дууг хаах"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"дууг нээх"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Асаах/унтраах цэс"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>-н <xliff:g id="ID_1">%1$d</xliff:g>-р хуудас"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Түгжээтэй дэлгэц"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Хянамж болгоомжийн алхмыг харах"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Хянамж болгоомжийн алхмыг харах"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Төхөөрөмжөө салгана уу"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Тэмдэглэл хөтлөх"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Тэмдэглэл хөтлөх, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Аудио хуваалцаж байна"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Нэвтрүүлэлт"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г нэвтрүүлэхээ зогсоох уу?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Хэрэв та <xliff:g id="SWITCHAPP">%1$s</xliff:g>-г нэвтрүүлсэн эсвэл гаралтыг өөрчилсөн бол таны одоогийн нэвтрүүлэлтийг зогсооно"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index f9d4aca9efcd..e781b45803ef 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"आणखी विजेट जोडा"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेट कस्टमाइझ करण्यासाठी प्रेस करून ठेवा"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेट कस्टमाइझ करा"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"विजेट संपादित करा"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"काढून टाका"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"विजेट जोडा"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"रिंग करा"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"व्हायब्रेट"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"म्यूट करा"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. अनम्यूट करण्यासाठी टॅप करा."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. व्हायब्रेट सेट करण्यासाठी टॅप करा. प्रवेशयोग्यता सेवा म्यूट केल्या जाऊ शकतात."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. म्यूट करण्यासाठी टॅप करा. प्रवेशक्षमता सेवा म्यूट केल्या जाऊ शकतात."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. व्हायब्रेट सेट करण्यासाठी टॅप करा."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. म्यूट करण्यासाठी टॅप करा."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"नॉइझ कंट्रोल"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलण्यासाठी टॅप करा"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करा"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"म्यूट काढून टाका"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पॉवर मेनू"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> पैकी <xliff:g id="ID_1">%1$d</xliff:g> पेज"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"लॉक स्क्रीन"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"काय काळजी घ्यावी ते पहा"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"काय काळजी घ्यावी ते पहा"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"तुमचे डिव्हाइस अनप्लग करा"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"नोंद घेणे"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"नोंद घेणे, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ऑडिओ शेअर करत आहे"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ब्रॉडकास्ट करत आहे"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> चे प्रसारण थांबवायचे आहे का?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तुम्ही <xliff:g id="SWITCHAPP">%1$s</xliff:g> चे प्रसारण केल्यास किंवा आउटपुट बदलल्यास, तुमचे सध्याचे प्रसारण बंद होईल"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index dafcfe009769..03cd0a0fab13 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tambahkan lagi widget"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Alih keluar"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Tambahkan widget"</string> @@ -573,11 +575,14 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Dering"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Getar"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Redam"</string> + <string name="media_device_cast" msgid="4786241789687569892">"Hantar"</string> + <string name="stream_notification_unavailable" msgid="4313854556205836435">"Tidak tersedia kerana deringan diredam"</string> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Ketik untuk menyahredam."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Ketik untuk menetapkan pada getar. Perkhidmatan kebolehaksesan mungkin diredamkan."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ketik untuk meredam. Perkhidmatan kebolehaksesan mungkin diredamkan."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Ketik untuk menetapkan pada getar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ketik untuk meredam."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kawalan Hingar"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Ketik untuk menukar mod pendering"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"redam"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"nyahredam"</string> @@ -832,6 +837,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu kuasa"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> daripada <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Kunci skrin"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Lihat langkah penjagaan"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Lihat langkah penjagaan"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Cabut palam peranti anda"</string> @@ -1186,6 +1195,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Pengambilan nota"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Pengambilan nota, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Perkongsian audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Menyiarkan"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Hentikan siaran <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jika anda siarkan <xliff:g id="SWITCHAPP">%1$s</xliff:g> atau tukarkan output, siaran semasa anda akan berhenti"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index e52b899870d2..c408118e48ce 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"နောက်ထပ်ဝိဂျက်များ ထည့်ရန်"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ဝိဂျက်များ စိတ်ကြိုက်လုပ်ရန် ကြာကြာနှိပ်ထားပါ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ဝိဂျက်များကို စိတ်ကြိုက်လုပ်ရန်"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ဝိဂျက်ပြင်ရန်"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ဖယ်ရှားရန်"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ဝိဂျက်ထည့်ရန်"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"အသံမြည်သည်"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"တုန်ခါသည်"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"အသံတိတ်သည်"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s။ အသံပြန်ဖွင့်ရန် တို့ပါ။"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s။ တုန်ခါမှုကို သတ်မှတ်ရန် တို့ပါ။ အများသုံးနိုင်မှု ဝန်ဆောင်မှုများကို အသံပိတ်ထားနိုင်ပါသည်။"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s။ အသံပိတ်ရန် တို့ပါ။ အများသုံးနိုင်မှု ဝန်ဆောင်မှုများကို အသံပိတ်ထားနိုင်ပါသည်။"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s။ တုန်ခါခြင်းသို့ သတ်မှတ်ရန်တို့ပါ။"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s။ အသံပိတ်ရန် တို့ပါ။"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ဆူညံသံ ထိန်းချုပ်ရန်"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"ဖုန်းခေါ်သံမုဒ်သို့ ပြောင်းရန် တို့ပါ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"အသံပိတ်ရန်"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"အသံဖွင့်ရန်"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ပါဝါမီနူး"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"စာမျက်နှာ <xliff:g id="ID_2">%2$d</xliff:g> အနက်မှ စာမျက်နှာ <xliff:g id="ID_1">%1$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"လော့ခ်ချထားချိန် မျက်နှာပြင်"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ဂရုပြုစရာ အဆင့်များ ကြည့်ရန်"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ဂရုပြုစရာ အဆင့်များ ကြည့်ရန်"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"သင့်စက်ကို ပလတ်ဖြုတ်ပါ"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>၊ <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"မှတ်စုလိုက်ခြင်း"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"မှတ်စုလိုက်ခြင်း၊ <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"အသံမျှဝေခြင်း"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ထုတ်လွှင့်ခြင်း"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ထုတ်လွှင့်ခြင်းကို ရပ်မလား။"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> ကို ထုတ်လွှင့်သောအခါ (သို့) အထွက်ကို ပြောင်းသောအခါ သင့်လက်ရှိထုတ်လွှင့်ခြင်း ရပ်သွားမည်"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index ed6e2931ed5f..2ce016ac586f 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Legg til flere moduler"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Trykk lenge for å tilpasse modulene"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tilpass moduler"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Endre modul"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Fjern"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Legg til modul"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrer"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Ignorer"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Trykk for å slå på lyden."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Trykk for å angi vibrasjon. Lyden kan bli slått av for tilgjengelighetstjenestene."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Trykk for å slå av lyden. Lyden kan bli slått av for tilgjengelighetstjenestene."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Trykk for å angi vibrasjon."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Trykk for å slå av lyden."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Støykontroll"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Trykk for å endre ringemodus"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"kutt lyden"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på lyden"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Av/på-meny"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Side <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Låseskjerm"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Se vedlikeholdstrinnene"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Se vedlikeholdstrinnene"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Koble fra enheten"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Notatskriving"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Notatskriving, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Deler lyd"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Kringkaster"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vil du stoppe kringkastingen av <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Hvis du kringkaster <xliff:g id="SWITCHAPP">%1$s</xliff:g> eller endrer utgangen, stopper den nåværende kringkastingen din"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index fb7680daf152..0096f480f67e 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"थप विजेटहरू हाल्नुहोस्"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेटहरू कस्टमाइज गर्न केही बेरसम्म थिच्नुहोस्"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेटहरू कस्टमाइज गर्नुहोस्"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"विजेट सम्पादन गर्नुहोस्"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"हटाउनुहोस्"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"विजेट हाल्नुहोस्"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"घन्टी"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"कम्पन"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"म्युट गर्नुहोस्"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s। अनम्यूट गर्नाका लागि ट्याप गर्नुहोस्।"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s। कम्पनमा सेट गर्नाका लागि ट्याप गर्नुहोस्। पहुँच सम्बन्धी सेवाहरू म्यूट हुन सक्छन्।"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। म्यूट गर्नाका लागि ट्याप गर्नुहोस्। पहुँच सम्बन्धी सेवाहरू म्यूट हुन सक्छन्।"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। कम्पन मोडमा सेट गर्न ट्याप गर्नुहोस्।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। म्यूट गर्न ट्याप गर्नुहोस्।"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"नोइज कन्ट्रोल"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"रिङ्गर मोड बदल्न ट्याप गर्नुहोस्"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्युट गर्नुहोस्"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्युट गर्नुहोस्"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"पावर मेनु"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> मध्ये पृष्ठ <xliff:g id="ID_1">%1$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"लक स्क्रिन"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"डिभाइसको हेरचाह गर्ने तरिका हेर्नुहोस्"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"डिभाइसको हेरचाह गर्ने तरिका हेर्नुहोस्"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"डिभाइस बिजुलीको स्रोतबाट निकाल्नुहोस्"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"नोट लेख्ने कार्य"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"नोट लेख्ने कार्य, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"अडियो सेयर गरिँदै छ"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"प्रसारण गरिँदै छ"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ब्रोडकास्ट गर्न छाड्ने हो?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"तपाईंले <xliff:g id="SWITCHAPP">%1$s</xliff:g> ब्रोडकास्ट गर्नुभयो वा आउटपुट परिवर्तन गर्नुभयो भने तपाईंको हालको ब्रोडकास्ट रोकिने छ"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index a649617a5559..723b9096cfcf 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Meer widgets toevoegen"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Houd lang ingedrukt om widgets aan te passen"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widgets aanpassen"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Widget bewerken"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Verwijderen"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Widget toevoegen"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Bellen"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Trillen"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Geluid staat uit"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tik om dempen op te heffen."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tik om in te stellen op trillen. Het geluid van toegankelijkheidsservices kan hierdoor uitgaan."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tik om te dempen. Het geluid van toegankelijkheidsservices kan hierdoor uitgaan."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tik om in te stellen op trillen."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tik om geluid uit te zetten."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Ruisonderdrukking"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tik om de beltoonmodus te wijzigen"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"geluid uit"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"geluid aanzetten"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Aan/uit-menu"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Vergrendelscherm"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Onderhoudsstappen bekijken"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Onderhoudsstappen bekijken"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Je apparaat loskoppelen"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Aantekeningen maken"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Aantekeningen maken, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Audio delen"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Uitzending"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Uitzending van <xliff:g id="APP_NAME">%1$s</xliff:g> stopzetten?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Als je <xliff:g id="SWITCHAPP">%1$s</xliff:g> uitzendt of de uitvoer wijzigt, wordt je huidige uitzending gestopt"</string> @@ -1236,9 +1248,9 @@ <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standaard notitie-app instellen in Instellingen"</string> <string name="install_app" msgid="5066668100199613936">"App installeren"</string> <string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"Swipe omhoog om door te gaan"</string> - <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Spiegelen naar extern scherm?"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirroren naar extern scherm?"</string> <string name="connected_display_dialog_dual_display_stop_warning" msgid="4174707498892447947">"Het scherm aan de binnenkant wordt gemirrord. Het scherm aan de voorkant wordt uitgezet."</string> - <string name="mirror_display" msgid="2515262008898122928">"Scherm spiegelen"</string> + <string name="mirror_display" msgid="2515262008898122928">"Scherm mirroren"</string> <string name="dismiss_dialog" msgid="2195508495854675882">"Sluiten"</string> <string name="connected_display_icon_desc" msgid="6373560639989971997">"Scherm verbonden"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microfoon en camera"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index b0f5022c9c17..612e012a2546 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ଅଧିକ ୱିଜେଟ ଯୋଗ କରନ୍ତୁ"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରିବା ପାଇଁ ଅଧିକ ସମୟ ଦବାନ୍ତୁ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ୱିଜେଟକୁ ଏଡିଟ କରନ୍ତୁ"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"କାଢ଼ି ଦିଅନ୍ତୁ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ୱିଜେଟ ଯୋଗ କରନ୍ତୁ"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"ରିଙ୍ଗ"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ଭାଇବ୍ରେଟ୍"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"ମ୍ୟୁଟ"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s। ଅନମ୍ୟୁଟ୍ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s। ଭାଇବ୍ରେଟ୍ ସେଟ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ। ଆକ୍ସେସିବିଲିଟୀ ସର୍ଭିସ୍ ମ୍ୟୁଟ୍ କରାଯାଇପାରେ।"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। ମ୍ୟୁଟ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ। ଆକ୍ସେସିବିଲିଟୀ ସର୍ଭିସ୍ ମ୍ୟୁଟ୍ କରାଯାଇପାରେ।"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। ଭାଇବ୍ରେଟରେ ସେଟ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। ମ୍ୟୁଟ୍ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ନଏଜ କଣ୍ଟ୍ରୋଲ"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"ରିଙ୍ଗର୍ ମୋଡ୍ ବଦଳାଇବାକୁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ମ୍ୟୁଟ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ଅନ୍-ମ୍ୟୁଟ୍ କରନ୍ତୁ"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ପାୱାର ମେନୁ"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"ପୃଷ୍ଠା <xliff:g id="ID_1">%1$d</xliff:g> ମୋଟ <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"ଲକ ସ୍କ୍ରିନ"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ଯତ୍ନ ନେବା ପାଇଁ ଷ୍ଟେପଗୁଡ଼ିକ ଦେଖନ୍ତୁ"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ଯତ୍ନ ନେବା ପାଇଁ ଷ୍ଟେପଗୁଡ଼ିକ ଦେଖନ୍ତୁ"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"ଆପଣଙ୍କ ଡିଭାଇସକୁ ଅନପ୍ଲଗ କରନ୍ତୁ"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"ନୋଟ-ଟେକିଂ"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"ନୋଟ-ଟେକିଂ, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ଅଡିଓ ସେୟାର କରାଯାଉଛି"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ବ୍ରଡକାଷ୍ଟ କରୁଛି"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ଯଦି ଆପଣ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ବ୍ରଡକାଷ୍ଟ କରନ୍ତି କିମ୍ବା ଆଉଟପୁଟ ବଦଳାନ୍ତି, ତେବେ ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ବ୍ରଡକାଷ୍ଟ ବନ୍ଦ ହୋଇଯିବ"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 6916fd2b3be9..c02641329304 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ਹੋਰ ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰੋ"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ਵਿਜੇਟਾਂ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਦਬਾਈ ਰੱਖੋ"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ਵਿਜੇਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ਵਿਜੇਟ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ਹਟਾਓ"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰੋ"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"ਘੰਟੀ"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"ਥਰਥਰਾਹਟ"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"ਮਿਊਟ"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s। ਅਣਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s। ਥਰਥਰਾਹਟ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। ਥਰਥਰਾਹਟ \'ਤੇ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ਸ਼ੋਰ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"ਰਿੰਗਰ ਮੋਡ ਨੂੰ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ਮਿਊਟ ਕਰੋ"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ਅਣਮਿਊਟ ਕਰੋ"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"ਪਾਵਰ ਮੀਨੂ"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> ਦਾ <xliff:g id="ID_1">%1$d</xliff:g> ਪੰਨਾ"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">" ਲਾਕ ਸਕ੍ਰੀਨ"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ਦੇਖਭਾਲ ਦੇ ਪੜਾਅ ਦੇਖੋ"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ਦੇਖਭਾਲ ਦੇ ਪੜਾਅ ਦੇਖੋ"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"ਆਪਣਾ ਡੀਵਾਈਸ ਅਣਪਲੱਗ ਕਰੋ"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"ਨੋਟ ਬਣਾਉਣਾ"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"ਨੋਟ ਬਣਾਉਣਾ, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ਆਡੀਓ ਨੂੰ ਸਾਂਝਾ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ਪ੍ਰਸਾਰਨ"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਦੇ ਪ੍ਰਸਾਰਨ ਨੂੰ ਰੋਕਣਾ ਹੈ?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ਜੇ ਤੁਸੀਂ <xliff:g id="SWITCHAPP">%1$s</xliff:g> ਦਾ ਪ੍ਰਸਾਰਨ ਕਰਦੇ ਹੋ ਜਾਂ ਆਊਟਪੁੱਟ ਬਦਲਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਪ੍ਰਸਾਰਨ ਰੁਕ ਜਾਵੇਗਾ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index c04d6dae6e0d..44639b990e48 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodaj więcej widżetów"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Przytrzymaj, aby dostosować widżety"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Dostosuj widżety"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Edytuj widżet"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Usuń"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodaj widżet"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Dzwonek"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Wibracje"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Wyciszenie"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Kliknij, by wyłączyć wyciszenie."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Kliknij, by włączyć wibracje. Ułatwienia dostępu mogą być wyciszone."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Kliknij, by wyciszyć. Ułatwienia dostępu mogą być wyciszone."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Kliknij, by włączyć wibracje."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Kliknij, by wyciszyć."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Tłumienie szumów"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Kliknij, aby zmienić tryb dzwonka"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"wycisz"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"wyłącz wyciszenie"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu zasilania"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Strona <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran blokady"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Zobacz instrukcję postępowania"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Zobacz instrukcję postępowania"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Odłącz urządzenie"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Notatki"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Notatki, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Udostępnia dźwięk"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmisja"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Zatrzymaj transmisję aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Jeśli transmitujesz aplikację <xliff:g id="SWITCHAPP">%1$s</xliff:g> lub zmieniasz dane wyjściowe, Twoja obecna transmisja zostanie zakończona"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index e82a1032dbc6..639a488c5226 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicione mais widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remover"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adicionar widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Tocar"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Desativar som"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toque para ativar o som."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toque para configurar para vibrar. É possível que os serviços de acessibilidade sejam silenciados."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toque para silenciar. É possível que os serviços de acessibilidade sejam silenciados."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toque para configurar para vibrar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toque para silenciar."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Controle de ruído"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Toque para mudar o modo da campainha"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu liga/desliga"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Tela de bloqueio"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver etapas de cuidado"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver etapas de cuidado"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desconecte seu dispositivo"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Anotações"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Anotações, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Compartilhando áudio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitindo"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 8ba907b4ee41..f34dea1dfbf2 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicionar mais widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha premido para personalizar os widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remover"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adicionar widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Toque"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Desativar som"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toque para reativar o som."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toque para ativar a vibração. Os serviços de acessibilidade podem ser silenciados."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toque para desativar o som. Os serviços de acessibilidade podem ser silenciados."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toque para ativar a vibração."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toque para desativar o som."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Controlo de ruído"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Toque para alterar o modo de campainha"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar som"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"reativar som"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu ligar/desligar"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Ecrã de bloqueio"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Veja os passos de manutenção"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Veja os passos de manutenção"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desligue o dispositivo"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Tomar notas"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Tomar notas, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"A partilhar áudio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"A transmitir"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão da app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se transmitir a app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou alterar a saída, a sua transmissão atual é interrompida"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index e82a1032dbc6..639a488c5226 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicione mais widgets"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar widgets"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Remover"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adicionar widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Tocar"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Desativar som"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toque para ativar o som."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toque para configurar para vibrar. É possível que os serviços de acessibilidade sejam silenciados."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toque para silenciar. É possível que os serviços de acessibilidade sejam silenciados."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Toque para configurar para vibrar."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Toque para silenciar."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Controle de ruído"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Toque para mudar o modo da campainha"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"desativar o som"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ativar o som"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menu liga/desliga"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Tela de bloqueio"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Ver etapas de cuidado"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Ver etapas de cuidado"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Desconecte seu dispositivo"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Anotações"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Anotações, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Compartilhando áudio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Transmitindo"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Interromper a transmissão do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Se você transmitir o app <xliff:g id="SWITCHAPP">%1$s</xliff:g> ou mudar a saída, a transmissão atual será interrompida"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 8cd2d77f9efb..7d8c2a31751c 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adaugă mai multe widgeturi"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Apasă lung pentru a personaliza widgeturi"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizează widgeturile"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Editează widgetul"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Elimină"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adaugă un widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Sonerie"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrații"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Blochează"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Atinge pentru a activa sunetul."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Atinge pentru a seta vibrarea. Sunetul se poate dezactiva pentru serviciile de accesibilitate."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Atinge pentru a dezactiva sunetul. Sunetul se poate dezactiva pentru serviciile de accesibilitate."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Atinge pentru a seta pe vibrații."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Atinge pentru a dezactiva sunetul."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Controlul zgomotului"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Atinge pentru a schimba modul soneriei"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"dezactivează sunetul"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"activează sunetul"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meniul de pornire"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> din <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Ecran de blocare"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Vezi pașii pentru îngrijire"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Vezi pașii pentru îngrijire"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Deconectează dispozitivul"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Luare de notițe"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Luare de notițe, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Se permite accesul la conținutul audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Se difuzează"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Oprești transmisia <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Dacă transmiți <xliff:g id="SWITCHAPP">%1$s</xliff:g> sau schimbi ieșirea, transmisia actuală se va opri"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 614eb0617fb4..37b7ae5f7b3d 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Добавить виджеты"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Нажмите и удерживайте, чтобы настроить виджеты."</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Настроить виджеты"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Изменить виджет"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Удалить"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Добавить виджет"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Со звуком"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрация"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Без звука"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Нажмите, чтобы включить звук."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Нажмите, чтобы включить вибрацию. Специальные возможности могут прекратить работу."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Нажмите, чтобы выключить звук. Специальные возможности могут прекратить работу."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Нажмите, чтобы включить вибрацию."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Нажмите, чтобы выключить звук."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контроль уровня шума"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Нажмите, чтобы изменить режим звонка."</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"отключить звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"включить звук"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопки питания"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Страница <xliff:g id="ID_1">%1$d</xliff:g> из <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Заблокированный экран"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Подробнее о действиях при перегреве…"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Подробнее о действиях при перегреве…"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Отключите устройство"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Создание заметок"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>: создание заметок"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Передает аудио"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляция"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Остановить трансляцию \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Если вы начнете транслировать \"<xliff:g id="SWITCHAPP">%1$s</xliff:g>\" или смените целевое устройство, текущая трансляция прервется."</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index d1bcee422bd4..c851f8583f0d 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"තවත් විජට් එක් කරන්න"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"විජට් අභිරුචිකරණය කිරීමට දිගු ඔබන්න"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"විජට්ටු අභිරුචි කරන්න"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"විජට්ටු සංස්කරණ කරන්න"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ඉවත් කරන්න"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"විජට්ටුව එක් කරන්න"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"නාද කරන්න"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"කම්පනය කරන්න"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"නිහඬ කරන්න"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. නිහඬ කිරීම ඉවත් කිරීමට තට්ටු කරන්න."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. කම්පනය කිරීමට තට්ටු කරන්න. ප්රවේශ්යතා සේවා නිහඬ කළ හැකිය."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. නිහඬ කිරීමට තට්ටු කරන්න. ප්රවේශ්යතා සේවා නිහඬ කළ හැකිය."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. කම්පනය කිරීමට සකස් කිරීමට තට්ටු කරන්න."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. නිහඬ කිරීමට තට්ටු කරන්න."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ඝෝෂාව පාලනය"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"නාදකය වෙනස් කිරීමට තට්ටු කරන්න"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"නිහඬ කරන්න"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"නිශ්ශබ්දතාවය ඉවත් කරන්න"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"බල මෙනුව"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g> න් <xliff:g id="ID_1">%1$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"අගුලු තිරය"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"රැකවරණ පියවර බලන්න"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"රැකවරණ පියවර බලන්න"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"ඔබේ උපාංගය ගලවන්න"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"සටහන් කර ගැනීම"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"සටහන් කර ගැනීම, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ශ්රව්ය බෙදා ගැනීම"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"විකාශනය කරමින්"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> විකාශනය කිරීම නවත්වන්නද?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"ඔබ <xliff:g id="SWITCHAPP">%1$s</xliff:g> විකාශනය කළහොත් හෝ ප්රතිදානය වෙනස් කළහොත්, ඔබගේ වත්මන් විකාශනය නවතිනු ඇත."</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 3e2b554f18b2..d25e3687b589 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pridať ďalšie miniaplikácie"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Miniaplikácie prispôsobíte dlhým stlačením"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prispôsobiť miniaplikácie"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Upraviť miniaplikáciu"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Odstrániť"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Pridať miniaplikáciu"</string> @@ -530,7 +532,7 @@ <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Toto zariadenie spravuje tvoj rodič. Vidí a môže spravovať informácie, napríklad aplikácie, ktoré používaš, tvoju polohu a čas používania."</string> <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string> <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Odomknutie udržiava TrustAgent"</string> - <string name="kg_prompt_after_adaptive_auth_lock" msgid="1265107698772588299">"Ochrana pred krádež.\nZar. uzamknuté, priveľa pokusov o odomk."</string> + <string name="kg_prompt_after_adaptive_auth_lock" msgid="1265107698772588299">"Ochrana pred krádežou\nUzamknuté, priveľa pokusov o odomknutie"</string> <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> <string name="accessibility_volume_settings" msgid="1458961116951564784">"Nastavenia zvuku"</string> <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatické titulkovanie médií"</string> @@ -573,19 +575,24 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Prezvoniť"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrovať"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Vypnúť zvuk"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Klepnutím zapnite zvuk."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Klepnutím aktivujte režim vibrovania. Služby dostupnosti je možné stlmiť."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Klepnutím vypnite zvuk. Služby dostupnosti je možné stlmiť."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Klepnutím nastavíte vibrovanie."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Klepnutím vypnete zvuk."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Ovládanie šumu"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Režim zvonenia zmeníte klepnutím"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnite zvuk"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"zapnite zvuk"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"zapnite vibrovanie"</string> <string name="volume_dialog_title" msgid="6502703403483577940">"Ovládacie prvky hlasitosti %s"</string> <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"Hovory a upozornenia spustia zvonenie (<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string> - <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> sa prehráva v zar."</string> - <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk prehrá zariad.:"</string> + <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> sa prehráva v:"</string> + <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk sa prehrá v:"</string> <string name="system_ui_tuner" msgid="1471348823289954729">"Tuner používateľského rozhrania systému"</string> <string name="status_bar" msgid="4357390266055077437">"Stavový riadok"</string> <string name="demo_mode" msgid="263484519766901593">"Ukážka používateľského rozhrania systému"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Ponuka vypínača"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Strana <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Uzamknutá obrazovka"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Zobraziť opatrenia"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Zobraziť opatrenia"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Odpojte zariadenie"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Zapisovanie poznámok"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Zapisovanie poznámok, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Zdieľa sa zvuk"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Vysiela"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Chcete zastaviť vysielanie aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ak vysielate aplikáciu <xliff:g id="SWITCHAPP">%1$s</xliff:g> alebo zmeníte výstup, aktuálne vysielanie bude zastavené"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 1ea97a1f4b43..eb56a44aa313 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte več pripomočkov"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pridržite za prilagajanje pripomočkov"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagajanje pripomočkov"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Urejanje pripomočka"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Odstrani"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodajanje pripomočka"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zvonjenje"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibriranje"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Utišano"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Dotaknite se, če želite vklopiti zvok."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Dotaknite se, če želite nastaviti vibriranje. V storitvah za dostopnost bo morda izklopljen zvok."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dotaknite se, če želite izklopiti zvok. V storitvah za dostopnost bo morda izklopljen zvok."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dotaknite se, če želite nastaviti vibriranje."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dotaknite se, če želite izklopiti zvok."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Omejevanje hrupa"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Dotaknite se, če želite spremeniti način zvonjenja."</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izklop zvoka"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"vklop zvoka"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Meni za vklop/izklop"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. stran od <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Zaklenjen zaslon"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Oglejte si navodila za ukrepanje"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Oglejte si navodila za ukrepanje"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Odklopite napravo"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Ustvarjanje zapiskov"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Ustvarjanje zapiskov, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Deljenje zvoka"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Oddajanje"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Želite ustaviti oddajanje aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Če oddajate aplikacijo <xliff:g id="SWITCHAPP">%1$s</xliff:g> ali spremenite izhod, bo trenutno oddajanje ustavljeno."</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index c3ccd81e6f62..eb8fa4372d2e 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Shto miniaplikacione të tjera"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Shtyp gjatë për të personalizuar miniaplikacionet"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizo miniaplikacionet"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Modifiko miniaplikacionin"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Hiq"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Shto miniaplikacionin"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Bjeri ziles"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Dridhje"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Pa zë"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Trokit për të aktivizuar."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Trokit për ta caktuar te dridhja. Shërbimet e qasshmërisë mund të çaktivizohen."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Trokit për të çaktivizuar. Shërbimet e qasshmërisë mund të çaktivizohen."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Trokit për ta vendosur në dridhje."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Trokit për ta çaktivizuar."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrolli i zhurmës"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Trokit për të ndryshuar modalitetin e ziles"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"çaktivizo audion"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"aktivizo audion"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menyja e energjisë"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Faqja <xliff:g id="ID_1">%1$d</xliff:g> nga <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekrani i kyçjes"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Shiko hapat për kujdesin"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Shiko hapat për kujdesin"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Shkëpute pajisjen"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Mbajtja e shënimeve"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Mbajtja e shënimeve, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Po ndahet audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Po transmeton"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Të ndalohet transmetimi i <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nëse transmeton <xliff:g id="SWITCHAPP">%1$s</xliff:g> ose ndryshon daljen, transmetimi yt aktual do të ndalojë"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 2309d7de205c..0644a8095675 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додајте још виџета"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Дуги притисак за прилагођавање виџета"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Прилагоди виџете"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Измени виџет"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Уклони"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Додај виџет"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Активирај звоно"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрирај"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Искључи звук"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Додирните да бисте укључили звук."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Додирните да бисте подесили на вибрацију. Звук услуга приступачности ће можда бити искључен."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Додирните да бисте искључили звук. Звук услуга приступачности ће можда бити искључен."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Додирните да бисте подесили на вибрацију."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Додирните да бисте искључили звук."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контрола шума"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Додирните да бисте променили режим звона"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"искључите звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"укључите звук"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Мени дугмета за укључивање"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>. страна од <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Закључан екран"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Погледајте упозорења"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Погледајте упозорења"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Искључите уређај"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Прављење бележака"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Прављење бележака, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Дели се звук"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Емитовање"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Желите да зауставите емитовање апликације <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ако емитујете апликацију <xliff:g id="SWITCHAPP">%1$s</xliff:g> или промените излаз, актуелно емитовање ће се зауставити"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index be80f7aefd2d..208891f4fbfa 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lägg till fler widgetar"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tryck länge för att anpassa widgetar"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Anpassa widgetar"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Redigera widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Ta bort"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Lägg till widget"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ringsignal"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibration"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Dölj"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tryck här om du vill slå på ljudet."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tryck här om du vill sätta på vibrationen. Tillgänglighetstjänster kanske inaktiveras."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tryck här om du vill stänga av ljudet. Tillgänglighetstjänsterna kanske inaktiveras."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tryck här om du vill aktivera vibrationsläget."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Tryck här om du vill stänga av ljudet."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Bruskontroll"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Tryck för att ändra ringsignalens läge"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"stänga av ljudet"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå på ljudet"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Startmeny"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sida <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Låsskärm"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Visa alla skötselråd"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Visa alla skötselråd"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Koppla ur enheten"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Anteckna"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Anteckna med <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Delar ljud"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Sänder"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Vill du sluta sända från <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Om en utsändning från <xliff:g id="SWITCHAPP">%1$s</xliff:g> pågår eller om du byter ljudutgång avbryts den nuvarande utsändningen"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 09998200c0f4..404cb487e445 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Weka wijeti zingine"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Bonyeza kwa muda mrefu uweke mapendeleo ya wijeti"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Badilisha wijeti upendavyo"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Badilisha wijeti"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Ondoa"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ongeza wijeti"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Piga"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Kutetema"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Zima sauti"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Gusa ili urejeshe."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Gusa ili uweke mtetemo. Huenda ikakomesha huduma za zana za walio na matatizo ya kuona au kusikia."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Gusa ili ukomeshe. Huenda ikakomesha huduma za zana za walio na matatizo ya kuona au kusikia."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Gusa ili uweke mtetemo."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Gusa ili usitishe."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kidhibiti cha Kelele"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Gusa ili ubadilishe hali ya programu inayotoa milio ya simu"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"zima sauti"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"washa sauti"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Menyu ya kuzima/kuwasha"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Ukurasa wa <xliff:g id="ID_1">%1$d</xliff:g> kati ya <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Skrini iliyofungwa"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Angalia hatua za utunzaji"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Angalia hatua za utunzaji"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Chomoa kifaa chako"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Kuandika madokezo"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Kuandika madokezo, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Watu wengine wanasikia sauti"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Inaarifu"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ungependa kusimamisha utangazaji kwenye <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Ikiwa unatangaza kwenye <xliff:g id="SWITCHAPP">%1$s</xliff:g> au unabadilisha maudhui, tangazo lako la sasa litasimamishwa"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 486d7f97f16e..03dd362e2b18 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"கூடுதல் விட்ஜெட்களைச் சேருங்கள்"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"விட்ஜெட்களைப் பிரத்தியேகமாக்க நீண்ட நேரம் அழுத்துக"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"விட்ஜெட்களைப் பிரத்தியேகமாக்குங்கள்"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"விட்ஜெட்டைத் திருத்து"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"அகற்றும்"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"விட்ஜெட்டைச் சேர்"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"ஒலி"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"அதிர்வு"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"அமைதி"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. ஒலி இயக்க, தட்டவும்."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. அதிர்விற்கு அமைக்க, தட்டவும். அணுகல்தன்மை சேவைகள் ஒலியடக்கப்படக்கூடும்."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. ஒலியடக்க, தட்டவும். அணுகல்தன்மை சேவைகள் ஒலியடக்கப்படக்கூடும்."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. அதிர்விற்கு அமைக்க, தட்டவும்."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. ஒலியடக்க, தட்டவும்."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"இரைச்சல் கட்டுப்பாடு"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"ரிங்கர் பயன்முறையை மாற்ற தட்டவும்"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ஒலியடக்கும்"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ஒலி இயக்கும்"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"பவர் மெனு"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"பக்கம் <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"லாக் ஸ்கிரீன்"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"மேலும் விவரங்களுக்கு இதைப் பார்க்கவும்"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"மேலும் விவரங்களுக்கு இதைப் பார்க்கவும்"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"சாதன இணைப்பைத் துண்டித்தல்"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"குறிப்பெடுத்தல்"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"குறிப்பெடுத்தல், <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ஆடியோ பகிரப்படுகிறது"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ஒலிபரப்புதல்"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் ஒலிபரப்பப்படுவதை நிறுத்தவா?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"நீங்கள் <xliff:g id="SWITCHAPP">%1$s</xliff:g> ஆப்ஸை ஒலிபரப்பினாலோ அவுட்புட்டை மாற்றினாலோ உங்களின் தற்போதைய ஒலிபரப்பு நிறுத்தப்படும்"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 227ba5a2ea4a..08067c93bead 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"మరిన్ని విడ్జెట్లను జోడించండి"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"విడ్జెట్లను అనుకూలీకరించడానికి, నొక్కి, ఉంచండి"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"విడ్జెట్లను అనుకూలంగా మార్చండి"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"విడ్జెట్ను ఎడిట్ చేయండి"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"తీసివేయండి"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"విడ్జెట్ను జోడించండి"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"రింగ్"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"వైబ్రేట్"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"మ్యూట్"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. అన్మ్యూట్ చేయడానికి నొక్కండి."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. వైబ్రేషన్కు సెట్ చేయడానికి నొక్కండి. యాక్సెస్ సామర్థ్య సేవలు మ్యూట్ చేయబడవచ్చు."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. మ్యూట్ చేయడానికి నొక్కండి. యాక్సెస్ సామర్థ్య సేవలు మ్యూట్ చేయబడవచ్చు."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. వైబ్రేట్ అయ్యేలా సెట్ చేయడం కోసం నొక్కండి."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. మ్యూట్ చేయడానికి నొక్కండి."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"నాయిస్ కంట్రోల్"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"రింగర్ మోడ్ను మార్చడానికి ట్యాప్ చేయండి"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"మ్యూట్ చేయి"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"అన్మ్యూట్ చేయి"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"పవర్ మెనూ"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_2">%2$d</xliff:g>లో <xliff:g id="ID_1">%1$d</xliff:g>వ పేజీ"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"లాక్ స్క్రీన్"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"తీసుకోవాల్సిన జాగ్రత్తలు ఏమిటో చూడండి"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"తీసుకోవాల్సిన జాగ్రత్తలు ఏమిటో చూడండి"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"మీ పరికరాన్ని అన్ప్లగ్ చేయండి"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"నోట్-టేకింగ్"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"నోట్-టేకింగ్, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"ఆడియోను షేర్ చేస్తున్నారు"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"ప్రసారం చేస్తోంది"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రసారం చేయడాన్ని ఆపివేయాలా?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"మీరు <xliff:g id="SWITCHAPP">%1$s</xliff:g> ప్రసారం చేస్తే లేదా అవుట్పుట్ను మార్చినట్లయితే, మీ ప్రస్తుత ప్రసారం ఆగిపోతుంది"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index d1e186fa73b4..98075c557bca 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"เพิ่มวิดเจ็ตอีก"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"กดค้างเพื่อปรับแต่งวิดเจ็ต"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ปรับแต่งวิดเจ็ต"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"แก้ไขวิดเจ็ต"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"นำออก"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"เพิ่มวิดเจ็ต"</string> @@ -573,11 +575,14 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"ทำให้ส่งเสียง"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"สั่น"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"ปิดเสียง"</string> + <string name="media_device_cast" msgid="4786241789687569892">"แคสต์"</string> + <string name="stream_notification_unavailable" msgid="4313854556205836435">"เปลี่ยนไม่ได้เนื่องจากปิดเสียงเรียกเข้า"</string> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s แตะเพื่อเปิดเสียง"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s แตะเพื่อตั้งค่าให้สั่น อาจมีการปิดเสียงบริการการเข้าถึง"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s แตะเพื่อปิดเสียง อาจมีการปิดเสียงบริการการเข้าถึง"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s แตะเพื่อตั้งค่าให้สั่น"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s แตะเพื่อปิดเสียง"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"การควบคุมเสียง"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"แตะเพื่อเปลี่ยนโหมดเสียงเรียกเข้า"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ปิดเสียง"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"เปิดเสียง"</string> @@ -832,6 +837,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"เมนูเปิด/ปิด"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"หน้า <xliff:g id="ID_1">%1$d</xliff:g> จาก <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"หน้าจอล็อก"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"ดูขั้นตอนในการดูแลรักษา"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"ดูขั้นตอนในการดูแลรักษา"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"ถอดปลั๊กอุปกรณ์"</string> @@ -1186,6 +1195,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"การจดบันทึก"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"การจดบันทึก <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"กำลังแชร์เสียง"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"กำลังออกอากาศ"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"หยุดการออกอากาศ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"หากคุณออกอากาศ <xliff:g id="SWITCHAPP">%1$s</xliff:g> หรือเปลี่ยนแปลงเอาต์พุต การออกอากาศในปัจจุบันจะหยุดลง"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index c929e4579df9..ff8d84f589b7 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Magdagdag ng higit pang widget"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pindutin nang matagal para i-customize ang mga widget"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"I-customize ang mga widget"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"I-edit ang widget"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Alisin"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Magdagdag ng widget"</string> @@ -573,11 +575,14 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ipa-ring"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"I-vibrate"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"I-mute"</string> + <string name="media_device_cast" msgid="4786241789687569892">"Mag-cast"</string> + <string name="stream_notification_unavailable" msgid="4313854556205836435">"Hindi available dahil naka-mute ang ring"</string> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. I-tap upang i-unmute."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. I-tap upang itakda na mag-vibrate. Maaaring i-mute ang mga serbisyo sa Accessibility."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. I-tap upang i-mute. Maaaring i-mute ang mga serbisyo sa Accessibility."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. I-tap upang itakda na mag-vibrate."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. I-tap upang i-mute."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Pagkontrol sa Ingay"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"I-tap para baguhin ang ringer mode"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"i-mute"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"i-unmute"</string> @@ -832,6 +837,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Power menu"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Page <xliff:g id="ID_1">%1$d</xliff:g> ng <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Lock screen"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Tingnan ang mga hakbang sa pangangalaga"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Tingnan ang mga hakbang sa pangangalaga"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Bunutin sa saksakan ang device"</string> @@ -1186,6 +1195,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Pagtatala"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Pagtatala, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Nagse-share ng audio"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Nagbo-broadcast"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Ihinto ang pag-broadcast ng <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Kung magbo-broadcast ka ng <xliff:g id="SWITCHAPP">%1$s</xliff:g> o babaguhin mo ang output, hihinto ang iyong kasalukuyang broadcast"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 9407fbbbf3d9..495000ba0318 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Daha fazla widget ekle"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widget\'ları özelleştirmek için uzun basın"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widget\'ları özelleştir"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Widget\'ı düzenle"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Kaldır"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Widget ekle"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Zili çaldır"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Titreşim"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Sesi kapat"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Sesi açmak için dokunun."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Titreşime ayarlamak için dokunun. Erişilebilirlik hizmetlerinin sesi kapatılabilir."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Sesi kapatmak için dokunun. Erişilebilirlik hizmetlerinin sesi kapatılabilir."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Titreşime ayarlamak için dokunun."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Sesi kapatmak için dokunun."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Gürültü Kontrolü"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Telefon zili modunu değiştirmek için dokunun"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"sesi kapat"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"sesi aç"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Güç menüsü"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Sayfa <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Kilit ekranı"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Bakımla ilgili adımlara bakın"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Bakımla ilgili adımlara bakın"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Cihazınızın fişini çekin"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Not alma"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Not alma, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Ses paylaşılıyor"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Yayınlama"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında anons durdurulsun mu?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"<xliff:g id="SWITCHAPP">%1$s</xliff:g> uygulamasında anons yapar veya çıkışı değiştirirseniz mevcut anonsunuz duraklatılır"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index b7a4999865de..67d5ffc3373a 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додати більше віджетів"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Утримуйте, щоб налаштувати віджети"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Налаштувати віджети"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Редагувати віджет"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Видалити"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Додати віджет"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Дзвінок"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вібросигнал"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Без звуку"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Торкніться, щоб увімкнути звук."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Торкніться, щоб налаштувати вібросигнал. Спеціальні можливості може бути вимкнено."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Торкніться, щоб вимкнути звук. Спеціальні можливості може бути вимкнено."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Торкніться, щоб налаштувати вібросигнал."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Торкніться, щоб вимкнути звук."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контроль шуму"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Торкніться, щоб змінити режим дзвінка"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"вимкнути звук"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"увімкнути звук"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Меню кнопки живлення"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Сторінка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Заблокований екран"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Переглянути запобіжні заходи"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Переглянути запобіжні заходи"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Від’єднайте пристрій"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Створення нотаток"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Створення нотаток, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Відтворюється аудіо"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Трансляція"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Зупинити трансляцію з додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Якщо ви зміните додаток (<xliff:g id="SWITCHAPP">%1$s</xliff:g>) або аудіовихід, поточну трансляцію буде припинено"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index f9155a0e06e6..7414ac62c4a8 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"مزید ویجٹس شامل کریں"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ویجٹس کو حسب ضرورت بنانے کے لیے لانگ پریس کریں"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ویجیٹس کو حسب ضرورت بنائیں"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"ویجیٹ میں ترمیم کریں"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"ہٹائیں"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ویجیٹ شامل کریں"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"رِنگ کریں"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"وائبریٹ"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"خاموش کریں"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s۔ آواز چالو کرنے کیلئے تھپتھپائیں۔"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s۔ ارتعاش پر سیٹ کرنے کیلئے تھپتھپائیں۔ ایکسیسبیلٹی سروسز شاید خاموش ہوں۔"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s۔ خاموش کرنے کیلئے تھپتھپائیں۔ ایکسیسبیلٹی سروسز شاید خاموش ہوں۔"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s۔ ارتعاش پر سیٹ کرنے کیلئے تھپتھپائیں۔"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s۔ خاموش کرنے کیلئے تھپتھپائیں۔"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"شور کنٹرول"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"رنگر وضع تبدیل کرنے کیلئے تھپتھپائیں"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"خاموش کریں"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"غیر خاموش کریں"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"پاور مینیو"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"صفحہ <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"مقفل اسکرین"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"نگہداشت کے اقدامات ملاحظہ کریں"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"نگہداشت کے اقدامات ملاحظہ کریں"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"اپنے آلہ کو ان پلگ کریں"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>، <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"نوٹ لکھنا"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"نوٹ لکھنا، <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"آڈیو کا اشتراک کرنا"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"نشریات"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> براڈکاسٹنگ روکیں؟"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"اگر آپ <xliff:g id="SWITCHAPP">%1$s</xliff:g> براڈکاسٹ کرتے ہیں یا آؤٹ پٹ کو تبدیل کرتے ہیں تو آپ کا موجودہ براڈکاسٹ رک جائے گا"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 82b6b460ef67..09e5ff04d9b6 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Koʻproq vidjetlar qoʻshish"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vidjetlarni sozlash uchun bosib turing"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Vidjetlarni moslashtirish"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Vidjetni tahrirlash"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Olib tashlash"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Vidjet kiritish"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Jiringlatish"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Tebranish"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Ovozsiz"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Ovozini yoqish uchun ustiga bosing."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tebranishni yoqish uchun ustiga bosing. Qulayliklar ishlamasligi mumkin."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ovozini o‘chirish uchun ustiga bosing. Qulayliklar ishlamasligi mumkin."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Tebranishni yoqish uchun ustiga bosing."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Ovozsiz qilish uchun ustiga bosing."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Shovqin boshqaruvi"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Jiringlagich rejimini oʻzgartirish uchun bosing"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"ovozsiz qilish"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ovozni yoqish"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Quvvat menyusi"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"<xliff:g id="ID_1">%1$d</xliff:g>-sahifa, jami: <xliff:g id="ID_2">%2$d</xliff:g> ta sahifa"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Ekran qulfi"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Batafsil axborot"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Batafsil axborot"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Qurilmani uzing"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Qayd olish"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>: qayd olish"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Audio ulashuvi"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Signal uzatish"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga translatsiya toʻxtatilsinmi?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Agar <xliff:g id="SWITCHAPP">%1$s</xliff:g> ilovasiga translatsiya qilsangiz yoki ovoz chiqishini oʻzgartirsangiz, joriy translatsiya toʻxtab qoladi"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 2a8d4cdce031..f7057e948b70 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Thêm tiện ích khác"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nhấn và giữ để tuỳ chỉnh tiện ích"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tuỳ chỉnh tiện ích"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Chỉnh sửa tiện ích"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Xoá"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Thêm tiện ích"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Đổ chuông"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Rung"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Tắt tiếng"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Nhấn để bật tiếng."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Nhấn để đặt chế độ rung. Bạn có thể tắt tiếng dịch vụ trợ năng."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Nhấn để tắt tiếng. Bạn có thể tắt tiếng dịch vụ trợ năng."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Nhấn để đặt chế độ rung."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Nhấn để tắt tiếng."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kiểm soát tiếng ồn"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Nhấn để thay đổi chế độ chuông"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"tắt tiếng"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"bật tiếng"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Trình đơn nguồn"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Trang <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Màn hình khóa"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Xem các bước chăm sóc"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Xem các bước chăm sóc"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Rút thiết bị ra"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Ghi chú"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Ghi chú, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Đang chia sẻ âm thanh"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Phát sóng"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Dừng phát <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Nếu bạn phát <xliff:g id="SWITCHAPP">%1$s</xliff:g> hoặc thay đổi đầu ra, phiên truyền phát hiện tại sẽ dừng"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index ddef35f6d1b8..2c87e2491814 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"添加更多微件"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"长按即可自定义微件"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自定义微件"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"修改微件"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"移除"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"添加微件"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"响铃"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"振动"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"静音"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s。点按即可取消静音。"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s。点按即可设为振动,但可能会同时将无障碍服务设为静音。"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。点按即可设为静音,但可能会同时将无障碍服务设为静音。"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。点按即可设为振动。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。点按即可设为静音。"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"噪声控制"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"点按即可更改振铃器模式"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"静音"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消静音"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"电源菜单"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 页,共 <xliff:g id="ID_2">%2$d</xliff:g> 页"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"锁定屏幕"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"查看处理步骤"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"查看处理步骤"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"拔出设备"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>,<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"记事"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"记事,<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"正在分享音频"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"正在广播"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止广播“<xliff:g id="APP_NAME">%1$s</xliff:g>”的内容吗?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果广播“<xliff:g id="SWITCHAPP">%1$s</xliff:g>”的内容或更改输出来源,当前的广播就会停止"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index dbf2cc0a25c8..78d7c7a0c9b4 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"新增更多小工具"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長按即可自訂小工具"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自訂小工具"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"編輯小工具"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"移除"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"新增小工具"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"鈴聲"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"震動"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"靜音"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s。輕按即可取消靜音。"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s。輕按即可設為震動。無障礙功能服務可能已經設為靜音。"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。輕按即可設為靜音。無障礙功能服務可能已經設為靜音。"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。輕按即可設為震動。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。輕按即可設為靜音。"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"噪音控制"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"輕按即可變更響鈴模式"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源選單"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁 (共 <xliff:g id="ID_2">%2$d</xliff:g> 頁)"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"螢幕鎖定"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"查看保養步驟"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"查看保養步驟"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"拔除裝置"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>,<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"做筆記"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"做筆記,<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"正在分享音訊"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止廣播「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如要廣播「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止廣播目前的內容"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index d92de1cf6af9..46d775086fc3 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"新增更多小工具"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長按即可自訂小工具"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自訂小工具"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"編輯小工具"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"移除"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"新增小工具"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"鈴聲"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"震動"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"靜音"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s。輕觸即可取消靜音。"</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s。輕觸即可設為震動,但系統可能會將無障礙服務一併設為靜音。"</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。輕觸即可設為靜音,但系統可能會將無障礙服務一併設為靜音。"</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。輕觸即可設為震動。"</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。輕觸即可設為靜音。"</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"噪音控制"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"輕觸即可變更鈴聲模式"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"靜音"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"取消靜音"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"電源鍵選單"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁,共 <xliff:g id="ID_2">%2$d</xliff:g> 頁"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"鎖定畫面"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"查看處理步驟"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"查看處理步驟"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"拔除裝置"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>,<xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"做筆記"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"做筆記,<xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"分享音訊"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"廣播"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"要停止播送「<xliff:g id="APP_NAME">%1$s</xliff:g>」的內容嗎?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"如果播送「<xliff:g id="SWITCHAPP">%1$s</xliff:g>」的內容或變更輸出來源,系統就會停止播送目前的內容"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 9cd70829c30c..f12c2bbdd81c 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -429,6 +429,8 @@ <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Engeza amawijethi engeziwe"</string> <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Cindezela isikhathi eside ukuze wenze ngokwezifiso amawijethi"</string> <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Yenza ngokwezifiso amawijethi"</string> + <!-- no translation found for icon_description_for_disabled_widget (4693151565003206943) --> + <skip /> <string name="edit_widget" msgid="9030848101135393954">"Hlela amawijethi"</string> <string name="button_to_remove_widget" msgid="3948204829181214098">"Susa"</string> <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Engeza iwijethi"</string> @@ -573,11 +575,16 @@ <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Khalisa"</string> <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Dlidlizela"</string> <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Thulisa"</string> + <!-- no translation found for media_device_cast (4786241789687569892) --> + <skip /> + <!-- no translation found for stream_notification_unavailable (4313854556205836435) --> + <skip /> <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Thepha ukuze ususe ukuthula."</string> <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Thepha ukuze usethe ukudlidliza. Amasevisi okufinyelela angathuliswa."</string> <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Thepha ukuze uthulise. Amasevisi okufinyelela angathuliswa."</string> <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Thepha ukuze usethele ekudlidlizeni."</string> <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Thepha ukuze uthulise."</string> + <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Ulawulo Lomsindo"</string> <string name="volume_ringer_change" msgid="3574969197796055532">"Thepha ukuze ushintshe imodi yokukhala"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"thulisa"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"susa ukuthula"</string> @@ -832,6 +839,10 @@ <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Imenyu yamandla"</string> <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Ikhasi <xliff:g id="ID_1">%1$d</xliff:g> kwangu-<xliff:g id="ID_2">%2$d</xliff:g>"</string> <string name="tuner_lock_screen" msgid="2267383813241144544">"Khiya isikrini"</string> + <!-- no translation found for finder_active (7907846989716941952) --> + <skip /> + <!-- no translation found for shutdown_progress (5464239146561542178) --> + <skip /> <string name="thermal_shutdown_dialog_help_text" msgid="6413474593462902901">"Bona izinyathelo zokunakekelwa"</string> <string name="high_temp_dialog_help_text" msgid="7380171287943345858">"Bona izinyathelo zokunakekelwa"</string> <string name="high_temp_alarm_title" msgid="8654754369605452169">"Khipha idivayisi yakho"</string> @@ -1186,6 +1197,7 @@ <string name="dream_overlay_weather_complication_desc" msgid="824503662089783824">"<xliff:g id="WEATHER_CONDITION">%1$s</xliff:g>, <xliff:g id="TEMPERATURE">%2$s</xliff:g>"</string> <string name="note_task_button_label" msgid="230135078402003532">"Ukuthatha amanothi"</string> <string name="note_task_shortcut_long_label" msgid="7729325091147319409">"Ukuthatha amanothi, <xliff:g id="NOTE_TAKING_APP">%1$s</xliff:g>"</string> + <string name="audio_sharing_description" msgid="8849060142768870004">"Yabelana ngomsindo"</string> <string name="broadcasting_description_is_broadcasting" msgid="765627502786404290">"Ukusakaza"</string> <string name="bt_le_audio_broadcast_dialog_title" msgid="3605428497924077811">"Misa ukusakaza i-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string> <string name="bt_le_audio_broadcast_dialog_sub_title" msgid="7889684551194225793">"Uma usakaza i-<xliff:g id="SWITCHAPP">%1$s</xliff:g> noma ushintsha okuphumayo, ukusakaza kwakho kwamanje kuzoma"</string> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index beaa708b4dcc..e181d079fc6d 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -101,7 +101,7 @@ <!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" --> <string name="quick_settings_tiles_stock" translatable="false"> - internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling + internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,font_scaling,record_issue </string> <!-- The tiles to display in QuickSettings --> diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index 71ae0d716429..035cfdc492d0 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -223,6 +223,7 @@ <item type="id" name="lock_icon" /> <item type="id" name="lock_icon_bg" /> <item type="id" name="burn_in_layer" /> + <item type="id" name="burn_in_layer_empty_view" /> <item type="id" name="communal_tutorial_indicator" /> <item type="id" name="nssl_placeholder_barrier_bottom" /> <item type="id" name="ambient_indication_container" /> diff --git a/packages/SystemUI/res/values/tiles_states_strings.xml b/packages/SystemUI/res/values/tiles_states_strings.xml index 7020d548f6b0..9036a35846af 100644 --- a/packages/SystemUI/res/values/tiles_states_strings.xml +++ b/packages/SystemUI/res/values/tiles_states_strings.xml @@ -222,6 +222,16 @@ <item>On</item> </string-array> + <!-- State names for record_issue tile: unavailable, off, on. + This subtitle is shown when the tile is in that particular state but does not set its own + subtitle, so some of these may never appear on screen. They should still be translated as + if they could appear. [CHAR LIMIT=32] --> + <string-array name="tile_states_record_issue"> + <item>Unavailable</item> + <item>Off</item> + <item>On</item> + </string-array> + <!-- State names for reverse (charging) tile: unavailable, off, on. This subtitle is shown when the tile is in that particular state but does not set its own subtitle, so some of these may never appear on screen. They should still be translated as diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt index 169a4e0f3501..f28d4052b5a8 100644 --- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt +++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt @@ -15,8 +15,6 @@ */ package com.android.keyguard -import com.android.systemui.keyguard.shared.model.KeyguardState.AOD -import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import android.content.BroadcastReceiver import android.content.Context import android.content.Intent @@ -43,14 +41,16 @@ import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags.REGION_SAMPLING import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState.AOD +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.log.core.Logger +import com.android.systemui.plugins.clocks.AlarmData import com.android.systemui.plugins.clocks.ClockController import com.android.systemui.plugins.clocks.ClockFaceController import com.android.systemui.plugins.clocks.ClockMessageBuffers import com.android.systemui.plugins.clocks.ClockTickRate -import com.android.systemui.plugins.clocks.AlarmData import com.android.systemui.plugins.clocks.WeatherData import com.android.systemui.plugins.clocks.ZenData import com.android.systemui.plugins.clocks.ZenData.ZenMode @@ -61,16 +61,18 @@ import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChang import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.ZenModeController import com.android.systemui.util.concurrency.DelayableExecutor +import java.util.Locale +import java.util.TimeZone +import java.util.concurrent.Executor +import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.Job import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.merge import kotlinx.coroutines.launch -import java.util.Locale -import java.util.TimeZone -import java.util.concurrent.Executor -import javax.inject.Inject /** * Controller for a Clock provided by the registry and used on the keyguard. Instantiated by @@ -93,11 +95,13 @@ constructor( private val featureFlags: FeatureFlagsClassic, private val zenModeController: ZenModeController, ) { - var loggers = listOf( - clockBuffers.infraMessageBuffer, - clockBuffers.smallClockMessageBuffer, - clockBuffers.largeClockMessageBuffer - ).map { Logger(it, TAG) } + var loggers = + listOf( + clockBuffers.infraMessageBuffer, + clockBuffers.smallClockMessageBuffer, + clockBuffers.largeClockMessageBuffer + ) + .map { Logger(it, TAG) } var clock: ClockController? = null get() = field @@ -108,11 +112,12 @@ constructor( } private fun disconnectClock(clock: ClockController?) { - if (clock == null) { return; } + if (clock == null) { + return + } smallClockOnAttachStateChangeListener?.let { clock.smallClock.view.removeOnAttachStateChangeListener(it) - smallClockFrame?.viewTreeObserver - ?.removeOnGlobalLayoutListener(onGlobalLayoutListener) + smallClockFrame?.viewTreeObserver?.removeOnGlobalLayoutListener(onGlobalLayoutListener) } largeClockOnAttachStateChangeListener?.let { clock.largeClock.view.removeOnAttachStateChangeListener(it) @@ -120,7 +125,9 @@ constructor( } private fun connectClock(clock: ClockController?) { - if (clock == null) { return; } + if (clock == null) { + return + } val clockStr = clock.toString() loggers.forEach { it.d({ "New Clock: $str1" }) { str1 = clockStr } } @@ -129,23 +136,27 @@ constructor( if (!regionSamplingEnabled) { updateColors() } else { - smallRegionSampler = createRegionSampler( - clock.smallClock.view, - mainExecutor, - bgExecutor, - regionSamplingEnabled, - isLockscreen = true, - ::updateColors - ).apply { startRegionSampler() } - - largeRegionSampler = createRegionSampler( - clock.largeClock.view, - mainExecutor, - bgExecutor, - regionSamplingEnabled, - isLockscreen = true, - ::updateColors - ).apply { startRegionSampler() } + smallRegionSampler = + createRegionSampler( + clock.smallClock.view, + mainExecutor, + bgExecutor, + regionSamplingEnabled, + isLockscreen = true, + ::updateColors + ) + .apply { startRegionSampler() } + + largeRegionSampler = + createRegionSampler( + clock.largeClock.view, + mainExecutor, + bgExecutor, + regionSamplingEnabled, + isLockscreen = true, + ::updateColors + ) + .apply { startRegionSampler() } updateColors() } @@ -158,49 +169,49 @@ constructor( } clock.events.onWeatherDataChanged(it) } - zenData?.let { - clock.events.onZenDataChanged(it) - } - alarmData?.let { - clock.events.onAlarmDataChanged(it) - } - - smallClockOnAttachStateChangeListener = object : OnAttachStateChangeListener { - var pastVisibility: Int? = null - override fun onViewAttachedToWindow(view: View) { - clock.events.onTimeFormatChanged(DateFormat.is24HourFormat(context)) - // Match the asing for view.parent's layout classes. - smallClockFrame = (view.parent as ViewGroup)?.also { frame -> - pastVisibility = frame.visibility - onGlobalLayoutListener = OnGlobalLayoutListener { - val currentVisibility = frame.visibility - if (pastVisibility != currentVisibility) { - pastVisibility = currentVisibility - // when small clock is visible, - // recalculate bounds and sample - if (currentVisibility == View.VISIBLE) { - smallRegionSampler?.stopRegionSampler() - smallRegionSampler?.startRegionSampler() + zenData?.let { clock.events.onZenDataChanged(it) } + alarmData?.let { clock.events.onAlarmDataChanged(it) } + + smallClockOnAttachStateChangeListener = + object : OnAttachStateChangeListener { + var pastVisibility: Int? = null + override fun onViewAttachedToWindow(view: View) { + clock.events.onTimeFormatChanged(DateFormat.is24HourFormat(context)) + // Match the asing for view.parent's layout classes. + smallClockFrame = + (view.parent as ViewGroup)?.also { frame -> + pastVisibility = frame.visibility + onGlobalLayoutListener = OnGlobalLayoutListener { + val currentVisibility = frame.visibility + if (pastVisibility != currentVisibility) { + pastVisibility = currentVisibility + // when small clock is visible, + // recalculate bounds and sample + if (currentVisibility == View.VISIBLE) { + smallRegionSampler?.stopRegionSampler() + smallRegionSampler?.startRegionSampler() + } + } } + frame.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener) } - } - frame.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener) } - } - override fun onViewDetachedFromWindow(p0: View) { - smallClockFrame?.viewTreeObserver + override fun onViewDetachedFromWindow(p0: View) { + smallClockFrame + ?.viewTreeObserver ?.removeOnGlobalLayoutListener(onGlobalLayoutListener) + } } - } clock.smallClock.view.addOnAttachStateChangeListener(smallClockOnAttachStateChangeListener) - largeClockOnAttachStateChangeListener = object : OnAttachStateChangeListener { - override fun onViewAttachedToWindow(p0: View) { - clock.events.onTimeFormatChanged(DateFormat.is24HourFormat(context)) + largeClockOnAttachStateChangeListener = + object : OnAttachStateChangeListener { + override fun onViewAttachedToWindow(p0: View) { + clock.events.onTimeFormatChanged(DateFormat.is24HourFormat(context)) + } + override fun onViewDetachedFromWindow(p0: View) {} } - override fun onViewDetachedFromWindow(p0: View) {} - } clock.largeClock.view.addOnAttachStateChangeListener(largeClockOnAttachStateChangeListener) } @@ -263,7 +274,9 @@ constructor( bgExecutor, regionSamplingEnabled, isLockscreen, - ) { updateColors() } + ) { + updateColors() + } } var smallRegionSampler: RegionSampler? = null @@ -364,35 +377,36 @@ constructor( } } - private val zenModeCallback = object : ZenModeController.Callback { - override fun onZenChanged(zen: Int) { - var mode = ZenMode.fromInt(zen) - if (mode == null) { - Log.e(TAG, "Failed to get zen mode from int: $zen") - return - } - - zenData = ZenData( - mode, - if (mode == ZenMode.OFF) SysuiR.string::dnd_is_off.name - else SysuiR.string::dnd_is_on.name - ).also { data -> - mainExecutor.execute { - clock?.run { events.onZenDataChanged(data) } + private val zenModeCallback = + object : ZenModeController.Callback { + override fun onZenChanged(zen: Int) { + var mode = ZenMode.fromInt(zen) + if (mode == null) { + Log.e(TAG, "Failed to get zen mode from int: $zen") + return } + + zenData = + ZenData( + mode, + if (mode == ZenMode.OFF) SysuiR.string::dnd_is_off.name + else SysuiR.string::dnd_is_on.name + ) + .also { data -> + mainExecutor.execute { clock?.run { events.onZenDataChanged(data) } } + } } - } - override fun onNextAlarmChanged() { - val nextAlarmMillis = zenModeController.getNextAlarm() - alarmData = AlarmData( - if (nextAlarmMillis > 0) nextAlarmMillis else null, - SysuiR.string::status_bar_alarm.name - ).also { data -> - clock?.run { events.onAlarmDataChanged(data) } + override fun onNextAlarmChanged() { + val nextAlarmMillis = zenModeController.getNextAlarm() + alarmData = + AlarmData( + if (nextAlarmMillis > 0) nextAlarmMillis else null, + SysuiR.string::status_bar_alarm.name + ) + .also { data -> clock?.run { events.onAlarmDataChanged(data) } } } } - } fun registerListeners(parent: View) { if (isRegistered) { @@ -413,6 +427,7 @@ constructor( listenForDozing(this) if (migrateClocksToBlueprint()) { listenForDozeAmountTransition(this) + listenForAnyStateToAodTransition(this) } else { listenForDozeAmount(this) } @@ -444,12 +459,15 @@ constructor( largeRegionSampler?.stopRegionSampler() smallTimeListener?.stop() largeTimeListener?.stop() - clock?.smallClock?.view - ?.removeOnAttachStateChangeListener(smallClockOnAttachStateChangeListener) - smallClockFrame?.viewTreeObserver - ?.removeOnGlobalLayoutListener(onGlobalLayoutListener) - clock?.largeClock?.view - ?.removeOnAttachStateChangeListener(largeClockOnAttachStateChangeListener) + clock + ?.smallClock + ?.view + ?.removeOnAttachStateChangeListener(smallClockOnAttachStateChangeListener) + smallClockFrame?.viewTreeObserver?.removeOnGlobalLayoutListener(onGlobalLayoutListener) + clock + ?.largeClock + ?.view + ?.removeOnAttachStateChangeListener(largeClockOnAttachStateChangeListener) } /** @@ -473,12 +491,10 @@ constructor( largeTimeListener = null clock?.let { - smallTimeListener = TimeListener(it.smallClock, mainExecutor).apply { - update(shouldTimeListenerRun) - } - largeTimeListener = TimeListener(it.largeClock, mainExecutor).apply { - update(shouldTimeListenerRun) - } + smallTimeListener = + TimeListener(it.smallClock, mainExecutor).apply { update(shouldTimeListenerRun) } + largeTimeListener = + TimeListener(it.largeClock, mainExecutor).apply { update(shouldTimeListenerRun) } } } @@ -517,7 +533,27 @@ constructor( @VisibleForTesting internal fun listenForDozeAmountTransition(scope: CoroutineScope): Job { return scope.launch { - keyguardTransitionInteractor.dozeAmountTransition.collect { handleDoze(it.value) } + merge( + keyguardTransitionInteractor.aodToLockscreenTransition.map { step -> + step.copy(value = 1f - step.value) + }, + keyguardTransitionInteractor.lockscreenToAodTransition, + ) + .collect { handleDoze(it.value) } + } + } + + /** + * When keyguard is displayed again after being gone, the clock must be reset to full dozing. + */ + @VisibleForTesting + internal fun listenForAnyStateToAodTransition(scope: CoroutineScope): Job { + return scope.launch { + keyguardTransitionInteractor + .transitionStepsToState(AOD) + .filter { it.transitionState == TransitionState.STARTED } + .filter { it.from != LOCKSCREEN } + .collect { handleDoze(1f) } } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java index fc4e122d235b..4c3f623595bf 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java @@ -103,7 +103,7 @@ class KeyguardEsimArea extends Button implements View.OnClickListener { public static boolean isEsimLocked(Context context, int subId) { EuiccManager euiccManager = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE); - if (!euiccManager.isEnabled()) { + if (euiccManager == null || !euiccManager.isEnabled()) { return false; } SubscriptionInfo sub = SubscriptionManager.from(context).getActiveSubscriptionInfo(subId); @@ -118,6 +118,10 @@ class KeyguardEsimArea extends Button implements View.OnClickListener { @Override public void onClick(View v) { + if (mEuiccManager == null) { + Log.e(TAG, "EuiccManager not present"); + return; + } SubscriptionInfo sub = SubscriptionManager.from(mContext) .getActiveSubscriptionInfo(mSubscriptionId); if (sub == null) { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java index 7473e0c62d1d..490ad5c4136d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java @@ -86,8 +86,9 @@ public class KeyguardPasswordViewController }; private final View.OnKeyListener mKeyListener = (v, keyCode, keyEvent) -> { + // Ignore SPACE as a confirm key to allow the space character within passwords. final boolean isKeyboardEnterKey = keyEvent != null - && KeyEvent.isConfirmKey(keyCode) + && KeyEvent.isConfirmKey(keyCode) && keyCode != KeyEvent.KEYCODE_SPACE && keyEvent.getAction() == KeyEvent.ACTION_UP; if (isKeyboardEnterKey) { verifyPasswordAndUnlock(); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java index 9421f150a38a..c0ae4a1f4036 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java @@ -53,9 +53,6 @@ import com.android.systemui.Dumpable; import com.android.systemui.animation.ViewHierarchyAnimator; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; -import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; -import com.android.systemui.keyguard.shared.model.TransitionState; -import com.android.systemui.keyguard.shared.model.TransitionStep; import com.android.systemui.plugins.clocks.ClockController; import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.power.shared.model.ScreenPowerState; @@ -104,7 +101,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV private final Rect mClipBounds = new Rect(); private final KeyguardInteractor mKeyguardInteractor; private final PowerInteractor mPowerInteractor; - private final KeyguardTransitionInteractor mKeyguardTransitionInteractor; private final DozeParameters mDozeParameters; private View mStatusArea = null; @@ -112,7 +108,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV private Boolean mSplitShadeEnabled = false; private Boolean mStatusViewCentered = true; - private boolean mGoneToAodTransitionRunning = false; private DumpManager mDumpManager; private final TransitionListenerAdapter mKeyguardStatusAlignmentTransitionListener = @@ -181,7 +176,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV KeyguardLogger logger, InteractionJankMonitor interactionJankMonitor, KeyguardInteractor keyguardInteractor, - KeyguardTransitionInteractor keyguardTransitionInteractor, DumpManager dumpManager, PowerInteractor powerInteractor) { super(keyguardStatusView); @@ -197,7 +191,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV mDumpManager = dumpManager; mKeyguardInteractor = keyguardInteractor; mPowerInteractor = powerInteractor; - mKeyguardTransitionInteractor = keyguardTransitionInteractor; } @Override @@ -232,6 +225,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV mDumpManager.registerDumpable(getInstanceName(), this); if (migrateClocksToBlueprint()) { startCoroutines(EmptyCoroutineContext.INSTANCE); + mView.setVisibility(View.GONE); } } @@ -247,15 +241,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV dozeTimeTick(); } }, context); - - collectFlow(mView, mKeyguardTransitionInteractor.getGoneToAodTransition(), - (TransitionStep step) -> { - if (step.getTransitionState() == TransitionState.RUNNING) { - mGoneToAodTransitionRunning = true; - } else { - mGoneToAodTransitionRunning = false; - } - }, context); } public KeyguardStatusView getView() { @@ -326,7 +311,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV * Set keyguard status view alpha. */ public void setAlpha(float alpha) { - if (!mKeyguardVisibilityHelper.isVisibilityAnimating() && !mGoneToAodTransitionRunning) { + if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) { mView.setAlpha(alpha); } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java index 2000028dff41..77054bd29147 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java @@ -88,6 +88,10 @@ public class KeyguardVisibilityHelper { boolean keyguardFadingAway, boolean goingToFullShade, int oldStatusBarState) { + if (migrateClocksToBlueprint()) { + log("Ignoring all of KeyguardVisibilityelper"); + return; + } Assert.isMainThread(); PropertyAnimator.cancelAnimation(mView, AnimatableProperty.ALPHA); boolean isOccluded = mKeyguardStateController.isOccluded(); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index f4cd5b963e41..9de71c1880fe 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -17,6 +17,7 @@ package com.android.systemui.biometrics; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; +import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION; @@ -43,6 +44,7 @@ import android.os.Looper; import android.os.UserManager; import android.util.Log; import android.view.Display; +import android.view.DisplayInfo; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -160,6 +162,8 @@ public class AuthContainerView extends LinearLayout private final ImageView mBackgroundView; private final ScrollView mBiometricScrollView; private final View mPanelView; + private final List<FingerprintSensorPropertiesInternal> mFpProps; + private final List<FaceSensorPropertiesInternal> mFaceProps; private final float mTranslationY; @VisibleForTesting @ContainerState int mContainerState = STATE_UNKNOWN; private final Set<Integer> mFailedModalities = new HashSet<Integer>(); @@ -374,6 +378,8 @@ public class AuthContainerView extends LinearLayout mPromptSelectorInteractorProvider = promptSelectorInteractorProvider; mCredentialViewModelProvider = credentialViewModelProvider; mPromptViewModel = promptViewModel; + mFpProps = fpProps; + mFaceProps = faceProps; showPrompt(config, layoutInflater, promptViewModel, Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds), @@ -521,7 +527,7 @@ public class AuthContainerView extends LinearLayout @Override public void onOrientationChanged() { if (!constraintBp()) { - maybeUpdatePositionForUdfps(true /* invalidate */); + updatePositionByCapability(true /* invalidate */); } } @@ -549,7 +555,7 @@ public class AuthContainerView extends LinearLayout } if (!constraintBp()) { - maybeUpdatePositionForUdfps(false /* invalidate */); + updatePositionByCapability(false /* invalidate */); } if (mConfig.mSkipIntro) { @@ -615,6 +621,22 @@ public class AuthContainerView extends LinearLayout }; } + private void updatePositionByCapability(boolean forceInvalidate) { + final FingerprintSensorPropertiesInternal fpProp = Utils.findFirstSensorProperties( + mFpProps, mConfig.mSensorIds); + final FaceSensorPropertiesInternal faceProp = Utils.findFirstSensorProperties( + mFaceProps, mConfig.mSensorIds); + if (fpProp != null && fpProp.isAnyUdfpsType()) { + maybeUpdatePositionForUdfps(forceInvalidate /* invalidate */); + } + if (faceProp != null && mBiometricView.isFaceOnly()) { + alwaysUpdatePositionAtScreenBottom(forceInvalidate /* invalidate */); + } + if (fpProp != null && fpProp.sensorType == TYPE_POWER_BUTTON) { + alwaysUpdatePositionAtScreenBottom(forceInvalidate /* invalidate */); + } + } + private static boolean shouldUpdatePositionForUdfps(@NonNull View view) { if (view instanceof BiometricPromptLayout) { // this will force the prompt to align itself on the edge of the screen @@ -632,11 +654,14 @@ public class AuthContainerView extends LinearLayout if (display == null) { return false; } + + final DisplayInfo cachedDisplayInfo = new DisplayInfo(); + display.getDisplayInfo(cachedDisplayInfo); if (mBiometricView == null || !shouldUpdatePositionForUdfps(mBiometricView.asView())) { return false; } - final int displayRotation = display.getRotation(); + final int displayRotation = cachedDisplayInfo.rotation; switch (displayRotation) { case Surface.ROTATION_0: mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM); @@ -668,6 +693,38 @@ public class AuthContainerView extends LinearLayout return true; } + private boolean alwaysUpdatePositionAtScreenBottom(boolean invalidate) { + final Display display = getDisplay(); + if (display == null) { + return false; + } + if (mBiometricView == null || !shouldUpdatePositionForUdfps(mBiometricView.asView())) { + return false; + } + + final int displayRotation = display.getRotation(); + switch (displayRotation) { + case Surface.ROTATION_0: + case Surface.ROTATION_90: + case Surface.ROTATION_270: + case Surface.ROTATION_180: + mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM); + setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); + break; + default: + Log.e(TAG, "Unsupported display rotation: " + displayRotation); + mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM); + setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); + break; + } + + if (invalidate) { + mPanelView.invalidateOutline(); + } + + return true; + } + private void setScrollViewGravity(int gravity) { final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mBiometricScrollView.getLayoutParams(); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt index c8fb0449279f..8e5a97bd5d8d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/DisplayStateRepository.kt @@ -17,6 +17,7 @@ package com.android.systemui.biometrics.data.repository import android.content.Context +import android.util.DisplayMetrics import android.util.Size import android.view.DisplayInfo import com.android.systemui.biometrics.shared.model.DisplayRotation @@ -29,8 +30,10 @@ import com.android.systemui.display.data.repository.DeviceStateRepository.Device import com.android.systemui.display.data.repository.DisplayRepository import javax.inject.Inject import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn @@ -53,6 +56,9 @@ interface DisplayStateRepository { /** Provides the current display size */ val currentDisplaySize: StateFlow<Size> + + /** Provides whether the current display is large screen */ + val isLargeScreen: Flow<Boolean> } @SysUISingleton @@ -121,6 +127,15 @@ constructor( ), ) + override val isLargeScreen: Flow<Boolean> = + currentDisplayInfo + .map { + // TODO: This works, but investigate better way to handle this + it.logicalWidth * 160 / it.logicalDensityDpi > DisplayMetrics.DENSITY_XXXHIGH && + it.logicalHeight * 160 / it.logicalDensityDpi > DisplayMetrics.DENSITY_XXHIGH + } + .distinctUntilChanged() + companion object { const val TAG = "DisplayStateRepositoryImpl" } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt index 427361d4b17a..7d6721903c37 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractor.kt @@ -68,6 +68,8 @@ interface DisplayStateInteractor { /** Called on configuration changes, used to keep the display state in sync */ fun onConfigurationChanged(newConfig: Configuration) + + val isLargeScreen: Flow<Boolean> } /** Encapsulates logic for interacting with the display state. */ @@ -138,6 +140,8 @@ constructor( .sample(defaultDisplay) .map { it?.state == Display.STATE_OFF } + override val isLargeScreen: Flow<Boolean> = displayStateRepository.isLargeScreen + companion object { private const val TAG = "DisplayStateInteractor" } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt index 96582cb56dd7..e58c8ff92c03 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt @@ -31,7 +31,6 @@ import android.text.style.BulletSpan import android.view.LayoutInflater import android.view.View import android.widget.LinearLayout -import android.widget.ScrollView import android.widget.Space import android.widget.TextView import androidx.lifecycle.Lifecycle @@ -46,7 +45,7 @@ import kotlinx.coroutines.launch /** Sub-binder for [BiometricPromptLayout.customized_view_container]. */ object BiometricCustomizedViewBinder { - fun bind(customizedViewContainer: ScrollView, spaceAbove: Space, viewModel: PromptViewModel) { + fun bind(customizedViewContainer: LinearLayout, spaceAbove: Space, viewModel: PromptViewModel) { customizedViewContainer.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { launch { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt index ea3924732d41..e48f05d09fc4 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt @@ -32,7 +32,7 @@ import android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO import android.view.accessibility.AccessibilityManager import android.widget.Button import android.widget.ImageView -import android.widget.ScrollView +import android.widget.LinearLayout import android.widget.TextView import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.Lifecycle @@ -100,7 +100,7 @@ object BiometricViewBinder { val subtitleView = view.requireViewById<TextView>(R.id.subtitle) val descriptionView = view.requireViewById<TextView>(R.id.description) val customizedViewContainer = - view.requireViewById<ScrollView>(R.id.customized_view_container) + view.requireViewById<LinearLayout>(R.id.customized_view_container) // set selected to enable marquee unless a screen reader is enabled logoView.isSelected = @@ -118,7 +118,7 @@ object BiometricViewBinder { val iconSizeOverride = if (constraintBp()) { - viewModel.fingerprintAffordanceSize + null } else { (view as BiometricPromptLayout).updatedFingerprintAffordanceSize } @@ -652,6 +652,8 @@ class Spaghetti( fun isCoex() = modalities.hasFaceAndFingerprint + fun isFaceOnly() = modalities.hasFaceOnly + fun asView() = view } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt index 8336d5e5ae28..478ef8f296b2 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt @@ -100,6 +100,8 @@ object BiometricViewSizeBinder { val leftGuideline = view.requireViewById<Guideline>(R.id.leftGuideline) val rightGuideline = view.requireViewById<Guideline>(R.id.rightGuideline) val bottomGuideline = view.requireViewById<Guideline>(R.id.bottomGuideline) + val topGuideline = view.requireViewById<Guideline>(R.id.topGuideline) + val midGuideline = view.findViewById<Guideline>(R.id.midGuideline) val iconHolderView = view.requireViewById<View>(R.id.biometric_icon) val panelView = view.requireViewById<View>(R.id.panel) @@ -118,6 +120,23 @@ object BiometricViewSizeBinder { largeConstraintSet.setGuidelineEnd(rightGuideline.id, 0) largeConstraintSet.setGuidelineEnd(bottomGuideline.id, 0) + // TODO: Investigate better way to handle 180 rotations + val flipConstraintSet = ConstraintSet() + flipConstraintSet.clone(mediumConstraintSet) + flipConstraintSet.connect( + R.id.scrollView, + ConstraintSet.START, + R.id.midGuideline, + ConstraintSet.START + ) + flipConstraintSet.connect( + R.id.scrollView, + ConstraintSet.END, + R.id.rightGuideline, + ConstraintSet.END + ) + flipConstraintSet.setHorizontalBias(R.id.biometric_icon, .2f) + // Round the panel outline panelView.outlineProvider = object : ViewOutlineProvider() { @@ -133,70 +152,51 @@ object BiometricViewSizeBinder { .getInsets(WindowInsets.Type.navigationBars()) .bottom + // TODO: Move to viewmodel fun measureBounds(position: PromptPosition) { - val width = min(windowBounds.height(), windowBounds.width()) + val density = windowManager.currentWindowMetrics.density + val width = min((640 * density).toInt(), windowBounds.width()) var left = -1 - var top = -1 var right = -1 var bottom = -1 + var mid = -1 when { position.isTop -> { left = windowBounds.centerX() - width / 2 + viewModel.promptMargin - top = viewModel.promptMargin right = windowBounds.centerX() - width / 2 + viewModel.promptMargin bottom = iconHolderView.centerY() * 2 - iconHolderView.centerY() / 4 } position.isBottom -> { - if (view.isLandscape()) { - left = windowBounds.centerX() - width / 2 + viewModel.promptMargin - top = iconHolderView.centerY() - right = windowBounds.centerX() - width / 2 + viewModel.promptMargin - bottom = bottomInset + viewModel.promptMargin - } else { - left = windowBounds.centerX() - width / 2 + viewModel.promptMargin - top = - windowBounds.height() - - (windowBounds.height() - iconHolderView.centerY()) * 2 + - viewModel.promptMargin - right = windowBounds.centerX() - width / 2 + viewModel.promptMargin - bottom = viewModel.promptMargin - } + left = windowBounds.centerX() - width / 2 + viewModel.promptMargin + right = windowBounds.centerX() - width / 2 + viewModel.promptMargin + bottom = viewModel.promptMargin } - - // For Udfps exclusive left and right, measure guideline to center - // icon in BP position.isLeft -> { left = viewModel.promptMargin - top = - windowBounds.height() - - (windowBounds.height() - iconHolderView.centerY()) * 2 + - viewModel.promptMargin - right = + mid = abs( windowBounds.width() - iconHolderView.centerX() * 2 + viewModel.promptMargin ) + right = windowBounds.width() - (windowBounds.width() * .85).toInt() bottom = bottomInset + viewModel.promptMargin } position.isRight -> { - left = + left = windowBounds.width() - (windowBounds.width() * .85).toInt() + right = viewModel.promptMargin + bottom = bottomInset + viewModel.promptMargin + mid = abs( iconHolderView.centerX() - (windowBounds.width() - iconHolderView.centerX()) - viewModel.promptMargin ) - top = - windowBounds.height() - - (windowBounds.height() - iconHolderView.centerY()) * 2 + - viewModel.promptMargin - right = viewModel.promptMargin - bottom = bottomInset + viewModel.promptMargin } } - val bounds = Rect(left, top, right, bottom) + val bounds = Rect(left, mid, right, bottom) if (bounds.shouldAdjustLeftGuideline()) { leftGuideline.setGuidelineBegin(bounds.left) smallConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left) @@ -212,6 +212,18 @@ object BiometricViewSizeBinder { smallConstraintSet.setGuidelineEnd(bottomGuideline.id, bounds.bottom) mediumConstraintSet.setGuidelineEnd(bottomGuideline.id, bounds.bottom) } + + if (position.isBottom) { + topGuideline.setGuidelinePercent(.25f) + mediumConstraintSet.setGuidelinePercent(topGuideline.id, .25f) + } else { + topGuideline.setGuidelinePercent(0f) + mediumConstraintSet.setGuidelinePercent(topGuideline.id, 0f) + } + + if (mid != -1 && midGuideline != null) { + midGuideline.setGuidelineBegin(mid) + } } fun setConstraintSetVisibility() { @@ -242,6 +254,12 @@ object BiometricViewSizeBinder { combine(viewModel.position, viewModel.size, ::Pair).collect { (position, size) -> view.doOnAttach { + if (position.isLeft) { + flipConstraintSet.applyTo(view) + } else if (position.isRight) { + mediumConstraintSet.applyTo(view) + } + measureBounds(position) setConstraintSetVisibility() when { @@ -462,8 +480,14 @@ object BiometricViewSizeBinder { } private fun View.isLandscape(): Boolean { - val r = context.display?.rotation - return r == Surface.ROTATION_90 || r == Surface.ROTATION_270 + val r = context.display.rotation + return if ( + context.resources.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation) + ) { + r == Surface.ROTATION_0 || r == Surface.ROTATION_180 + } else { + r == Surface.ROTATION_90 || r == Surface.ROTATION_270 + } } private fun View.showContentOrHide(forceHide: Boolean = false): Int { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt index 2e47375b69fe..3469cfa210ba 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt @@ -37,6 +37,7 @@ import com.android.systemui.util.kotlin.Utils.Companion.toQuint import com.android.systemui.util.kotlin.Utils.Companion.toTriple import com.android.systemui.util.kotlin.sample import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch /** Sub-binder for [BiometricPromptLayout.iconView]. */ @@ -62,6 +63,12 @@ object PromptIconViewBinder { iconOverlayView.layoutParams.width = iconViewLayoutParamSizeOverride.first iconOverlayView.layoutParams.height = iconViewLayoutParamSizeOverride.second + } else { + iconView.layoutParams.width = viewModel.fingerprintIconWidth.first() + iconView.layoutParams.height = viewModel.fingerprintIconWidth.first() + + iconOverlayView.layoutParams.width = viewModel.fingerprintIconWidth.first() + iconOverlayView.layoutParams.height = viewModel.fingerprintIconWidth.first() } var faceIcon: AnimatedVectorDrawable? = null @@ -77,15 +84,12 @@ object PromptIconViewBinder { } launch { - var width: Int - var height: Int + var width = 0 + var height = 0 viewModel.activeAuthType.collect { activeAuthType -> when (activeAuthType) { AuthType.Fingerprint, AuthType.Coex -> { - width = viewModel.fingerprintIconWidth - height = viewModel.fingerprintIconHeight - /** * View is only set visible in BiometricViewSizeBinder once * PromptSize is determined that accounts for iconView size, to @@ -113,7 +117,7 @@ object PromptIconViewBinder { } } - if (iconViewLayoutParamSizeOverride == null) { + if (width != 0 && height != 0) { iconView.layoutParams.width = width iconView.layoutParams.height = height iconOverlayView.layoutParams.width = width diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt index b7cffaf2bcde..257eb4a60328 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt @@ -159,8 +159,8 @@ constructor( val lastPulseLightToDark: Flow<Boolean> = _lastPulseLightToDark.asStateFlow() /** Layout params for fingerprint iconView */ - val fingerprintIconWidth: Int = promptViewModel.fingerprintIconWidth - val fingerprintIconHeight: Int = promptViewModel.fingerprintIconHeight + val fingerprintIconWidth: Flow<Int> = promptViewModel.fingerprintSensorDiameter + val fingerprintIconHeight: Flow<Int> = promptViewModel.fingerprintSensorDiameter /** Layout params for face iconView */ val faceIconWidth: Int = promptViewModel.faceIconWidth diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt index 2c749baadb9c..61aeffe03b5d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt @@ -85,14 +85,15 @@ constructor( val faceIconHeight: Int = context.resources.getDimensionPixelSize(R.dimen.biometric_dialog_face_icon_size) - val fingerprintSensorDiameter: Int = - (udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds.width() * - udfpsOverlayInteractor.udfpsOverlayParams.value.scaleFactor) - .toInt() - val fingerprintAffordanceSize: Pair<Int, Int>? = - if (fingerprintSensorDiameter != 0) - Pair(fingerprintSensorDiameter, fingerprintSensorDiameter) - else null + val fingerprintSensorDiameter: Flow<Int> = + combine(modalities, udfpsOverlayInteractor.udfpsOverlayParams) { modalities, overlayParams + -> + if (modalities.hasUdfps) { + overlayParams.sensorBounds.width() + } else { + fingerprintIconWidth + } + } private val _accessibilityHint = MutableSharedFlow<String>() @@ -157,12 +158,13 @@ constructor( /** The current position of the prompt */ val position: Flow<PromptPosition> = - combine(_forceLargeSize, modalities, displayStateInteractor.currentRotation) { - forceLarge, - modalities, - rotation -> + combine( + _forceLargeSize, + displayStateInteractor.isLargeScreen, + displayStateInteractor.currentRotation + ) { forceLarge, isLargeScreen, rotation -> when { - forceLarge || !modalities.hasUdfps -> PromptPosition.Bottom + forceLarge || isLargeScreen -> PromptPosition.Bottom rotation == DisplayRotation.ROTATION_90 -> PromptPosition.Right rotation == DisplayRotation.ROTATION_270 -> PromptPosition.Left rotation == DisplayRotation.ROTATION_180 -> PromptPosition.Top @@ -344,22 +346,22 @@ constructor( /** If the indicator (help, error) message should be shown. */ val isIndicatorMessageVisible: Flow<Boolean> = combine( - size, - message, - ) { size, message -> - size.isNotSmall && message.message.isNotBlank() - } - .distinctUntilChanged() + size, + position, + message, + ) { size, _, message -> + size.isNotSmall && message.message.isNotBlank() + } /** If the auth is pending confirmation and the confirm button should be shown. */ val isConfirmButtonVisible: Flow<Boolean> = combine( - size, - isPendingConfirmation, - ) { size, isPendingConfirmation -> - size.isNotSmall && isPendingConfirmation - } - .distinctUntilChanged() + size, + position, + isPendingConfirmation, + ) { size, _, isPendingConfirmation -> + size.isNotSmall && isPendingConfirmation + } /** If the icon can be used as a confirmation button. */ val isIconConfirmButton: Flow<Boolean> = size.map { it.isNotSmall }.distinctUntilChanged() @@ -367,28 +369,25 @@ constructor( /** If the negative button should be shown. */ val isNegativeButtonVisible: Flow<Boolean> = combine( - size, - isAuthenticated, - promptSelectorInteractor.isCredentialAllowed, - ) { size, authState, credentialAllowed -> - size.isNotSmall && authState.isNotAuthenticated && !credentialAllowed - } - .distinctUntilChanged() + size, + position, + isAuthenticated, + promptSelectorInteractor.isCredentialAllowed, + ) { size, _, authState, credentialAllowed -> + size.isNotSmall && authState.isNotAuthenticated && !credentialAllowed + } /** If the cancel button should be shown (. */ val isCancelButtonVisible: Flow<Boolean> = combine( - size, - isAuthenticated, - isNegativeButtonVisible, - isConfirmButtonVisible, - ) { size, authState, showNegativeButton, showConfirmButton -> - size.isNotSmall && - authState.isAuthenticated && - !showNegativeButton && - showConfirmButton - } - .distinctUntilChanged() + size, + position, + isAuthenticated, + isNegativeButtonVisible, + isConfirmButtonVisible, + ) { size, _, authState, showNegativeButton, showConfirmButton -> + size.isNotSmall && authState.isAuthenticated && !showNegativeButton && showConfirmButton + } private val _canTryAgainNow = MutableStateFlow(false) /** @@ -397,35 +396,34 @@ constructor( */ val canTryAgainNow: Flow<Boolean> = combine( - _canTryAgainNow, - size, - isAuthenticated, - isRetrySupported, - ) { readyToTryAgain, size, authState, supportsRetry -> - readyToTryAgain && size.isNotSmall && supportsRetry && authState.isNotAuthenticated - } - .distinctUntilChanged() + _canTryAgainNow, + size, + position, + isAuthenticated, + isRetrySupported, + ) { readyToTryAgain, size, _, authState, supportsRetry -> + readyToTryAgain && size.isNotSmall && supportsRetry && authState.isNotAuthenticated + } /** If the try again button show be shown (only the button, see [canTryAgainNow]). */ val isTryAgainButtonVisible: Flow<Boolean> = combine( - canTryAgainNow, - modalities, - ) { tryAgainIsPossible, modalities -> - tryAgainIsPossible && modalities.hasFaceOnly - } - .distinctUntilChanged() + canTryAgainNow, + modalities, + ) { tryAgainIsPossible, modalities -> + tryAgainIsPossible && modalities.hasFaceOnly + } /** If the credential fallback button show be shown. */ val isCredentialButtonVisible: Flow<Boolean> = combine( - size, - isAuthenticated, - promptSelectorInteractor.isCredentialAllowed, - ) { size, authState, credentialAllowed -> - size.isNotSmall && authState.isNotAuthenticated && credentialAllowed - } - .distinctUntilChanged() + size, + position, + isAuthenticated, + promptSelectorInteractor.isCredentialAllowed, + ) { size, _, authState, credentialAllowed -> + size.isNotSmall && authState.isNotAuthenticated && credentialAllowed + } private val history = PromptHistoryImpl() private var messageJob: Job? = null diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/SimBouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/SimBouncerRepository.kt index 269878b43dab..b9e1c55fbade 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/SimBouncerRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/SimBouncerRepository.kt @@ -92,7 +92,7 @@ constructor( keyguardUpdateMonitor: KeyguardUpdateMonitor, private val subscriptionManager: SubscriptionManagerProxy, broadcastDispatcher: BroadcastDispatcher, - euiccManager: EuiccManager, + euiccManager: EuiccManager?, ) : SimBouncerRepository { private val isPukScreenAvailable: Boolean = resources.getBoolean(com.android.internal.R.bool.config_enable_puk_unlock_screen) @@ -163,7 +163,9 @@ constructor( @SuppressLint("MissingPermission") override val isLockedEsim: StateFlow<Boolean?> = activeSubscriptionInfo - .map { info -> info?.let { euiccManager.isEnabled && info.isEmbedded } } + .map { info -> + info?.let { euiccManager != null && euiccManager.isEnabled && info.isEmbedded } + } .stateIn( scope = applicationScope, started = SharingStarted.Eagerly, diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorModule.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorModule.kt index efa77926a423..0f61eef7cb96 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorModule.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorModule.kt @@ -50,7 +50,7 @@ object BouncerInteractorModule { } @Provides - fun provideEuiccManager(@Application applicationContext: Context): EuiccManager { - return applicationContext.getSystemService(Context.EUICC_SERVICE) as EuiccManager + fun provideEuiccManager(@Application applicationContext: Context): EuiccManager? { + return applicationContext.getSystemService(Context.EUICC_SERVICE) as EuiccManager? } } diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractor.kt index 99d1f1370f4f..c3d4cb30e700 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractor.kt @@ -61,7 +61,7 @@ constructor( private val telephonyManager: TelephonyManager, @Main private val resources: Resources, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, - private val euiccManager: EuiccManager, + private val euiccManager: EuiccManager?, // TODO(b/307977401): Replace this with `MobileConnectionsInteractor` when available. mobileConnectionsRepository: MobileConnectionsRepository, ) { @@ -141,11 +141,13 @@ constructor( UserHandle.SYSTEM ) applicationScope.launch(backgroundDispatcher) { - euiccManager.switchToSubscription( - INVALID_SUBSCRIPTION_ID, - activeSubscription.portIndex, - callbackIntent, - ) + if (euiccManager != null) { + euiccManager.switchToSubscription( + INVALID_SUBSCRIPTION_ID, + activeSubscription.portIndex, + callbackIntent, + ) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt b/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt new file mode 100644 index 000000000000..e789475b7877 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlags.kt @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.bouncer.shared.flag + +import com.android.systemui.Flags +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.scene.shared.flag.SceneContainerFlags +import dagger.Module +import dagger.Provides + +interface ComposeBouncerFlags { + + /** + * Returns `true` if the Compose bouncer is enabled or if the scene container framework is + * enabled; `false` otherwise. + */ + fun isComposeBouncerOrSceneContainerEnabled(): Boolean + + /** + * Returns `true` if only compose bouncer is enabled and scene container framework is not + * enabled. + */ + @Deprecated( + "Avoid using this, this is meant to be used only by the glue code " + + "that includes compose bouncer in legacy keyguard.", + replaceWith = ReplaceWith("isComposeBouncerOrSceneContainerEnabled()") + ) + fun isOnlyComposeBouncerEnabled(): Boolean +} + +class ComposeBouncerFlagsImpl(private val sceneContainerFlags: SceneContainerFlags) : + ComposeBouncerFlags { + + override fun isComposeBouncerOrSceneContainerEnabled(): Boolean { + return sceneContainerFlags.isEnabled() || Flags.composeBouncer() + } + + @Deprecated( + "Avoid using this, this is meant to be used only by the glue code " + + "that includes compose bouncer in legacy keyguard.", + replaceWith = ReplaceWith("isComposeBouncerOrSceneContainerEnabled()") + ) + override fun isOnlyComposeBouncerEnabled(): Boolean { + return !sceneContainerFlags.isEnabled() && Flags.composeBouncer() + } +} + +@Module +object ComposeBouncerFlagsModule { + @Provides + @SysUISingleton + fun impl(sceneContainerFlags: SceneContainerFlags): ComposeBouncerFlags { + return ComposeBouncerFlagsImpl(sceneContainerFlags) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt index dd253a8f6eff..36d3ed52b655 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt @@ -4,10 +4,10 @@ import android.view.ViewGroup import com.android.keyguard.KeyguardMessageAreaController import com.android.keyguard.ViewMediatorCallback import com.android.keyguard.dagger.KeyguardBouncerComponent -import com.android.systemui.Flags import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor +import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags import com.android.systemui.bouncer.ui.BouncerDialogFactory import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel @@ -55,12 +55,15 @@ constructor( class BouncerViewBinder @Inject constructor( + private val composeBouncerFlags: ComposeBouncerFlags, private val legacyBouncerDependencies: Lazy<LegacyBouncerDependencies>, private val composeBouncerDependencies: Lazy<ComposeBouncerDependencies>, ) { fun bind(view: ViewGroup) { if ( - ComposeFacade.isComposeAvailable() && Flags.composeBouncer() && COMPOSE_BOUNCER_ENABLED + COMPOSE_BOUNCER_ENABLED && + composeBouncerFlags.isOnlyComposeBouncerEnabled() && + ComposeFacade.isComposeAvailable() ) { val deps = composeBouncerDependencies.get() ComposeBouncerViewBinder.bind( diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt index 4466cbbe05be..62875783ef5f 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt @@ -28,6 +28,7 @@ import com.android.systemui.authentication.shared.model.AuthenticationWipeModel import com.android.systemui.bouncer.domain.interactor.BouncerActionButtonInteractor import com.android.systemui.bouncer.domain.interactor.BouncerInteractor import com.android.systemui.bouncer.domain.interactor.SimBouncerInteractor +import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags import com.android.systemui.bouncer.shared.model.BouncerActionButtonModel import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text @@ -35,7 +36,6 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.inputmethod.domain.interactor.InputMethodInteractor -import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.user.domain.interactor.SelectedUserInteractor import com.android.systemui.user.ui.viewmodel.UserActionViewModel import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel @@ -72,7 +72,7 @@ class BouncerViewModel( private val simBouncerInteractor: SimBouncerInteractor, private val authenticationInteractor: AuthenticationInteractor, private val selectedUserInteractor: SelectedUserInteractor, - flags: SceneContainerFlags, + flags: ComposeBouncerFlags, selectedUser: Flow<UserViewModel>, users: Flow<List<UserViewModel>>, userSwitcherMenu: Flow<List<UserActionViewModel>>, @@ -233,7 +233,7 @@ class BouncerViewModel( private var lockoutCountdownJob: Job? = null init { - if (flags.isEnabled()) { + if (flags.isComposeBouncerOrSceneContainerEnabled()) { // Keeps the lockout dialog up-to-date. applicationScope.launch { bouncerInteractor.onLockoutStarted.collect { @@ -478,7 +478,7 @@ object BouncerViewModelModule { actionButtonInteractor: BouncerActionButtonInteractor, authenticationInteractor: AuthenticationInteractor, selectedUserInteractor: SelectedUserInteractor, - flags: SceneContainerFlags, + flags: ComposeBouncerFlags, userSwitcherViewModel: UserSwitcherViewModel, clock: SystemClock, devicePolicyManager: DevicePolicyManager, diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt index cf7d60140aee..baae986c494d 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt @@ -62,6 +62,10 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.UserRepository import com.google.errorprone.annotations.CompileTimeConstant +import java.io.PrintWriter +import java.util.Arrays +import java.util.stream.Collectors +import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job @@ -83,10 +87,6 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.io.PrintWriter -import java.util.Arrays -import java.util.stream.Collectors -import javax.inject.Inject /** * API to run face authentication and detection for device entry / on keyguard (as opposed to the @@ -431,11 +431,11 @@ constructor( override fun onAuthenticationFailed() { _isAuthenticated.value = false faceAuthLogger.authenticationFailed() + _authenticationStatus.value = FailedFaceAuthenticationStatus() if (!_isLockedOut.value) { // onAuthenticationError gets invoked before onAuthenticationFailed when the // last auth attempt locks out face authentication. - // Skip updating the authentication status in such a scenario. - _authenticationStatus.value = FailedFaceAuthenticationStatus() + // Skip onFaceAuthRequestCompleted in such a scenario. onFaceAuthRequestCompleted() } } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractor.kt index 6bfe8d91b5fc..846013cef326 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/BiometricMessageInteractor.kt @@ -21,9 +21,12 @@ import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInte import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.deviceentry.shared.model.ErrorFaceAuthenticationStatus +import com.android.systemui.deviceentry.shared.model.FaceFailureMessage +import com.android.systemui.deviceentry.shared.model.FaceLockoutMessage import com.android.systemui.deviceentry.shared.model.FaceMessage import com.android.systemui.deviceentry.shared.model.FaceTimeoutMessage import com.android.systemui.deviceentry.shared.model.FailedFaceAuthenticationStatus +import com.android.systemui.deviceentry.shared.model.FingerprintFailureMessage import com.android.systemui.deviceentry.shared.model.FingerprintLockoutMessage import com.android.systemui.deviceentry.shared.model.FingerprintMessage import com.android.systemui.deviceentry.shared.model.HelpFaceAuthenticationStatus @@ -97,11 +100,7 @@ constructor( fingerprintAuthInteractor.fingerprintHelp .sample(biometricSettingsInteractor.fingerprintAuthCurrentlyAllowed, ::Pair) .filter { (_, fingerprintAuthAllowed) -> fingerprintAuthAllowed } - .map { (helpStatus, _) -> - FingerprintMessage( - helpStatus.msg, - ) - } + .map { (helpStatus, _) -> FingerprintMessage(helpStatus.msg) } private val fingerprintFailMessage: Flow<FingerprintMessage> = fingerprintPropertyInteractor.isUdfps.flatMapLatest { isUdfps -> @@ -109,7 +108,7 @@ constructor( .sample(biometricSettingsInteractor.fingerprintAuthCurrentlyAllowed) .filter { fingerprintAuthAllowed -> fingerprintAuthAllowed } .map { - FingerprintMessage( + FingerprintFailureMessage( if (isUdfps) { resources.getString( com.android.internal.R.string.fingerprint_udfps_error_not_match @@ -118,7 +117,7 @@ constructor( resources.getString( com.android.internal.R.string.fingerprint_error_not_match ) - }, + } ) } } @@ -154,7 +153,7 @@ constructor( faceFailure .sample(biometricSettingsInteractor.faceAuthCurrentlyAllowed) .filter { faceAuthCurrentlyAllowed -> faceAuthCurrentlyAllowed } - .map { FaceMessage(resources.getString(R.string.keyguard_face_failed)) } + .map { FaceFailureMessage(resources.getString(R.string.keyguard_face_failed)) } private val faceErrorMessage: Flow<FaceMessage> = faceError @@ -173,6 +172,7 @@ constructor( FaceTimeoutMessage(status.msg) } } + status.isLockoutError() -> FaceLockoutMessage(status.msg) else -> FaceMessage(status.msg) } } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/BiometricMessageModels.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/BiometricMessageModels.kt index 59c3f7f8aded..2ced8c41713f 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/BiometricMessageModels.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/BiometricMessageModels.kt @@ -32,9 +32,15 @@ data class FaceTimeoutMessage( private val faceTimeoutMessage: String?, ) : FaceMessage(faceTimeoutMessage) +data class FaceLockoutMessage(private val msg: String?) : FaceMessage(msg) + +data class FaceFailureMessage(private val msg: String) : FaceMessage(msg) + /** Fingerprint biometric message */ open class FingerprintMessage(fingerprintMessage: String?) : BiometricMessage(fingerprintMessage) data class FingerprintLockoutMessage( private val fingerprintLockoutMessage: String?, ) : FingerprintMessage(fingerprintLockoutMessage) + +data class FingerprintFailureMessage(private val msg: String?) : FingerprintMessage(msg) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt index 0ea53906b7f8..7ad5aac63837 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardClockRepository.kt @@ -59,7 +59,7 @@ interface KeyguardClockRepository { val currentClock: StateFlow<ClockController?> - val previewClock: StateFlow<ClockController> + val previewClockPair: StateFlow<Pair<ClockController, ClockController>> val clockEventController: ClockEventController fun setClockSize(@ClockSize size: Int) @@ -120,13 +120,14 @@ constructor( initialValue = clockRegistry.createCurrentClock() ) - override val previewClock: StateFlow<ClockController> = + override val previewClockPair: StateFlow<Pair<ClockController, ClockController>> = currentClockId - .map { clockRegistry.createCurrentClock() } + .map { Pair(clockRegistry.createCurrentClock(), clockRegistry.createCurrentClock()) } .stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), - initialValue = clockRegistry.createCurrentClock() + initialValue = + Pair(clockRegistry.createCurrentClock(), clockRegistry.createCurrentClock()) ) @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt index 64e28700aa74..ad0c3fb0c53a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt @@ -24,7 +24,6 @@ import com.android.systemui.biometrics.AuthController import com.android.systemui.biometrics.data.repository.FacePropertyRepository import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow -import com.android.systemui.common.shared.model.Position import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main @@ -80,12 +79,6 @@ interface KeyguardRepository { val keyguardAlpha: StateFlow<Float> /** - * Observable of the relative offset of the lock-screen clock from its natural position on the - * screen. - */ - val clockPosition: StateFlow<Position> - - /** * Observable for whether the keyguard is showing. * * Note: this is also `true` when the lock-screen is occluded with an `Activity` "above" it in @@ -240,11 +233,6 @@ interface KeyguardRepository { fun setKeyguardAlpha(alpha: Float) /** - * Sets the relative offset of the lock-screen clock from its natural position on the screen. - */ - fun setClockPosition(x: Int, y: Int) - - /** * Returns whether the keyguard bottom area should be constrained to the top of the lock icon */ fun isUdfpsSupported(): Boolean @@ -323,9 +311,6 @@ constructor( private val _keyguardAlpha = MutableStateFlow(1f) override val keyguardAlpha = _keyguardAlpha.asStateFlow() - private val _clockPosition = MutableStateFlow(Position(0, 0)) - override val clockPosition = _clockPosition.asStateFlow() - private val _clockShouldBeCentered = MutableStateFlow(true) override val clockShouldBeCentered: Flow<Boolean> = _clockShouldBeCentered.asStateFlow() @@ -677,10 +662,6 @@ constructor( _keyguardAlpha.value = alpha } - override fun setClockPosition(x: Int, y: Int) { - _clockPosition.value = Position(x, y) - } - override fun isUdfpsSupported(): Boolean = keyguardUpdateMonitor.isUdfpsSupported override fun setQuickSettingsVisible(isVisible: Boolean) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt index 7ae70a9a3e7c..ee892a800b63 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractor.kt @@ -63,18 +63,19 @@ constructor( burnInHelperWrapper.burnInProgressOffset() ) - val keyguardBurnIn: Flow<BurnInModel> = - combine( - burnInOffset(R.dimen.burn_in_prevention_offset_x, isXAxis = true), - burnInOffset(R.dimen.burn_in_prevention_offset_y, isXAxis = false).map { - it * 2 - - context.resources.getDimensionPixelSize(R.dimen.burn_in_prevention_offset_y) + /** Given the max x,y dimens, determine the current translation shifts. */ + fun burnIn(xDimenResourceId: Int, yDimenResourceId: Int): Flow<BurnInModel> { + return combine( + burnInOffset(xDimenResourceId, isXAxis = true), + burnInOffset(yDimenResourceId, isXAxis = false).map { + it * 2 - context.resources.getDimensionPixelSize(yDimenResourceId) } ) { translationX, translationY -> BurnInModel(translationX, translationY, burnInHelperWrapper.burnInScale()) } .distinctUntilChanged() .stateIn(scope, SharingStarted.Lazily, BurnInModel()) + } /** * Use for max burn-in offsets that are NOT specified in pixels. This flow will recalculate the diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt index d2a7486eed0b..e5bb5a081b70 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardBottomAreaInteractor.kt @@ -22,6 +22,8 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.data.repository.KeyguardRepository import javax.inject.Inject import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow /** Encapsulates business-logic specifically related to the keyguard bottom area. */ @SysUISingleton @@ -35,10 +37,12 @@ constructor( /** The amount of alpha for the UI components of the bottom area. */ val alpha: Flow<Float> = repository.bottomAreaAlpha /** The position of the keyguard clock. */ - val clockPosition: Flow<Position> = repository.clockPosition + private val _clockPosition = MutableStateFlow(Position(0, 0)) + @Deprecated("with migrateClocksToBlueprint()") + val clockPosition: Flow<Position> = _clockPosition.asStateFlow() fun setClockPosition(x: Int, y: Int) { - repository.setClockPosition(x, y) + _clockPosition.value = Position(x, y) } fun setAlpha(alpha: Float) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt index 196770ae2f9a..2cf91563b3e4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt @@ -44,7 +44,8 @@ constructor( val currentClock: StateFlow<ClockController?> = keyguardClockRepository.currentClock - val previewClock: StateFlow<ClockController> = keyguardClockRepository.previewClock + val previewClockPair: StateFlow<Pair<ClockController, ClockController>> = + keyguardClockRepository.previewClockPair var clock: ClockController? by keyguardClockRepository.clockEventController::clock diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt index 78749ead7ef9..8b06b85e70c9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt @@ -27,7 +27,6 @@ import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.common.shared.model.NotificationContainerBounds -import com.android.systemui.common.shared.model.Position import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.data.repository.KeyguardRepository @@ -232,9 +231,6 @@ constructor( /** The approximate location on the screen of the face unlock sensor, if one is available. */ val faceSensorLocation: Flow<Point?> = repository.faceSensorLocation - /** The position of the keyguard clock. */ - val clockPosition: Flow<Position> = repository.clockPosition - @Deprecated("Use the relevant TransitionViewModel") val keyguardAlpha: Flow<Float> = repository.keyguardAlpha @@ -342,10 +338,6 @@ constructor( repository.setQuickSettingsVisible(isVisible) } - fun setClockPosition(x: Int, y: Int) { - repository.setClockPosition(x, y) - } - fun setAlpha(alpha: Float) { repository.setKeyguardAlpha(alpha) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt index 719edd7e8535..37b331cd8455 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt @@ -35,6 +35,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.OFF import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep +import com.android.systemui.util.kotlin.pairwise import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -46,6 +47,7 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.shareIn +import kotlinx.coroutines.flow.stateIn /** Encapsulates business-logic related to the keyguard transitions. */ @OptIn(ExperimentalCoroutinesApi::class) @@ -206,6 +208,21 @@ constructor( .shareIn(scope, SharingStarted.Eagerly, replay = 1) /** + * A pair of the most recent STARTED step, and the transition step immediately preceding it. The + * transition framework enforces that the previous step is either a CANCELED or FINISHED step, + * and that the previous step was *to* the state the STARTED step is *from*. + * + * This flow can be used to access the previous step to determine whether it was CANCELED or + * FINISHED. In the case of a CANCELED step, we can also figure out which state we were coming + * from when we were canceled. + */ + val startedStepWithPrecedingStep = + transitions + .pairwise() + .filter { it.newValue.transitionState == TransitionState.STARTED } + .stateIn(scope, SharingStarted.Eagerly, null) + + /** * The last [KeyguardState] to which we [TransitionState.FINISHED] a transition. * * WARNING: This will NOT emit a value if a transition is CANCELED, and will also not emit a diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt index b81793ecec64..cff74b333530 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt @@ -19,7 +19,9 @@ package com.android.systemui.keyguard.domain.interactor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.shared.model.BiometricUnlockModel import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor +import com.android.systemui.util.kotlin.sample import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow @@ -121,19 +123,27 @@ constructor( * want to know if the AOD/clock/notifs/etc. are visible. */ val lockscreenVisibility: Flow<Boolean> = - combine( - transitionInteractor.startedKeyguardTransitionStep, - transitionInteractor.finishedKeyguardState, - ) { startedStep, finishedState -> - // If we finished the transition, use the finished state. If we're running a - // transition, use the state we're transitioning FROM. This can be different from - // the last finished state if a transition is interrupted. For example, if we were - // transitioning from GONE to AOD and then started AOD -> LOCKSCREEN mid-transition, - // we want to immediately use the visibility for AOD (lockscreenVisibility=true) - // even though the lastFinishedState is still GONE (lockscreenVisibility=false). - if (finishedState == startedStep.to) finishedState else startedStep.from + transitionInteractor.currentKeyguardState + .sample(transitionInteractor.startedStepWithPrecedingStep, ::Pair) + .map { (currentState, startedWithPrev) -> + val startedFromStep = startedWithPrev?.previousValue + val startedStep = startedWithPrev?.newValue + val returningToGoneAfterCancellation = + startedStep?.to == KeyguardState.GONE && + startedFromStep?.transitionState == TransitionState.CANCELED && + startedFromStep.from == KeyguardState.GONE + + if (!returningToGoneAfterCancellation) { + // By default, apply the lockscreen visibility of the current state. + KeyguardState.lockscreenVisibleInState(currentState) + } else { + // If we're transitioning to GONE after a prior canceled transition from GONE, + // then this is the camera launch transition from an asleep state back to GONE. + // We don't want to show the lockscreen since we're aborting the lock and going + // back to GONE. + KeyguardState.lockscreenVisibleInState(KeyguardState.GONE) + } } - .map(KeyguardState::lockscreenVisibleInState) .distinctUntilChanged() /** diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt index 66fc99567d42..462d5e6568b0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt @@ -36,6 +36,7 @@ import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.lifecycle.repeatWhenAttached +import com.android.systemui.res.R import javax.inject.Inject import kotlin.math.max import kotlinx.coroutines.launch @@ -127,6 +128,7 @@ constructor( runTransition(constraintLayout, transition, Config.DEFAULT) { // Add and remove views of sections that are not contained by the other. blueprint.replaceViews(prevBluePrint, constraintLayout) + logAlphaVisibilityOfAppliedConstraintSet(cs, clockViewModel) cs.applyTo(constraintLayout) } @@ -153,6 +155,7 @@ constructor( ), transition, ) { + logAlphaVisibilityOfAppliedConstraintSet(cs, clockViewModel) cs.applyTo(constraintLayout) } Trace.endSection() @@ -205,4 +208,23 @@ constructor( apply() } } + + private fun logAlphaVisibilityOfAppliedConstraintSet( + cs: ConstraintSet, + viewModel: KeyguardClockViewModel + ) { + if (!DEBUG || viewModel.clock == null) return + val smallClockViewId = R.id.lockscreen_clock_view + val largeClockViewId = viewModel.clock!!.largeClock.layout.views[0].id + Log.i( + TAG, + "applyCsToSmallClock: vis=${cs.getVisibility(smallClockViewId)} " + + "alpha=${cs.getConstraint(smallClockViewId).propertySet}" + ) + Log.i( + TAG, + "applyCsToLargeClock: vis=${cs.getVisibility(largeClockViewId)} " + + "alpha=${cs.getConstraint(largeClockViewId).propertySet}" + ) + } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt index b56c99864c0b..46c354a45c92 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt @@ -72,38 +72,47 @@ object KeyguardPreviewClockViewBinder { @JvmStatic fun bind( context: Context, + displayId: Int, rootView: ConstraintLayout, viewModel: KeyguardPreviewClockViewModel, clockEventController: ClockEventController, - updateClockAppearance: KSuspendFunction1<ClockController, Unit> + updateClockAppearance: KSuspendFunction1<ClockController, Unit>, ) { + // TODO(b/327668072): When this function is called multiple times, the clock view can be + // gone due to a race condition on removeView and addView. rootView.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.STARTED) { launch { - combine(viewModel.selectedClockSize, viewModel.previewClock) { _, clock -> + combine(viewModel.selectedClockSize, viewModel.previewClockPair) { _, clock -> clock } - .collect { previewClock -> - viewModel.lastClock?.let { lastClock -> - (lastClock.largeClock.layout.views + - lastClock.smallClock.layout.views) + .collect { previewClockPair -> + viewModel.lastClockPair?.let { clockPair -> + (clockPair.first.largeClock.layout.views + + clockPair.first.smallClock.layout.views) + .forEach { rootView.removeView(it) } + (clockPair.second.largeClock.layout.views + + clockPair.second.smallClock.layout.views) .forEach { rootView.removeView(it) } } - viewModel.lastClock = previewClock - clockEventController.clock = previewClock - updateClockAppearance(previewClock) + viewModel.lastClockPair = previewClockPair + val clockPreview = + if (displayId == 0) previewClockPair.first + else previewClockPair.second + clockEventController.clock = clockPreview + updateClockAppearance(clockPreview) if (viewModel.shouldHighlightSelectedAffordance) { - (previewClock.largeClock.layout.views + - previewClock.smallClock.layout.views) + (clockPreview.largeClock.layout.views + + clockPreview.smallClock.layout.views) .forEach { it.alpha = KeyguardPreviewRenderer.DIM_ALPHA } } - previewClock.largeClock.layout.views.forEach { + clockPreview.largeClock.layout.views.forEach { (it.parent as? ViewGroup)?.removeView(it) rootView.addView(it) } - previewClock.smallClock.layout.views.forEach { + clockPreview.smallClock.layout.views.forEach { (it.parent as? ViewGroup)?.removeView(it) rootView.addView(it) } @@ -164,10 +173,12 @@ object KeyguardPreviewClockViewBinder { viewModel: KeyguardPreviewClockViewModel ) { val cs = ConstraintSet().apply { clone(rootView) } - val clock = viewModel.previewClock.value + val clockPair = viewModel.previewClockPair.value applyClockDefaultConstraints(context, cs) - clock.largeClock.layout.applyPreviewConstraints(cs) - clock.smallClock.layout.applyPreviewConstraints(cs) + clockPair.first.largeClock.layout.applyPreviewConstraints(cs) + clockPair.first.smallClock.layout.applyPreviewConstraints(cs) + clockPair.second.largeClock.layout.applyPreviewConstraints(cs) + clockPair.second.smallClock.layout.applyPreviewConstraints(cs) // When selectedClockSize is the initial value, make both clocks invisible to avoid // flickering @@ -185,8 +196,10 @@ object KeyguardPreviewClockViewBinder { } cs.apply { - setVisibility(clock.largeClock.layout.views, largeClockVisibility) - setVisibility(clock.smallClock.layout.views, smallClockVisibility) + setVisibility(clockPair.first.largeClock.layout.views, largeClockVisibility) + setVisibility(clockPair.first.smallClock.layout.views, smallClockVisibility) + setVisibility(clockPair.second.largeClock.layout.views, largeClockVisibility) + setVisibility(clockPair.second.smallClock.layout.views, smallClockVisibility) } cs.applyTo(rootView) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt index f95efaab75f4..7c76e6afc074 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt @@ -408,6 +408,7 @@ constructor( if (migrateClocksToBlueprint()) { KeyguardPreviewClockViewBinder.bind( context, + displayId, keyguardRootView, clockViewModel, clockController, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt index 98bebd091f1a..e67a3245bc85 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt @@ -21,6 +21,8 @@ import android.content.Context import android.view.View import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet +import androidx.constraintlayout.widget.ConstraintSet.BOTTOM +import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.keyguard.ui.view.KeyguardRootView @@ -37,13 +39,18 @@ constructor( private val clockViewModel: KeyguardClockViewModel, ) : KeyguardSection() { private lateinit var burnInLayer: AodBurnInLayer + private lateinit var emptyView: View override fun addViews(constraintLayout: ConstraintLayout) { if (!migrateClocksToBlueprint()) { return } // The burn-in layer requires at least 1 view at all times - val emptyView = View(context, null).apply { id = View.generateViewId() } + emptyView = + View(context, null).apply { + id = R.id.burn_in_layer_empty_view + visibility = View.GONE + } constraintLayout.addView(emptyView) burnInLayer = AodBurnInLayer(context).apply { @@ -70,6 +77,13 @@ constructor( if (!migrateClocksToBlueprint()) { return } + + constraintSet.apply { + // The empty view should not occupy any space + constrainHeight(R.id.burn_in_layer_empty_view, 1) + constrainWidth(R.id.burn_in_layer_empty_view, 0) + connect(R.id.burn_in_layer_empty_view, BOTTOM, PARENT_ID, BOTTOM) + } } override fun removeViews(constraintLayout: ConstraintLayout) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt index a22671d42e94..a183b720c087 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt @@ -52,6 +52,11 @@ internal fun ConstraintSet.setVisibility( visibility: Int, ) = views.forEach { view -> this.setVisibility(view.id, visibility) } +internal fun ConstraintSet.setAlpha( + views: Iterable<View>, + alpha: Float, +) = views.forEach { view -> this.setAlpha(view.id, alpha) } + open class ClockSection @Inject constructor( @@ -101,6 +106,8 @@ constructor( return constraintSet.apply { setVisibility(getTargetClockFace(clock).views, VISIBLE) setVisibility(getNonTargetClockFace(clock).views, GONE) + setAlpha(getTargetClockFace(clock).views, 1F) + setAlpha(getNonTargetClockFace(clock).views, 0F) if (!keyguardClockViewModel.useLargeClock) { connect(sharedR.id.bc_smartspace_view, TOP, sharedR.id.date_smartspace_view, BOTTOM) } @@ -179,7 +186,7 @@ constructor( context.resources.getDimensionPixelSize(customizationR.dimen.clock_padding_start) + context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal) ) - var smallClockTopMargin = + val smallClockTopMargin = if (splitShadeStateController.shouldUseSplitNotificationShade(context.resources)) { context.resources.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin) } else { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt index f65f3760f082..4ddd039edbaa 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/transitions/ClockSizeTransition.kt @@ -200,7 +200,7 @@ class ClockSizeTransition( arrayOf(PROP_VISIBILITY, PROP_ALPHA, PROP_BOUNDS, SMARTSPACE_BOUNDS) private val DEBUG = true - private val TAG = ClockFaceInTransition::class.simpleName!! + private val TAG = VisibilityBoundsTransition::class.simpleName!! } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt index 7be390a4526f..62fc1da5a444 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt @@ -18,6 +18,7 @@ package com.android.systemui.keyguard.ui.viewmodel +import android.util.Log import android.util.MathUtils import com.android.app.animation.Interpolators import com.android.keyguard.KeyguardClockSwitch @@ -62,6 +63,8 @@ constructor( private val occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel, private val keyguardClockViewModel: KeyguardClockViewModel, ) { + private val TAG = "AodBurnInViewModel" + /** Horizontal translation for elements that need to apply anti-burn-in tactics. */ fun translationX( params: BurnInParameters, @@ -71,8 +74,17 @@ constructor( /** Vertical translation for elements that need to apply anti-burn-in tactics. */ fun translationY( - params: BurnInParameters, + burnInParams: BurnInParameters, ): Flow<Float> { + val params = + if (burnInParams.minViewY < burnInParams.topInset) { + // minViewY should never be below the inset. Correct it if needed + Log.w(TAG, "minViewY is below topInset: $burnInParams") + burnInParams.copy(minViewY = burnInParams.topInset) + } else { + burnInParams + } + return configurationInteractor .dimensionPixelSize(R.dimen.keyguard_enter_from_top_translation_y) .flatMapLatest { enterFromTopAmount -> @@ -125,7 +137,10 @@ constructor( keyguardTransitionInteractor.dozeAmountTransition.map { Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it.value) }, - burnInInteractor.keyguardBurnIn, + burnInInteractor.burnIn( + xDimenResourceId = R.dimen.burn_in_prevention_offset_x, + yDimenResourceId = R.dimen.burn_in_prevention_offset_y + ) ) { interpolated, burnIn -> val useScaleOnly = (clockController(params.clockControllerProvider) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt index 6458edaecd9e..e35e06533f8c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt @@ -17,10 +17,14 @@ package com.android.systemui.keyguard.ui.viewmodel import com.android.systemui.Flags.keyguardBottomAreaRefactor +import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.doze.util.BurnInHelperWrapper +import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor +import com.android.systemui.keyguard.shared.model.BurnInModel +import com.android.systemui.res.R import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine @@ -32,9 +36,10 @@ class KeyguardIndicationAreaViewModel @Inject constructor( private val keyguardInteractor: KeyguardInteractor, - bottomAreaInteractor: KeyguardBottomAreaInteractor, + private val bottomAreaInteractor: KeyguardBottomAreaInteractor, keyguardBottomAreaViewModel: KeyguardBottomAreaViewModel, private val burnInHelperWrapper: BurnInHelperWrapper, + private val burnInInteractor: BurnInInteractor, private val shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel, configurationInteractor: ConfigurationInteractor, ) { @@ -63,24 +68,37 @@ constructor( } .distinctUntilChanged() } + + private val burnIn: Flow<BurnInModel> = + burnInInteractor + .burnIn( + xDimenResourceId = R.dimen.burn_in_prevention_offset_x, + yDimenResourceId = R.dimen.default_burn_in_prevention_offset, + ) + .distinctUntilChanged() + /** An observable for the x-offset by which the indication area should be translated. */ val indicationAreaTranslationX: Flow<Float> = - if (keyguardBottomAreaRefactor()) { - keyguardInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged() + if (migrateClocksToBlueprint() || keyguardBottomAreaRefactor()) { + burnIn.map { it.translationX.toFloat() } } else { bottomAreaInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged() } /** Returns an observable for the y-offset by which the indication area should be translated. */ fun indicationAreaTranslationY(defaultBurnInOffset: Int): Flow<Float> { - return keyguardInteractor.dozeAmount - .map { dozeAmount -> - dozeAmount * - (burnInHelperWrapper.burnInOffset( - /* amplitude = */ defaultBurnInOffset * 2, - /* xAxis= */ false, - ) - defaultBurnInOffset) - } - .distinctUntilChanged() + return if (migrateClocksToBlueprint()) { + burnIn.map { it.translationY.toFloat() } + } else { + keyguardInteractor.dozeAmount + .map { dozeAmount -> + dozeAmount * + (burnInHelperWrapper.burnInOffset( + /* amplitude = */ defaultBurnInOffset * 2, + /* xAxis= */ false, + ) - defaultBurnInOffset) + } + .distinctUntilChanged() + } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt index f95a8a727644..b9ff25926f02 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewClockViewModel.kt @@ -45,9 +45,10 @@ constructor( val isSmallClockVisible: Flow<Boolean> = interactor.selectedClockSize.map { it == SettingsClockSize.SMALL } - var lastClock: ClockController? = null + var lastClockPair: Pair<ClockController, ClockController>? = null - val previewClock: StateFlow<ClockController> = interactor.previewClock + val previewClockPair: StateFlow<Pair<ClockController, ClockController>> = + interactor.previewClockPair val selectedClockSize: StateFlow<SettingsClockSize?> = interactor.selectedClockSize.stateIn( diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControlsRefactorFlag.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControlsRefactorFlag.kt new file mode 100644 index 000000000000..2850b4bb2358 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaControlsRefactorFlag.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.media.controls.util + +import com.android.systemui.Flags +import com.android.systemui.flags.FlagToken +import com.android.systemui.flags.RefactorFlagUtils + +/** Helper for reading or using the media_controls_refactor flag state. */ +@Suppress("NOTHING_TO_INLINE") +object MediaControlsRefactorFlag { + /** The aconfig flag name */ + const val FLAG_NAME = Flags.FLAG_MEDIA_CONTROLS_REFACTOR + + /** A token used for dependency declaration */ + val token: FlagToken + get() = FlagToken(FLAG_NAME, isEnabled) + + /** Is the flag enabled? */ + @JvmStatic + inline val isEnabled + get() = Flags.mediaControlsRefactor() + + /** + * Called to ensure code is only run when the flag is enabled. This protects users from the + * unintended behaviors caused by accidentally running new logic, while also crashing on an eng + * build to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun isUnexpectedlyInLegacyMode() = + RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME) + + /** + * Called to ensure code is only run when the flag is disabled. This will throw an exception if + * the flag is enabled to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME) +} diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt index 15747b9eb515..d4bd6daedfab 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaFlags.kt @@ -58,4 +58,7 @@ constructor( /** Check whether to use scene framework */ fun isSceneContainerEnabled() = sceneContainerFlags.isEnabled() && MediaInSceneContainerFlag.isEnabled + + /** Check whether to use media refactor code */ + fun isMediaControlsRefactorEnabled() = MediaControlsRefactorFlag.isEnabled } diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt index e1741c73d453..7c7efd0be8ed 100644 --- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewController.kt @@ -26,12 +26,13 @@ import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.android.systemui.res.R +import com.android.systemui.Flags.pssAppSelectorAbruptExitFix import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorScope import com.android.systemui.mediaprojection.appselector.data.RecentTask import com.android.systemui.mediaprojection.appselector.view.RecentTasksAdapter.RecentTaskClickListener import com.android.systemui.mediaprojection.appselector.view.TaskPreviewSizeProvider.TaskPreviewSizeListener +import com.android.systemui.res.R import com.android.systemui.util.recycler.HorizontalSpacerItemDecoration import javax.inject.Inject @@ -122,14 +123,7 @@ constructor( override fun onRecentAppClicked(task: RecentTask, view: View) { val launchCookie = LaunchCookie() - val activityOptions = - ActivityOptions.makeScaleUpAnimation( - view, - /* startX= */ 0, - /* startY= */ 0, - view.width, - view.height - ) + val activityOptions = createAnimation(task, view) activityOptions.pendingIntentBackgroundActivityStartMode = MODE_BACKGROUND_ACTIVITY_START_ALLOWED activityOptions.setLaunchCookie(launchCookie) @@ -139,6 +133,28 @@ constructor( resultHandler.returnSelectedApp(launchCookie) } + private fun createAnimation(task: RecentTask, view: View): ActivityOptions = + if (pssAppSelectorAbruptExitFix() && task.isForegroundTask) { + // When the selected task is in the foreground, the scale up animation doesn't work. + // We fallback to the default close animation. + ActivityOptions.makeCustomTaskAnimation( + view.context, + /* enterResId= */ 0, + /* exitResId= */ com.android.internal.R.anim.resolver_close_anim, + /* handler = */ null, + /* startedListener = */ null, + /* finishedListener = */ null + ) + } else { + ActivityOptions.makeScaleUpAnimation( + view, + /* startX= */ 0, + /* startY= */ 0, + view.width, + view.height + ) + } + override fun onTaskSizeChanged(size: Rect) { views?.recentsContainer?.setTaskHeightSize() } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt index 168fa088cff2..15b8cfb3834d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SubtitleArrayMapping.kt @@ -39,6 +39,7 @@ object SubtitleArrayMapping { subtitleIdsMap["cast"] = R.array.tile_states_cast subtitleIdsMap["night"] = R.array.tile_states_night subtitleIdsMap["screenrecord"] = R.array.tile_states_screenrecord + subtitleIdsMap["record_issue"] = R.array.tile_states_record_issue subtitleIdsMap["reverse"] = R.array.tile_states_reverse subtitleIdsMap["reduce_brightness"] = R.array.tile_states_reduce_brightness subtitleIdsMap["cameratoggle"] = R.array.tile_states_cameratoggle diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt index b1e2467e007b..20f3c4d9735b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt @@ -85,7 +85,13 @@ constructor( override fun getTileLabel(): CharSequence = mContext.getString(R.string.qs_record_issue_label) - override fun isAvailable(): Boolean = recordIssueQsTile() + /** + * There are SELinux constraints that are stopping this tile from reaching production builds. + * Once those are resolved, this condition will be removed, but the solution (of properly + * creating a distince SELinux context for com.android.systemui) is complex and will take time + * to implement. + */ + override fun isAvailable(): Boolean = android.os.Build.IS_DEBUGGABLE && recordIssueQsTile() override fun newTileState(): QSTile.BooleanState = QSTile.BooleanState().apply { diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt index c7d3a4af24c9..7d2468b2f016 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt @@ -17,6 +17,7 @@ package com.android.systemui.scene import com.android.systemui.CoreStartable +import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlagsModule import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor import com.android.systemui.scene.domain.startable.SceneContainerStartable import com.android.systemui.scene.shared.flag.SceneContainerFlagsModule @@ -34,6 +35,7 @@ import dagger.multibindings.IntoMap [ BouncerSceneModule::class, CommunalSceneModule::class, + ComposeBouncerFlagsModule::class, EmptySceneModule::class, GoneSceneModule::class, LockscreenSceneModule::class, diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index fd3c480a334f..7bcb1da5c2bf 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -1296,10 +1296,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mView.getContext().getDisplay()); mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController(); mKeyguardStatusViewController.init(); - } - mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled); - mKeyguardStatusViewController.getView().addOnLayoutChangeListener( + mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled); + mKeyguardStatusViewController.getView().addOnLayoutChangeListener( (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { int oldHeight = oldBottom - oldTop; if (v.getHeight() != oldHeight) { @@ -1307,7 +1306,8 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } }); - updateClockAppearance(); + updateClockAppearance(); + } } @Override @@ -1334,7 +1334,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump private void onSplitShadeEnabledChanged() { mShadeLog.logSplitShadeChanged(mSplitShadeEnabled); - mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled); + if (!migrateClocksToBlueprint()) { + mKeyguardStatusViewController.setSplitShadeEnabled(mSplitShadeEnabled); + } // Reset any left over overscroll state. It is a rare corner case but can happen. mQsController.setOverScrollAmount(0); mScrimController.setNotificationsOverScrollAmount(0); @@ -1449,11 +1451,13 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mStatusBarStateListener.onDozeAmountChanged(mStatusBarStateController.getDozeAmount(), mStatusBarStateController.getInterpolatedDozeAmount()); - mKeyguardStatusViewController.setKeyguardStatusViewVisibility( - mBarState, - false, - false, - mBarState); + if (!migrateClocksToBlueprint()) { + mKeyguardStatusViewController.setKeyguardStatusViewVisibility( + mBarState, + false, + false, + mBarState); + } if (mKeyguardQsUserSwitchController != null) { mKeyguardQsUserSwitchController.setKeyguardQsUserSwitchVisibility( mBarState, @@ -1673,13 +1677,11 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mKeyguardStatusViewController.setLockscreenClockY( mClockPositionAlgorithm.getExpandedPreferredClockY()); } - if (keyguardBottomAreaRefactor()) { - mKeyguardInteractor.setClockPosition( - mClockPositionResult.clockX, mClockPositionResult.clockY); - } else { + if (!(migrateClocksToBlueprint() || keyguardBottomAreaRefactor())) { mKeyguardBottomAreaInteractor.setClockPosition( mClockPositionResult.clockX, mClockPositionResult.clockY); } + boolean animate = mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending(); boolean animateClock = (animate || mAnimateNextPositionUpdate) && shouldAnimateClockChange; @@ -1757,13 +1759,11 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } private void updateKeyguardStatusViewAlignment(boolean animate) { - boolean shouldBeCentered = shouldKeyguardStatusViewBeCentered(); - ConstraintLayout layout; if (migrateClocksToBlueprint()) { - layout = mKeyguardViewConfigurator.getKeyguardRootView(); - } else { - layout = mNotificationContainerParent; + return; } + boolean shouldBeCentered = shouldKeyguardStatusViewBeCentered(); + ConstraintLayout layout = mNotificationContainerParent; mKeyguardStatusViewController.updateAlignment( layout, mSplitShadeEnabled, shouldBeCentered, animate); mKeyguardUnfoldTransition.ifPresent(t -> t.setStatusViewCentered(shouldBeCentered)); @@ -3339,6 +3339,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump /** Updates the views to the initial state for the fold to AOD animation. */ @Override public void prepareFoldToAodAnimation() { + if (migrateClocksToBlueprint()) { + return; + } // Force show AOD UI even if we are not locked showAodUi(); @@ -3360,6 +3363,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump @Override public void startFoldToAodAnimation(Runnable startAction, Runnable endAction, Runnable cancelAction) { + if (migrateClocksToBlueprint()) { + return; + } final ViewPropertyAnimator viewAnimator = mView.animate(); viewAnimator.cancel(); viewAnimator @@ -3395,6 +3401,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump /** Cancels fold to AOD transition and resets view state. */ @Override public void cancelFoldToAodAnimation() { + if (migrateClocksToBlueprint()) { + return; + } cancelAnimation(); resetAlpha(); resetTranslation(); @@ -4471,11 +4480,13 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } } - mKeyguardStatusViewController.setKeyguardStatusViewVisibility( - statusBarState, - keyguardFadingAway, - goingToFullShade, - mBarState); + if (!migrateClocksToBlueprint()) { + mKeyguardStatusViewController.setKeyguardStatusViewVisibility( + statusBarState, + keyguardFadingAway, + goingToFullShade, + mBarState); + } if (!keyguardBottomAreaRefactor()) { setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 7ee3a70bc6be..1ec86aea49d8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -1286,6 +1286,13 @@ public class KeyguardIndicationController { && msgId != BIOMETRIC_HELP_FACE_NOT_AVAILABLE; final boolean faceAuthFailed = biometricSourceType == FACE && msgId == BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; // ran through matcher & failed + if (faceAuthFailed && mFaceLockedOutThisAuthSession) { + mKeyguardLogger.logBiometricMessage( + "skipped showing faceAuthFailed message due to lockout", + msgId, + helpString); + return; + } final boolean fpAuthFailed = biometricSourceType == FINGERPRINT && msgId == BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED; // ran matcher & failed final boolean isUnlockWithFingerprintPossible = canUnlockWithFingerprint(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java index 143fc324f8c7..3cf61e211e42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGroupingUtil.java @@ -34,6 +34,8 @@ import com.android.internal.widget.ConversationLayout; import com.android.internal.widget.ImageFloatingTextView; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationContentView; +import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation; +import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; import java.util.ArrayList; import java.util.HashSet; @@ -253,7 +255,8 @@ public class NotificationGroupingUtil { } public void init() { - View header = mParentRow.getNotificationViewWrapper().getNotificationHeader(); + NotificationViewWrapper wrapper = mParentRow.getNotificationViewWrapper(); + View header = wrapper == null ? null : wrapper.getNotificationHeader(); mParentView = header == null ? null : header.findViewById(mId); mParentData = mExtractor == null ? null : mExtractor.extractData(mParentRow); mApply = !mComparator.isEmpty(mParentView); @@ -326,6 +329,9 @@ public class NotificationGroupingUtil { @Override public boolean isEmpty(View view) { + if (AsyncGroupHeaderViewInflation.isEnabled() && view == null) { + return true; + } if (view instanceof ImageView) { return ((ImageView) view).getDrawable() == null; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java index 639e23ae0765..deaf1d1bc764 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java @@ -363,10 +363,11 @@ public class PreparationCoordinator implements Coordinator { NotifInflater.Params getInflaterParams(NotifUiAdjustment adjustment, String reason) { return new NotifInflater.Params( - adjustment.isMinimized(), - reason, - adjustment.isSnoozeEnabled(), - adjustment.isChildInGroup() + /* isLowPriority = */ adjustment.isMinimized(), + /* reason = */ reason, + /* showSnooze = */ adjustment.isSnoozeEnabled(), + /* isChildInGroup = */ adjustment.isChildInGroup(), + /* isGroupSummary = */ adjustment.isGroupSummary() ); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt index 29627e14e4a0..f03c3139ca8f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt @@ -119,6 +119,9 @@ class SensitiveContentCoordinatorImpl @Inject constructor( val needsRedaction = lockscreenUserManager.needsRedaction(entry) val isSensitive = userPublic && needsRedaction entry.setSensitive(isSensitive || shouldProtectNotification, deviceSensitive) + if (screenshareNotificationHiding()) { + entry.row?.setPublicExpanderVisible(!shouldProtectNotification) + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt index c0b187be42f3..18460c3e3766 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt @@ -60,5 +60,6 @@ interface NotifInflater { val reason: String, val showSnooze: Boolean, val isChildInGroup: Boolean = false, + val isGroupSummary: Boolean = false, ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt index e1d2cdc65d5a..bab94b50018e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt @@ -20,6 +20,7 @@ import android.app.Notification import android.app.RemoteInput import android.graphics.drawable.Icon import android.text.TextUtils +import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation /** @@ -36,6 +37,7 @@ class NotifUiAdjustment internal constructor( val isMinimized: Boolean, val needsRedaction: Boolean, val isChildInGroup: Boolean, + val isGroupSummary: Boolean, ) { companion object { @JvmStatic @@ -55,6 +57,8 @@ class NotifUiAdjustment internal constructor( // !oldAdjustment.isChildInGroup && newAdjustment.isChildInGroup -> true AsyncHybridViewInflation.isEnabled && oldAdjustment.isChildInGroup != newAdjustment.isChildInGroup -> true + AsyncGroupHeaderViewInflation.isEnabled && + !oldAdjustment.isGroupSummary && newAdjustment.isGroupSummary -> true else -> false } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt index 6f44c13a3e71..0b9d19df3a75 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt @@ -123,6 +123,7 @@ class NotifUiAdjustmentProvider @Inject constructor( isSnoozeEnabled = isSnoozeSettingsEnabled && !entry.isCanceled, isMinimized = isEntryMinimized(entry), needsRedaction = lockscreenUserManager.needsRedaction(entry), - isChildInGroup = groupMembershipManager.isChildInGroup(entry), + isChildInGroup = entry.sbn.isAppOrSystemGroupChild, + isGroupSummary = entry.sbn.isAppOrSystemGroupSummary, ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java index 954e80505cbe..c5b55c7b1d9b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java @@ -21,6 +21,8 @@ import static com.android.systemui.statusbar.notification.row.NotificationRowCon import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED; import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC; import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE; +import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_GROUP_SUMMARY_HEADER; +import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER; import static java.util.Objects.requireNonNull; @@ -50,6 +52,7 @@ import com.android.systemui.statusbar.notification.row.RowContentBindParams; import com.android.systemui.statusbar.notification.row.RowContentBindStage; import com.android.systemui.statusbar.notification.row.RowInflaterTask; import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent; +import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation; import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; @@ -271,6 +274,17 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { } } + if (AsyncGroupHeaderViewInflation.isEnabled()) { + if (inflaterParams.isGroupSummary()) { + params.requireContentViews(FLAG_GROUP_SUMMARY_HEADER); + if (isLowPriority) { + params.requireContentViews(FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER); + } + } else { + params.markContentViewsFreeable(FLAG_GROUP_SUMMARY_HEADER); + params.markContentViewsFreeable(FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER); + } + } params.rebindAllContentViews(); mLogger.logRequestingRebind(entry, inflaterParams); mRowContentBindStage.requestRebind(entry, en -> { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java index 73580343fab7..61cdea190a43 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java @@ -547,13 +547,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } private void setContentAlpha(float contentAlpha) { - View contentView = getContentView(); - if (contentView.hasOverlappingRendering()) { - int layerType = contentAlpha == 0.0f || contentAlpha == 1.0f ? LAYER_TYPE_NONE - : LAYER_TYPE_HARDWARE; - contentView.setLayerType(layerType, null); - } - contentView.setAlpha(contentAlpha); + setAlphaAndLayerType(getContentView(), contentAlpha); // After updating the current view, reset all views. if (contentAlpha == 1f) { resetAllContentAlphas(); @@ -561,6 +555,19 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } /** + * Set a content view's alpha value and hardware layer type for fluent animations + * @param contentView the view to set + * @param alpha the alpha value to set + */ + protected void setAlphaAndLayerType(View contentView, float alpha) { + if (contentView.hasOverlappingRendering()) { + int layerType = alpha == 0.0f || alpha == 1.0f ? LAYER_TYPE_NONE : LAYER_TYPE_HARDWARE; + contentView.setLayerType(layerType, null); + } + contentView.setAlpha(alpha); + } + + /** * If a subclass's {@link #getContentView()} returns different views depending on state, * this method is an opportunity to reset the alpha of ALL content views, not just the * current one, which may prevent a content view that is temporarily hidden from being reset. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index decb244947ff..8d5302231fc1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -100,7 +100,9 @@ import com.android.systemui.statusbar.notification.collection.render.GroupMember import com.android.systemui.statusbar.notification.logging.NotificationCounters; import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag; +import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; +import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization; import com.android.systemui.statusbar.notification.stack.AmbientState; import com.android.systemui.statusbar.notification.stack.AnimationProperties; import com.android.systemui.statusbar.notification.stack.ExpandableViewState; @@ -218,6 +220,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private boolean mShowingPublic; private boolean mSensitive; private boolean mSensitiveHiddenInGeneral; + private boolean mShowPublicExpander = true; private boolean mShowingPublicInitialized; private boolean mHideSensitiveForIntrinsicHeight; private float mHeaderVisibleAmount = DEFAULT_HEADER_VISIBLE_AMOUNT; @@ -586,7 +589,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mMenuRow.setAppName(mAppName); } if (mIsSummaryWithChildren) { - mChildrenContainer.recreateNotificationHeader(mExpandClickListener, isConversation()); + if (!AsyncGroupHeaderViewInflation.isEnabled()) { + // We create the header from the background thread instead + mChildrenContainer.recreateNotificationHeader(mExpandClickListener, + isConversation()); + } mChildrenContainer.onNotificationUpdated(); } if (mAnimationRunning) { @@ -599,8 +606,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mNotificationParent.updateChildrenAppearance(); } onAttachedChildrenCountChanged(); - // The public layouts expand button is always visible - mPublicLayout.updateExpandButtons(true); + mPublicLayout.updateExpandButtons(mShowPublicExpander); updateLimits(); updateShelfIconColor(); if (mUpdateSelfBackgroundOnUpdate) { @@ -668,7 +674,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView public int getOriginalIconColor() { if (mIsSummaryWithChildren && !shouldShowPublic()) { - return mChildrenContainer.getVisibleWrapper().getOriginalIconColor(); + if (!AsyncGroupHeaderViewInflation.isEnabled()) { + return mChildrenContainer.getVisibleWrapper().getOriginalIconColor(); + } } int color = getShowingLayout().getOriginalIconColor(); if (color != Notification.COLOR_INVALID) { @@ -1513,6 +1521,40 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return mChildrenContainer; } + /** + * @return An non-null instance of mChildrenContainer, inflate it if not yet. + */ + public @NonNull NotificationChildrenContainer getChildrenContainerNonNull() { + if (mChildrenContainer == null) { + mChildrenContainerStub.inflate(); + } + return mChildrenContainer; + } + + /** + * Set the group notification header view + * @param headerView header view to set + */ + public void setGroupHeader(NotificationHeaderView headerView) { + NotificationChildrenContainer childrenContainer = getChildrenContainerNonNull(); + childrenContainer.setGroupHeader( + /* headerView= */ headerView, + /* onClickListener= */ mExpandClickListener + ); + } + + /** + * Set the low-priority group notification header view + * @param headerView header view to set + */ + public void setLowPriorityGroupHeader(NotificationHeaderView headerView) { + NotificationChildrenContainer childrenContainer = getChildrenContainerNonNull(); + childrenContainer.setLowPriorityGroupHeader( + /* headerViewLowPriority= */ headerView, + /* onClickListener= */ mExpandClickListener + ); + } + public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) { boolean wasAboveShelf = isAboveShelf(); boolean changed = headsUpAnimatingAway != mHeadsupDisappearRunning; @@ -1565,7 +1607,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView @Override public View getShelfTransformationTarget() { if (mIsSummaryWithChildren && !shouldShowPublic()) { - return mChildrenContainer.getVisibleWrapper().getShelfTransformationTarget(); + NotificationViewWrapper viewWrapper = mChildrenContainer.getVisibleWrapper(); + if (AsyncGroupHeaderViewInflation.isEnabled() && viewWrapper == null) { + return null; + } + return viewWrapper.getShelfTransformationTarget(); } return getShowingLayout().getShelfTransformationTarget(); } @@ -2710,10 +2756,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView && mChildrenContainer.getNotificationChildCount() > 0; if (mIsSummaryWithChildren) { Trace.beginSection("ExpNotRow#onChildCountChanged (summary)"); - NotificationViewWrapper wrapper = mChildrenContainer.getNotificationViewWrapper(); - if (wrapper == null || wrapper.getNotificationHeader() == null) { - mChildrenContainer.recreateNotificationHeader(mExpandClickListener, - isConversation()); + if (!AsyncGroupHeaderViewInflation.isEnabled()) { + NotificationViewWrapper wrapper = mChildrenContainer.getNotificationViewWrapper(); + if (wrapper == null || wrapper.getNotificationHeader() == null) { + mChildrenContainer.recreateNotificationHeader(mExpandClickListener, + isConversation()); + } } } if (!mIsSummaryWithChildren && wasSummary) { @@ -2837,6 +2885,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } } + /** Sets whether this notification row should show the notification expander or not */ + public void setPublicExpanderVisible(boolean showPublicExpander) { + if (mShowPublicExpander != showPublicExpander) { + mShowPublicExpander = showPublicExpander; + mPublicLayout.updateExpandButtons(mShowPublicExpander); + } + } + @Override public void setHideSensitiveForIntrinsicHeight(boolean hideSensitive) { mHideSensitiveForIntrinsicHeight = hideSensitive; @@ -2863,6 +2919,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) { return; } + float oldAlpha = getContentView().getAlpha(); if (!animated) { mPublicLayout.animate().cancel(); @@ -2873,6 +2930,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView resetAllContentAlphas(); mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE); updateChildrenVisibility(); + if (NotificationContentAlphaOptimization.isEnabled()) { + // We want to set the old alpha to the now-showing layout to avoid breaking an + // on-going animation + if (oldAlpha != 1f) { + setAlphaAndLayerType(mShowingPublic ? mPublicLayout : mPrivateLayout, oldAlpha); + } + } } else { animateShowingPublic(delay, duration, mShowingPublic); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java index e288e857bf4a..d308fa583f71 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java @@ -37,7 +37,9 @@ import android.os.Trace; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.util.Log; +import android.view.NotificationHeaderView; import android.view.View; +import android.view.ViewGroup; import android.widget.RemoteViews; import com.android.internal.annotations.VisibleForTesting; @@ -51,11 +53,13 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.notification.ConversationNotificationProcessor; import com.android.systemui.statusbar.notification.InflationException; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation; import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation; import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineConversationViewBinder; import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineViewBinder; import com.android.systemui.statusbar.notification.row.ui.viewmodel.SingleLineViewModel; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; +import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.policy.InflatedSmartReplyState; import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; @@ -387,6 +391,21 @@ public class NotificationContentInflater implements NotificationRowContentBinder logger.logAsyncTaskProgress(entryForLogging, "creating public remote view"); result.newPublicView = builder.makePublicContentView(isLowPriority); } + + if (AsyncGroupHeaderViewInflation.isEnabled()) { + if ((reInflateFlags & FLAG_GROUP_SUMMARY_HEADER) != 0) { + logger.logAsyncTaskProgress(entryForLogging, + "creating group summary remote view"); + result.mNewGroupHeaderView = builder.makeNotificationGroupHeader(); + } + + if ((reInflateFlags & FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER) != 0) { + logger.logAsyncTaskProgress(entryForLogging, + "creating low-priority group summary remote view"); + result.mNewLowPriorityGroupHeaderView = + builder.makeLowPriorityContentView(true /* useRegularSubtext */); + } + } setNotifsViewsInflaterFactory(result, row, notifLayoutInflaterFactoryProvider); result.packageContext = packageContext; result.headsUpStatusBarText = builder.getHeadsUpStatusBarText(false /* showingPublic */); @@ -534,6 +553,67 @@ public class NotificationContentInflater implements NotificationRowContentBinder runningInflations, applyCallback, logger); } + if (AsyncGroupHeaderViewInflation.isEnabled()) { + NotificationChildrenContainer childrenContainer = row.getChildrenContainerNonNull(); + if ((reInflateFlags & FLAG_GROUP_SUMMARY_HEADER) != 0) { + boolean isNewView = + !canReapplyRemoteView( + /* newView = */ result.mNewGroupHeaderView, + /* oldView = */ remoteViewCache + .getCachedView(entry, FLAG_GROUP_SUMMARY_HEADER)); + ApplyCallback applyCallback = new ApplyCallback() { + @Override + public void setResultView(View v) { + logger.logAsyncTaskProgress(entry, "group header view applied"); + result.mInflatedGroupHeaderView = (NotificationHeaderView) v; + } + + @Override + public RemoteViews getRemoteView() { + return result.mNewGroupHeaderView; + } + }; + logger.logAsyncTaskProgress(entry, "applying group header view"); + applyRemoteView(inflationExecutor, inflateSynchronously, result, reInflateFlags, + /* inflationId = */ FLAG_GROUP_SUMMARY_HEADER, + remoteViewCache, entry, row, isNewView, remoteViewClickHandler, callback, + /* parentLayout = */ childrenContainer, + /* existingView = */ childrenContainer.getNotificationHeader(), + /* existingWrapper = */ childrenContainer.getNotificationHeaderWrapper(), + runningInflations, applyCallback, logger); + } + + if ((reInflateFlags & FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER) != 0) { + boolean isNewView = + !canReapplyRemoteView( + /* newView = */ result.mNewLowPriorityGroupHeaderView, + /* oldView = */ remoteViewCache.getCachedView( + entry, FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER)); + ApplyCallback applyCallback = new ApplyCallback() { + @Override + public void setResultView(View v) { + logger.logAsyncTaskProgress(entry, + "low-priority group header view applied"); + result.mInflatedLowPriorityGroupHeaderView = (NotificationHeaderView) v; + } + + @Override + public RemoteViews getRemoteView() { + return result.mNewLowPriorityGroupHeaderView; + } + }; + logger.logAsyncTaskProgress(entry, "applying low priority group header view"); + applyRemoteView(inflationExecutor, inflateSynchronously, result, reInflateFlags, + /* inflationId = */ FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER, + remoteViewCache, entry, row, isNewView, remoteViewClickHandler, callback, + /* parentLayout = */ childrenContainer, + /* existingView = */ childrenContainer.getNotificationHeaderLowPriority(), + /* existingWrapper = */ childrenContainer + .getLowPriorityViewWrapper(), + runningInflations, applyCallback, logger); + } + } + // Let's try to finish, maybe nobody is even inflating anything finishIfDone(result, reInflateFlags, remoteViewCache, runningInflations, callback, entry, row, logger); @@ -560,7 +640,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder boolean isNewView, RemoteViews.InteractionHandler remoteViewClickHandler, @Nullable final InflationCallback callback, - NotificationContentView parentLayout, + ViewGroup parentLayout, View existingView, NotificationViewWrapper existingWrapper, final HashMap<Integer, CancellationSignal> runningInflations, @@ -702,6 +782,10 @@ public class NotificationContentInflater implements NotificationRowContentBinder return result; } + /** + * Notifications with undecorated custom views need to satisfy a minimum height to avoid visual + * issues. + */ private static boolean requiresHeightCheck(NotificationEntry entry) { // Undecorated custom views are disallowed from S onwards if (entry.targetSdk >= Build.VERSION_CODES.S) { @@ -845,6 +929,39 @@ public class NotificationContentInflater implements NotificationRowContentBinder } } + if (AsyncGroupHeaderViewInflation.isEnabled()) { + if ((reInflateFlags & FLAG_GROUP_SUMMARY_HEADER) != 0) { + if (result.mInflatedGroupHeaderView != null) { + row.setIsLowPriority(false); + row.setGroupHeader(/* headerView= */ result.mInflatedGroupHeaderView); + remoteViewCache.putCachedView(entry, FLAG_GROUP_SUMMARY_HEADER, + result.mNewGroupHeaderView); + } else if (remoteViewCache.hasCachedView(entry, FLAG_GROUP_SUMMARY_HEADER)) { + // Re-inflation case. Only update if it's still cached (i.e. view has not + // been freed while inflating). + remoteViewCache.putCachedView(entry, FLAG_GROUP_SUMMARY_HEADER, + result.mNewGroupHeaderView); + } + } + + if ((reInflateFlags & FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER) != 0) { + if (result.mInflatedLowPriorityGroupHeaderView != null) { + // New view case, set row to low priority + row.setIsLowPriority(true); + row.setLowPriorityGroupHeader( + /* headerView= */ result.mInflatedLowPriorityGroupHeaderView); + remoteViewCache.putCachedView(entry, FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER, + result.mNewLowPriorityGroupHeaderView); + } else if (remoteViewCache.hasCachedView(entry, + FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER)) { + // Re-inflation case. Only update if it's still cached (i.e. view has not + // been freed while inflating). + remoteViewCache.putCachedView(entry, FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER, + result.mNewGroupHeaderView); + } + } + } + entry.headsUpStatusBarText = result.headsUpStatusBarText; entry.headsUpStatusBarTextPublic = result.headsUpStatusBarTextPublic; if (endListener != null) { @@ -1147,6 +1264,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder private RemoteViews newHeadsUpView; private RemoteViews newExpandedView; private RemoteViews newPublicView; + private RemoteViews mNewGroupHeaderView; + private RemoteViews mNewLowPriorityGroupHeaderView; @VisibleForTesting Context packageContext; @@ -1155,6 +1274,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder private View inflatedHeadsUpView; private View inflatedExpandedView; private View inflatedPublicView; + private NotificationHeaderView mInflatedGroupHeaderView; + private NotificationHeaderView mInflatedLowPriorityGroupHeaderView; private CharSequence headsUpStatusBarText; private CharSequence headsUpStatusBarTextPublic; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterLogger.kt index ee9462c60674..15c705579bf7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterLogger.kt @@ -27,6 +27,8 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_SINGLE_LINE +import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_GROUP_SUMMARY_HEADER +import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag import javax.inject.Inject @@ -145,6 +147,12 @@ constructor(@NotifInflationLog private val buffer: LogBuffer) { if (flag and FLAG_CONTENT_VIEW_SINGLE_LINE != 0) { l.add("SINGLE_LINE") } + if (flag and FLAG_GROUP_SUMMARY_HEADER != 0) { + l.add("GROUP_SUMMARY_HEADER") + } + if (flag and FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER != 0) { + l.add("LOW_PRIORITY_GROUP_SUMMARY_HEADER") + } return l.joinToString("|") } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index 374248252d1f..50bc3d31aa42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -238,7 +238,10 @@ public class NotificationContentView extends FrameLayout implements Notification mMinContractedHeight = getResources().getDimensionPixelSize( R.dimen.min_notification_layout_height); if (AsyncHybridViewInflation.isEnabled()) { - //TODO: set the height with a more reasonable min single-line height + //TODO (b/217799515): single-line view height is the greater of two heights: text view + // height and icon height (when there's an icon). icon height is fixed to be + // conversation_single_line_face_pile_size (24dp), the text view's height is 16sp, + // its pixel height changes with the system's font scaling factor. mMinSingleLineHeight = getResources().getDimensionPixelSize( R.dimen.conversation_single_line_face_pile_size); } @@ -843,7 +846,7 @@ public class NotificationContentView extends FrameLayout implements Notification if (mSingleLineView != null) { return getViewHeight(VISIBLE_TYPE_SINGLELINE); } else { - Log.wtf(TAG, "getMinHeight: mSingleLineView == null"); + //TODO(b/217799515): investigate the impact of min-height value return mMinSingleLineHeight; } } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java index 736140c44dfd..b0fd47587782 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java @@ -81,6 +81,8 @@ public interface NotificationRowContentBinder { FLAG_CONTENT_VIEW_HEADS_UP, FLAG_CONTENT_VIEW_PUBLIC, FLAG_CONTENT_VIEW_SINGLE_LINE, + FLAG_GROUP_SUMMARY_HEADER, + FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER, FLAG_CONTENT_VIEW_ALL}) @interface InflationFlag {} /** @@ -108,7 +110,17 @@ public interface NotificationRowContentBinder { */ int FLAG_CONTENT_VIEW_SINGLE_LINE = 1 << 4; - int FLAG_CONTENT_VIEW_ALL = (1 << 5) - 1; + /** + * The notification group summary header view + */ + int FLAG_GROUP_SUMMARY_HEADER = 1 << 5; + + /** + * The notification low-priority group summary header view + */ + int FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER = 1 << 6; + + int FLAG_CONTENT_VIEW_ALL = (1 << 7) - 1; /** * Parameters for content view binding @@ -129,6 +141,11 @@ public interface NotificationRowContentBinder { * Use increased height when binding heads up views. */ public boolean usesIncreasedHeadsUpHeight; + + /** + * Is group summary notification + */ + public boolean mIsGroupSummary; } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationContentAlphaOptimization.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationContentAlphaOptimization.kt new file mode 100644 index 000000000000..c70359533eba --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationContentAlphaOptimization.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.shared + +import com.android.systemui.Flags +import com.android.systemui.flags.FlagToken +import com.android.systemui.flags.RefactorFlagUtils + +/** Helper for reading or using the Async Group Header Inflation flag state. */ +@Suppress("NOTHING_TO_INLINE") +object NotificationContentAlphaOptimization { + /** The aconfig flag name */ + const val FLAG_NAME = Flags.FLAG_NOTIFICATION_CONTENT_ALPHA_OPTIMIZATION + + /** A token used for dependency declaration */ + val token: FlagToken + get() = FlagToken(FLAG_NAME, isEnabled) + + /** Is the async inflation of group header views enabled */ + @JvmStatic + inline val isEnabled + get() = Flags.notificationContentAlphaOptimization() + + /** + * Called to ensure code is only run when the flag is enabled. This protects users from the + * unintended behaviors caused by accidentally running new logic, while also crashing on an eng + * build to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun isUnexpectedlyInLegacyMode() = + RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME) + + /** + * Called to ensure code is only run when the flag is disabled. This will throw an exception if + * the flag is enabled to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME) +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java index abf6c27c68ac..fa973001cec7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java @@ -55,6 +55,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.notification.row.HybridGroupManager; import com.android.systemui.statusbar.notification.row.HybridNotificationView; +import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation; import com.android.systemui.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; @@ -131,6 +132,7 @@ public class NotificationChildrenContainer extends ViewGroup private int mUntruncatedChildCount; private boolean mContainingNotificationIsFaded = false; private RoundableState mRoundableState; + private int mMinSingleLineHeight; private NotificationChildrenContainerLogger mLogger; @@ -183,6 +185,8 @@ public class NotificationChildrenContainer extends ViewGroup com.android.internal.R.dimen.notification_content_margin) - mNotificationHeaderMargin; mHybridGroupManager.initDimens(); + mMinSingleLineHeight = getResources().getDimensionPixelSize( + R.dimen.conversation_single_line_face_pile_size); } @NonNull @@ -385,16 +389,31 @@ public class NotificationChildrenContainer extends ViewGroup return mAttachedChildren.size(); } - public void recreateNotificationHeader(OnClickListener listener, boolean isConversation) { + /** + * Re-create the Notification header view + * @param listener OnClickListener of the header view + * @param isConversation if the notification group is a conversation group + */ + public void recreateNotificationHeader( + OnClickListener listener, + boolean isConversation + ) { + // We don't want to inflate headers from the main thread when async inflation enabled + AsyncGroupHeaderViewInflation.assertInLegacyMode(); + // TODO(b/217799515): remove traces from this function in a follow-up change Trace.beginSection("NotifChildCont#recreateHeader"); mHeaderClickListener = listener; mIsConversation = isConversation; StatusBarNotification notification = mContainingNotification.getEntry().getSbn(); final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(), notification.getNotification()); + Trace.beginSection("recreateHeader#makeNotificationGroupHeader"); RemoteViews header = builder.makeNotificationGroupHeader(); + Trace.endSection(); if (mNotificationHeader == null) { + Trace.beginSection("recreateHeader#apply"); mNotificationHeader = (NotificationHeaderView) header.apply(getContext(), this); + Trace.endSection(); mNotificationHeader.findViewById(com.android.internal.R.id.expand_button) .setVisibility(VISIBLE); mNotificationHeader.setOnClickListener(mHeaderClickListener); @@ -407,7 +426,9 @@ public class NotificationChildrenContainer extends ViewGroup addView(mNotificationHeader, 0); invalidate(); } else { + Trace.beginSection("recreateHeader#reapply"); header.reapply(getContext(), mNotificationHeader); + Trace.endSection(); } mNotificationHeaderWrapper.setExpanded(mChildrenExpanded); mNotificationHeaderWrapper.onContentUpdated(mContainingNotification); @@ -417,12 +438,105 @@ public class NotificationChildrenContainer extends ViewGroup Trace.endSection(); } + private void removeGroupHeader() { + if (mNotificationHeader == null) { + return; + } + removeView(mNotificationHeader); + mNotificationHeader = null; + mNotificationHeaderWrapper = null; + } + + private void removeLowPriorityGroupHeader() { + if (mNotificationHeaderLowPriority == null) { + return; + } + removeView(mNotificationHeaderLowPriority); + mNotificationHeaderLowPriority = null; + mNotificationHeaderWrapperLowPriority = null; + } + + /** + * Set the group header view + * @param headerView view to set + * @param onClickListener OnClickListener of the header view + */ + public void setGroupHeader( + NotificationHeaderView headerView, + OnClickListener onClickListener + ) { + if (AsyncGroupHeaderViewInflation.isUnexpectedlyInLegacyMode()) return; + mHeaderClickListener = onClickListener; + + removeGroupHeader(); + + if (headerView == null) { + return; + } + + mNotificationHeader = headerView; + mNotificationHeader.findViewById(com.android.internal.R.id.expand_button) + .setVisibility(VISIBLE); + mNotificationHeader.setOnClickListener(mHeaderClickListener); + mNotificationHeaderWrapper = + (NotificationHeaderViewWrapper) NotificationViewWrapper.wrap( + getContext(), + mNotificationHeader, + mContainingNotification); + mNotificationHeaderWrapper.setOnRoundnessChangedListener(this::invalidate); + addView(mNotificationHeader, 0); + invalidate(); + + mNotificationHeaderWrapper.setExpanded(mChildrenExpanded); + mNotificationHeaderWrapper.onContentUpdated(mContainingNotification); + + updateHeaderVisibility(false /* animate */); + updateChildrenAppearance(); + + Trace.endSection(); + } + + /** + * Set the low-priority group header view + * @param headerViewLowPriority header view to set + * @param onClickListener OnClickListener of the header view + */ + public void setLowPriorityGroupHeader( + NotificationHeaderView headerViewLowPriority, + OnClickListener onClickListener + ) { + if (AsyncGroupHeaderViewInflation.isUnexpectedlyInLegacyMode()) return; + removeLowPriorityGroupHeader(); + if (headerViewLowPriority == null) { + return; + } + + mNotificationHeaderLowPriority = headerViewLowPriority; + mNotificationHeaderLowPriority.findViewById(com.android.internal.R.id.expand_button) + .setVisibility(VISIBLE); + mNotificationHeaderLowPriority.setOnClickListener(onClickListener); + mNotificationHeaderWrapperLowPriority = + (NotificationHeaderViewWrapper) NotificationViewWrapper.wrap( + getContext(), + mNotificationHeaderLowPriority, + mContainingNotification); + mNotificationHeaderWrapperLowPriority.setOnRoundnessChangedListener(this::invalidate); + addView(mNotificationHeaderLowPriority, 0); + invalidate(); + + mNotificationHeaderWrapperLowPriority.onContentUpdated(mContainingNotification); + updateHeaderVisibility(false /* animate */); + updateChildrenAppearance(); + } + /** * Recreate the low-priority header. * * @param builder a builder to reuse. Otherwise the builder will be recovered. */ - private void recreateLowPriorityHeader(Notification.Builder builder, boolean isConversation) { + @VisibleForTesting + void recreateLowPriorityHeader(Notification.Builder builder, boolean isConversation) { + AsyncGroupHeaderViewInflation.assertInLegacyMode(); RemoteViews header; StatusBarNotification notification = mContainingNotification.getEntry().getSbn(); if (mIsLowPriority) { @@ -527,8 +641,10 @@ public class NotificationChildrenContainer extends ViewGroup * @param alpha alpha value to apply to the content */ public void setContentAlpha(float alpha) { - for (int i = 0; i < mNotificationHeader.getChildCount(); i++) { - mNotificationHeader.getChildAt(i).setAlpha(alpha); + if (mNotificationHeader != null) { + for (int i = 0; i < mNotificationHeader.getChildCount(); i++) { + mNotificationHeader.getChildAt(i).setAlpha(alpha); + } } for (ExpandableNotificationRow child : getAttachedChildren()) { child.setContentAlpha(alpha); @@ -564,7 +680,11 @@ public class NotificationChildrenContainer extends ViewGroup */ private int getIntrinsicHeight(float maxAllowedVisibleChildren) { if (showingAsLowPriority()) { - return mNotificationHeaderLowPriority.getHeight(); + if (AsyncGroupHeaderViewInflation.isEnabled()) { + return mHeaderHeight; + } else { + return mNotificationHeaderLowPriority.getHeight(); + } } int intrinsicHeight = mNotificationHeaderMargin + mCurrentHeaderTranslation; int visibleChildren = 0; @@ -1023,6 +1143,14 @@ public class NotificationChildrenContainer extends ViewGroup return mCurrentHeader; } + public NotificationHeaderView getNotificationHeader() { + return mNotificationHeader; + } + + public NotificationHeaderView getNotificationHeaderLowPriority() { + return mNotificationHeaderLowPriority; + } + private void updateHeaderVisibility(boolean animate) { ViewGroup desiredHeader; ViewGroup currentHeader = mCurrentHeader; @@ -1032,6 +1160,10 @@ public class NotificationChildrenContainer extends ViewGroup return; } + if (AsyncGroupHeaderViewInflation.isEnabled() && desiredHeader == null) { + return; + } + if (animate) { if (desiredHeader != null && currentHeader != null) { currentHeader.setVisibility(VISIBLE); @@ -1271,6 +1403,9 @@ public class NotificationChildrenContainer extends ViewGroup boolean likeHighPriority, int headerTranslation) { if (!likeHighPriority && showingAsLowPriority()) { + if (AsyncGroupHeaderViewInflation.isEnabled()) { + return mHeaderHeight; + } if (mNotificationHeaderLowPriority == null) { Log.e(TAG, "getMinHeight: low priority header is null", new Exception()); return 0; @@ -1295,8 +1430,12 @@ public class NotificationChildrenContainer extends ViewGroup if (singleLineView != null) { minExpandHeight += singleLineView.getHeight(); } else { - Log.e(TAG, "getMinHeight: child " + child.getEntry().getKey() - + " single line view is null", new Exception()); + if (AsyncGroupHeaderViewInflation.isEnabled()) { + minExpandHeight += mMinSingleLineHeight; + } else { + Log.e(TAG, "getMinHeight: child " + child.getEntry().getKey() + + " single line view is null", new Exception()); + } } visibleChildren++; } @@ -1309,15 +1448,19 @@ public class NotificationChildrenContainer extends ViewGroup } public void reInflateViews(OnClickListener listener, StatusBarNotification notification) { - if (mNotificationHeader != null) { - removeView(mNotificationHeader); - mNotificationHeader = null; - } - if (mNotificationHeaderLowPriority != null) { - removeView(mNotificationHeaderLowPriority); - mNotificationHeaderLowPriority = null; + if (!AsyncGroupHeaderViewInflation.isEnabled()) { + // When Async header inflation is enabled, we do not reinflate headers because they are + // inflated from the background thread + if (mNotificationHeader != null) { + removeView(mNotificationHeader); + mNotificationHeader = null; + } + if (mNotificationHeaderLowPriority != null) { + removeView(mNotificationHeaderLowPriority); + mNotificationHeaderLowPriority = null; + } + recreateNotificationHeader(listener, mIsConversation); } - recreateNotificationHeader(listener, mIsConversation); initDimens(); for (int i = 0; i < mDividers.size(); i++) { View prevDivider = mDividers.get(i); @@ -1395,7 +1538,9 @@ public class NotificationChildrenContainer extends ViewGroup public void setIsLowPriority(boolean isLowPriority) { mIsLowPriority = isLowPriority; if (mContainingNotification != null) { /* we're not yet set up yet otherwise */ - recreateLowPriorityHeader(null /* existingBuilder */, mIsConversation); + if (!AsyncGroupHeaderViewInflation.isEnabled()) { + recreateLowPriorityHeader(null /* existingBuilder */, mIsConversation); + } updateHeaderVisibility(false /* animate */); } if (mUserLocked) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index e397a70ea1f2..9c03405304ef 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -124,6 +124,7 @@ import com.android.systemui.statusbar.policy.ScrollAdapter; import com.android.systemui.statusbar.policy.SplitShadeStateController; import com.android.systemui.util.Assert; import com.android.systemui.util.ColorUtilKt; +import com.android.systemui.util.Compile; import com.android.systemui.util.DumpUtilsKt; import com.google.errorprone.annotations.CompileTimeConstant; @@ -150,6 +151,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable public static final float BACKGROUND_ALPHA_DIMMED = 0.7f; private static final String TAG = "StackScroller"; private static final boolean SPEW = Log.isLoggable(TAG, Log.VERBOSE); + private static final boolean DEBUG_UPDATE_SIDE_PADDING = Compile.IS_DEBUG; private boolean mShadeNeedsToClose = false; @@ -218,6 +220,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable int mBottomInset = 0; private float mQsExpansionFraction; private final int mSplitShadeMinContentHeight; + private String mLastUpdateSidePaddingDumpString; /** * The algorithm which calculates the properties for our children @@ -1106,15 +1109,28 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } void updateSidePadding(int viewWidth) { + final boolean portrait = + getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; + + mLastUpdateSidePaddingDumpString = "viewWidth=" + viewWidth + + " skinnyNotifsInLandscape=" + mSkinnyNotifsInLandscape + + " portrait=" + portrait; + + if (DEBUG_UPDATE_SIDE_PADDING) { + Log.v(TAG, "updateSidePadding: " + mLastUpdateSidePaddingDumpString); + } + if (viewWidth == 0 || !mSkinnyNotifsInLandscape) { mSidePaddings = mMinimumPaddings; return; } + // Portrait is easy, just use the dimen for paddings - if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { + if (portrait) { mSidePaddings = mMinimumPaddings; return; } + final int innerWidth = viewWidth - mMinimumPaddings * 2; final int qsTileWidth = (innerWidth - mQsTilePadding * 3) / 4; mSidePaddings = mMinimumPaddings + qsTileWidth + mQsTilePadding; @@ -4992,6 +5008,17 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable public void generateHeadsUpAnimation(NotificationEntry entry, boolean isHeadsUp) { ExpandableNotificationRow row = entry.getHeadsUpAnimationView(); + generateHeadsUpAnimation(row, isHeadsUp); + } + + /** + * Notifies the NSSL, that the given view would need a HeadsUp animation, when it is being + * added to this container. + * + * @param row to animate + * @param isHeadsUp true for appear, false for disappear animations + */ + public void generateHeadsUpAnimation(ExpandableNotificationRow row, boolean isHeadsUp) { final boolean add = mAnimationsEnabled && (isHeadsUp || mHeadsUpGoingAwayAnimationsAllowed); if (SPEW) { Log.v(TAG, "generateHeadsUpAnimation:" @@ -5294,6 +5321,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable println(pw, "translationX", getTranslationX()); println(pw, "translationY", getTranslationY()); println(pw, "translationZ", getTranslationZ()); + println(pw, "skinnyNotifsInLandscape", mSkinnyNotifsInLandscape); + println(pw, "minimumPaddings", mMinimumPaddings); + println(pw, "qsTilePadding", mQsTilePadding); + println(pw, "sidePaddings", mSidePaddings); + println(pw, "lastUpdateSidePadding", mLastUpdateSidePaddingDumpString); mNotificationStackSizeCalculator.dump(pw, args); }); pw.println(); @@ -5725,11 +5757,17 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mShelf.updateAppearance(); } - void setTopHeadsUpRow(ExpandableNotificationRow topHeadsUpRow) { + /** + * @param topHeadsUpRow the first headsUp row in z-order. + */ + public void setTopHeadsUpRow(ExpandableNotificationRow topHeadsUpRow) { mTopHeadsUpRow = topHeadsUpRow; } - void setNumHeadsUp(long numHeadsUp) { + /** + * @param numHeadsUp the number of active alerting notifications. + */ + public void setNumHeadsUp(long numHeadsUp) { mNumHeadsUp = numHeadsUp; mAmbientState.setHasHeadsUpEntries(numHeadsUp > 0); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index d10ca3d31de2..6b47ac113928 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -239,10 +239,22 @@ public class PhoneStatusBarView extends FrameLayout { ViewGroup.LayoutParams layoutParams = getLayoutParams(); mStatusBarHeight = SystemBarUtils.getStatusBarHeight(mContext); layoutParams.height = mStatusBarHeight - waterfallTopInset; + updateSystemIconsContainerHeight(); updatePaddings(); setLayoutParams(layoutParams); } + private void updateSystemIconsContainerHeight() { + View systemIconsContainer = findViewById(R.id.system_icons); + ViewGroup.LayoutParams layoutParams = systemIconsContainer.getLayoutParams(); + int newSystemIconsHeight = + getResources().getDimensionPixelSize(R.dimen.status_bar_system_icons_height); + if (layoutParams.height != newSystemIconsHeight) { + layoutParams.height = newSystemIconsHeight; + systemIconsContainer.setLayoutParams(layoutParams); + } + } + private void updatePaddings() { int statusBarPaddingStart = getResources().getDimensionPixelSize( R.dimen.status_bar_padding_start); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt index a39bfe00be28..68a0e9cc1bf8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone import android.app.StatusBarManager.WINDOW_STATUS_BAR import android.graphics.Point import android.util.Log +import android.view.InputDevice import android.view.MotionEvent import android.view.View import android.view.ViewGroup @@ -81,7 +82,22 @@ private constructor( statusContainer.setOnHoverListener( statusOverlayHoverListenerFactory.createDarkAwareListener(statusContainer) ) - statusContainer.setOnClickListener { shadeViewController.expand(/* animate= */true) } + statusContainer.setOnTouchListener(object : View.OnTouchListener { + override fun onTouch(v: View, event: MotionEvent): Boolean { + // We want to handle only mouse events here to avoid stealing finger touches from + // status bar which expands shade when swiped down on. We're using onTouchListener + // instead of onClickListener as the later will lead to isClickable being set to + // true and hence ALL touches always being intercepted. See [View.OnTouchEvent] + if (event.source == InputDevice.SOURCE_MOUSE) { + if (event.action == MotionEvent.ACTION_UP) { + v.performClick() + shadeViewController.expand(/* animate= */ true) + } + return true + } + return false + } + }) progressProvider?.setReadyToHandleTransition(true) configurationController.addCallback(configurationListener) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt index be843ba8699f..deae576662e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt @@ -22,7 +22,6 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.statusbar.phone.StatusBarLocation import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor -import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger import com.android.systemui.statusbar.pipeline.mobile.ui.VerboseMobileViewLogger @@ -31,6 +30,8 @@ import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flatMapLatest @@ -58,9 +59,8 @@ constructor( private val flags: FeatureFlagsClassic, @Application private val scope: CoroutineScope, ) { - @VisibleForTesting val mobileIconSubIdCache = mutableMapOf<Int, MobileIconViewModel>() @VisibleForTesting - val mobileIconInteractorSubIdCache = mutableMapOf<Int, MobileIconInteractor>() + val reuseCache = mutableMapOf<Int, Pair<MobileIconViewModel, CoroutineScope>>() val subscriptionIdsFlow: StateFlow<List<Int>> = interactor.filteredSubscriptions @@ -109,24 +109,37 @@ constructor( } private fun commonViewModelForSub(subId: Int): MobileIconViewModelCommon { - return mobileIconSubIdCache[subId] - ?: MobileIconViewModel( - subId, - interactor.getMobileConnectionInteractorForSubId(subId), - airplaneModeInteractor, - constants, - flags, - scope, - ) - .also { mobileIconSubIdCache[subId] = it } + return reuseCache.getOrPut(subId) { createViewModel(subId) }.first } - private fun invalidateCaches(subIds: List<Int>) { - val subIdsToRemove = mobileIconSubIdCache.keys.filter { !subIds.contains(it) } - subIdsToRemove.forEach { mobileIconSubIdCache.remove(it) } + private fun createViewModel(subId: Int): Pair<MobileIconViewModel, CoroutineScope> { + // Create a child scope so we can cancel it + val vmScope = scope.createChildScope() + val vm = + MobileIconViewModel( + subId, + interactor.getMobileConnectionInteractorForSubId(subId), + airplaneModeInteractor, + constants, + flags, + vmScope, + ) + + return Pair(vm, vmScope) + } - mobileIconInteractorSubIdCache.keys + private fun CoroutineScope.createChildScope() = + CoroutineScope(coroutineContext + Job(coroutineContext[Job])) + + private fun invalidateCaches(subIds: List<Int>) { + reuseCache.keys .filter { !subIds.contains(it) } - .forEach { subId -> mobileIconInteractorSubIdCache.remove(subId) } + .forEach { id -> + reuseCache + .remove(id) + // Cancel the view model's scope after removing it + ?.second + ?.cancel() + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java index 2c1780d3b304..530e49c83802 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java @@ -304,14 +304,15 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { if (!isPinned) { headsUpEntry.mWasUnpinned = true; } - if (entry.isRowPinned() != isPinned) { - entry.setRowPinned(isPinned); + if (headsUpEntry.isPinned() != isPinned) { + headsUpEntry.setPinned(isPinned); updatePinnedMode(); if (isPinned && entry.getSbn() != null) { - mUiEventLogger.logWithInstanceId( + mUiEventLogger.logWithInstanceId( NotificationPeekEvent.NOTIFICATION_PEEK, entry.getSbn().getUid(), entry.getSbn().getPackageName(), entry.getSbn().getInstanceId()); } + // TODO(b/325936094) convert these listeners to collecting a flow for (OnHeadsUpChangedListener listener : mListeners) { if (isPinned) { listener.onHeadsUpPinned(entry); @@ -662,6 +663,14 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager { updateEntry(true /* updatePostTime */, "setEntry"); } + public boolean isPinned() { + return mEntry != null && mEntry.isRowPinned(); + } + + public void setPinned(boolean pinned) { + if (mEntry != null) mEntry.setRowPinned(pinned); + } + /** * Updates an entry's removal time. * @param updatePostTime whether or not to refresh the post time diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt index 0f8a81399be8..3d0d8fb4abe4 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt @@ -21,8 +21,8 @@ import android.view.View import android.view.ViewTreeObserver import android.widget.FrameLayout import androidx.test.filters.SmallTest -import com.android.systemui.SysuiTestCase import com.android.systemui.Flags as AConfigFlags +import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository @@ -319,7 +319,10 @@ class ClockEventControllerTest : SysuiTestCase() { fun listenForDozeAmountTransition_updatesClockDozeAmount() = runBlocking(IMMEDIATE) { val transitionStep = MutableStateFlow(TransitionStep()) - whenever(keyguardTransitionInteractor.dozeAmountTransition).thenReturn(transitionStep) + whenever(keyguardTransitionInteractor.lockscreenToAodTransition) + .thenReturn(transitionStep) + whenever(keyguardTransitionInteractor.aodToLockscreenTransition) + .thenReturn(transitionStep) val job = underTest.listenForDozeAmountTransition(this) transitionStep.value = @@ -336,6 +339,48 @@ class ClockEventControllerTest : SysuiTestCase() { } @Test + fun listenForTransitionToAodFromGone_updatesClockDozeAmountToOne() = + runBlocking(IMMEDIATE) { + val transitionStep = MutableStateFlow(TransitionStep()) + whenever(keyguardTransitionInteractor.transitionStepsToState(KeyguardState.AOD)) + .thenReturn(transitionStep) + + val job = underTest.listenForAnyStateToAodTransition(this) + transitionStep.value = + TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + transitionState = TransitionState.STARTED, + ) + yield() + + verify(animations, times(2)).doze(1f) + + job.cancel() + } + + @Test + fun listenForTransitionToAodFromLockscreen_neverUpdatesClockDozeAmount() = + runBlocking(IMMEDIATE) { + val transitionStep = MutableStateFlow(TransitionStep()) + whenever(keyguardTransitionInteractor.transitionStepsToState(KeyguardState.AOD)) + .thenReturn(transitionStep) + + val job = underTest.listenForAnyStateToAodTransition(this) + transitionStep.value = + TransitionStep( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.AOD, + transitionState = TransitionState.STARTED, + ) + yield() + + verify(animations, never()).doze(1f) + + job.cancel() + } + + @Test fun unregisterListeners_validate() = runBlocking(IMMEDIATE) { underTest.unregisterListeners() diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java index 13fb42ce8c3e..90587d7386ce 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java @@ -16,8 +16,6 @@ package com.android.keyguard; -import static kotlinx.coroutines.flow.FlowKt.emptyFlow; - import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -32,7 +30,6 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory; -import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.power.data.repository.FakePowerRepository; import com.android.systemui.power.domain.interactor.PowerInteractorFactory; import com.android.systemui.res.R; @@ -62,7 +59,6 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase { @Mock protected KeyguardStatusViewController mControllerMock; @Mock protected InteractionJankMonitor mInteractionJankMonitor; @Mock protected ViewTreeObserver mViewTreeObserver; - @Mock protected KeyguardTransitionInteractor mKeyguardTransitionInteractor; @Mock protected DumpManager mDumpManager; protected FakeKeyguardRepository mFakeKeyguardRepository; protected FakePowerRepository mFakePowerRepository; @@ -93,7 +89,6 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase { mKeyguardLogger, mInteractionJankMonitor, deps.getKeyguardInteractor(), - mKeyguardTransitionInteractor, mDumpManager, PowerInteractorFactory.create( mFakePowerRepository @@ -110,7 +105,6 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase { when(mKeyguardStatusView.getViewTreeObserver()).thenReturn(mViewTreeObserver); when(mKeyguardClockSwitchController.getView()).thenReturn(mKeyguardClockSwitch); - when(mKeyguardTransitionInteractor.getGoneToAodTransition()).thenReturn(emptyFlow()); when(mKeyguardStatusView.findViewById(R.id.keyguard_status_area)) .thenReturn(mKeyguardStatusAreaView); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt index df52265384fa..d0b1dd52c7e7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/BurnInInteractorTest.kt @@ -122,7 +122,13 @@ class BurnInInteractorTest : SysuiTestCase() { testScope.runTest { whenever(burnInHelperWrapper.burnInScale()).thenReturn(0.5f) - val burnInModel by collectLastValue(underTest.keyguardBurnIn) + val burnInModel by + collectLastValue( + underTest.burnIn( + xDimenResourceId = R.dimen.burn_in_prevention_offset_x, + yDimenResourceId = R.dimen.burn_in_prevention_offset_y + ) + ) // After time tick, returns the configured values fakeKeyguardRepository.dozeTimeTick(10) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt index a4483bdac467..6d605a564022 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt @@ -375,4 +375,323 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { values ) } + + @Test + fun testLockscreenVisibility_usesFromState_ifCanceled() = + testScope.runTest { + val values by collectValues(underTest.lockscreenVisibility) + + transitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope + ) + + runCurrent() + + assertEquals( + listOf( + // Initially should be true, as we start in LOCKSCREEN. + true, + // Then, false, since we finish in GONE. + false, + ), + values + ) + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.GONE, + to = KeyguardState.AOD, + ) + ) + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.RUNNING, + from = KeyguardState.GONE, + to = KeyguardState.AOD, + ) + ) + runCurrent() + + assertEquals( + listOf( + true, + // Should remain false as we transition from GONE. + false, + ), + values + ) + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.CANCELED, + from = KeyguardState.GONE, + to = KeyguardState.AOD, + ) + ) + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.AOD, + to = KeyguardState.LOCKSCREEN, + ) + ) + + runCurrent() + + assertEquals( + listOf( + true, + false, + // If we cancel and then go from LS -> GONE, we should immediately flip to the + // visibility of the from state (LS). + true, + ), + values + ) + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.FINISHED, + from = KeyguardState.AOD, + to = KeyguardState.LOCKSCREEN, + ) + ) + + runCurrent() + + assertEquals( + listOf( + true, + false, + true, + ), + values + ) + } + + /** + * Tests the special case for insecure camera launch. CANCELING a transition from GONE and then + * STARTING a transition back to GONE should never show the lockscreen, even though the current + * state during the AOD/isAsleep -> GONE transition is AOD (where lockscreen visibility = true). + */ + @Test + fun testLockscreenVisibility_falseDuringTransitionToGone_fromCanceledGone() = + testScope.runTest { + val values by collectValues(underTest.lockscreenVisibility) + + transitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope + ) + + runCurrent() + assertEquals( + listOf( + true, + // Not visible since we're GONE. + false, + ), + values + ) + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.GONE, + to = KeyguardState.AOD, + ) + ) + runCurrent() + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.RUNNING, + from = KeyguardState.GONE, + to = KeyguardState.AOD, + ) + ) + runCurrent() + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.CANCELED, + from = KeyguardState.GONE, + to = KeyguardState.AOD, + ) + ) + runCurrent() + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.AOD, + to = KeyguardState.GONE, + ) + ) + runCurrent() + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.RUNNING, + from = KeyguardState.AOD, + to = KeyguardState.GONE, + ) + ) + runCurrent() + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.FINISHED, + from = KeyguardState.AOD, + to = KeyguardState.GONE, + ) + ) + + runCurrent() + assertEquals( + listOf( + true, + // Remains not visible from GONE -> AOD (canceled) -> AOD since we never + // FINISHED in AOD, and special-case handling for the insecure camera launch + // ensures that we use the lockscreen visibility for GONE (false) if we're + // STARTED to GONE after a CANCELED from GONE. + false, + ), + values + ) + + transitionRepository.sendTransitionSteps( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + testScope, + ) + + assertEquals( + listOf( + true, + false, + // Make sure there's no stuck overrides or something - we should make lockscreen + // visible again once we're finished in LOCKSCREEN. + true, + ), + values + ) + } + + /** */ + @Test + fun testLockscreenVisibility_trueDuringTransitionToGone_fromNotCanceledGone() = + testScope.runTest { + val values by collectValues(underTest.lockscreenVisibility) + + transitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.GONE, + testScope + ) + + runCurrent() + assertEquals( + listOf( + true, + // Not visible when finished in GONE. + false, + ), + values + ) + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.GONE, + to = KeyguardState.AOD, + ) + ) + runCurrent() + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.RUNNING, + from = KeyguardState.GONE, + to = KeyguardState.AOD, + ) + ) + runCurrent() + + assertEquals( + listOf( + true, + // Still not visible during GONE -> AOD. + false, + ), + values + ) + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.FINISHED, + from = KeyguardState.GONE, + to = KeyguardState.AOD, + ) + ) + runCurrent() + + assertEquals( + listOf( + true, + false, + // Visible now that we're FINISHED in AOD. + true + ), + values + ) + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + from = KeyguardState.AOD, + to = KeyguardState.GONE, + ) + ) + runCurrent() + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.RUNNING, + from = KeyguardState.AOD, + to = KeyguardState.GONE, + ) + ) + runCurrent() + + assertEquals( + listOf( + true, + false, + // Remains visible from AOD during transition. + true + ), + values + ) + + transitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.FINISHED, + from = KeyguardState.AOD, + to = KeyguardState.GONE, + ) + ) + + runCurrent() + assertEquals( + listOf( + true, + false, + true, + // Until we're finished in GONE again. + false + ), + values + ) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt new file mode 100644 index 000000000000..ac4107359dbc --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.mediaprojection.appselector.view + +import android.app.ActivityOptions +import android.app.IActivityTaskManager +import android.os.Bundle +import android.view.View +import android.view.ViewGroup +import androidx.test.filters.SmallTest +import com.android.systemui.Flags.FLAG_PSS_APP_SELECTOR_ABRUPT_EXIT_FIX +import com.android.systemui.SysuiTestCase +import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorResultHandler +import com.android.systemui.mediaprojection.appselector.data.RecentTask +import com.android.systemui.util.mockito.mock +import com.google.common.truth.Expect +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.mockito.ArgumentCaptor +import org.mockito.ArgumentMatchers.eq +import org.mockito.Mockito.any +import org.mockito.Mockito.verify + +@SmallTest +class MediaProjectionRecentsViewControllerTest : SysuiTestCase() { + + @get:Rule val expect: Expect = Expect.create() + + private val recentTasksAdapter = mock<RecentTasksAdapter>() + private val tasksAdapterFactory = RecentTasksAdapter.Factory { _, _ -> recentTasksAdapter } + private val taskViewSizeProvider = mock<TaskPreviewSizeProvider>() + private val activityTaskManager = mock<IActivityTaskManager>() + private val resultHandler = mock<MediaProjectionAppSelectorResultHandler>() + private val bundleCaptor = ArgumentCaptor.forClass(Bundle::class.java) + + private val task = + RecentTask( + taskId = 123, + displayId = 456, + userId = 789, + topActivityComponent = null, + baseIntentComponent = null, + colorBackground = null, + isForegroundTask = false + ) + + private val taskView = + View(context).apply { + layoutParams = ViewGroup.LayoutParams(/* width = */ 100, /* height = */ 200) + } + + private val controller = + MediaProjectionRecentsViewController( + tasksAdapterFactory, + taskViewSizeProvider, + activityTaskManager, + resultHandler + ) + + @Test + fun onRecentAppClicked_taskWithSameIdIsStartedFromRecents() { + controller.onRecentAppClicked(task, taskView) + + verify(activityTaskManager).startActivityFromRecents(eq(task.taskId), any()) + } + + @Test + fun onRecentAppClicked_launchDisplayIdIsSet() { + controller.onRecentAppClicked(task, taskView) + + assertThat(getStartedTaskActivityOptions().launchDisplayId).isEqualTo(task.displayId) + } + + @Test + fun onRecentAppClicked_taskNotInForeground_usesScaleUpAnimation() { + controller.onRecentAppClicked(task, taskView) + + assertThat(getStartedTaskActivityOptions().animationType) + .isEqualTo(ActivityOptions.ANIM_SCALE_UP) + } + + @Test + fun onRecentAppClicked_taskInForeground_flagOff_usesScaleUpAnimation() { + mSetFlagsRule.disableFlags(FLAG_PSS_APP_SELECTOR_ABRUPT_EXIT_FIX) + + controller.onRecentAppClicked(task, taskView) + + assertThat(getStartedTaskActivityOptions().animationType) + .isEqualTo(ActivityOptions.ANIM_SCALE_UP) + } + + @Test + fun onRecentAppClicked_taskInForeground_flagOn_usesDefaultAnimation() { + mSetFlagsRule.enableFlags(FLAG_PSS_APP_SELECTOR_ABRUPT_EXIT_FIX) + val foregroundTask = task.copy(isForegroundTask = true) + + controller.onRecentAppClicked(foregroundTask, taskView) + + expect + .that(getStartedTaskActivityOptions().animationType) + .isEqualTo(ActivityOptions.ANIM_CUSTOM) + expect.that(getStartedTaskActivityOptions().overrideTaskTransition).isTrue() + expect + .that(getStartedTaskActivityOptions().customExitResId) + .isEqualTo(com.android.internal.R.anim.resolver_close_anim) + expect.that(getStartedTaskActivityOptions().customEnterResId).isEqualTo(0) + } + + private fun getStartedTaskActivityOptions(): ActivityOptions { + verify(activityTaskManager) + .startActivityFromRecents(eq(task.taskId), bundleCaptor.capture()) + return ActivityOptions.fromBundle(bundleCaptor.value) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java index fd7b1399d03f..f8771b26476c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java @@ -461,7 +461,6 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { mKeyguardLogger, mInteractionJankMonitor, mKeyguardInteractor, - mKeyguardTransitionInteractor, mDumpManager, mPowerInteractor)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java index a8002e10d3a7..1504d4c1f033 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java @@ -92,6 +92,21 @@ import java.util.Set; @TestableLooper.RunWithLooper public class KeyguardIndicationControllerTest extends KeyguardIndicationControllerBaseTest { @Test + public void afterFaceLockout_skipShowingFaceNotRecognized() { + createController(); + onFaceLockoutError("lockout"); + verifyIndicationShown(INDICATION_TYPE_BIOMETRIC_MESSAGE, "lockout"); + clearInvocations(mRotateTextViewController); + + // WHEN face sends an onBiometricHelp BIOMETRIC_HELP_FACE_NOT_RECOGNIZED (face fail) + mKeyguardUpdateMonitorCallback.onBiometricHelp( + BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, + "Face not recognized", + BiometricSourceType.FACE); + verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE); // no updated message + } + + @Test public void createController_setIndicationAreaAgain_destroysPreviousRotateTextViewController() { // GIVEN a controller with a mocked rotate text view controlller final KeyguardIndicationRotateTextViewController mockedRotateTextViewController = @@ -1243,7 +1258,7 @@ public class KeyguardIndicationControllerTest extends KeyguardIndicationControll public void onBiometricFailed_resetFaceHelpMessageDeferral() { createController(); - // WHEN face sends an onBiometricHelp BIOMETRIC_HELP_FACE_NOT_RECOGNIZED + // WHEN face sends an onBiometricAuthFailed mKeyguardUpdateMonitorCallback.onBiometricAuthFailed(BiometricSourceType.FACE); // THEN face help message deferral is reset diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt index 7d99d05e3f0b..457d2f09ed9e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt @@ -34,6 +34,7 @@ import com.android.systemui.statusbar.notification.collection.coordinator.dagger import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Invalidator import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController import com.android.systemui.user.domain.interactor.SelectedUserInteractor @@ -130,6 +131,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(false, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true) } @Test @@ -156,6 +158,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(true, false) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false) } @Test @@ -196,6 +199,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(false, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true) } @Test @@ -222,6 +226,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(true, false) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false) } @Test @@ -262,6 +267,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(false, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true) } @Test @@ -288,6 +294,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(true, false) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false) } @Test @@ -329,6 +336,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(false, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true) } @Test @@ -356,6 +364,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(true, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false) } @Test @@ -396,6 +405,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(true, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true) } @Test @@ -422,6 +432,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(true, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false) } @Test @@ -462,6 +473,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(false, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true) } @Test @@ -489,6 +501,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(true, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false) } @Test @@ -531,6 +544,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(true, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(true) } @Test @@ -559,6 +573,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!).setSensitive(true, true) + verify(entry.representativeEntry!!.row!!).setPublicExpanderVisible(false) } @Test @@ -584,6 +599,7 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { onBeforeRenderListListener.onBeforeRenderList(listOf(entry)) verify(entry.representativeEntry!!, never()).setSensitive(any(), any()) + verify(entry.representativeEntry!!.row!!, never()).setPublicExpanderVisible(any()) } private fun fakeNotification(notifUserId: Int, needsRedaction: Boolean): ListEntry { @@ -591,7 +607,11 @@ class SensitiveContentCoordinatorTest : SysuiTestCase() { mock<UserHandle>().apply { whenever(identifier).thenReturn(notifUserId) } val mockSbn: StatusBarNotification = mock<StatusBarNotification>().apply { whenever(user).thenReturn(mockUserHandle) } - val mockEntry = mock<NotificationEntry>().apply { whenever(sbn).thenReturn(mockSbn) } + val mockRow: ExpandableNotificationRow = mock<ExpandableNotificationRow>() + val mockEntry = mock<NotificationEntry>().apply { + whenever(sbn).thenReturn(mockSbn) + whenever(row).thenReturn(mockRow) + } whenever(lockscreenUserManager.needsRedaction(mockEntry)).thenReturn(needsRedaction) whenever(mockEntry.rowExists()).thenReturn(true) return object : ListEntry("key", 0) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt index 73c49c023dd5..115a0d367e87 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt @@ -31,6 +31,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager +import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.eq @@ -46,6 +47,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.inOrder +import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.`when` as whenever @@ -141,12 +143,14 @@ class NotifUiAdjustmentProviderTest : SysuiTestCase() { fun changeIsChildInGroup_asyncHybirdFlagEnabled_needReInflation() { // Given: an Entry that is not child in group // AsyncHybridViewInflation flag is enabled - whenever(groupMembershipManager.isChildInGroup(entry)).thenReturn(false) + val spySbn = spy(entry.sbn) + entry.sbn = spySbn + whenever(spySbn.isAppOrSystemGroupChild).thenReturn(false) val oldAdjustment = adjustmentProvider.calculateAdjustment(entry) assertThat(oldAdjustment.isChildInGroup).isFalse() // When: the Entry becomes a group child - whenever(groupMembershipManager.isChildInGroup(entry)).thenReturn(true) + whenever(spySbn.isAppOrSystemGroupChild).thenReturn(true) val newAdjustment = adjustmentProvider.calculateAdjustment(entry) assertThat(newAdjustment.isChildInGroup).isTrue() assertThat(newAdjustment).isNotEqualTo(oldAdjustment) @@ -160,12 +164,14 @@ class NotifUiAdjustmentProviderTest : SysuiTestCase() { fun changeIsChildInGroup_asyncHybirdFlagDisabled_noNeedForReInflation() { // Given: an Entry that is not child in group // AsyncHybridViewInflation flag is disabled - whenever(groupMembershipManager.isChildInGroup(entry)).thenReturn(false) + val spySbn = spy(entry.sbn) + entry.sbn = spySbn + whenever(spySbn.isAppOrSystemGroupChild).thenReturn(false) val oldAdjustment = adjustmentProvider.calculateAdjustment(entry) assertThat(oldAdjustment.isChildInGroup).isFalse() // When: the Entry becomes a group child - whenever(groupMembershipManager.isChildInGroup(entry)).thenReturn(true) + whenever(spySbn.isAppOrSystemGroupChild).thenReturn(true) val newAdjustment = adjustmentProvider.calculateAdjustment(entry) assertThat(newAdjustment.isChildInGroup).isTrue() assertThat(newAdjustment).isNotEqualTo(oldAdjustment) @@ -173,4 +179,24 @@ class NotifUiAdjustmentProviderTest : SysuiTestCase() { // Then: need no re-inflation assertFalse(NotifUiAdjustment.needReinflate(oldAdjustment, newAdjustment)) } + + @Test + @EnableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME) + fun changeIsGroupSummary_needReInflation() { + // Given: an Entry that is not a group summary + val spySbn = spy(entry.sbn) + entry.sbn = spySbn + whenever(spySbn.isAppOrSystemGroupSummary).thenReturn(false) + val oldAdjustment = adjustmentProvider.calculateAdjustment(entry) + assertThat(oldAdjustment.isGroupSummary).isFalse() + + // When: the Entry becomes a group summary + whenever(spySbn.isAppOrSystemGroupSummary).thenReturn(true) + val newAdjustment = adjustmentProvider.calculateAdjustment(entry) + assertThat(newAdjustment.isGroupSummary).isTrue() + assertThat(newAdjustment).isNotEqualTo(oldAdjustment) + + // Then: Need re-inflation + assertTrue(NotifUiAdjustment.needReinflate(oldAdjustment, newAdjustment)) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java index 49ba9156bd33..42a6924b95e1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java @@ -69,6 +69,7 @@ import com.android.systemui.statusbar.notification.SourceType; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener; import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper; +import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization; import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer; import com.android.systemui.statusbar.phone.KeyguardBypassController; @@ -330,6 +331,61 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { } @Test + @EnableFlags(NotificationContentAlphaOptimization.FLAG_NAME) + public void setHideSensitive_shouldNotDisturbAnimation() throws Exception { + //Given: A row that is during alpha animation + ExpandableNotificationRow row = mNotificationTestHelper.createRow(); + + assertEquals(row.getPrivateLayout(), row.getContentView()); + row.setContentAlpha(0.5f); + + //When: Set its hideSensitive without changing the content view to show + row.setHideSensitive( + /* hideSensitive= */ false, + /* animated= */ false, + /* delay= */ 0L, + /* duration= */ 0L + ); + assertEquals(row.getPrivateLayout(), row.getContentView()); + + //Then: The alpha value should not be reset + assertEquals(0.5f, row.getPrivateLayout().getAlpha(), 0); + } + + @Test + @EnableFlags(NotificationContentAlphaOptimization.FLAG_NAME) + public void setHideSensitive_changeContent_shouldNotDisturbAnimation() throws Exception { + + // Given: A sensitive row that has public version but is not hiding sensitive, + // and is during an animation that sets its alpha value to be 0.5f + Notification publicNotif = mNotificationTestHelper.createNotification(); + publicNotif.publicVersion = mNotificationTestHelper.createNotification(); + ExpandableNotificationRow row = mNotificationTestHelper.createRow(publicNotif); + row.setSensitive(true, false); + row.setContentAlpha(0.5f); + + assertEquals(0.5f, row.getPrivateLayout().getAlpha(), 0); + assertEquals(View.VISIBLE, row.getPrivateLayout().getVisibility()); + + // When: Change its hideSensitive and changes the content view to show the public version + row.setHideSensitive( + /* hideSensitive= */ true, + /* animated= */ false, + /* delay= */ 0L, + /* duration= */ 0L + ); + + // Then: The alpha value of private layout should be reset to 1, private layout be + // INVISIBLE; + // The alpha value of public layout should be 0.5 to preserve the animation state, public + // layout should be VISIBLE + assertEquals(View.INVISIBLE, row.getPrivateLayout().getVisibility()); + assertEquals(1f, row.getPrivateLayout().getAlpha(), 0); + assertEquals(View.VISIBLE, row.getPublicLayout().getVisibility()); + assertEquals(0.5f, row.getPublicLayout().getAlpha(), 0); + } + + @Test public void testReinflatedOnDensityChange() throws Exception { ExpandableNotificationRow row = mNotificationTestHelper.createRow(); NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java index be976a1c9eaf..1f38a73020b2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java @@ -16,11 +16,17 @@ package com.android.systemui.statusbar.notification.stack; +import static org.junit.Assert.assertNull; + +import android.app.Notification; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; import android.view.NotificationHeaderView; import android.view.View; +import android.widget.RemoteViews; import androidx.test.filters.SmallTest; @@ -28,6 +34,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.notification.SourceType; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationTestHelper; +import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderViewInflation; import com.android.systemui.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper; import org.junit.Assert; @@ -40,6 +47,7 @@ import java.util.List; @SmallTest @RunWith(AndroidTestingRunner.class) @RunWithLooper +//@DisableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME) public class NotificationChildrenContainerTest extends SysuiTestCase { private ExpandableNotificationRow mGroup; @@ -138,6 +146,7 @@ public class NotificationChildrenContainerTest extends SysuiTestCase { } @Test + @DisableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME) public void testLowPriorityHeaderCleared() { mGroup.setIsLowPriority(true); NotificationHeaderView lowPriorityHeaderView = @@ -145,11 +154,12 @@ public class NotificationChildrenContainerTest extends SysuiTestCase { Assert.assertEquals(View.VISIBLE, lowPriorityHeaderView.getVisibility()); Assert.assertSame(mChildrenContainer, lowPriorityHeaderView.getParent()); mGroup.setIsLowPriority(false); - Assert.assertNull(lowPriorityHeaderView.getParent()); - Assert.assertNull(mChildrenContainer.getLowPriorityViewWrapper()); + assertNull(lowPriorityHeaderView.getParent()); + assertNull(mChildrenContainer.getLowPriorityViewWrapper()); } @Test + @DisableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME) public void testRecreateNotificationHeader_hasHeader() { mChildrenContainer.recreateNotificationHeader(null, false); Assert.assertNotNull("Children container must have a header after recreation", @@ -157,6 +167,76 @@ public class NotificationChildrenContainerTest extends SysuiTestCase { } @Test + @EnableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME) + public void testSetLowPriorityWithAsyncInflation_noHeaderReInflation() { + mChildrenContainer.setIsLowPriority(true); + assertNull("We don't inflate header from the main thread with Async " + + "Inflation enabled", mChildrenContainer.getCurrentHeaderView()); + } + + @Test + @EnableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME) + public void setLowPriorityBeforeLowPriorityHeaderSet() { + + //Given: the children container does not have a low-priority header, and is not low-priority + assertNull(mChildrenContainer.getLowPriorityViewWrapper()); + mGroup.setIsLowPriority(false); + + //When: set the children container to be low-priority and set the low-priority header + mGroup.setIsLowPriority(true); + mGroup.setLowPriorityGroupHeader(createHeaderView(/* lowPriorityHeader= */ true)); + + //Then: the low-priority group header should be visible + NotificationHeaderView lowPriorityHeaderView = + mChildrenContainer.getLowPriorityViewWrapper().getNotificationHeader(); + Assert.assertEquals(View.VISIBLE, lowPriorityHeaderView.getVisibility()); + Assert.assertSame(mChildrenContainer, lowPriorityHeaderView.getParent()); + + //When: set the children container to be not low-priority and set the normal header + mGroup.setIsLowPriority(false); + mGroup.setGroupHeader(createHeaderView(/* lowPriorityHeader= */ false)); + + //Then: the low-priority group header should not be visible , normal header should be + // visible + Assert.assertEquals(View.INVISIBLE, lowPriorityHeaderView.getVisibility()); + Assert.assertEquals( + View.VISIBLE, + mChildrenContainer.getNotificationHeaderWrapper().getNotificationHeader() + .getVisibility() + ); + } + + @Test + @EnableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME) + public void changeLowPriorityAfterHeaderSet() { + + //Given: the children container does not have headers, and is not low-priority + assertNull(mChildrenContainer.getLowPriorityViewWrapper()); + assertNull(mChildrenContainer.getNotificationHeaderWrapper()); + mGroup.setIsLowPriority(false); + + //When: set the set the normal header + mGroup.setGroupHeader(createHeaderView(/* lowPriorityHeader= */ false)); + + //Then: the group header should be visible + NotificationHeaderView headerView = + mChildrenContainer.getNotificationHeaderWrapper().getNotificationHeader(); + Assert.assertEquals(View.VISIBLE, headerView.getVisibility()); + Assert.assertSame(mChildrenContainer, headerView.getParent()); + + //When: set the set the row to be low priority, and set the low-priority header + mGroup.setIsLowPriority(true); + mGroup.setLowPriorityGroupHeader(createHeaderView(/* lowPriorityHeader= */ true)); + + //Then: the header view should not be visible, the low-priority group header should be + // visible + Assert.assertEquals(View.INVISIBLE, headerView.getVisibility()); + NotificationHeaderView lowPriorityHeaderView = + mChildrenContainer.getLowPriorityViewWrapper().getNotificationHeader(); + Assert.assertEquals(View.VISIBLE, lowPriorityHeaderView.getVisibility()); + } + + @Test public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_last_child() { List<ExpandableNotificationRow> children = mChildrenContainer.getAttachedChildren(); ExpandableNotificationRow notificationRow = children.get(children.size() - 1); @@ -170,6 +250,7 @@ public class NotificationChildrenContainerTest extends SysuiTestCase { } @Test + @DisableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME) public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_header() { NotificationHeaderViewWrapper header = mChildrenContainer.getNotificationHeaderWrapper(); Assert.assertEquals(0f, header.getTopRoundness(), 0.001f); @@ -180,6 +261,7 @@ public class NotificationChildrenContainerTest extends SysuiTestCase { } @Test + @DisableFlags(AsyncGroupHeaderViewInflation.FLAG_NAME) public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_headerLowPriority() { mChildrenContainer.setIsLowPriority(true); @@ -190,4 +272,17 @@ public class NotificationChildrenContainerTest extends SysuiTestCase { Assert.assertEquals(1f, header.getTopRoundness(), 0.001f); } + + private NotificationHeaderView createHeaderView(boolean lowPriority) { + Notification notification = mNotificationTestHelper.createNotification(); + final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(), + notification); + RemoteViews headerRemoteViews; + if (lowPriority) { + headerRemoteViews = builder.makeLowPriorityContentView(true); + } else { + headerRemoteViews = builder.makeNotificationGroupHeader(); + } + return (NotificationHeaderView) headerRemoteViews.apply(getContext(), mChildrenContainer); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt index 1687ccbf5826..3792d5c1d6b9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt @@ -20,6 +20,7 @@ import android.app.StatusBarManager.WINDOW_STATE_HIDDEN import android.app.StatusBarManager.WINDOW_STATE_HIDING import android.app.StatusBarManager.WINDOW_STATE_SHOWING import android.app.StatusBarManager.WINDOW_STATUS_BAR +import android.view.InputDevice import android.view.LayoutInflater import android.view.MotionEvent import android.view.View @@ -239,11 +240,42 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() { controller = createAndInitController(view) } val statusContainer = view.requireViewById<View>(R.id.system_icons) - statusContainer.performClick() + statusContainer.dispatchTouchEvent( + getMotionEventFromSource( + MotionEvent.ACTION_UP, + 0, + 0, + InputDevice.SOURCE_MOUSE + ) + ) verify(shadeViewController).expand(any()) } @Test + fun statusIconContainerIsNotHandlingTouchScreenTouches() { + val view = createViewMock() + InstrumentationRegistry.getInstrumentation().runOnMainSync { + controller = createAndInitController(view) + } + val statusContainer = view.requireViewById<View>(R.id.system_icons) + val handled = statusContainer.dispatchTouchEvent( + getMotionEventFromSource( + MotionEvent.ACTION_UP, + 0, + 0, + InputDevice.SOURCE_TOUCHSCREEN + ) + ) + assertThat(handled).isFalse() + } + + private fun getMotionEventFromSource(action: Int, x: Int, y: Int, source: Int): MotionEvent { + val ev = MotionEvent.obtain(0, 0, action, x.toFloat(), y.toFloat(), 0) + ev.source = source + return ev + } + + @Test fun shadeIsNotExpandedOnStatusBarGeneralClick() { val view = createViewMock() InstrumentationRegistry.getInstrumentation().runOnMainSync { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt index 5e8b62e799c1..fd2dead02c6c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt @@ -26,6 +26,7 @@ import android.view.LayoutInflater import android.view.MotionEvent import android.view.PrivacyIndicatorBounds import android.view.RoundedCorners +import android.view.View import android.view.WindowInsets import android.widget.FrameLayout import androidx.test.filters.SmallTest @@ -50,6 +51,8 @@ import org.mockito.Mockito.verify class PhoneStatusBarViewTest : SysuiTestCase() { private lateinit var view: PhoneStatusBarView + private val systemIconsContainer: View + get() = view.requireViewById(R.id.system_icons) private val contentInsetsProvider = mock<StatusBarContentInsetsProvider>() private val windowController = mock<StatusBarWindowController>() @@ -62,6 +65,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() { ) mDependency.injectTestDependency(DarkIconDispatcher::class.java, mock<DarkIconDispatcher>()) mDependency.injectTestDependency(StatusBarWindowController::class.java, windowController) + context.ensureTestableResources() view = spy(createStatusBarView()) whenever(view.rootWindowInsets).thenReturn(emptyWindowInsets()) whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) @@ -217,7 +221,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() { val newInsets = Insets.NONE whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) - .thenReturn(newInsets) + .thenReturn(newInsets) view.onConfigurationChanged(Configuration()) assertThat(view.paddingLeft).isEqualTo(previousInsets.left) @@ -239,7 +243,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() { val newInsets = Insets.NONE whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) - .thenReturn(newInsets) + .thenReturn(newInsets) configuration.densityDpi = 456 view.onConfigurationChanged(configuration) @@ -262,7 +266,7 @@ class PhoneStatusBarViewTest : SysuiTestCase() { val newInsets = Insets.NONE whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) - .thenReturn(newInsets) + .thenReturn(newInsets) configuration.fontScale = 2f view.onConfigurationChanged(configuration) @@ -273,6 +277,19 @@ class PhoneStatusBarViewTest : SysuiTestCase() { } @Test + fun onConfigurationChanged_systemIconsHeightChanged_containerHeightIsUpdated() { + val newHeight = 123456 + context.orCreateTestableResources.addOverride( + R.dimen.status_bar_system_icons_height, + newHeight + ) + + view.onConfigurationChanged(Configuration()) + + assertThat(systemIconsContainer.layoutParams.height).isEqualTo(newHeight) + } + + @Test fun onApplyWindowInsets_updatesLeftTopRightPaddingsBasedOnInsets() { val insets = Insets.of(/* left = */ 90, /* top = */ 10, /* right = */ 45, /* bottom = */ 50) whenever(contentInsetsProvider.getStatusBarContentInsetsForCurrentRotation()) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt index 1f27a289e52c..47899a66b772 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt @@ -38,9 +38,12 @@ import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat +import junit.framework.Assert.assertFalse +import junit.framework.Assert.assertTrue import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.isActive import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest @@ -156,14 +159,35 @@ class MobileIconsViewModelTest : SysuiTestCase() { val model2 = underTest.viewModelForSub(2, StatusBarLocation.QS) // Both impls are cached - assertThat(underTest.mobileIconSubIdCache) - .containsExactly(1, model1.commonImpl, 2, model2.commonImpl) + assertThat(underTest.reuseCache.keys).containsExactly(1, 2) // SUB_1 is removed from the list... interactor.filteredSubscriptions.value = listOf(SUB_2) // ... and dropped from the cache - assertThat(underTest.mobileIconSubIdCache).containsExactly(2, model2.commonImpl) + assertThat(underTest.reuseCache.keys).containsExactly(2) + } + + @Test + fun caching_invalidatedViewModelsAreCanceled() = + testScope.runTest { + // Retrieve models to trigger caching + val model1 = underTest.viewModelForSub(1, StatusBarLocation.HOME) + val model2 = underTest.viewModelForSub(2, StatusBarLocation.QS) + + var scope1 = underTest.reuseCache[1]?.second + var scope2 = underTest.reuseCache[2]?.second + + // Scopes are not canceled + assertTrue(scope1!!.isActive) + assertTrue(scope2!!.isActive) + + // SUB_1 is removed from the list... + interactor.filteredSubscriptions.value = listOf(SUB_2) + + // scope1 is canceled + assertFalse(scope1!!.isActive) + assertTrue(scope2!!.isActive) } @Test diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt index 3b5ff38e3663..1b951d95df11 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeDisplayStateRepository.kt @@ -19,6 +19,7 @@ package com.android.systemui.biometrics.data.repository import android.util.Size import com.android.systemui.biometrics.shared.model.DisplayRotation +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -33,6 +34,9 @@ class FakeDisplayStateRepository : DisplayStateRepository { private val _currentDisplaySize = MutableStateFlow<Size>(Size(0, 0)) override val currentDisplaySize: StateFlow<Size> = _currentDisplaySize.asStateFlow() + private val _isLargeScreen = MutableStateFlow<Boolean>(false) + override val isLargeScreen: Flow<Boolean> = _isLargeScreen.asStateFlow() + override val isReverseDefaultRotation = false fun setIsInRearDisplayMode(isInRearDisplayMode: Boolean) { diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt index 8ad0a080a9dd..5c3e1f410e63 100644 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/mediaoutput/MediaOutputModule.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/ComposeBouncerFlagsKosmos.kt @@ -14,8 +14,11 @@ * limitations under the License. */ -package com.android.systemui.volume.panel.component.mediaoutput +package com.android.systemui.bouncer.shared.flag -import dagger.Module +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags -@Module interface MediaOutputModule +var Kosmos.fakeComposeBouncerFlags by + Kosmos.Fixture { FakeComposeBouncerFlags(fakeSceneContainerFlags) } +val Kosmos.composeBouncerFlags by Kosmos.Fixture<ComposeBouncerFlags> { fakeComposeBouncerFlags } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt new file mode 100644 index 000000000000..c116bbd32f9e --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/shared/flag/FakeComposeBouncerFlags.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.bouncer.shared.flag + +import com.android.systemui.scene.shared.flag.SceneContainerFlags + +class FakeComposeBouncerFlags( + private val sceneContainerFlags: SceneContainerFlags, + var composeBouncerEnabled: Boolean = false +) : ComposeBouncerFlags { + override fun isComposeBouncerOrSceneContainerEnabled(): Boolean { + return sceneContainerFlags.isEnabled() || composeBouncerEnabled + } + + @Deprecated( + "Avoid using this, this is meant to be used only by the glue code " + + "that includes compose bouncer in legacy keyguard.", + replaceWith = ReplaceWith("isComposeBouncerOrSceneContainerEnabled()") + ) + override fun isOnlyComposeBouncerEnabled(): Boolean = composeBouncerEnabled +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt index 99dfe94af3df..6d97238ba48b 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelKosmos.kt @@ -21,12 +21,12 @@ import com.android.systemui.authentication.domain.interactor.authenticationInter import com.android.systemui.bouncer.domain.interactor.bouncerActionButtonInteractor import com.android.systemui.bouncer.domain.interactor.bouncerInteractor import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor +import com.android.systemui.bouncer.shared.flag.composeBouncerFlags import com.android.systemui.inputmethod.domain.interactor.inputMethodInteractor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope -import com.android.systemui.scene.shared.flag.sceneContainerFlags import com.android.systemui.user.domain.interactor.selectedUserInteractor import com.android.systemui.user.ui.viewmodel.userSwitcherViewModel import com.android.systemui.util.mockito.mock @@ -42,7 +42,7 @@ val Kosmos.bouncerViewModel by Fixture { simBouncerInteractor = simBouncerInteractor, authenticationInteractor = authenticationInteractor, selectedUserInteractor = selectedUserInteractor, - flags = sceneContainerFlags, + flags = composeBouncerFlags, selectedUser = userSwitcherViewModel.selectedUser, users = userSwitcherViewModel.users, userSwitcherMenu = userSwitcherViewModel.menu, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt index 534f773fa334..592fa3892dc9 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardClockRepository.kt @@ -45,8 +45,15 @@ class FakeKeyguardClockRepository @Inject constructor() : KeyguardClockRepositor private val _currentClock = MutableStateFlow(null) override val currentClock = _currentClock - private val _previewClock = MutableStateFlow(Mockito.mock(ClockController::class.java)) - override val previewClock: StateFlow<ClockController> = _previewClock + private val _previewClockPair = + MutableStateFlow( + Pair( + Mockito.mock(ClockController::class.java), + Mockito.mock(ClockController::class.java) + ) + ) + override val previewClockPair: StateFlow<Pair<ClockController, ClockController>> = + _previewClockPair override val clockEventController: ClockEventController get() = mock() diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt index 793e2d7efcda..1e305d67d40d 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.data.repository import android.graphics.Point -import com.android.systemui.common.shared.model.Position import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.shared.model.BiometricUnlockModel import com.android.systemui.keyguard.shared.model.BiometricUnlockSource @@ -58,9 +57,6 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository { private val _bottomAreaAlpha = MutableStateFlow(1f) override val bottomAreaAlpha: StateFlow<Float> = _bottomAreaAlpha - private val _clockPosition = MutableStateFlow(Position(0, 0)) - override val clockPosition: StateFlow<Position> = _clockPosition - private val _isKeyguardShowing = MutableStateFlow(false) override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing @@ -149,10 +145,6 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository { _bottomAreaAlpha.value = alpha } - override fun setClockPosition(x: Int, y: Int) { - _clockPosition.value = Position(x, y) - } - fun setKeyguardShowing(isShowing: Boolean) { _isKeyguardShowing.value = isShowing } diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/captioning/CaptioningModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettingsKosmos.kt index aeb5c5d72be6..df6fc41e5f3e 100644 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/volume/panel/component/captioning/CaptioningModule.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettingsKosmos.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.android.systemui.volume.panel.component.captioning +package com.android.systemui.util.settings -import dagger.Module +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.Kosmos.Fixture -@Module interface CaptioningModule +val Kosmos.fakeGlobalSettings: FakeGlobalSettings by Fixture { FakeGlobalSettings() } diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java index f31eb44f23f5..6ca60be25023 100644 --- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java +++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java @@ -39,7 +39,9 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; +import android.graphics.Point; import android.graphics.Rect; +import android.hardware.display.DisplayManager; import android.os.FileUtils; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -49,16 +51,22 @@ import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.Xml; +import android.view.Display; +import android.view.DisplayInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; +import com.android.modules.utils.TypedXmlPullParser; +import com.android.modules.utils.TypedXmlSerializer; import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.List; /** @@ -102,6 +110,9 @@ public class WallpaperBackupAgent extends BackupAgent { @VisibleForTesting static final String WALLPAPER_INFO_STAGE = "wallpaper-info-stage"; + @VisibleForTesting + static final String WALLPAPER_BACKUP_DEVICE_INFO_STAGE = "wallpaper-backup-device-info-stage"; + static final String EMPTY_SENTINEL = "empty"; static final String QUOTA_SENTINEL = "quota"; @@ -110,6 +121,11 @@ public class WallpaperBackupAgent extends BackupAgent { static final String SYSTEM_GENERATION = "system_gen"; static final String LOCK_GENERATION = "lock_gen"; + /** + * An approximate area threshold to compare device dimension similarity + */ + static final int AREA_THRESHOLD = 50; // TODO: determine appropriate threshold + // If this file exists, it means we exceeded our quota last time private File mQuotaFile; private boolean mQuotaExceeded; @@ -121,6 +137,8 @@ public class WallpaperBackupAgent extends BackupAgent { private boolean mSystemHasLiveComponent; private boolean mLockHasLiveComponent; + private DisplayManager mDisplayManager; + @Override public void onCreate() { if (DEBUG) { @@ -137,6 +155,8 @@ public class WallpaperBackupAgent extends BackupAgent { mBackupManager = new BackupManager(getBaseContext()); mEventLogger = new WallpaperEventLogger(mBackupManager, /* wallpaperAgent */ this); + + mDisplayManager = getSystemService(DisplayManager.class); } @Override @@ -175,6 +195,7 @@ public class WallpaperBackupAgent extends BackupAgent { mSystemHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM) != null; mLockHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_LOCK) != null; + backupDeviceInfoFile(data); backupWallpaperInfoFile(/* sysOrLockChanged= */ sysChanged || lockChanged, data); backupSystemWallpaperFile(sharedPrefs, sysChanged, sysGeneration, data); backupLockWallpaperFileIfItExists(sharedPrefs, lockChanged, lockGeneration, data); @@ -191,6 +212,50 @@ public class WallpaperBackupAgent extends BackupAgent { } } + /** + * This method backs up the device dimension information. The device data will always get + * overwritten when triggering a backup + */ + private void backupDeviceInfoFile(FullBackupDataOutput data) + throws IOException { + final File deviceInfoStage = new File(getFilesDir(), WALLPAPER_BACKUP_DEVICE_INFO_STAGE); + + // save the dimensions of the device with xml formatting + Point dimensions = getScreenDimensions(); + Point secondaryDimensions = getRealSize(getSmallerDisplay()); + + deviceInfoStage.createNewFile(); + FileOutputStream fstream = new FileOutputStream(deviceInfoStage, false); + TypedXmlSerializer out = Xml.resolveSerializer(fstream); + out.startDocument(null, true); + out.startTag(null, "dimensions"); + + out.startTag(null, "width"); + out.text(String.valueOf(dimensions.x)); + out.endTag(null, "width"); + + out.startTag(null, "height"); + out.text(String.valueOf(dimensions.y)); + out.endTag(null, "height"); + + out.startTag(null, "secondarywidth"); + out.text(String.valueOf(secondaryDimensions != null ? secondaryDimensions.x : 0)); + out.endTag(null, "secondarywidth"); + + out.startTag(null, "secondaryheight"); + out.text(String.valueOf(secondaryDimensions != null ? secondaryDimensions.y : 0)); + out.endTag(null, "secondaryheight"); + + out.endTag(null, "dimensions"); + out.endDocument(); + fstream.flush(); + FileUtils.sync(fstream); + fstream.close(); + + if (DEBUG) Slog.v(TAG, "Storing device dimension data"); + backupFile(deviceInfoStage, data); + } + private void backupWallpaperInfoFile(boolean sysOrLockChanged, FullBackupDataOutput data) throws IOException { final ParcelFileDescriptor wallpaperInfoFd = mWallpaperManager.getWallpaperInfoFile(); @@ -364,9 +429,22 @@ public class WallpaperBackupAgent extends BackupAgent { final File infoStage = new File(filesDir, WALLPAPER_INFO_STAGE); final File imageStage = new File(filesDir, SYSTEM_WALLPAPER_STAGE); final File lockImageStage = new File(filesDir, LOCK_WALLPAPER_STAGE); + final File deviceDimensionsStage = new File(filesDir, WALLPAPER_BACKUP_DEVICE_INFO_STAGE); boolean lockImageStageExists = lockImageStage.exists(); try { + // Parse the device dimensions of the source device and compare with target to + // to identify whether we need to skip the remainder of the restore process + Pair<Point, Point> sourceDeviceDimensions = parseDeviceDimensions( + deviceDimensionsStage); + + Point targetDeviceDimensions = getScreenDimensions(); + if (sourceDeviceDimensions != null + && isSourceDeviceSignificantlySmallerThanTarget(sourceDeviceDimensions.first, + targetDeviceDimensions)) { + Slog.d(TAG, "The source device is significantly smaller than target"); + } + // First parse the live component name so that we know for logging if we care about // logging errors with the image restore. ComponentName wpService = parseWallpaperComponent(infoStage, "wp"); @@ -400,6 +478,7 @@ public class WallpaperBackupAgent extends BackupAgent { infoStage.delete(); imageStage.delete(); lockImageStage.delete(); + deviceDimensionsStage.delete(); SharedPreferences prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); prefs.edit() @@ -409,6 +488,66 @@ public class WallpaperBackupAgent extends BackupAgent { } } + /** + * This method parses the given file for the backed up device dimensions + * + * @param deviceDimensions the file which holds the device dimensions + * @return the backed up device dimensions + */ + private Pair<Point, Point> parseDeviceDimensions(File deviceDimensions) { + int width = 0, height = 0, secondaryHeight = 0, secondaryWidth = 0; + try { + TypedXmlPullParser parser = Xml.resolvePullParser( + new FileInputStream(deviceDimensions)); + + while (parser.next() != XmlPullParser.END_TAG) { + if (parser.getEventType() != XmlPullParser.START_TAG) { + continue; + } + + String name = parser.getName(); + + switch (name) { + case "width": + String widthText = readText(parser); + width = Integer.valueOf(widthText); + break; + + case "height": + String textHeight = readText(parser); + height = Integer.valueOf(textHeight); + break; + + case "secondarywidth": + String secondaryWidthText = readText(parser); + secondaryWidth = Integer.valueOf(secondaryWidthText); + break; + + case "secondaryheight": + String secondaryHeightText = readText(parser); + secondaryHeight = Integer.valueOf(secondaryHeightText); + break; + default: + break; + } + } + return new Pair<>(new Point(width, height), new Point(secondaryWidth, secondaryHeight)); + + } catch (Exception e) { + return null; + } + } + + private static String readText(TypedXmlPullParser parser) + throws IOException, XmlPullParserException { + String result = ""; + if (parser.next() == XmlPullParser.TEXT) { + result = parser.getText(); + parser.nextTag(); + } + return result; + } + @VisibleForTesting void updateWallpaperComponent(ComponentName wpService, int which) throws IOException { @@ -500,6 +639,7 @@ public class WallpaperBackupAgent extends BackupAgent { mEventLogger.onLockImageWallpaperRestoreFailed(error); } } + private Rect parseCropHint(File wallpaperInfo, String sectionTag) { Rect cropHint = new Rect(); try (FileInputStream stream = new FileInputStream(wallpaperInfo)) { @@ -537,7 +677,7 @@ public class WallpaperBackupAgent extends BackupAgent { if (type != XmlPullParser.START_TAG) continue; String tag = parser.getName(); if (!sectionTag.equals(tag)) continue; - for (Pair<Integer, String> pair: List.of( + for (Pair<Integer, String> pair : List.of( new Pair<>(WallpaperManager.PORTRAIT, "Portrait"), new Pair<>(WallpaperManager.LANDSCAPE, "Landscape"), new Pair<>(WallpaperManager.SQUARE_PORTRAIT, "SquarePortrait"), @@ -691,6 +831,94 @@ public class WallpaperBackupAgent extends BackupAgent { }; } + /** + * This method retrieves the dimensions of the largest display of the device + * + * @return a @{Point} object that contains the dimensions of the largest display on the device + */ + private Point getScreenDimensions() { + Point largetDimensions = null; + int maxArea = 0; + + for (Display display : getInternalDisplays()) { + Point displaySize = getRealSize(display); + + int width = displaySize.x; + int height = displaySize.y; + int area = width * height; + + if (area > maxArea) { + maxArea = area; + largetDimensions = displaySize; + } + } + + return largetDimensions; + } + + private Point getRealSize(Display display) { + DisplayInfo displayInfo = new DisplayInfo(); + display.getDisplayInfo(displayInfo); + return new Point(displayInfo.logicalWidth, displayInfo.logicalHeight); + } + + /** + * This method returns the smaller display on a multi-display device + * + * @return Display that corresponds to the smaller display on a device or null if ther is only + * one Display on a device + */ + private Display getSmallerDisplay() { + List<Display> internalDisplays = getInternalDisplays(); + Point largestDisplaySize = getScreenDimensions(); + + // Find the first non-matching internal display + for (Display display : internalDisplays) { + Point displaySize = getRealSize(display); + if (displaySize.x != largestDisplaySize.x || displaySize.y != largestDisplaySize.y) { + return display; + } + } + + // If no smaller display found, return null, as there is only a single display + return null; + } + + /** + * This method retrieves the collection of Display objects available in the device. + * i.e. non-external displays are ignored + * + * @return list of displays corresponding to each display in the device + */ + private List<Display> getInternalDisplays() { + Display[] allDisplays = mDisplayManager.getDisplays( + DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED); + + List<Display> internalDisplays = new ArrayList<>(); + for (Display display : allDisplays) { + if (display.getType() == Display.TYPE_INTERNAL) { + internalDisplays.add(display); + } + } + return internalDisplays; + } + + /** + * This method compares the source and target dimensions, and returns true if there is a + * significant difference in area between them and the source dimensions are smaller than the + * target dimensions. + * + * @param sourceDimensions is the dimensions of the source device + * @param targetDimensions is the dimensions of the target device + */ + @VisibleForTesting + boolean isSourceDeviceSignificantlySmallerThanTarget(Point sourceDimensions, + Point targetDimensions) { + int rawAreaDelta = (targetDimensions.x * targetDimensions.y) + - (sourceDimensions.x * sourceDimensions.y); + return rawAreaDelta > AREA_THRESHOLD; + } + @VisibleForTesting boolean isDeviceInRestore() { try { diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java index 3ecdf3f101a5..79e7bf04dadf 100644 --- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java +++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java @@ -59,6 +59,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.graphics.Point; import android.graphics.Rect; import android.os.FileUtils; import android.os.ParcelFileDescriptor; @@ -676,7 +677,7 @@ public class WallpaperBackupAgentTest { mWallpaperBackupAgent.onRestoreFinished(); - for (String wallpaper: List.of(WALLPAPER_IMG_LOCK, WALLPAPER_IMG_SYSTEM)) { + for (String wallpaper : List.of(WALLPAPER_IMG_LOCK, WALLPAPER_IMG_SYSTEM)) { DataTypeResult result = getLoggingResult(wallpaper, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); @@ -840,6 +841,26 @@ public class WallpaperBackupAgentTest { testParseCropHints(testMap); } + @Test + public void test_sourceDimensionsAreLargerThanTarget() { + // source device is larger than target, expecting to get false + Point sourceDimensions = new Point(2208, 1840); + Point targetDimensions = new Point(1080, 2092); + boolean isSourceSmaller = mWallpaperBackupAgent + .isSourceDeviceSignificantlySmallerThanTarget(sourceDimensions, targetDimensions); + assertThat(isSourceSmaller).isEqualTo(false); + } + + @Test + public void test_sourceDimensionsMuchSmallerThanTarget() { + // source device is smaller than target, expecting to get true + Point sourceDimensions = new Point(1080, 2092); + Point targetDimensions = new Point(2208, 1840); + boolean isSourceSmaller = mWallpaperBackupAgent + .isSourceDeviceSignificantlySmallerThanTarget(sourceDimensions, targetDimensions); + assertThat(isSourceSmaller).isEqualTo(true); + } + private void testParseCropHints(Map<Integer, Rect> testMap) throws Exception { assumeTrue(multiCrop()); mockRestoredStaticWallpaperFile(testMap); @@ -934,7 +955,7 @@ public class WallpaperBackupAgentTest { TypedXmlSerializer out = Xml.resolveSerializer(fstream); out.startDocument(null, true); out.startTag(null, "wp"); - for (Map.Entry<Integer, Rect> entry: crops.entrySet()) { + for (Map.Entry<Integer, Rect> entry : crops.entrySet()) { String orientation = switch (entry.getKey()) { case WallpaperManager.PORTRAIT -> "Portrait"; case WallpaperManager.LANDSCAPE -> "Landscape"; diff --git a/proto/src/criticalevents/critical_event_log.proto b/proto/src/criticalevents/critical_event_log.proto index cffcd0941df8..71d291a6f877 100644 --- a/proto/src/criticalevents/critical_event_log.proto +++ b/proto/src/criticalevents/critical_event_log.proto @@ -61,6 +61,12 @@ message CriticalEventProto { NativeCrash native_crash = 6; SystemServerStarted system_server_started = 7; InstallPackages install_packages = 8; + ExcessiveBinderCalls excessive_binder_calls = 9; + } + + message ExcessiveBinderCalls { + // The uid sending many calls. + optional int32 uid = 1; } message InstallPackages {} diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp index 41a4a1ad1ccb..e535f0a05a02 100644 --- a/ravenwood/Android.bp +++ b/ravenwood/Android.bp @@ -77,6 +77,7 @@ java_library { libs: [ "android.test.mock", "framework-minus-apex.ravenwood", + "ravenwood-framework", "services.core.ravenwood", "junit", ], @@ -102,6 +103,21 @@ java_library { visibility: ["//visibility:public"], } +// Library used to publish a handful of `android.ravenwood` APIs into +// the Ravenwood BCP; we don't want to publish these APIs into the BCP +// on physical devices, which is why this is a separate library +java_library { + name: "ravenwood-framework", + srcs: [ + "framework-src/**/*.java", + ], + libs: [ + "framework-minus-apex.ravenwood", + ], + sdk_version: "core_current", + visibility: ["//visibility:public"], +} + java_host_for_device { name: "androidx.test.monitor-for-device", libs: [ diff --git a/ravenwood/framework-src/android/ravenwood/example/BlueManager.java b/ravenwood/framework-src/android/ravenwood/example/BlueManager.java new file mode 100644 index 000000000000..fc713b1bd164 --- /dev/null +++ b/ravenwood/framework-src/android/ravenwood/example/BlueManager.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.ravenwood.example; + +import android.annotation.SystemService; +import android.os.RemoteException; +import android.os.ServiceManager; + +@SystemService(BlueManager.SERVICE_NAME) +public class BlueManager { + public static final String SERVICE_NAME = "example_blue"; + + public String getInterfaceDescriptor() { + try { + return ServiceManager.getService(SERVICE_NAME).getInterfaceDescriptor(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } +} diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/LockscreenSceneModule.kt b/ravenwood/framework-src/android/ravenwood/example/RedManager.java index fc3912e2aa52..381a901f234a 100644 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/LockscreenSceneModule.kt +++ b/ravenwood/framework-src/android/ravenwood/example/RedManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 The Android Open Source Project + * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,18 +14,21 @@ * limitations under the License. */ -package com.android.systemui.scene +package android.ravenwood.example; -import com.android.systemui.keyguard.shared.model.LockscreenSceneBlueprint -import dagger.Module -import dagger.Provides +import android.annotation.SystemService; +import android.os.RemoteException; +import android.os.ServiceManager; -@Module -interface LockscreenSceneModule { - companion object { - @Provides - fun providesLockscreenBlueprints(): Set<LockscreenSceneBlueprint> { - return emptySet() +@SystemService(RedManager.SERVICE_NAME) +public class RedManager { + public static final String SERVICE_NAME = "example_red"; + + public String getInterfaceDescriptor() { + try { + return ServiceManager.getService(SERVICE_NAME).getInterfaceDescriptor(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } } diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java index c17d0903f856..109ef76b535f 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java @@ -26,6 +26,8 @@ import android.os.Looper; import android.os.PermissionEnforcer; import android.os.ServiceManager; import android.os.UserHandle; +import android.ravenwood.example.BlueManager; +import android.ravenwood.example.RedManager; import android.test.mock.MockContext; import android.util.ArrayMap; import android.util.Singleton; @@ -53,16 +55,23 @@ public class RavenwoodContext extends MockContext { mPackageName = packageName; mMainThread = mainThread; + // Services provided by a typical shipping device registerService(ClipboardManager.class, - Context.CLIPBOARD_SERVICE, asSingleton(() -> + Context.CLIPBOARD_SERVICE, memoize(() -> new ClipboardManager(this, getMainThreadHandler()))); registerService(PermissionEnforcer.class, Context.PERMISSION_ENFORCER_SERVICE, () -> mEnforcer); registerService(SerialManager.class, - Context.SERIAL_SERVICE, asSingleton(() -> + Context.SERIAL_SERVICE, memoize(() -> new SerialManager(this, ISerialManager.Stub.asInterface( ServiceManager.getService(Context.SERIAL_SERVICE))) )); + + // Additional services we provide for testing purposes + registerService(BlueManager.class, + BlueManager.SERVICE_NAME, memoize(() -> new BlueManager())); + registerService(RedManager.class, + RedManager.SERVICE_NAME, memoize(() -> new RedManager())); } @Override @@ -143,9 +152,12 @@ public class RavenwoodContext extends MockContext { } /** - * Wrap the given {@link Supplier} to become a memoized singleton. + * Wrap the given {@link Supplier} to become memoized. + * + * The underlying {@link Supplier} will only be invoked once, and that result will be cached + * and returned for any future requests. */ - private static <T> Supplier<T> asSingleton(ThrowingSupplier<T> supplier) { + private static <T> Supplier<T> memoize(ThrowingSupplier<T> supplier) { final Singleton<T> singleton = new Singleton<>() { @Override protected T create() { diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java index 3de96c0990ea..cd6b61df392f 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java @@ -19,13 +19,19 @@ package android.platform.test.ravenwood; import android.content.ClipboardManager; import android.hardware.SerialManager; import android.os.SystemClock; +import android.ravenwood.example.BlueManager; +import android.ravenwood.example.RedManager; import android.util.ArrayMap; +import android.util.ArraySet; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.SystemServiceManager; import com.android.server.utils.TimingsTraceAndSlog; +import java.util.List; +import java.util.Set; + public class RavenwoodSystemServer { /** * Set of services that we know how to provide under Ravenwood. We keep this set distinct @@ -37,16 +43,21 @@ public class RavenwoodSystemServer { */ private static final ArrayMap<Class<?>, String> sKnownServices = new ArrayMap<>(); - // TODO: expand SystemService API to support dependency expression, so we don't need test - // authors to exhaustively declare all transitive services - static { + // Services provided by a typical shipping device sKnownServices.put(ClipboardManager.class, "com.android.server.FakeClipboardService$Lifecycle"); sKnownServices.put(SerialManager.class, "com.android.server.SerialService$Lifecycle"); + + // Additional services we provide for testing purposes + sKnownServices.put(BlueManager.class, + "com.android.server.example.BlueManagerService$Lifecycle"); + sKnownServices.put(RedManager.class, + "com.android.server.example.RedManagerService$Lifecycle"); } + private static Set<Class<?>> sStartedServices; private static TimingsTraceAndSlog sTimings; private static SystemServiceManager sServiceManager; @@ -54,6 +65,7 @@ public class RavenwoodSystemServer { // Avoid overhead if no services required if (rule.mServicesRequired.isEmpty()) return; + sStartedServices = new ArraySet<>(); sTimings = new TimingsTraceAndSlog(); sServiceManager = new SystemServiceManager(rule.mContext); sServiceManager.setStartInfo(false, @@ -61,17 +73,7 @@ public class RavenwoodSystemServer { SystemClock.uptimeMillis()); LocalServices.addService(SystemServiceManager.class, sServiceManager); - for (Class<?> service : rule.mServicesRequired) { - final String target = sKnownServices.get(service); - if (target == null) { - throw new RuntimeException("The requested service " + service - + " is not yet supported under the Ravenwood deviceless testing " - + "environment; consider requesting support from the API owner or " - + "consider using Mockito; more details at go/ravenwood-docs"); - } else { - sServiceManager.startService(target); - } - } + startServices(rule.mServicesRequired); sServiceManager.sealStartedServices(); // TODO: expand to include additional boot phases when relevant @@ -85,5 +87,26 @@ public class RavenwoodSystemServer { LocalServices.removeServiceForTest(SystemServiceManager.class); sServiceManager = null; sTimings = null; + sStartedServices = null; + } + + private static void startServices(List<Class<?>> serviceClasses) { + for (Class<?> serviceClass : serviceClasses) { + // Quietly ignore duplicate requests if service already started + if (sStartedServices.contains(serviceClass)) continue; + sStartedServices.add(serviceClass); + + final String serviceName = sKnownServices.get(serviceClass); + if (serviceName == null) { + throw new RuntimeException("The requested service " + serviceClass + + " is not yet supported under the Ravenwood deviceless testing " + + "environment; consider requesting support from the API owner or " + + "consider using Mockito; more details at go/ravenwood-docs"); + } + + // Start service and then depth-first traversal of any dependencies + final SystemService instance = sServiceManager.startService(serviceName); + startServices(instance.getDependencies()); + } } } diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java index a520d4ccafa1..52ea3402fa62 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java @@ -35,6 +35,8 @@ import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; @@ -127,7 +129,7 @@ public class RavenwoodRule implements TestRule { final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties(); - final ArraySet<Class<?>> mServicesRequired = new ArraySet<>(); + final List<Class<?>> mServicesRequired = new ArrayList<>(); volatile Context mContext; volatile Instrumentation mInstrumentation; diff --git a/ravenwood/services-test/test/com/android/ravenwood/RavenwoodServicesDependenciesTest.java b/ravenwood/services-test/test/com/android/ravenwood/RavenwoodServicesDependenciesTest.java new file mode 100644 index 000000000000..efe468d0df25 --- /dev/null +++ b/ravenwood/services-test/test/com/android/ravenwood/RavenwoodServicesDependenciesTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.ravenwood; + +import static org.junit.Assert.assertEquals; + +import android.platform.test.ravenwood.RavenwoodRule; +import android.ravenwood.example.BlueManager; +import android.ravenwood.example.RedManager; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class RavenwoodServicesDependenciesTest { + // NOTE: we carefully only ask for RedManager here, and rely on Ravenwood internals to spin + // up the implicit dependency on BlueManager + @Rule + public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() + .setProcessSystem() + .setServicesRequired(RedManager.class) + .build(); + + @Test + public void testDirect() { + final RedManager red = mRavenwood.getContext().getSystemService( + RedManager.class); + assertEquals("blue+red", red.getInterfaceDescriptor()); + } + + @Test + public void testIndirect() { + final BlueManager blue = mRavenwood.getContext().getSystemService( + BlueManager.class); + assertEquals("blue", blue.getInterfaceDescriptor()); + } +} diff --git a/sax/tests/saxtests/Android.bp b/sax/tests/saxtests/Android.bp index cbd19c36dd73..446ee9394179 100644 --- a/sax/tests/saxtests/Android.bp +++ b/sax/tests/saxtests/Android.bp @@ -15,6 +15,9 @@ android_test { "android.test.runner", "android.test.base", ], - static_libs: ["junit"], + static_libs: [ + "junit", + "androidx.test.rules", + ], platform_apis: true, } diff --git a/sax/tests/saxtests/src/android/sax/SafeSaxTest.java b/sax/tests/saxtests/src/android/sax/SafeSaxTest.java index a68fc9ab2290..2a08f5480825 100644 --- a/sax/tests/saxtests/src/android/sax/SafeSaxTest.java +++ b/sax/tests/saxtests/src/android/sax/SafeSaxTest.java @@ -17,18 +17,16 @@ package android.sax; import android.graphics.Bitmap; -import android.sax.Element; -import android.sax.ElementListener; -import android.sax.EndTextElementListener; -import android.sax.RootElement; -import android.sax.StartElementListener; -import android.sax.TextElementListener; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; import android.util.Xml; + +import androidx.test.filters.LargeTest; +import androidx.test.filters.SmallTest; + +import com.android.frameworks.saxtests.R; import com.android.internal.util.XmlUtils; + import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; @@ -40,8 +38,6 @@ import java.io.IOException; import java.io.InputStream; import java.time.Instant; -import com.android.frameworks.saxtests.R; - public class SafeSaxTest extends AndroidTestCase { private static final String TAG = SafeSaxTest.class.getName(); diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 43c018cfeea3..cbb66dc18f28 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -4659,8 +4659,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { - new AccessibilityShellCommand(this, mSystemActionPerformer).exec(this, in, out, err, args, - callback, resultReceiver); + new AccessibilityShellCommand(mContext, this, mSystemActionPerformer) + .exec(this, in, out, err, args, callback, resultReceiver); } private final class InteractionBridge { diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java index 8cf5547b05ec..490803228337 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java @@ -16,8 +16,10 @@ package com.android.server.accessibility; +import android.Manifest; import android.annotation.NonNull; import android.app.ActivityManager; +import android.content.Context; import android.os.Binder; import android.os.Process; import android.os.ShellCommand; @@ -26,18 +28,27 @@ import android.os.UserHandle; import com.android.server.LocalServices; import com.android.server.wm.WindowManagerInternal; +import java.io.File; +import java.io.IOException; import java.io.PrintWriter; /** * Shell command implementation for the accessibility manager service */ final class AccessibilityShellCommand extends ShellCommand { - final @NonNull AccessibilityManagerService mService; - final @NonNull SystemActionPerformer mSystemActionPerformer; - final @NonNull WindowManagerInternal mWindowManagerService; + @NonNull + final Context mContext; + @NonNull + final AccessibilityManagerService mService; + @NonNull + final SystemActionPerformer mSystemActionPerformer; + @NonNull + final WindowManagerInternal mWindowManagerService; - AccessibilityShellCommand(@NonNull AccessibilityManagerService service, + AccessibilityShellCommand(@NonNull Context context, + @NonNull AccessibilityManagerService service, @NonNull SystemActionPerformer systemActionPerformer) { + mContext = context; mService = service; mSystemActionPerformer = systemActionPerformer; mWindowManagerService = LocalServices.getService(WindowManagerInternal.class); @@ -61,6 +72,8 @@ final class AccessibilityShellCommand extends ShellCommand { case "start-trace": case "stop-trace": return mService.getTraceManager().onShellCommand(cmd, this); + case "check-hidraw": + return checkHidraw(); } return -1; } @@ -106,6 +119,67 @@ final class AccessibilityShellCommand extends ShellCommand { return -1; } + private int checkHidraw() { + mContext.enforceCallingPermission(Manifest.permission.MANAGE_ACCESSIBILITY, + "Missing MANAGE_ACCESSIBILITY permission"); + String subcommand = getNextArgRequired(); + File hidrawNode = new File(getNextArgRequired()); + switch (subcommand) { + case "read" -> { + return checkHidrawRead(hidrawNode); + } + case "write" -> { + return checkHidrawWrite(hidrawNode); + } + case "descriptor" -> { + return checkHidrawDescriptor(hidrawNode); + } + default -> { + getErrPrintWriter().print("Unknown subcommand " + subcommand); + return -1; + } + } + } + + private int checkHidrawRead(File hidrawNode) { + if (!hidrawNode.canRead()) { + getErrPrintWriter().println("Unable to read from " + hidrawNode); + return -1; + } + // Tests executing this command using UiAutomation#executeShellCommand will not receive + // the command's exit value, so print the path to stdout to indicate success. + getOutPrintWriter().print(hidrawNode.getAbsolutePath()); + return 0; + } + + private int checkHidrawWrite(File hidrawNode) { + if (!hidrawNode.canWrite()) { + getErrPrintWriter().println("Unable to write to " + hidrawNode); + return -1; + } + // Tests executing this command using UiAutomation#executeShellCommand will not receive + // the command's exit value, so print the path to stdout to indicate success. + getOutPrintWriter().print(hidrawNode.getAbsolutePath()); + return 0; + } + + private int checkHidrawDescriptor(File hidrawNode) { + BrailleDisplayConnection.BrailleDisplayScanner scanner = + BrailleDisplayConnection.createScannerForShell(); + byte[] descriptor = scanner.getDeviceReportDescriptor(hidrawNode.toPath()); + if (descriptor == null) { + getErrPrintWriter().println("Unable to read descriptor for " + hidrawNode); + return -1; + } + try { + // Print the descriptor bytes to stdout. + getRawOutputStream().write(descriptor); + return 0; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + private Integer parseUserId() { final String option = getNextOption(); if (option != null) { @@ -131,6 +205,8 @@ final class AccessibilityShellCommand extends ShellCommand { pw.println(" Get whether binding to services provided by instant apps is allowed."); pw.println(" call-system-action <ACTION_ID>"); pw.println(" Calls the system action with the given action id."); + pw.println(" check-hidraw [read|write|descriptor] <HIDRAW_NODE_PATH>"); + pw.println(" Checks if the system can perform various actions on the HIDRAW node."); mService.getTraceManager().onHelp(pw); } } diff --git a/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java b/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java index 40b6ff01965e..8b41873636a9 100644 --- a/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java @@ -116,6 +116,13 @@ class BrailleDisplayConnection extends IBrailleDisplayConnection.Stub { } /** + * Used for `cmd accessibility` to check hidraw access. + */ + static BrailleDisplayScanner createScannerForShell() { + return getDefaultNativeScanner(new DefaultNativeInterface()); + } + + /** * Interface to scan for properties of connected Braille displays. * * <p>Helps simplify testing Braille Display APIs using test data without requiring @@ -125,7 +132,6 @@ class BrailleDisplayConnection extends IBrailleDisplayConnection.Stub { * @see #getDefaultNativeScanner * @see #setTestData */ - @VisibleForTesting interface BrailleDisplayScanner { Collection<Path> getHidrawNodePaths(@NonNull Path directory); @@ -441,7 +447,7 @@ class BrailleDisplayConnection extends IBrailleDisplayConnection.Stub { * from HIDRAW nodes and perform ioctls using the provided {@link NativeInterface}. */ @VisibleForTesting - BrailleDisplayScanner getDefaultNativeScanner(@NonNull NativeInterface nativeInterface) { + static BrailleDisplayScanner getDefaultNativeScanner(@NonNull NativeInterface nativeInterface) { Objects.requireNonNull(nativeInterface); return new BrailleDisplayScanner() { private static final String HIDRAW_DEVICE_GLOB = "hidraw*"; @@ -576,7 +582,7 @@ class BrailleDisplayConnection extends IBrailleDisplayConnection.Stub { } /** Native interface that actually calls native HIDRAW ioctls. */ - private class DefaultNativeInterface implements NativeInterface { + private static class DefaultNativeInterface implements NativeInterface { @Override public int getHidrawDescSize(int fd) { return nativeGetHidrawDescSize(fd); @@ -598,11 +604,11 @@ class BrailleDisplayConnection extends IBrailleDisplayConnection.Stub { } } - private native int nativeGetHidrawDescSize(int fd); + private static native int nativeGetHidrawDescSize(int fd); - private native byte[] nativeGetHidrawDesc(int fd, int descSize); + private static native byte[] nativeGetHidrawDesc(int fd, int descSize); - private native String nativeGetHidrawUniq(int fd); + private static native String nativeGetHidrawUniq(int fd); - private native int nativeGetHidrawBusType(int fd); + private static native int nativeGetHidrawBusType(int fd); } diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index e1291e5f75ec..285e54c30167 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -33,8 +33,10 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManagerInternal; import android.content.ComponentName; +import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.graphics.Rect; import android.metrics.LogMaker; @@ -251,6 +253,26 @@ final class AutofillManagerServiceImpl @Override // from PerUserSystemService protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent) throws NameNotFoundException { + final List<ResolveInfo> resolveInfos = + getContext().getPackageManager().queryIntentServicesAsUser( + new Intent(AutofillService.SERVICE_INTERFACE), + PackageManager.GET_META_DATA, + mUserId); + boolean currentPackageStillHasAutofillIntentFilter = false; + for (ResolveInfo resolveInfo : resolveInfos) { + final ServiceInfo serviceInfo = resolveInfo.serviceInfo; + if (serviceInfo.getComponentName().equals(serviceComponent)) { + currentPackageStillHasAutofillIntentFilter = true; + break; + } + } + if (!currentPackageStillHasAutofillIntentFilter) { + Slog.w(TAG, + "Autofill service from '" + serviceComponent.getPackageName() + "' does" + + "not have intent filter " + AutofillService.SERVICE_INTERFACE); + throw new SecurityException("Service does not declare intent filter " + + AutofillService.SERVICE_INTERFACE); + } mInfo = new AutofillServiceInfo(getContext(), serviceComponent, mUserId); return mInfo.getServiceInfo(); } diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java index e666442af9c9..8fece8257b89 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java @@ -167,6 +167,9 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // List of packages that have RestoreAnyVersion set to true but do not support V-> U downgrade. private List<String> mVToUDenylist; + // Whether we have already initialised the V to U allowlist/denylist + private Boolean mAreVToUListsSet = false; + // Key/value: bookkeeping about staged data and files for agent access private File mBackupDataName; private File mStageName; @@ -235,18 +238,6 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { backupManagerService.getAgentTimeoutParameters(), "Timeout parameters cannot be null"); mBackupEligibilityRules = backupEligibilityRules; - mVToUAllowlist = - createVToUList( - Settings.Secure.getStringForUser( - backupManagerService.getContext().getContentResolver(), - Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, - mUserId)); - mVToUDenylist = - createVToUList( - Settings.Secure.getStringForUser( - backupManagerService.getContext().getContentResolver(), - Settings.Secure.V_TO_U_RESTORE_DENYLIST, - mUserId)); if (targetPackage != null) { // Single package restore @@ -661,11 +652,38 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // installed. If the app has not declared that it is prepared to // handle this case, we do not attempt the restore. if (mIsSystemRestore - && isVToUDowngrade(mPmAgent.getSourceSdk(), android.os.Build.VERSION.SDK_INT)) { + && isVToUDowngrade(mPmAgent.getSourceSdk(), + android.os.Build.VERSION.SDK_INT)) { + if (!mAreVToUListsSet) { + mVToUAllowlist = + createVToUList( + Settings.Secure.getStringForUser( + backupManagerService.getContext().getContentResolver(), + Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, + mUserId)); + mVToUDenylist = + createVToUList( + Settings.Secure.getStringForUser( + backupManagerService.getContext().getContentResolver(), + Settings.Secure.V_TO_U_RESTORE_DENYLIST, + mUserId)); + logVToUListsToBMM(); + mAreVToUListsSet = true; + } if (isPackageEligibleForVToURestore(mCurrentPackage)) { + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE, + mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + addRestoreOperationTypeToEvent(/* extras= */null)); Slog.i(TAG, "Package " + pkgName + " is eligible for V to U downgrade scenario"); } else { + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_PKG_NOT_ELIGIBLE, + mCurrentPackage, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + addRestoreOperationTypeToEvent(/* extras= */null)); String message = "Package not eligible for V to U downgrade scenario"; Slog.i(TAG, pkgName + " : " + message); EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, pkgName, message); @@ -1696,14 +1714,25 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { // (and not in the denylist) // - The package has restoreAnyVersion set to true and is not part of the denylist if (mVToUDenylist.contains(mCurrentPackage.packageName)){ + if (DEBUG) { + Slog.i(TAG, mCurrentPackage.packageName + " : Package is in V to U denylist"); + } return false; } else if ((mCurrentPackage.applicationInfo.flags & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) == 0) { // package has restoreAnyVersion set to false + if (DEBUG) { + Slog.i(TAG, mCurrentPackage.packageName + + " : Package has restoreAnyVersion=false and is in V to U allowlist"); + } return mVToUAllowlist.contains(mCurrentPackage.packageName); } else { // package has restoreAnyVersion set to true and is nor in denylist + if (DEBUG) { + Slog.i(TAG, mCurrentPackage.packageName + + " : Package has restoreAnyVersion=true and is not in V to U denylist"); + } return true; } } @@ -1748,4 +1777,31 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { monitoringExtras); } + private void logVToUListsToBMM() { + // send a BMM event with the allowlist + Bundle monitoringExtrasAllowlist = + mBackupManagerMonitorEventSender.putMonitoringExtra( + null, + BackupManagerMonitor.EXTRA_LOG_V_TO_U_ALLOWLIST, + mVToUAllowlist.toString()); + monitoringExtrasAllowlist = addRestoreOperationTypeToEvent(monitoringExtrasAllowlist); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_SET_LIST, + null, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtrasAllowlist); + // send a BMM event with the denylist + Bundle monitoringExtrasDenylist = + mBackupManagerMonitorEventSender.putMonitoringExtra( + null, + BackupManagerMonitor.EXTRA_LOG_V_TO_U_DENYLIST, + mVToUDenylist.toString()); + monitoringExtrasDenylist = addRestoreOperationTypeToEvent(monitoringExtrasDenylist); + mBackupManagerMonitorEventSender.monitorEvent( + BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_SET_LIST, + null, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + monitoringExtrasDenylist); + } + } diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java index 797aed9297a3..6d315ba38b31 100644 --- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java +++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java @@ -146,7 +146,6 @@ public class BackupManagerMonitorDumpsysUtils { + eventBundle.getString(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME)); } - // TODO(b/296818666): add extras to the events addAgentLogsIfAvailable(eventBundle, pw); addExtrasIfAvailable(eventBundle, pw); } catch (java.io.IOException e) { @@ -203,6 +202,11 @@ public class BackupManagerMonitorDumpsysUtils { * EXTRA_LOG_RESTORE_VERSION [int]: the version of the package on the source * EXTRA_LOG_RESTORE_ANYWAY [bool]: if the package allows restore any version * EXTRA_LOG_RESTORE_VERSION_TARGET [int]: an extra to record the package version on the target + * + * When we are performing a V to U downgrade (event with id V_TO_U_RESTORE_SET_LIST) we record + * the value of the V to U allowlist and denylist: + * EXTRA_LOG_V_TO_U_ALLOWLIST[string] + * EXTRA_LOG_V_TO_U_DENYLIST[string] */ private void addExtrasIfAvailable(Bundle eventBundle, PrintWriter pw) { if (eventBundle.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID) == @@ -216,12 +220,29 @@ public class BackupManagerMonitorDumpsysUtils { + eventBundle.getLong(BackupManagerMonitor.EXTRA_LOG_RESTORE_VERSION)); } if (eventBundle.containsKey( - BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION)) { + BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION)) { pw.println("\t\tPackage version on target: " + eventBundle.getLong( BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION)); } } + + if (eventBundle.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID) + == BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_SET_LIST) { + if (eventBundle.containsKey( + BackupManagerMonitor.EXTRA_LOG_V_TO_U_DENYLIST)) { + pw.println("\t\tV to U Denylist : " + + eventBundle.getString( + BackupManagerMonitor.EXTRA_LOG_V_TO_U_DENYLIST)); + } + + if (eventBundle.containsKey( + BackupManagerMonitor.EXTRA_LOG_V_TO_U_ALLOWLIST)) { + pw.println("\t\tV to U Allowllist : " + + eventBundle.getString( + BackupManagerMonitor.EXTRA_LOG_V_TO_U_ALLOWLIST)); + } + } } /* @@ -342,10 +363,14 @@ public class BackupManagerMonitorDumpsysUtils { case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_ERROR_FULL_RESTORE -> "Transport error full restore"; case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_COMPLETE -> "Restore complete"; - case BackupManagerMonitor.LOG_EVENT_ID_START_PACKAGE_RESTORE -> - "Start package restore"; - case BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE -> - "Agent failure"; + case BackupManagerMonitor.LOG_EVENT_ID_START_PACKAGE_RESTORE -> "Start package restore"; + case BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE -> "Agent failure"; + case BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE -> + "V to U restore pkg eligible"; + case BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_PKG_NOT_ELIGIBLE -> + "V to U restore pkg not eligible"; + case BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_SET_LIST -> + "V to U restore lists"; default -> "Unknown log event ID: " + code; }; return id; diff --git a/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java b/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java index 679243496e95..2899c055afbd 100644 --- a/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java +++ b/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java @@ -168,7 +168,7 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { void startScan() { enforceInitialized(); - if (DEBUG) Log.i(TAG, "startScan()"); + Slog.i(TAG, "startBleScan()"); // This method should not be called if scan is already in progress. if (mScanning) { Slog.w(TAG, "Scan is already in progress."); @@ -228,7 +228,7 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { void stopScanIfNeeded() { enforceInitialized(); - if (DEBUG) Log.i(TAG, "stopScan()"); + Slog.i(TAG, "stopBleScan()"); if (!mScanning) { if (DEBUG) Log.d(TAG, " > not scanning."); return; diff --git a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java index caca48d3aa02..3da9693b75c9 100644 --- a/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java +++ b/services/companion/java/com/android/server/companion/presence/CompanionDevicePresenceMonitor.java @@ -41,7 +41,9 @@ import android.os.UserManager; import android.util.Log; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseBooleanArray; +import com.android.internal.annotations.GuardedBy; import com.android.server.companion.AssociationStore; import java.io.PrintWriter; @@ -100,12 +102,24 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange private final @NonNull Set<Integer> mNearbyBleDevices = new HashSet<>(); private final @NonNull Set<Integer> mReportedSelfManagedDevices = new HashSet<>(); private final @NonNull Set<ParcelUuid> mConnectedUuidDevices = new HashSet<>(); + @GuardedBy("mBtDisconnectedDevices") + private final @NonNull Set<Integer> mBtDisconnectedDevices = new HashSet<>(); + + // A map to track device presence within 10 seconds of Bluetooth disconnection. + // The key is the association ID, and the boolean value indicates if the device + // was detected again within that time frame. + @GuardedBy("mBtDisconnectedDevices") + private final @NonNull SparseBooleanArray mBtDisconnectedDevicesBlePresence = + new SparseBooleanArray(); // Tracking "simulated" presence. Used for debugging and testing only. private final @NonNull Set<Integer> mSimulated = new HashSet<>(); private final SimulatedDevicePresenceSchedulerHelper mSchedulerHelper = new SimulatedDevicePresenceSchedulerHelper(); + private final BleDeviceDisappearedScheduler mBleDeviceDisappearedScheduler = + new BleDeviceDisappearedScheduler(); + public CompanionDevicePresenceMonitor(UserManager userManager, @NonNull AssociationStore associationStore, @NonNull ObservableUuidStore observableUuidStore, @NonNull Callback callback) { @@ -227,13 +241,24 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange @Override public void onBluetoothCompanionDeviceConnected(int associationId) { - Slog.i(TAG, "onBluetoothCompanionDeviceConnected: " - + "associationId( " + associationId + " )"); - onDevicePresenceEvent(mConnectedBtDevices, associationId, EVENT_BT_CONNECTED); - // Stop scanning for BLE devices when this device is connected - // and there are no other devices to connect to. - if (canStopBleScan()) { - mBleScanner.stopScanIfNeeded(); + synchronized (mBtDisconnectedDevices) { + // A device is considered reconnected within 10 seconds if a pending BLE lost report is + // followed by a detected Bluetooth connection. + boolean isReconnected = mBtDisconnectedDevices.contains(associationId); + if (isReconnected) { + Slog.i(TAG, "Device ( " + associationId + " ) is reconnected within 10s."); + mBleDeviceDisappearedScheduler.unScheduleDeviceDisappeared(associationId); + } + + Slog.i(TAG, "onBluetoothCompanionDeviceConnected: " + + "associationId( " + associationId + " )"); + onDevicePresenceEvent(mConnectedBtDevices, associationId, EVENT_BT_CONNECTED); + + // Stop the BLE scan if all devices report BT connected status and BLE was present. + if (canStopBleScan()) { + mBleScanner.stopScanIfNeeded(); + } + } } @@ -245,6 +270,14 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange mBleScanner.startScan(); onDevicePresenceEvent(mConnectedBtDevices, associationId, EVENT_BT_DISCONNECTED); + // If current device is BLE present but BT is disconnected , means it will be + // potentially out of range later. Schedule BLE disappeared callback. + if (isBlePresent(associationId)) { + synchronized (mBtDisconnectedDevices) { + mBtDisconnectedDevices.add(associationId); + } + mBleDeviceDisappearedScheduler.scheduleBleDeviceDisappeared(associationId); + } } @Override @@ -281,6 +314,12 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange @Override public void onBleCompanionDeviceFound(int associationId) { onDevicePresenceEvent(mNearbyBleDevices, associationId, EVENT_BLE_APPEARED); + synchronized (mBtDisconnectedDevices) { + final boolean isCurrentPresent = mBtDisconnectedDevicesBlePresence.get(associationId); + if (mBtDisconnectedDevices.contains(associationId) && isCurrentPresent) { + mBleDeviceDisappearedScheduler.unScheduleDeviceDisappeared(associationId); + } + } } @Override @@ -351,6 +390,16 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange switch (event) { case EVENT_BLE_APPEARED: + synchronized (mBtDisconnectedDevices) { + // If a BLE device is detected within 10 seconds after BT is disconnected, + // flag it as BLE is present. + if (mBtDisconnectedDevices.contains(associationId)) { + Slog.i(TAG, "Device ( " + associationId + " ) is present," + + " do not need to send the callback with event ( " + + EVENT_BLE_APPEARED + " )."); + mBtDisconnectedDevicesBlePresence.append(associationId, true); + } + } case EVENT_BT_CONNECTED: case EVENT_SELF_MANAGED_APPEARED: final boolean added = presentDevicesForSource.add(associationId); @@ -403,6 +452,8 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange mNearbyBleDevices.remove(id); mReportedSelfManagedDevices.remove(id); mSimulated.remove(id); + mBtDisconnectedDevices.remove(id); + mBtDisconnectedDevicesBlePresence.delete(id); // Do NOT call mCallback.onDeviceDisappeared()! // CompanionDeviceManagerService will know that the association is removed, and will do @@ -425,14 +476,21 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange throw new SecurityException("Caller is neither Shell nor Root"); } + /** + * The BLE scan can be only stopped if all the devices have been reported + * BT connected and BLE presence and are not pending to report BLE lost. + */ private boolean canStopBleScan() { for (AssociationInfo ai : mAssociationStore.getAssociations()) { int id = ai.getId(); - // The BLE scan cannot be stopped if there's a device is not yet connected. - if (ai.isNotifyOnDeviceNearby() && !isBtConnected(id)) { - Slog.i(TAG, "The BLE scan cannot be stopped, " - + "device( " + id + " ) is not yet connected"); - return false; + synchronized (mBtDisconnectedDevices) { + if (ai.isNotifyOnDeviceNearby() && !(isBtConnected(id) + && isBlePresent(id) && mBtDisconnectedDevices.isEmpty())) { + Slog.i(TAG, "The BLE scan cannot be stopped, " + + "device( " + id + " ) is not yet connected " + + "OR the BLE is not current present Or is pending to report BLE lost"); + return false; + } } } return true; @@ -512,4 +570,51 @@ public class CompanionDevicePresenceMonitor implements AssociationStore.OnChange } } } + + private class BleDeviceDisappearedScheduler extends Handler { + BleDeviceDisappearedScheduler() { + super(Looper.getMainLooper()); + } + + void scheduleBleDeviceDisappeared(int associationId) { + if (hasMessages(associationId)) { + removeMessages(associationId); + } + Slog.i(TAG, "scheduleBleDeviceDisappeared for Device: ( " + associationId + " )."); + sendEmptyMessageDelayed(associationId, 10 * 1000 /* 10 seconds */); + } + + void unScheduleDeviceDisappeared(int associationId) { + if (hasMessages(associationId)) { + Slog.i(TAG, "unScheduleDeviceDisappeared for Device( " + associationId + " )"); + synchronized (mBtDisconnectedDevices) { + mBtDisconnectedDevices.remove(associationId); + mBtDisconnectedDevicesBlePresence.delete(associationId); + } + + removeMessages(associationId); + } + } + + @Override + public void handleMessage(@NonNull Message msg) { + final int associationId = msg.what; + synchronized (mBtDisconnectedDevices) { + final boolean isCurrentPresent = mBtDisconnectedDevicesBlePresence.get( + associationId); + // If a device hasn't reported after 10 seconds and is not currently present, + // assume BLE is lost and trigger the onDeviceEvent callback with the + // EVENT_BLE_DISAPPEARED event. + if (mBtDisconnectedDevices.contains(associationId) + && !isCurrentPresent) { + Slog.i(TAG, "Device ( " + associationId + " ) is likely BLE out of range, " + + "sending callback with event ( " + EVENT_BLE_DISAPPEARED + " )"); + onDevicePresenceEvent(mNearbyBleDevices, associationId, EVENT_BLE_DISAPPEARED); + } + + mBtDisconnectedDevices.remove(associationId); + mBtDisconnectedDevicesBlePresence.delete(associationId); + } + } + } } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java index d4ff699c88a7..6b5ba96f6b1b 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java @@ -50,7 +50,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManagerInternal; import android.app.ActivityThread; -import android.app.admin.DevicePolicyManagerInternal; +import android.app.admin.DevicePolicyCache; import android.app.assist.ActivityId; import android.content.ComponentName; import android.content.ContentCaptureOptions; @@ -940,7 +940,7 @@ public class ContentCaptureManagerService extends return new ContentProtectionConsentManager( BackgroundThread.getHandler(), getContext().getContentResolver(), - LocalServices.getService(DevicePolicyManagerInternal.class)); + DevicePolicyCache.getInstance()); } @Nullable diff --git a/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionConsentManager.java b/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionConsentManager.java index 488a51a56fee..9aa5d2fce6b8 100644 --- a/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionConsentManager.java +++ b/services/contentcapture/java/com/android/server/contentprotection/ContentProtectionConsentManager.java @@ -16,8 +16,13 @@ package com.android.server.contentprotection; +import static android.view.contentprotection.flags.Flags.manageDevicePolicyEnabled; + import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.admin.DevicePolicyCache; +import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.ContentResolver; import android.database.ContentObserver; @@ -28,6 +33,7 @@ import android.provider.Settings; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.LocalServices; /** * Manages consent for content protection. @@ -45,6 +51,8 @@ public class ContentProtectionConsentManager { @NonNull private final ContentResolver mContentResolver; + @NonNull private final DevicePolicyCache mDevicePolicyCache; + @NonNull private final DevicePolicyManagerInternal mDevicePolicyManagerInternal; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) @@ -53,54 +61,98 @@ public class ContentProtectionConsentManager { private volatile boolean mCachedPackageVerifierConsent; - private volatile boolean mCachedContentProtectionConsent; + private volatile boolean mCachedContentProtectionUserConsent; public ContentProtectionConsentManager( @NonNull Handler handler, @NonNull ContentResolver contentResolver, - @NonNull DevicePolicyManagerInternal devicePolicyManagerInternal) { + @NonNull DevicePolicyCache devicePolicyCache) { mContentResolver = contentResolver; - mDevicePolicyManagerInternal = devicePolicyManagerInternal; + mDevicePolicyCache = devicePolicyCache; + mDevicePolicyManagerInternal = LocalServices.getService(DevicePolicyManagerInternal.class); mContentObserver = new SettingsObserver(handler); - contentResolver.registerContentObserver( - Settings.Global.getUriFor(KEY_PACKAGE_VERIFIER_USER_CONSENT), - /* notifyForDescendants= */ false, - mContentObserver, - UserHandle.USER_ALL); - - mCachedPackageVerifierConsent = isPackageVerifierConsentGranted(); - mCachedContentProtectionConsent = isContentProtectionConsentGranted(); + registerSettingsGlobalObserver(KEY_PACKAGE_VERIFIER_USER_CONSENT); + registerSettingsGlobalObserver(KEY_CONTENT_PROTECTION_USER_CONSENT); + readPackageVerifierConsentGranted(); + readContentProtectionUserConsentGranted(); } - /** - * Returns true if all the consents are granted - */ + /** Returns true if the consent is ultimately granted. */ public boolean isConsentGranted(@UserIdInt int userId) { - return mCachedPackageVerifierConsent - && mCachedContentProtectionConsent - && !isUserOrganizationManaged(userId); + return mCachedPackageVerifierConsent && isContentProtectionConsentGranted(userId); } + /** + * Not always cached internally and can be expensive, when possible prefer to use {@link + * #mCachedPackageVerifierConsent} instead. + */ private boolean isPackageVerifierConsentGranted() { - // Not always cached internally return Settings.Global.getInt( mContentResolver, KEY_PACKAGE_VERIFIER_USER_CONSENT, /* def= */ 0) >= 1; } - private boolean isContentProtectionConsentGranted() { - // Not always cached internally + /** + * Not always cached internally and can be expensive, when possible prefer to use {@link + * #mCachedContentProtectionUserConsent} instead. + */ + private boolean isContentProtectionUserConsentGranted() { return Settings.Global.getInt( mContentResolver, KEY_CONTENT_PROTECTION_USER_CONSENT, /* def= */ 0) >= 0; } + private void readPackageVerifierConsentGranted() { + mCachedPackageVerifierConsent = isPackageVerifierConsentGranted(); + } + + private void readContentProtectionUserConsentGranted() { + mCachedContentProtectionUserConsent = isContentProtectionUserConsentGranted(); + } + + /** Always cached internally, cheap and safe to use. */ private boolean isUserOrganizationManaged(@UserIdInt int userId) { - // Cached internally return mDevicePolicyManagerInternal.isUserOrganizationManaged(userId); } + /** Always cached internally, cheap and safe to use. */ + private boolean isContentProtectionPolicyGranted(@UserIdInt int userId) { + if (!manageDevicePolicyEnabled()) { + return false; + } + + @DevicePolicyManager.ContentProtectionPolicy + int policy = mDevicePolicyCache.getContentProtectionPolicy(userId); + + return switch (policy) { + case DevicePolicyManager.CONTENT_PROTECTION_ENABLED -> true; + case DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY -> + mCachedContentProtectionUserConsent; + default -> false; + }; + } + + /** Always cached internally, cheap and safe to use. */ + private boolean isContentProtectionConsentGranted(@UserIdInt int userId) { + if (!manageDevicePolicyEnabled()) { + return mCachedContentProtectionUserConsent && !isUserOrganizationManaged(userId); + } + + return isUserOrganizationManaged(userId) + ? isContentProtectionPolicyGranted(userId) + : mCachedContentProtectionUserConsent; + } + + private void registerSettingsGlobalObserver(@NonNull String key) { + registerSettingsObserver(Settings.Global.getUriFor(key)); + } + + private void registerSettingsObserver(@NonNull Uri uri) { + mContentResolver.registerContentObserver( + uri, /* notifyForDescendants= */ false, mContentObserver, UserHandle.USER_ALL); + } + private final class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler) { @@ -108,17 +160,20 @@ public class ContentProtectionConsentManager { } @Override - public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { + public void onChange(boolean selfChange, @Nullable Uri uri, @UserIdInt int userId) { + if (uri == null) { + return; + } final String property = uri.getLastPathSegment(); if (property == null) { return; } switch (property) { case KEY_PACKAGE_VERIFIER_USER_CONSENT: - mCachedPackageVerifierConsent = isPackageVerifierConsentGranted(); + readPackageVerifierConsentGranted(); return; case KEY_CONTENT_PROTECTION_USER_CONSENT: - mCachedContentProtectionConsent = isContentProtectionConsentGranted(); + readContentProtectionUserConsentGranted(); return; default: Slog.w(TAG, "Ignoring unexpected property: " + property); diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java index 7dc9f10e646c..4de85fe9f2ff 100644 --- a/services/core/java/com/android/server/SystemService.java +++ b/services/core/java/com/android/server/SystemService.java @@ -39,7 +39,9 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Objects; /** * The base class for services running in the system process. Override and implement @@ -135,6 +137,7 @@ public abstract class SystemService { public @interface BootPhase {} private final Context mContext; + private final List<Class<?>> mDependencies; /** * Class representing user in question in the lifecycle callbacks. @@ -332,7 +335,28 @@ public abstract class SystemService { * @param context The system server context. */ public SystemService(@NonNull Context context) { + this(context, Collections.emptyList()); + } + + /** + * Initializes the system service. + * <p> + * Subclasses must define a single argument constructor that accepts the context + * and passes it to super. + * </p> + * + * @param context The system server context. + * @param dependencies The list of dependencies that this service requires to operate. + * Currently only used by the Ravenwood deviceless testing environment to + * understand transitive dependencies needed to support a specific test. + * For example, including {@code PowerManager.class} here indicates that + * this service requires the {@code PowerManager} and/or {@code + * PowerManagerInternal} APIs to function. + * @hide + */ + public SystemService(@NonNull Context context, @NonNull List<Class<?>> dependencies) { mContext = context; + mDependencies = Objects.requireNonNull(dependencies); } /** @@ -356,6 +380,22 @@ public abstract class SystemService { } /** + * Get the list of dependencies that this service requires to operate. + * + * Currently only used by the Ravenwood deviceless testing environment to understand transitive + * dependencies needed to support a specific test. + * + * For example, including {@code PowerManager.class} here indicates that this service + * requires the {@code PowerManager} and/or {@code PowerManagerInternal} APIs to function. + * + * @hide + */ + @NonNull + public final List<Class<?>> getDependencies() { + return mDependencies; + } + + /** * Returns true if the system is running in safe mode. * TODO: we should define in which phase this becomes valid * diff --git a/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java b/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java index 96fee9296215..0e0bf81253e6 100644 --- a/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java +++ b/services/core/java/com/android/server/adaptiveauth/AdaptiveAuthService.java @@ -20,6 +20,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOM import android.app.KeyguardManager; import android.content.Context; +import android.content.pm.PackageManager; import android.hardware.biometrics.AuthenticationStateListener; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricSourceType; @@ -187,6 +188,11 @@ public class AdaptiveAuthService extends SystemService { } private void reportAuthAttempt(int authType, boolean success, int userId) { + // Disable adaptive auth for automotive devices by default + if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { + return; + } + if (success) { // Deleting the entry effectively resets the counter of failed attempts for the user mFailedAttemptsForUser.delete(userId); diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 7d3af99b74d1..b8e09cce93b9 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -372,15 +372,6 @@ public final class ActiveServices { @Overridable public static final long FGS_BOOT_COMPLETED_RESTRICTIONS = 296558535L; - /** - * Disables foreground service background starts in System Alert Window for all types - * unless it already has a System Overlay Window. - */ - @ChangeId - @EnabledSince(targetSdkVersion = VERSION_CODES.VANILLA_ICE_CREAM) - @Overridable - public static final long FGS_SAW_RESTRICTIONS = 319471980L; - final ActivityManagerService mAm; // Maximum number of services that we allow to start in the background @@ -8535,31 +8526,10 @@ public final class ActiveServices { } } - // The flag being enabled isn't enough to deny background start: we need to also check - // if there is a system alert UI present. if (ret == REASON_DENIED) { - // Flag check: are we disabling SAW FGS background starts? - final boolean shouldDisableSaw = Flags.fgsDisableSaw() - && CompatChanges.isChangeEnabled(FGS_BOOT_COMPLETED_RESTRICTIONS, callingUid); - if (shouldDisableSaw) { - final ProcessRecord processRecord = mAm - .getProcessRecordLocked(targetService.processName, - targetService.appInfo.uid); - if (processRecord != null) { - if (processRecord.mState.hasOverlayUi()) { - if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid, - callingPackage)) { - ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION; - } - } - } else { - Slog.e(TAG, "Could not find process record for SAW check"); - } - } else { - if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid, - callingPackage)) { - ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION; - } + if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid, + callingPackage)) { + ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION; } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index e222878a5dd3..663ba8a38d77 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -9028,6 +9028,7 @@ public class ActivityManagerService extends IActivityManager.Stub Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid " + Process.myUid()); BinderProxy.dumpProxyDebugInfo(); + CriticalEventLog.getInstance().logExcessiveBinderCalls(uid); if (uid == Process.SYSTEM_UID) { Slog.i(TAG, "Skipping kill (uid is SYSTEM)"); } else { diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 34ba7f0debb0..3abfe082db27 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -1468,7 +1468,7 @@ class UserController implements Handler.Callback { // Send PROFILE_INACCESSIBLE broadcast if a profile was stopped final UserInfo userInfo = getUserInfo(userId); - if (userInfo.isProfile()) { + if (userInfo != null && userInfo.isProfile()) { UserInfo parent = mInjector.getUserManager().getProfileParent(userId); if (parent != null) { broadcastProfileAccessibleStateChanged(userId, parent.id, diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig index e955b00566b8..c06bdf90a75a 100644 --- a/services/core/java/com/android/server/am/flags.aconfig +++ b/services/core/java/com/android/server/am/flags.aconfig @@ -23,13 +23,6 @@ flag { } flag { - name: "fgs_disable_saw" - namespace: "backstage_power" - description: "Disable System Alert Window FGS start" - bug: "296558535" -} - -flag { name: "bfgs_managed_network_access" namespace: "backstage_power" description: "Restrict network access for certain applications in BFGS process state" @@ -60,3 +53,10 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + namespace: "backstage_power" + name: "defer_outgoing_bcasts" + description: "Defer outgoing broadcasts from processes in freezable state" + bug: "327496592" +} diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java index 007b7462f637..fb826c824354 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java @@ -24,6 +24,7 @@ import android.app.SynchronousUserSwitchObserver; import android.app.TaskStackListener; import android.content.Context; import android.content.pm.UserInfo; +import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricFaceConstants; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.ComponentInfoInternal; @@ -39,6 +40,7 @@ import android.hardware.face.FaceEnrollOptions; import android.hardware.face.FaceSensorPropertiesInternal; import android.hardware.face.IFaceServiceReceiver; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -64,6 +66,7 @@ import com.android.server.biometrics.sensors.AuthenticationStateListeners; import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.BiometricScheduler; import com.android.server.biometrics.sensors.BiometricStateCallback; +import com.android.server.biometrics.sensors.BiometricUtils; import com.android.server.biometrics.sensors.ClientMonitorCallback; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback; @@ -359,6 +362,17 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { null /* callback */); } + if (Build.isDebuggable()) { + BiometricUtils<Face> utils = FaceUtils.getInstance( + mFaceSensors.keyAt(0)); + for (UserInfo user : UserManager.get(mContext).getAliveUsers()) { + List<Face> enrollments = utils.getBiometricsForUser(mContext, user.id); + Slog.d(getTag(), "Expecting enrollments for user " + user.id + ": " + + enrollments.stream().map( + BiometricAuthenticator.Identifier::getBiometricId).toList()); + } + } + return mDaemon; } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java index a104cf4e1726..c04c47e2d95a 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java @@ -27,6 +27,7 @@ import android.app.TaskStackListener; import android.content.Context; import android.content.pm.UserInfo; import android.content.res.TypedArray; +import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.ComponentInfoInternal; import android.hardware.biometrics.IInvalidationCallback; @@ -46,6 +47,7 @@ import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.ISidefpsController; import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -71,6 +73,7 @@ import com.android.server.biometrics.sensors.AuthenticationStateListeners; import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.BiometricScheduler; import com.android.server.biometrics.sensors.BiometricStateCallback; +import com.android.server.biometrics.sensors.BiometricUtils; import com.android.server.biometrics.sensors.ClientMonitorCallback; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.ClientMonitorCompositeCallback; @@ -382,6 +385,17 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi null /* callback */); } + if (Build.isDebuggable()) { + BiometricUtils<Fingerprint> utils = FingerprintUtils.getInstance( + mFingerprintSensors.keyAt(0)); + for (UserInfo user : UserManager.get(mContext).getAliveUsers()) { + List<Fingerprint> enrollments = utils.getBiometricsForUser(mContext, user.id); + Slog.d(getTag(), "Expecting enrollments for user " + user.id + ": " + + enrollments.stream().map( + BiometricAuthenticator.Identifier::getBiometricId).toList()); + } + } + return mDaemon; } diff --git a/services/core/java/com/android/server/criticalevents/CriticalEventLog.java b/services/core/java/com/android/server/criticalevents/CriticalEventLog.java index 816c3490d0a0..036284f53749 100644 --- a/services/core/java/com/android/server/criticalevents/CriticalEventLog.java +++ b/services/core/java/com/android/server/criticalevents/CriticalEventLog.java @@ -30,6 +30,7 @@ import com.android.server.criticalevents.nano.CriticalEventProto; import com.android.server.criticalevents.nano.CriticalEventProto.AppNotResponding; import com.android.server.criticalevents.nano.CriticalEventProto.HalfWatchdog; import com.android.server.criticalevents.nano.CriticalEventProto.InstallPackages; +import com.android.server.criticalevents.nano.CriticalEventProto.ExcessiveBinderCalls; import com.android.server.criticalevents.nano.CriticalEventProto.JavaCrash; import com.android.server.criticalevents.nano.CriticalEventProto.NativeCrash; import com.android.server.criticalevents.nano.CriticalEventProto.SystemServerStarted; @@ -143,6 +144,15 @@ public class CriticalEventLog { return System.currentTimeMillis(); } + /** Logs when a uid sends an excessive number of binder calls. */ + public void logExcessiveBinderCalls(int uid) { + CriticalEventProto event = new CriticalEventProto(); + ExcessiveBinderCalls calls = new ExcessiveBinderCalls(); + calls.uid = uid; + event.setExcessiveBinderCalls(calls); + log(event); + } + /** Logs when one or more packages are installed. */ public void logInstallPackagesStarted() { CriticalEventProto event = new CriticalEventProto(); diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 23ca81468294..76f303596bdb 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -1725,6 +1725,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mTempBrightnessEvent.setBrightness(brightnessState); mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId); mTempBrightnessEvent.setDisplayState(state); + mTempBrightnessEvent.setDisplayPolicy(mPowerRequest.policy); mTempBrightnessEvent.setReason(mBrightnessReason); mTempBrightnessEvent.setHbmMax(mBrightnessRangeController.getCurrentBrightnessMax()); mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode()); diff --git a/services/core/java/com/android/server/display/brightness/BrightnessEvent.java b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java index 5423b74711a2..82b401a7cc83 100644 --- a/services/core/java/com/android/server/display/brightness/BrightnessEvent.java +++ b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java @@ -16,6 +16,9 @@ package com.android.server.display.brightness; +import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_OFF; +import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.policyToString; + import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT; import static com.android.server.display.config.DisplayBrightnessMappingConfig.autoBrightnessModeToString; @@ -46,6 +49,7 @@ public final class BrightnessEvent { private int mDisplayId; private String mPhysicalDisplayId; private int mDisplayState; + private int mDisplayPolicy; private long mTime; private float mLux; private float mPreThresholdLux; @@ -85,6 +89,7 @@ public final class BrightnessEvent { mDisplayId = that.getDisplayId(); mPhysicalDisplayId = that.getPhysicalDisplayId(); mDisplayState = that.mDisplayState; + mDisplayPolicy = that.mDisplayPolicy; mTime = that.getTime(); // Lux values mLux = that.getLux(); @@ -117,6 +122,7 @@ public final class BrightnessEvent { mTime = SystemClock.uptimeMillis(); mPhysicalDisplayId = ""; mDisplayState = Display.STATE_UNKNOWN; + mDisplayPolicy = POLICY_OFF; // Lux values mLux = 0; mPreThresholdLux = 0; @@ -155,6 +161,7 @@ public final class BrightnessEvent { && mDisplayId == that.mDisplayId && mPhysicalDisplayId.equals(that.mPhysicalDisplayId) && mDisplayState == that.mDisplayState + && mDisplayPolicy == that.mDisplayPolicy && Float.floatToRawIntBits(mLux) == Float.floatToRawIntBits(that.mLux) && Float.floatToRawIntBits(mPreThresholdLux) == Float.floatToRawIntBits(that.mPreThresholdLux) @@ -191,6 +198,7 @@ public final class BrightnessEvent { + "disp=" + mDisplayId + ", physDisp=" + mPhysicalDisplayId + ", displayState=" + Display.stateToString(mDisplayState) + + ", displayPolicy=" + policyToString(mDisplayPolicy) + ", brt=" + mBrightness + ((mFlags & FLAG_USER_SET) != 0 ? "(user_set)" : "") + ", initBrt=" + mInitialBrightness + ", rcmdBrt=" + mRecommendedBrightness @@ -251,6 +259,10 @@ public final class BrightnessEvent { mDisplayState = state; } + public void setDisplayPolicy(int policy) { + mDisplayPolicy = policy; + } + public float getLux() { return mLux; } diff --git a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java index 277a4d40c7e4..f53b9411a6a7 100644 --- a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java +++ b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java @@ -21,6 +21,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.role.RoleManager; import android.content.Intent; import android.hardware.input.KeyboardLayout; import android.icu.util.ULocale; @@ -37,6 +38,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.KeyboardConfiguredProto.KeyboardLayoutConfig; import com.android.internal.os.KeyboardConfiguredProto.RepeatedKeyboardLayoutConfig; import com.android.internal.util.FrameworkStatsLog; +import com.android.server.policy.ModifierShortcutManager; import java.lang.annotation.Retention; import java.util.ArrayList; @@ -318,6 +320,13 @@ public final class KeyboardMetricsCollector { } } + // The shortcut may be targeting a system role rather than using an intent selector, + // so check for that. + String role = intent.getStringExtra(ModifierShortcutManager.EXTRA_ROLE); + if (!TextUtils.isEmpty(role)) { + return getLogEventFromRole(role); + } + Set<String> intentCategories = intent.getCategories(); if (intentCategories == null || intentCategories.isEmpty() || !intentCategories.contains(Intent.CATEGORY_LAUNCHER)) { @@ -363,6 +372,23 @@ public final class KeyboardMetricsCollector { return null; } } + + /** + * Find KeyboardLogEvent corresponding to the provide system role name. + * Returns {@code null} if no matching event found. + */ + @Nullable + private static KeyboardLogEvent getLogEventFromRole(String role) { + if (RoleManager.ROLE_BROWSER.equals(role)) { + return LAUNCH_DEFAULT_BROWSER; + } else if (RoleManager.ROLE_SMS.equals(role)) { + return LAUNCH_DEFAULT_MESSAGING; + } else { + Log.w(TAG, "Keyboard shortcut to launch " + + role + " not supported for logging"); + return null; + } + } } /** diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 307b70a89634..3dedca9c42ba 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -1397,43 +1397,57 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub private void onFinishPackageChangesInternal() { synchronized (ImfLock.class) { - if (!isChangingPackagesOfCurrentUserLocked()) { - return; - } - if (!shouldRebuildInputMethodListLocked()) { - return; + final int userId = getChangingUserId(); + final boolean isCurrentUser = (userId == mSettings.getUserId()); + AdditionalSubtypeMap additionalSubtypeMap; + final InputMethodSettings settings; + if (isCurrentUser) { + additionalSubtypeMap = mAdditionalSubtypeMap; + settings = mSettings; + } else { + additionalSubtypeMap = AdditionalSubtypeUtils.load(userId); + settings = queryInputMethodServicesInternal(mContext, userId, + additionalSubtypeMap, DirectBootAwareness.AUTO); } InputMethodInfo curIm = null; - String curInputMethodId = mSettings.getSelectedInputMethod(); - final List<InputMethodInfo> methodList = mSettings.getMethodList(); + String curInputMethodId = settings.getSelectedInputMethod(); + final List<InputMethodInfo> methodList = settings.getMethodList(); final int numImes = methodList.size(); - if (curInputMethodId != null) { - for (int i = 0; i < numImes; i++) { - InputMethodInfo imi = methodList.get(i); - final String imiId = imi.getId(); - if (imiId.equals(curInputMethodId)) { - curIm = imi; - } - - int change = isPackageDisappearing(imi.getPackageName()); - if (change == PACKAGE_TEMPORARY_CHANGE - || change == PACKAGE_PERMANENT_CHANGE) { - Slog.i(TAG, "Input method uninstalled, disabling: " - + imi.getComponent()); + for (int i = 0; i < numImes; i++) { + InputMethodInfo imi = methodList.get(i); + final String imiId = imi.getId(); + if (imiId.equals(curInputMethodId)) { + curIm = imi; + } + int change = isPackageDisappearing(imi.getPackageName()); + if (change == PACKAGE_TEMPORARY_CHANGE || change == PACKAGE_PERMANENT_CHANGE) { + Slog.i(TAG, "Input method uninstalled, disabling: " + imi.getComponent()); + if (isCurrentUser) { setInputMethodEnabledLocked(imi.getId(), false); - } else if (change == PACKAGE_UPDATING) { - Slog.i(TAG, - "Input method reinstalling, clearing additional subtypes: " - + imi.getComponent()); - mAdditionalSubtypeMap = - mAdditionalSubtypeMap.cloneWithRemoveOrSelf(imi.getId()); - AdditionalSubtypeUtils.save(mAdditionalSubtypeMap, - mSettings.getMethodMap(), mSettings.getUserId()); + } else { + settings.buildAndPutEnabledInputMethodsStrRemovingId( + new StringBuilder(), + settings.getEnabledInputMethodsAndSubtypeList(), + imi.getId()); + } + } else if (change == PACKAGE_UPDATING) { + Slog.i(TAG, "Input method reinstalling, clearing additional subtypes: " + + imi.getComponent()); + additionalSubtypeMap = + additionalSubtypeMap.cloneWithRemoveOrSelf(imi.getId()); + AdditionalSubtypeUtils.save(additionalSubtypeMap, + settings.getMethodMap(), userId); + if (isCurrentUser) { + mAdditionalSubtypeMap = additionalSubtypeMap; } } } + if (!isCurrentUser || !shouldRebuildInputMethodListLocked()) { + return; + } + buildInputMethodListLocked(false /* resetDefaultEnabledIme */); boolean changed = false; @@ -1443,7 +1457,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub if (change == PACKAGE_TEMPORARY_CHANGE || change == PACKAGE_PERMANENT_CHANGE) { final PackageManager userAwarePackageManager = - getPackageManagerForUser(mContext, mSettings.getUserId()); + getPackageManagerForUser(mContext, userId); ServiceInfo si = null; try { si = userAwarePackageManager.getServiceInfo(curIm.getComponent(), diff --git a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java index 62d44557ae4c..db6a9af0fe62 100644 --- a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java +++ b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java @@ -72,6 +72,7 @@ import com.android.internal.util.FunctionalUtils.ThrowingRunnable; import com.android.internal.view.IInputMethodManager; import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; @@ -404,6 +405,13 @@ public class ZeroJankProxy extends IInputMethodManager.Stub { in, out, err, args, callback, resultReceiver); } + @Override + protected void dump(@NonNull FileDescriptor fd, + @NonNull PrintWriter fout, + @Nullable String[] args) { + ((InputMethodManagerService) mInner).dump(fd, fout, args); + } + private void sendOnStartInputResult( IInputMethodClient client, InputBindResult res, int startInputSeq) { InputMethodManagerService service = (InputMethodManagerService) mInner; diff --git a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java index 2522f7b82353..470cc049a82b 100644 --- a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java @@ -109,20 +109,15 @@ public final class StationaryThrottlingLocationProvider extends DelegateLocation synchronized (mLock) { mDeviceIdleHelper.addListener(this); - mDeviceIdle = mDeviceIdleHelper.isDeviceIdle(); - mDeviceStationaryHelper.addListener(this); - mDeviceStationary = false; - mDeviceStationaryRealtimeMs = Long.MIN_VALUE; - - onThrottlingChangedLocked(false); + onDeviceIdleChanged(mDeviceIdleHelper.isDeviceIdle()); } } @Override protected void onStop() { synchronized (mLock) { - mDeviceStationaryHelper.removeListener(this); mDeviceIdleHelper.removeListener(this); + onDeviceIdleChanged(false); mIncomingRequest = ProviderRequest.EMPTY_REQUEST; mOutgoingRequest = ProviderRequest.EMPTY_REQUEST; @@ -155,13 +150,26 @@ public final class StationaryThrottlingLocationProvider extends DelegateLocation } mDeviceIdle = deviceIdle; - onThrottlingChangedLocked(false); + if (deviceIdle) { + // device stationary helper will deliver an immediate listener update + mDeviceStationaryHelper.addListener(this); + } else { + mDeviceStationaryHelper.removeListener(this); + mDeviceStationary = false; + mDeviceStationaryRealtimeMs = Long.MIN_VALUE; + onThrottlingChangedLocked(false); + } } } @Override public void onDeviceStationaryChanged(boolean deviceStationary) { synchronized (mLock) { + if (!mDeviceIdle) { + // stationary detection is only registered while idle - ignore late notifications + return; + } + if (mDeviceStationary == deviceStationary) { return; } diff --git a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java index a597edd93515..8fdc22b81769 100644 --- a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java @@ -59,7 +59,7 @@ public class ProxyLocationProvider extends AbstractLocationProvider implements private static final String EXTRA_LOCATION_TAGS = "android:location_allow_listed_tags"; private static final String LOCATION_TAGS_SEPARATOR = ";"; - private static final long RESET_DELAY_MS = 1000; + private static final long RESET_DELAY_MS = 10000; /** * Creates and registers this proxy. If no suitable service is available for the proxy, returns diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index a3ec3c52ca20..29ea0713e0a8 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -1870,9 +1870,10 @@ public class LockSettingsService extends ILockSettings.Stub { } } - private void onPostPasswordChanged(LockscreenCredential newCredential, int userHandle) { - updatePasswordHistory(newCredential, userHandle); - mContext.getSystemService(TrustManager.class).reportEnabledTrustAgentsChanged(userHandle); + private void onPostPasswordChanged(LockscreenCredential newCredential, int userId) { + updatePasswordHistory(newCredential, userId); + mContext.getSystemService(TrustManager.class).reportEnabledTrustAgentsChanged(userId); + sendMainUserCredentialChangedNotificationIfNeeded(userId); } /** @@ -3056,7 +3057,6 @@ public class LockSettingsService extends ILockSettings.Stub { setCurrentLskfBasedProtectorId(newProtectorId, userId); LockPatternUtils.invalidateCredentialTypeCache(); synchronizeUnifiedChallengeForProfiles(userId, profilePasswords); - sendMainUserCredentialChangedNotificationIfNeeded(userId); setUserPasswordMetrics(credential, userId); mUnifiedProfilePasswordCache.removePassword(userId); diff --git a/services/core/java/com/android/server/media/MediaSession2Record.java b/services/core/java/com/android/server/media/MediaSession2Record.java index a110e5637f82..7af5c08f5ffa 100644 --- a/services/core/java/com/android/server/media/MediaSession2Record.java +++ b/services/core/java/com/android/server/media/MediaSession2Record.java @@ -35,12 +35,11 @@ import java.io.PrintWriter; * Keeps the record of {@link Session2Token} to help send command to the corresponding session. */ // TODO(jaewan): Do not call service method directly -- introduce listener instead. -public class MediaSession2Record implements MediaSessionRecordImpl { +public class MediaSession2Record extends MediaSessionRecordImpl { private static final String TAG = "MediaSession2Record"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final Object mLock = new Object(); - private final int mUniqueId; @GuardedBy("mLock") private final Session2Token mSessionToken; @GuardedBy("mLock") @@ -64,13 +63,12 @@ public class MediaSession2Record implements MediaSessionRecordImpl { MediaSessionService service, Looper handlerLooper, int pid, - int policies, - int uniqueId) { + int policies) { // The lock is required to prevent `Controller2Callback` from using partially initialized // `MediaSession2Record.this`. synchronized (mLock) { + mUniqueId = sNextMediaSessionRecordId.getAndIncrement(); mSessionToken = sessionToken; - mUniqueId = uniqueId; mService = service; mHandlerExecutor = new HandlerExecutor(new Handler(handlerLooper)); mController = new MediaController2.Builder(service.getContext(), sessionToken) @@ -101,13 +99,6 @@ public class MediaSession2Record implements MediaSessionRecordImpl { } @Override - public int getUniqueId() { - synchronized (mLock) { - return mUniqueId; - } - } - - @Override public String getPackageName() { return mSessionToken.getPackageName(); } @@ -210,7 +201,7 @@ public class MediaSession2Record implements MediaSessionRecordImpl { @Override public void dump(PrintWriter pw, String prefix) { - pw.println(prefix + "uniqueId=" + mUniqueId); + pw.println(prefix + "uniqueId=" + getUniqueId()); pw.println(prefix + "token=" + mSessionToken); pw.println(prefix + "controller=" + mController); @@ -220,7 +211,7 @@ public class MediaSession2Record implements MediaSessionRecordImpl { @Override public String toString() { - return getPackageName() + "/" + mUniqueId + " (userId=" + getUserId() + ")"; + return getPackageName() + "/" + getUniqueId() + " (userId=" + getUserId() + ")"; } private class Controller2Callback extends MediaController2.ControllerCallback { diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 15527041d8eb..a9a82725223d 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -96,7 +96,7 @@ import java.util.concurrent.CopyOnWriteArrayList; * MediaSession wrapper class instead. */ // TODO(jaewan): Do not call service method directly -- introduce listener instead. -public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionRecordImpl { +public class MediaSessionRecord extends MediaSessionRecordImpl implements IBinder.DeathRecipient { /** * {@link android.media.session.MediaSession#setMediaButtonBroadcastReceiver( @@ -173,7 +173,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR private final int mUserId; private final String mPackageName; private final String mTag; - private final int mUniqueId; private final Bundle mSessionInfo; private final ControllerStub mController; private final MediaSession.Token mSessionToken; @@ -231,18 +230,17 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR String ownerPackageName, ISessionCallback cb, String tag, - int uniqueId, Bundle sessionInfo, MediaSessionService service, Looper handlerLooper, int policies) throws RemoteException { + mUniqueId = sNextMediaSessionRecordId.getAndIncrement(); mOwnerPid = ownerPid; mOwnerUid = ownerUid; mUserId = userId; mPackageName = ownerPackageName; mTag = tag; - mUniqueId = uniqueId; mSessionInfo = sessionInfo; mController = new ControllerStub(); mSessionToken = new MediaSession.Token(ownerUid, mController); @@ -303,16 +301,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } /** - * Get the unique id of this session record. - * - * @return a unique id of this session record. - */ - @Override - public int getUniqueId() { - return mUniqueId; - } - - /** * Get the info for this session. * * @return Info that identifies this session. @@ -724,7 +712,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR @Override public String toString() { - return mPackageName + "/" + mTag + "/" + mUniqueId + " (userId=" + mUserId + ")"; + return mPackageName + "/" + mTag + "/" + getUniqueId() + " (userId=" + mUserId + ")"; } @Override diff --git a/services/core/java/com/android/server/media/MediaSessionRecordImpl.java b/services/core/java/com/android/server/media/MediaSessionRecordImpl.java index e53a2dbe8101..e4b2fad5f309 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecordImpl.java +++ b/services/core/java/com/android/server/media/MediaSessionRecordImpl.java @@ -25,39 +25,37 @@ import android.view.KeyEvent; import com.android.server.media.MediaSessionPolicyProvider.SessionPolicy; import java.io.PrintWriter; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; /** * Common interfaces between {@link MediaSessionRecord} and {@link MediaSession2Record}. */ -public interface MediaSessionRecordImpl extends AutoCloseable { +public abstract class MediaSessionRecordImpl { - /** - * Get the unique id of this session record. - * - * @return a unique id of this session record. - */ - int getUniqueId(); + static final AtomicInteger sNextMediaSessionRecordId = new AtomicInteger(1); + int mUniqueId; /** * Get the info for this session. * * @return Info that identifies this session. */ - String getPackageName(); + public abstract String getPackageName(); /** * Get the UID this session was created for. * * @return The UID for this session. */ - int getUid(); + public abstract int getUid(); /** * Get the user id this session was created for. * * @return The user id for this session. */ - int getUserId(); + public abstract int getUserId(); /** * Get the {@link ForegroundServiceDelegationOptions} needed for notifying activity manager @@ -66,7 +64,7 @@ public interface MediaSessionRecordImpl extends AutoCloseable { * @return the {@link ForegroundServiceDelegationOptions} needed for notifying the activity * manager service with changes in the {@link PlaybackState} for this session. */ - ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions(); + public abstract ForegroundServiceDelegationOptions getForegroundServiceDelegationOptions(); /** * Check if this session has system priority and should receive media buttons before any other @@ -74,7 +72,7 @@ public interface MediaSessionRecordImpl extends AutoCloseable { * * @return True if this is a system priority session, false otherwise */ - boolean isSystemPriority(); + public abstract boolean isSystemPriority(); /** * Send a volume adjustment to the session owner. Direction must be one of @@ -95,7 +93,7 @@ public interface MediaSessionRecordImpl extends AutoCloseable { * @param useSuggested True to use adjustSuggestedStreamVolumeForUid instead of * adjustStreamVolumeForUid */ - void adjustVolume(String packageName, String opPackageName, int pid, int uid, + public abstract void adjustVolume(String packageName, String opPackageName, int pid, int uid, boolean asSystemService, int direction, int flags, boolean useSuggested); /** @@ -105,7 +103,7 @@ public interface MediaSessionRecordImpl extends AutoCloseable { * @return True if the session is active, false otherwise. */ // TODO(jaewan): Find better naming, or remove this from the MediaSessionRecordImpl. - boolean isActive(); + public abstract boolean isActive(); /** * Check if the session's playback active state matches with the expectation. This always @@ -115,7 +113,7 @@ public interface MediaSessionRecordImpl extends AutoCloseable { * @param expected True if playback is expected to be active. False otherwise. * @return True if the session's playback matches with the expectation. False otherwise. */ - boolean checkPlaybackActiveState(boolean expected); + public abstract boolean checkPlaybackActiveState(boolean expected); /** * Check whether the playback type is local or remote. @@ -128,7 +126,7 @@ public interface MediaSessionRecordImpl extends AutoCloseable { * * @return {@code true} if the playback is local. {@code false} if the playback is remote. */ - boolean isPlaybackTypeLocal(); + public abstract boolean isPlaybackTypeLocal(); /** * Sends media button. @@ -145,27 +143,27 @@ public interface MediaSessionRecordImpl extends AutoCloseable { * @return {@code true} if the attempt to send media button was successfully. * {@code false} otherwise. */ - boolean sendMediaButton(String packageName, int pid, int uid, boolean asSystemService, - KeyEvent ke, int sequenceId, ResultReceiver cb); + public abstract boolean sendMediaButton(String packageName, int pid, int uid, + boolean asSystemService, KeyEvent ke, int sequenceId, ResultReceiver cb); /** * Returns whether the media session can handle volume key events. * * @return True if this media session can handle volume key events, false otherwise. */ - boolean canHandleVolumeKey(); + public abstract boolean canHandleVolumeKey(); /** * Get session policies from custom policy provider set when MediaSessionRecord is instantiated. * If custom policy does not exist, will return null. */ @SessionPolicy - int getSessionPolicies(); + public abstract int getSessionPolicies(); /** * Overwrite session policies that have been set when MediaSessionRecord is instantiated. */ - void setSessionPolicies(@SessionPolicy int policies); + public abstract void setSessionPolicies(@SessionPolicy int policies); /** * Dumps internal state @@ -173,16 +171,37 @@ public interface MediaSessionRecordImpl extends AutoCloseable { * @param pw print writer * @param prefix prefix */ - void dump(PrintWriter pw, String prefix); + public abstract void dump(PrintWriter pw, String prefix); /** - * Override {@link AutoCloseable#close} to tell it not to throw exception. + * Similar to {@link AutoCloseable#close} without throwing an exception. */ - @Override - void close(); + public abstract void close(); + + /** + * Get the unique id of this session record. + * + * @return a unique id of this session record. + */ + public int getUniqueId() { + return mUniqueId; + } /** * Returns whether {@link #close()} is called before. */ - boolean isClosed(); + public abstract boolean isClosed(); + + @Override + public final boolean equals(Object o) { + if (this == o) return true; + if (o == null || !(o instanceof MediaSessionRecordImpl)) return false; + MediaSessionRecordImpl that = (MediaSessionRecordImpl) o; + return mUniqueId == that.mUniqueId; + } + + @Override + public final int hashCode() { + return Objects.hash(mUniqueId); + } } diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 9e98a5809650..42851747c5cb 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -106,7 +106,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; /** * System implementation of MediaSessionManager @@ -128,6 +127,22 @@ public class MediaSessionService extends SystemService implements Monitor { */ private static final String MEDIA_BUTTON_RECEIVER = "media_button_receiver"; + /** + * Action reported to UsageStatsManager when a media session becomes active and user engaged + * for a given app. App is expected to show an ongoing notification after this. + */ + private static final String USAGE_STATS_ACTION_START = "start"; + + /** + * Action reported to UsageStatsManager when a media session is no longer active and user + * engaged for a given app. If media session only pauses for a brief time the event will not + * necessarily be reported in case user is still "engaging" and will restart it momentarily. + * In such case, action may be reported after a short delay to ensure user is truly no longer + * engaging. Afterwards, the app is no longer expected to show an ongoing notification. + */ + private static final String USAGE_STATS_ACTION_STOP = "stop"; + private static final String USAGE_STATS_CATEGORY = "android.media"; + private final Context mContext; private final SessionManagerImpl mSessionManagerImpl; private final MessageHandler mHandler = new MessageHandler(); @@ -156,8 +171,6 @@ public class MediaSessionService extends SystemService implements Monitor { /* Maps uid with all user engaging session tokens associated to it */ private final SparseArray<Set<MediaSession.Token>> mUserEngagingSessions = new SparseArray<>(); - private final AtomicInteger mNextMediaSessionRecordId = new AtomicInteger(1); - // The FullUserRecord of the current users. (i.e. The foreground user that isn't a profile) // It's always not null after the MediaSessionService is started. private FullUserRecord mCurrentFullUserRecord; @@ -196,8 +209,7 @@ public class MediaSessionService extends SystemService implements Monitor { MediaSessionService.this, mRecordThread.getLooper(), pid, - /* policies= */ 0, - /* uniqueId= */ mNextMediaSessionRecordId.getAndIncrement()); + /* policies= */ 0); synchronized (mLock) { FullUserRecord user = getFullUserRecordLocked(record.getUserId()); if (user != null) { @@ -639,13 +651,15 @@ public class MediaSessionService extends SystemService implements Monitor { if (userEngaged) { if (!mUserEngagingSessions.contains(sessionUid)) { mUserEngagingSessions.put(sessionUid, new HashSet<>()); - reportUserInteractionEvent(/* action= */ "start", record.getUserId(), packageName); + reportUserInteractionEvent( + USAGE_STATS_ACTION_START, record.getUserId(), packageName); } mUserEngagingSessions.get(sessionUid).add(token); } else if (mUserEngagingSessions.contains(sessionUid)) { mUserEngagingSessions.get(sessionUid).remove(token); if (mUserEngagingSessions.get(sessionUid).isEmpty()) { - reportUserInteractionEvent(/* action= */ "stop", record.getUserId(), packageName); + reportUserInteractionEvent( + USAGE_STATS_ACTION_STOP, record.getUserId(), packageName); mUserEngagingSessions.remove(sessionUid); } } @@ -653,7 +667,7 @@ public class MediaSessionService extends SystemService implements Monitor { private void reportUserInteractionEvent(String action, int userId, String packageName) { PersistableBundle extras = new PersistableBundle(); - extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, "android.media"); + extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, USAGE_STATS_CATEGORY); extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, action); mUsageStatsManagerInternal.reportUserInteractionEvent(packageName, userId, extras); } @@ -806,7 +820,6 @@ public class MediaSessionService extends SystemService implements Monitor { callerPackageName, cb, tag, - /* uniqueId= */ mNextMediaSessionRecordId.getAndIncrement(), sessionInfo, this, mRecordThread.getLooper(), diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 31bfc6954416..18b495bfce5d 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -1252,7 +1252,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { if (isUidStateChangeRelevant(callbackInfo, procState, procStateSeq, capability)) { callbackInfo.update(uid, procState, procStateSeq, capability); if (!callbackInfo.isPending) { - mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, callbackInfo) + mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, uid, 0) .sendToTarget(); callbackInfo.isPending = true; } @@ -1264,7 +1264,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { synchronized (mUidStateCallbackInfos) { mUidStateCallbackInfos.remove(uid); } - // TODO: b/327058756 - Remove any pending UID_MSG_STATE_CHANGED on the handler. mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget(); } }; @@ -5870,13 +5869,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private final Handler.Callback mUidEventHandlerCallback = new Handler.Callback() { @Override public boolean handleMessage(Message msg) { + final int uid = msg.arg1; switch (msg.what) { case UID_MSG_STATE_CHANGED: { - handleUidChanged((UidStateCallbackInfo) msg.obj); + handleUidChanged(uid); return true; } case UID_MSG_GONE: { - final int uid = msg.arg1; handleUidGone(uid); return true; } @@ -5887,23 +5886,27 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } }; - void handleUidChanged(@NonNull UidStateCallbackInfo uidStateCallbackInfo) { + void handleUidChanged(int uid) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged"); try { - boolean updated; - final int uid; final int procState; final long procStateSeq; final int capability; - synchronized (mUidRulesFirstLock) { - synchronized (mUidStateCallbackInfos) { - uid = uidStateCallbackInfo.uid; - procState = uidStateCallbackInfo.procState; - procStateSeq = uidStateCallbackInfo.procStateSeq; - capability = uidStateCallbackInfo.capability; - uidStateCallbackInfo.isPending = false; + synchronized (mUidStateCallbackInfos) { + final UidStateCallbackInfo uidStateCallbackInfo = mUidStateCallbackInfos.get(uid); + if (uidStateCallbackInfo == null) { + // This can happen if UidObserver#onUidGone gets called before we reach + // here. In this case, there is no point in processing this change as this + // will immediately be followed by a call to handleUidGone anyway. + return; } - + procState = uidStateCallbackInfo.procState; + procStateSeq = uidStateCallbackInfo.procStateSeq; + capability = uidStateCallbackInfo.capability; + uidStateCallbackInfo.isPending = false; + } + final boolean updated; + synchronized (mUidRulesFirstLock) { // We received a uid state change callback, add it to the history so that it // will be useful for debugging. mLogger.uidStateChanged(uid, procState, procStateSeq, capability); @@ -5926,6 +5929,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { void handleUidGone(int uid) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone"); try { + synchronized (mUidStateCallbackInfos) { + if (mUidStateCallbackInfos.contains(uid)) { + // This can happen if UidObserver#onUidStateChanged gets called before we + // reach here. In this case, there is no point in processing this change as this + // will immediately be followed by a call to handleUidChanged anyway. + return; + } + } final boolean updated; synchronized (mUidRulesFirstLock) { updated = removeUidStateUL(uid); diff --git a/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java b/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java index ab650afe68a7..27b85746fec2 100644 --- a/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java +++ b/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java @@ -65,7 +65,9 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { mColorDisplayManager = context.getSystemService(ColorDisplayManager.class); mPowerManager = context.getSystemService(PowerManager.class); mUiModeManager = context.getSystemService(UiModeManager.class); - mWallpaperManager = context.getSystemService(WallpaperManager.class); + WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class); + mWallpaperManager = wallpaperManager != null && wallpaperManager.isWallpaperSupported() + ? wallpaperManager : null; } @Override diff --git a/services/core/java/com/android/server/om/IdmapDaemon.java b/services/core/java/com/android/server/om/IdmapDaemon.java index 15cfca5ca553..1b22154c10f6 100644 --- a/services/core/java/com/android/server/om/IdmapDaemon.java +++ b/services/core/java/com/android/server/om/IdmapDaemon.java @@ -51,8 +51,15 @@ class IdmapDaemon { // before stopping the service. private static final int SERVICE_TIMEOUT_MS = 10000; - // The amount of time in milliseconds to wait when attempting to connect to idmap service. - private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000; + // The device may enter CPU sleep while waiting for the service startup, and in that mode + // the uptime doesn't increment. Thus, we need to have two timeouts: a smaller one for the + // uptime and a longer one for the wall time in case when the device never advances the uptime, + // so the watchdog won't get triggered. + + // The amount of uptime in milliseconds to wait when attempting to connect to idmap service. + private static final int SERVICE_CONNECT_UPTIME_TIMEOUT_MS = 5000; + // The amount of wall time in milliseconds to wait. + private static final int SERVICE_CONNECT_WALLTIME_TIMEOUT_MS = 30000; private static final int SERVICE_CONNECT_INTERVAL_SLEEP_MS = 5; private static final String IDMAP_DAEMON = "idmap2d"; @@ -274,20 +281,29 @@ class IdmapDaemon { } } - final long endMillis = SystemClock.uptimeMillis() + SERVICE_CONNECT_TIMEOUT_MS; + long uptimeMillis = SystemClock.uptimeMillis(); + final long endUptimeMillis = uptimeMillis + SERVICE_CONNECT_UPTIME_TIMEOUT_MS; + long walltimeMillis = SystemClock.elapsedRealtime(); + final long endWalltimeMillis = walltimeMillis + SERVICE_CONNECT_WALLTIME_TIMEOUT_MS; + do { final IBinder binder = ServiceManager.getService(IDMAP_SERVICE); if (binder != null) { binder.linkToDeath( - () -> Slog.w(TAG, String.format("service '%s' died", IDMAP_SERVICE)), 0); + () -> Slog.w(TAG, + TextUtils.formatSimple("service '%s' died", IDMAP_SERVICE)), 0); return binder; } SystemClock.sleep(SERVICE_CONNECT_INTERVAL_SLEEP_MS); - } while (SystemClock.uptimeMillis() <= endMillis); + } while ((uptimeMillis = SystemClock.uptimeMillis()) <= endUptimeMillis + && (walltimeMillis = SystemClock.elapsedRealtime()) <= endWalltimeMillis); throw new TimeoutException( - String.format("Failed to connect to '%s' in %d milliseconds", IDMAP_SERVICE, - SERVICE_CONNECT_TIMEOUT_MS)); + TextUtils.formatSimple("Failed to connect to '%s' in %d/%d ms (spent %d/%d ms)", + IDMAP_SERVICE, SERVICE_CONNECT_UPTIME_TIMEOUT_MS, + SERVICE_CONNECT_WALLTIME_TIMEOUT_MS, + uptimeMillis - endUptimeMillis + SERVICE_CONNECT_UPTIME_TIMEOUT_MS, + walltimeMillis - endWalltimeMillis + SERVICE_CONNECT_WALLTIME_TIMEOUT_MS)); } private static void stopIdmapService() { diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 5bd8ca63c3ff..186cf5e37003 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -1170,6 +1170,7 @@ final class InstallPackageHelper { @GuardedBy("mPm.mInstallLock") private void preparePackageLI(InstallRequest request) throws PrepareFailure { + final int[] allUsers = mPm.mUserManager.getUserIds(); final int installFlags = request.getInstallFlags(); final boolean onExternal = request.getVolumeUuid() != null; final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0); @@ -1445,7 +1446,7 @@ final class InstallPackageHelper { systemApp = ps.isSystem(); request.setOriginUsers(ps.queryUsersInstalledOrHasData( - mPm.mUserManager.getUserIds())); + allUsers)); } final int numGroups = ArrayUtils.size(parsedPackage.getPermissionGroups()); @@ -1703,7 +1704,6 @@ final class InstallPackageHelper { final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; - final int[] allUsers; final int[] installedUsers; final int[] uninstalledUsers; @@ -1796,7 +1796,6 @@ final class InstallPackageHelper { } // In case of rollback, remember per-user/profile install state - allUsers = mPm.mUserManager.getUserIds(); installedUsers = ps.queryInstalledUsers(allUsers, true); uninstalledUsers = ps.queryInstalledUsers(allUsers, false); @@ -2220,7 +2219,7 @@ final class InstallPackageHelper { final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName); if (ps != null) { installRequest.setNewUsers( - ps.queryInstalledUsers(mPm.mUserManager.getUserIds(), true)); + ps.queryInstalledUsers(allUsers, true)); ps.setUpdateAvailable(false /*updateAvailable*/); File appMetadataFile = new File(ps.getPath(), APP_METADATA_FILE_NAME); @@ -2327,7 +2326,7 @@ final class InstallPackageHelper { // Retrieve the overlays for shared libraries of the package. if (!ps.getPkgState().getUsesLibraryInfos().isEmpty()) { for (SharedLibraryWrapper sharedLib : ps.getPkgState().getUsesLibraryInfos()) { - for (int currentUserId : UserManagerService.getInstance().getUserIds()) { + for (int currentUserId : allUsers) { if (sharedLib.getType() != SharedLibraryInfo.TYPE_DYNAMIC) { // TODO(146804378): Support overlaying static shared libraries continue; @@ -2416,9 +2415,8 @@ final class InstallPackageHelper { } // Set install reason for users that are having the package newly installed. - final int[] allUsersList = mPm.mUserManager.getUserIds(); if (userId == UserHandle.USER_ALL) { - for (int currentUserId : allUsersList) { + for (int currentUserId : allUsers) { if (!previousUserIds.contains(currentUserId) && ps.getInstalled(currentUserId)) { ps.setInstallReason(installReason, currentUserId); @@ -2438,7 +2436,7 @@ final class InstallPackageHelper { } // Ensure that the uninstall reason is UNKNOWN for users with the package installed. - for (int currentUserId : allUsersList) { + for (int currentUserId : allUsers) { if (ps.getInstalled(currentUserId)) { ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, currentUserId); } diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 9b0fec2c757b..6b56b85938c2 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -161,6 +161,9 @@ import java.util.zip.ZipOutputStream; public class LauncherAppsService extends SystemService { private static final String WM_TRACE_DIR = "/data/misc/wmtrace/"; private static final String VC_FILE_SUFFIX = ".vc"; + // TODO(b/310027945): Update the intent name. + private static final String PS_SETTINGS_INTENT = + "com.android.settings.action.PRIVATE_SPACE_SETUP_FLOW"; private static final Set<PosixFilePermission> WM_TRACE_FILE_PERMISSIONS = Set.of( PosixFilePermission.OWNER_WRITE, @@ -1777,6 +1780,27 @@ public class LauncherAppsService extends SystemService { } } + @Override + public @Nullable IntentSender getPrivateSpaceSettingsIntent() { + if (!canAccessHiddenProfile(getCallingUid(), getCallingPid())) { + Slog.e(TAG, "Caller cannot access hidden profiles"); + return null; + } + final long identity = Binder.clearCallingIdentity(); + try { + Intent psSettingsIntent = new Intent(PS_SETTINGS_INTENT); + psSettingsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_CLEAR_TASK); + final PendingIntent pi = PendingIntent.getActivity(mContext, + /* requestCode */ 0, + psSettingsIntent, + PendingIntent.FLAG_IMMUTABLE | FLAG_UPDATE_CURRENT); + return pi == null ? null : pi.getIntentSender(); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + @Nullable private IntentSender buildAppMarketIntentSenderForUser(@NonNull UserHandle user) { Intent appMarketIntent = new Intent(Intent.ACTION_MAIN); diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index a600eeabf62b..c1ab3f9e3eb9 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -520,7 +520,7 @@ public class ShortcutService extends IShortcutService.Stub { mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock); mShortcutDumpFiles = new ShortcutDumpFiles(this); mIsAppSearchEnabled = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI, - SystemUiDeviceConfigFlags.SHORTCUT_APPSEARCH_INTEGRATION, true) + SystemUiDeviceConfigFlags.SHORTCUT_APPSEARCH_INTEGRATION, false) && !injectIsLowRamDevice(); if (onlyForPackageManagerApis) { diff --git a/services/core/java/com/android/server/policy/ModifierShortcutManager.java b/services/core/java/com/android/server/policy/ModifierShortcutManager.java index 539bb6b22ba2..3a79d0df4819 100644 --- a/services/core/java/com/android/server/policy/ModifierShortcutManager.java +++ b/services/core/java/com/android/server/policy/ModifierShortcutManager.java @@ -17,6 +17,7 @@ package com.android.server.policy; import android.annotation.SuppressLint; +import android.app.role.RoleManager; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; @@ -45,6 +46,8 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; /** * Manages quick launch shortcuts by: @@ -52,8 +55,8 @@ import java.io.IOException; * <li> Returning a shortcut-matching intent to clients * <li> Returning particular kind of application intent by special key. */ -class ModifierShortcutManager { - private static final String TAG = "WindowManager"; +public class ModifierShortcutManager { + private static final String TAG = "ModifierShortcutManager"; private static final String TAG_BOOKMARKS = "bookmarks"; private static final String TAG_BOOKMARK = "bookmark"; @@ -63,9 +66,13 @@ class ModifierShortcutManager { private static final String ATTRIBUTE_SHORTCUT = "shortcut"; private static final String ATTRIBUTE_CATEGORY = "category"; private static final String ATTRIBUTE_SHIFT = "shift"; + private static final String ATTRIBUTE_ROLE = "role"; private final SparseArray<Intent> mIntentShortcuts = new SparseArray<>(); private final SparseArray<Intent> mShiftShortcuts = new SparseArray<>(); + private final SparseArray<String> mRoleShortcuts = new SparseArray<String>(); + private final SparseArray<String> mShiftRoleShortcuts = new SparseArray<String>(); + private final Map<String, Intent> mRoleIntents = new HashMap<String, Intent>(); private LongSparseArray<IShortcutService> mShortcutKeyServices = new LongSparseArray<>(); @@ -76,10 +83,12 @@ class ModifierShortcutManager { * usage page. We don't support quite that many yet... */ static SparseArray<String> sApplicationLaunchKeyCategories; + static SparseArray<String> sApplicationLaunchKeyRoles; static { + sApplicationLaunchKeyRoles = new SparseArray<String>(); sApplicationLaunchKeyCategories = new SparseArray<String>(); - sApplicationLaunchKeyCategories.append( - KeyEvent.KEYCODE_EXPLORER, Intent.CATEGORY_APP_BROWSER); + sApplicationLaunchKeyRoles.append( + KeyEvent.KEYCODE_EXPLORER, RoleManager.ROLE_BROWSER); sApplicationLaunchKeyCategories.append( KeyEvent.KEYCODE_ENVELOPE, Intent.CATEGORY_APP_EMAIL); sApplicationLaunchKeyCategories.append( @@ -92,14 +101,25 @@ class ModifierShortcutManager { KeyEvent.KEYCODE_CALCULATOR, Intent.CATEGORY_APP_CALCULATOR); } + public static final String EXTRA_ROLE = + "com.android.server.policy.ModifierShortcutManager.EXTRA_ROLE"; + private final Context mContext; private final Handler mHandler; + private final RoleManager mRoleManager; + private final PackageManager mPackageManager; private boolean mSearchKeyShortcutPending = false; private boolean mConsumeSearchKeyUp = true; ModifierShortcutManager(Context context, Handler handler) { mContext = context; mHandler = handler; + mPackageManager = mContext.getPackageManager(); + mRoleManager = mContext.getSystemService(RoleManager.class); + mRoleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), + (String roleName, UserHandle user) -> { + mRoleIntents.remove(roleName); + }, UserHandle.ALL); loadShortcuts(); } @@ -141,14 +161,42 @@ class ModifierShortcutManager { shortcutChar = Character.toLowerCase(kcm.getDisplayLabel(keyCode)); if (shortcutChar != 0) { shortcutIntent = shortcutMap.get(shortcutChar); + + if (shortcutIntent == null) { + // Check for role based shortcut + String role = isShiftOn ? mShiftRoleShortcuts.get(shortcutChar) + : mRoleShortcuts.get(shortcutChar); + if (role != null) { + shortcutIntent = getRoleLaunchIntent(role); + } + } } } return shortcutIntent; } + private Intent getRoleLaunchIntent(String role) { + Intent intent = mRoleIntents.get(role); + if (intent == null) { + if (mRoleManager.isRoleAvailable(role)) { + String rolePackage = mRoleManager.getDefaultApplication(role); + if (rolePackage != null) { + intent = mPackageManager.getLaunchIntentForPackage(rolePackage); + intent.putExtra(EXTRA_ROLE, role); + mRoleIntents.put(role, intent); + } else { + Log.w(TAG, "No default application for role " + role); + } + } else { + Log.w(TAG, "Role " + role + " is not available."); + } + } + return intent; + } + private void loadShortcuts() { - PackageManager packageManager = mContext.getPackageManager(); + try { XmlResourceParser parser = mContext.getResources().getXml( com.android.internal.R.xml.bookmarks); @@ -170,29 +218,37 @@ class ModifierShortcutManager { String shortcutName = parser.getAttributeValue(null, ATTRIBUTE_SHORTCUT); String categoryName = parser.getAttributeValue(null, ATTRIBUTE_CATEGORY); String shiftName = parser.getAttributeValue(null, ATTRIBUTE_SHIFT); + String roleName = parser.getAttributeValue(null, ATTRIBUTE_ROLE); if (TextUtils.isEmpty(shortcutName)) { - Log.w(TAG, "Unable to get shortcut for: " + packageName + "/" + className); + Log.w(TAG, "Shortcut required for bookmark with category=" + categoryName + + " packageName=" + packageName + " className=" + className + + " role=" + roleName + "shiftName=" + shiftName); continue; } final int shortcutChar = shortcutName.charAt(0); final boolean isShiftShortcut = (shiftName != null && shiftName.equals("true")); - final Intent intent; if (packageName != null && className != null) { + if (roleName != null || categoryName != null) { + Log.w(TAG, "Cannot specify role or category when package and class" + + " are present for bookmark packageName=" + packageName + + " className=" + className + " shortcutChar=" + shortcutChar); + continue; + } ComponentName componentName = new ComponentName(packageName, className); try { - packageManager.getActivityInfo(componentName, + mPackageManager.getActivityInfo(componentName, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_UNINSTALLED_PACKAGES); } catch (PackageManager.NameNotFoundException e) { - String[] packages = packageManager.canonicalToCurrentPackageNames( + String[] packages = mPackageManager.canonicalToCurrentPackageNames( new String[] { packageName }); componentName = new ComponentName(packages[0], className); try { - packageManager.getActivityInfo(componentName, + mPackageManager.getActivityInfo(componentName, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_UNINSTALLED_PACKAGES); @@ -207,10 +263,25 @@ class ModifierShortcutManager { intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.setComponent(componentName); } else if (categoryName != null) { + if (roleName != null) { + Log.w(TAG, "Cannot specify role bookmark when category is present for" + + " bookmark shortcutChar=" + shortcutChar + + " category= " + categoryName); + continue; + } intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, categoryName); + } else if (roleName != null) { + // We can't resolve the role at the time of this file being parsed as the + // device hasn't finished booting, so we will look it up lazily. + if (isShiftShortcut) { + mShiftRoleShortcuts.put(shortcutChar, roleName); + } else { + mRoleShortcuts.put(shortcutChar, roleName); + } + continue; } else { Log.w(TAG, "Unable to add bookmark for shortcut " + shortcutName - + ": missing package/class or category attributes"); + + ": missing package/class, category or role attributes"); continue; } @@ -298,10 +369,17 @@ class ModifierShortcutManager { // Invoke shortcuts using Meta. metaState &= ~KeyEvent.META_META_MASK; } else { + Intent intent = null; // Handle application launch keys. + String role = sApplicationLaunchKeyRoles.get(keyCode); String category = sApplicationLaunchKeyCategories.get(keyCode); - if (category != null) { - Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category); + if (role != null) { + intent = getRoleLaunchIntent(role); + } else if (category != null) { + intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category); + } + + if (intent != null) { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { mContext.startActivityAsUser(intent, UserHandle.CURRENT); @@ -309,7 +387,7 @@ class ModifierShortcutManager { Slog.w(TAG, "Dropping application launch key because " + "the activity to which it is registered was not found: " + "keyCode=" + KeyEvent.keyCodeToString(keyCode) + "," - + " category=" + category); + + " category=" + category + " role=" + role); } logKeyboardShortcut(keyEvent, KeyboardLogEvent.getLogEventFromIntent(intent)); return true; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 428fca082f75..e9a7fe1371ac 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -6410,7 +6410,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private boolean performHapticFeedback(int effectId, boolean always, String reason) { return performHapticFeedback(Process.myUid(), mContext.getOpPackageName(), - effectId, always, reason); + effectId, always, reason, false /* fromIme */); } @Override @@ -6420,7 +6420,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override public boolean performHapticFeedback(int uid, String packageName, int effectId, - boolean always, String reason) { + boolean always, String reason, boolean fromIme) { if (!mVibrator.hasVibrator()) { return false; } @@ -6431,7 +6431,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } VibrationAttributes attrs = mHapticFeedbackVibrationProvider.getVibrationAttributesForHapticFeedback( - effectId, /* bypassVibrationIntensitySetting= */ always); + effectId, /* bypassVibrationIntensitySetting= */ always, fromIme); VibratorFrameworkStatsLogger.logPerformHapticsFeedbackIfKeyboard(uid, effectId); mVibrator.vibrate(uid, packageName, effect, reason, attrs); return true; diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index 2174fd62ea00..5956594acd26 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -1072,7 +1072,7 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { * Call from application to perform haptic feedback on its window. */ public boolean performHapticFeedback(int uid, String packageName, int effectId, - boolean always, String reason); + boolean always, String reason, boolean fromIme); /** * Called when we have started keeping the screen on because a window diff --git a/services/core/java/com/android/server/vibrator/GroupedAggregatedLogRecords.java b/services/core/java/com/android/server/vibrator/GroupedAggregatedLogRecords.java new file mode 100644 index 000000000000..7ee29016a58b --- /dev/null +++ b/services/core/java/com/android/server/vibrator/GroupedAggregatedLogRecords.java @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.vibrator; + +import android.os.SystemClock; +import android.util.IndentingPrintWriter; +import android.util.SparseArray; +import android.util.proto.ProtoOutputStream; + +import java.util.ArrayDeque; + +/** + * A generic grouped list of aggregated log records to be printed in dumpsys. + * + * <p>This can be used to dump history of operations or requests to the vibrator services, e.g. + * vibration requests grouped by usage or vibration parameters sent to the vibrator control service. + * + * @param <T> The type of log entries aggregated in this record. + */ +abstract class GroupedAggregatedLogRecords<T extends GroupedAggregatedLogRecords.SingleLogRecord> { + private final SparseArray<ArrayDeque<AggregatedLogRecord<T>>> mGroupedRecords; + private final int mSizeLimit; + private final int mAggregationTimeLimitMs; + + GroupedAggregatedLogRecords(int sizeLimit, int aggregationTimeLimitMs) { + mGroupedRecords = new SparseArray<>(); + mSizeLimit = sizeLimit; + mAggregationTimeLimitMs = aggregationTimeLimitMs; + } + + /** Prints a header to identify the group to be logged. */ + abstract void dumpGroupHeader(IndentingPrintWriter pw, int groupKey); + + /** Returns the {@link ProtoOutputStream} repeated field id to log records of this group. */ + abstract long findGroupKeyProtoFieldId(int groupKey); + + /** + * Adds given entry to this record list, dropping the oldest record if size limit was reached + * for its group. + * + * @param record The new {@link SingleLogRecord} to be recorded. + * @return The oldest {@link AggregatedLogRecord} entry being dropped from the group list if + * it's full, null otherwise. + */ + final synchronized AggregatedLogRecord<T> add(T record) { + int groupKey = record.getGroupKey(); + if (!mGroupedRecords.contains(groupKey)) { + mGroupedRecords.put(groupKey, new ArrayDeque<>(mSizeLimit)); + } + ArrayDeque<AggregatedLogRecord<T>> records = mGroupedRecords.get(groupKey); + if (mAggregationTimeLimitMs > 0 && !records.isEmpty()) { + AggregatedLogRecord<T> lastAggregatedRecord = records.getLast(); + if (lastAggregatedRecord.mayAggregate(record, mAggregationTimeLimitMs)) { + lastAggregatedRecord.record(record); + return null; + } + } + AggregatedLogRecord<T> removedRecord = null; + if (records.size() >= mSizeLimit) { + removedRecord = records.removeFirst(); + } + records.addLast(new AggregatedLogRecord<>(record)); + return removedRecord; + } + + final synchronized void dump(IndentingPrintWriter pw) { + for (int i = 0; i < mGroupedRecords.size(); i++) { + dumpGroupHeader(pw, mGroupedRecords.keyAt(i)); + pw.increaseIndent(); + for (AggregatedLogRecord<T> records : mGroupedRecords.valueAt(i)) { + records.dump(pw); + } + pw.decreaseIndent(); + pw.println(); + } + } + + final synchronized void dump(ProtoOutputStream proto) { + for (int i = 0; i < mGroupedRecords.size(); i++) { + long fieldId = findGroupKeyProtoFieldId(mGroupedRecords.keyAt(i)); + for (AggregatedLogRecord<T> records : mGroupedRecords.valueAt(i)) { + records.dump(proto, fieldId); + } + } + } + + /** + * Represents an aggregation of log record entries that can be printed in a compact manner. + * + * <p>The aggregation is controlled by a time limit on the difference between the creation time + * of two consecutive entries that {@link SingleLogRecord#mayAggregate}. + * + * @param <T> The type of log entries aggregated in this record. + */ + static final class AggregatedLogRecord<T extends SingleLogRecord> { + private final T mFirst; + private T mLatest; + private int mCount; + + AggregatedLogRecord(T record) { + mLatest = mFirst = record; + mCount = 1; + } + + T getLatest() { + return mLatest; + } + + synchronized boolean mayAggregate(T record, long timeLimitMs) { + long timeDeltaMs = Math.abs(mLatest.getCreateUptimeMs() - record.getCreateUptimeMs()); + return mLatest.mayAggregate(record) && timeDeltaMs < timeLimitMs; + } + + synchronized void record(T record) { + mLatest = record; + mCount++; + } + + synchronized void dump(IndentingPrintWriter pw) { + mFirst.dump(pw); + if (mCount == 1) { + return; + } + if (mCount > 2) { + pw.println("-> Skipping " + (mCount - 2) + " aggregated entries, latest:"); + } + mLatest.dump(pw); + } + + synchronized void dump(ProtoOutputStream proto, long fieldId) { + mFirst.dump(proto, fieldId); + if (mCount > 1) { + mLatest.dump(proto, fieldId); + } + } + } + + /** + * Represents a single log entry that can be grouped and aggregated for compact logging. + * + * <p>Entries are first grouped by an integer group key, and then aggregated with consecutive + * entries of same group within a limited timespan. + */ + interface SingleLogRecord { + + /** The group identifier for this record (e.g. vibration usage). */ + int getGroupKey(); + + /** + * The timestamp in millis that should be used for aggregation of close entries. + * + * <p>Should be {@link SystemClock#uptimeMillis()} to be used for calculations. + */ + long getCreateUptimeMs(); + + /** + * Returns true if this record can be aggregated with the given one (e.g. the represent the + * same vibration request from the same process client). + */ + boolean mayAggregate(SingleLogRecord record); + + /** Writes this record into given {@link IndentingPrintWriter}. */ + void dump(IndentingPrintWriter pw); + + /** Writes this record into given {@link ProtoOutputStream} field. */ + void dump(ProtoOutputStream proto, long fieldId); + } +} diff --git a/services/core/java/com/android/server/vibrator/HalVibration.java b/services/core/java/com/android/server/vibrator/HalVibration.java index 70e2e27a3bae..8f755f4ecec8 100644 --- a/services/core/java/com/android/server/vibrator/HalVibration.java +++ b/services/core/java/com/android/server/vibrator/HalVibration.java @@ -54,12 +54,18 @@ final class HalVibration extends Vibration { /** Vibration status. */ private Vibration.Status mStatus; + /** Reported scale values applied to the vibration effects. */ + private int mScaleLevel; + private float mAdaptiveScale; + HalVibration(@NonNull IBinder token, @NonNull CombinedVibration effect, @NonNull CallerInfo callerInfo) { super(token, callerInfo); mOriginalEffect = effect; mEffectToPlay = effect; mStatus = Vibration.Status.RUNNING; + mScaleLevel = VibrationScaler.SCALE_NONE; + mAdaptiveScale = VibrationScaler.ADAPTIVE_SCALE_NONE; } /** @@ -119,20 +125,24 @@ final class HalVibration extends Vibration { } /** - * Scales the {@link #getEffectToPlay()} and each fallback effect with a scaling transformation. - * - * @param scaler A {@link VibrationEffect.Transformation<Integer>} that takes one of the - * {@code VibrationAttributes.USAGE_*} as the modifier to scale the effect - * based on the user settings. + * Scales the {@link #getEffectToPlay()} and each fallback effect based on the vibration usage. */ - public void scaleEffects(VibrationEffect.Transformation<Integer> scaler) { + public void scaleEffects(VibrationScaler scaler) { int vibrationUsage = callerInfo.attrs.getUsage(); - CombinedVibration newEffect = mEffectToPlay.transform(scaler, vibrationUsage); + + // Save scale values for debugging purposes. + mScaleLevel = scaler.getScaleLevel(vibrationUsage); + mAdaptiveScale = scaler.getAdaptiveHapticsScale(vibrationUsage); + + // Scale all VibrationEffect instances in given CombinedVibration. + CombinedVibration newEffect = mEffectToPlay.transform(scaler::scale, vibrationUsage); if (!Objects.equals(mEffectToPlay, newEffect)) { mEffectToPlay = newEffect; } + + // Scale all fallback VibrationEffect instances that can be used by VibrationThread. for (int i = 0; i < mFallbacks.size(); i++) { - mFallbacks.setValueAt(i, scaler.transform(mFallbacks.valueAt(i), vibrationUsage)); + mFallbacks.setValueAt(i, scaler.scale(mFallbacks.valueAt(i), vibrationUsage)); } } @@ -171,7 +181,7 @@ final class HalVibration extends Vibration { CombinedVibration originalEffect = Objects.equals(mOriginalEffect, mEffectToPlay) ? null : mOriginalEffect; return new Vibration.DebugInfo(mStatus, stats, mEffectToPlay, originalEffect, - /* scale= */ 0, callerInfo); + mScaleLevel, mAdaptiveScale, callerInfo); } /** Return {@link VibrationStats.StatsInfo} with read-only metrics about this vibration. */ diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java b/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java index a34621642bcd..9756094e5af0 100644 --- a/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java +++ b/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java @@ -19,8 +19,8 @@ package com.android.server.vibrator; import android.annotation.Nullable; import android.content.res.Resources; import android.os.VibrationEffect; -import android.os.vibrator.Flags; import android.os.VibratorInfo; +import android.os.vibrator.Flags; import android.os.vibrator.persistence.ParsedVibration; import android.os.vibrator.persistence.VibrationXmlParser; import android.text.TextUtils; @@ -73,8 +73,6 @@ import java.io.IOException; * * <p>After a successful parsing of the customization XML file, it returns a {@link SparseArray} * that maps each customized haptic feedback effect ID to its respective {@link VibrationEffect}. - * - * @hide */ final class HapticFeedbackCustomization { private static final String TAG = "HapticFeedbackCustomization"; @@ -104,8 +102,6 @@ final class HapticFeedbackCustomization { * @throws {@link IOException} if an IO error occurs while parsing the customization XML. * @throws {@link CustomizationParserException} for any non-IO error that occurs when parsing * the XML, like an invalid XML content or an invalid haptic feedback constant. - * - * @hide */ @Nullable static SparseArray<VibrationEffect> loadVibrations(Resources res, VibratorInfo vibratorInfo) @@ -202,8 +198,6 @@ final class HapticFeedbackCustomization { /** * Represents an error while parsing a haptic feedback customization XML. - * - * @hide */ static final class CustomizationParserException extends Exception { private CustomizationParserException(String message) { diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java index 519acec2f7b4..96f045d7e258 100644 --- a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java +++ b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java @@ -34,8 +34,6 @@ import java.io.PrintWriter; /** * Provides the {@link VibrationEffect} and {@link VibrationAttributes} for haptic feedback. - * - * @hide */ public final class HapticFeedbackVibrationProvider { private static final String TAG = "HapticFeedbackVibrationProvider"; @@ -58,17 +56,14 @@ public final class HapticFeedbackVibrationProvider { private float mKeyboardVibrationFixedAmplitude; - /** @hide */ public HapticFeedbackVibrationProvider(Resources res, Vibrator vibrator) { this(res, vibrator.getInfo()); } - /** @hide */ public HapticFeedbackVibrationProvider(Resources res, VibratorInfo vibratorInfo) { this(res, vibratorInfo, loadHapticCustomizations(res, vibratorInfo)); } - /** @hide */ @VisibleForTesting HapticFeedbackVibrationProvider( Resources res, VibratorInfo vibratorInfo, @@ -190,10 +185,11 @@ public final class HapticFeedbackVibrationProvider { * to get. * @param bypassVibrationIntensitySetting {@code true} if the returned attribute should bypass * vibration intensity settings. {@code false} otherwise. + * @param fromIme the haptic feedback is performed from an IME. * @return the {@link VibrationAttributes} that should be used for the provided haptic feedback. */ public VibrationAttributes getVibrationAttributesForHapticFeedback( - int effectId, boolean bypassVibrationIntensitySetting) { + int effectId, boolean bypassVibrationIntensitySetting, boolean fromIme) { VibrationAttributes attrs; switch (effectId) { case HapticFeedbackConstants.EDGE_SQUEEZE: @@ -209,7 +205,7 @@ public final class HapticFeedbackVibrationProvider { break; case HapticFeedbackConstants.KEYBOARD_TAP: case HapticFeedbackConstants.KEYBOARD_RELEASE: - attrs = createKeyboardVibrationAttributes(); + attrs = createKeyboardVibrationAttributes(fromIme); break; default: attrs = TOUCH_VIBRATION_ATTRIBUTES; @@ -222,7 +218,7 @@ public final class HapticFeedbackVibrationProvider { if (shouldBypassInterruptionPolicy(effectId)) { flags |= VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY; } - if (shouldBypassIntensityScale(effectId)) { + if (shouldBypassIntensityScale(effectId, fromIme)) { flags |= VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE; } @@ -337,9 +333,9 @@ public final class HapticFeedbackVibrationProvider { /* fallbackForPredefinedEffect= */ predefinedEffectFallback); } - private boolean shouldBypassIntensityScale(int effectId) { - if (!Flags.keyboardCategoryEnabled() || mKeyboardVibrationFixedAmplitude < 0) { - // shouldn't bypass if not support keyboard category or no fixed amplitude + private boolean shouldBypassIntensityScale(int effectId, boolean isIme) { + if (!Flags.keyboardCategoryEnabled() || mKeyboardVibrationFixedAmplitude < 0 || !isIme) { + // Shouldn't bypass if not support keyboard category, no fixed amplitude or not an IME. return false; } switch (effectId) { @@ -353,8 +349,9 @@ public final class HapticFeedbackVibrationProvider { return false; } - private static VibrationAttributes createKeyboardVibrationAttributes() { - if (!Flags.keyboardCategoryEnabled()) { + private VibrationAttributes createKeyboardVibrationAttributes(boolean fromIme) { + // Use touch attribute when the keyboard category is disable or it's not from an IME. + if (!Flags.keyboardCategoryEnabled() || !fromIme) { return TOUCH_VIBRATION_ATTRIBUTES; } diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java index b2e808ac8e95..b490f57a936e 100644 --- a/services/core/java/com/android/server/vibrator/Vibration.java +++ b/services/core/java/com/android/server/vibrator/Vibration.java @@ -218,12 +218,13 @@ abstract class Vibration { private final long mDurationMs; @Nullable private final CombinedVibration mOriginalEffect; - private final float mScale; + private final int mScaleLevel; + private final float mAdaptiveScale; private final Status mStatus; DebugInfo(Status status, VibrationStats stats, @Nullable CombinedVibration playedEffect, - @Nullable CombinedVibration originalEffect, float scale, - @NonNull CallerInfo callerInfo) { + @Nullable CombinedVibration originalEffect, int scaleLevel, + float adaptiveScale, @NonNull CallerInfo callerInfo) { Objects.requireNonNull(callerInfo); mCreateTime = stats.getCreateTimeDebug(); mStartTime = stats.getStartTimeDebug(); @@ -231,7 +232,8 @@ abstract class Vibration { mDurationMs = stats.getDurationDebug(); mPlayedEffect = playedEffect; mOriginalEffect = originalEffect; - mScale = scale; + mScaleLevel = scaleLevel; + mAdaptiveScale = adaptiveScale; mCallerInfo = callerInfo; mStatus = status; } @@ -246,7 +248,8 @@ abstract class Vibration { + ", status: " + mStatus.name().toLowerCase(Locale.ROOT) + ", playedEffect: " + mPlayedEffect + ", originalEffect: " + mOriginalEffect - + ", scale: " + String.format(Locale.ROOT, "%.2f", mScale) + + ", scaleLevel: " + VibrationScaler.scaleLevelToString(mScaleLevel) + + ", adaptiveScale: " + String.format(Locale.ROOT, "%.2f", mAdaptiveScale) + ", callerInfo: " + mCallerInfo; } @@ -259,26 +262,39 @@ abstract class Vibration { void dumpCompact(IndentingPrintWriter pw) { boolean isExternalVibration = mPlayedEffect == null; String timingsStr = String.format(Locale.ROOT, - "%s | %8s | %20s | duration: %5dms | start: %12s | end: %10s", + "%s | %8s | %20s | duration: %5dms | start: %12s | end: %12s", DEBUG_DATE_TIME_FORMAT.format(new Date(mCreateTime)), isExternalVibration ? "external" : "effect", mStatus.name().toLowerCase(Locale.ROOT), mDurationMs, mStartTime == 0 ? "" : DEBUG_TIME_FORMAT.format(new Date(mStartTime)), mEndTime == 0 ? "" : DEBUG_TIME_FORMAT.format(new Date(mEndTime))); - String callerInfoStr = String.format(Locale.ROOT, - " | %s (uid=%d, deviceId=%d) | usage: %s (audio=%s) | flags: %s | reason: %s", - mCallerInfo.opPkg, mCallerInfo.uid, mCallerInfo.deviceId, - mCallerInfo.attrs.usageToString(), - AudioAttributes.usageToString(mCallerInfo.attrs.getAudioUsage()), + String paramStr = String.format(Locale.ROOT, + " | scale: %8s (adaptive=%.2f) | flags: %4s | usage: %s", + VibrationScaler.scaleLevelToString(mScaleLevel), mAdaptiveScale, Long.toBinaryString(mCallerInfo.attrs.getFlags()), - mCallerInfo.reason); + mCallerInfo.attrs.usageToString()); + // Optional, most vibrations have category unknown so skip them to simplify the logs + String categoryStr = + mCallerInfo.attrs.getCategory() != VibrationAttributes.CATEGORY_UNKNOWN + ? " | category=" + VibrationAttributes.categoryToString( + mCallerInfo.attrs.getCategory()) + : ""; + // Optional, most vibrations should not be defined via AudioAttributes + // so skip them to simplify the logs + String audioUsageStr = + mCallerInfo.attrs.getOriginalAudioUsage() != AudioAttributes.USAGE_UNKNOWN + ? " | audioUsage=" + AudioAttributes.usageToString( + mCallerInfo.attrs.getOriginalAudioUsage()) + : ""; + String callerStr = String.format(Locale.ROOT, + " | %s (uid=%d, deviceId=%d) | reason: %s", + mCallerInfo.opPkg, mCallerInfo.uid, mCallerInfo.deviceId, mCallerInfo.reason); String effectStr = String.format(Locale.ROOT, - " | played: %s | original: %s | scale: %.2f", + " | played: %s | original: %s", mPlayedEffect == null ? null : mPlayedEffect.toDebugString(), - mOriginalEffect == null ? null : mOriginalEffect.toDebugString(), - mScale); - pw.println(timingsStr + callerInfoStr + effectStr); + mOriginalEffect == null ? null : mOriginalEffect.toDebugString()); + pw.println(timingsStr + paramStr + categoryStr + audioUsageStr + callerStr + effectStr); } /** Write this info into given {@link PrintWriter}. */ @@ -293,7 +309,8 @@ abstract class Vibration { + (mEndTime == 0 ? null : DEBUG_DATE_TIME_FORMAT.format(new Date(mEndTime)))); pw.println("playedEffect = " + mPlayedEffect); pw.println("originalEffect = " + mOriginalEffect); - pw.println("scale = " + String.format(Locale.ROOT, "%.2f", mScale)); + pw.println("scale = " + VibrationScaler.scaleLevelToString(mScaleLevel)); + pw.println("adaptiveScale = " + String.format(Locale.ROOT, "%.2f", mAdaptiveScale)); pw.println("callerInfo = " + mCallerInfo); pw.decreaseIndent(); } @@ -310,6 +327,7 @@ abstract class Vibration { final VibrationAttributes attrs = mCallerInfo.attrs; proto.write(VibrationAttributesProto.USAGE, attrs.getUsage()); proto.write(VibrationAttributesProto.AUDIO_USAGE, attrs.getAudioUsage()); + proto.write(VibrationAttributesProto.CATEGORY, attrs.getCategory()); proto.write(VibrationAttributesProto.FLAGS, attrs.getFlags()); proto.end(attrsToken); diff --git a/services/core/java/com/android/server/vibrator/VibrationScaler.java b/services/core/java/com/android/server/vibrator/VibrationScaler.java index 5d17884c769b..d9ca71003aae 100644 --- a/services/core/java/com/android/server/vibrator/VibrationScaler.java +++ b/services/core/java/com/android/server/vibrator/VibrationScaler.java @@ -26,10 +26,14 @@ import android.os.Vibrator; import android.os.vibrator.Flags; import android.os.vibrator.PrebakedSegment; import android.os.vibrator.VibrationEffectSegment; +import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.SparseArray; +import android.util.proto.ProtoOutputStream; +import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Locale; /** Controls vibration scaling. */ final class VibrationScaler { @@ -37,13 +41,12 @@ final class VibrationScaler { // Scale levels. Each level, except MUTE, is defined as the delta between the current setting // and the default intensity for that type of vibration (i.e. current - default). - private static final int SCALE_VERY_LOW = - ExternalVibrationScale.ScaleLevel.SCALE_VERY_LOW; // -2 - private static final int SCALE_LOW = ExternalVibrationScale.ScaleLevel.SCALE_LOW; // -1 - private static final int SCALE_NONE = ExternalVibrationScale.ScaleLevel.SCALE_NONE; // 0 - private static final int SCALE_HIGH = ExternalVibrationScale.ScaleLevel.SCALE_HIGH; // 1 - private static final int SCALE_VERY_HIGH = - ExternalVibrationScale.ScaleLevel.SCALE_VERY_HIGH; // 2 + static final int SCALE_VERY_LOW = ExternalVibrationScale.ScaleLevel.SCALE_VERY_LOW; // -2 + static final int SCALE_LOW = ExternalVibrationScale.ScaleLevel.SCALE_LOW; // -1 + static final int SCALE_NONE = ExternalVibrationScale.ScaleLevel.SCALE_NONE; // 0 + static final int SCALE_HIGH = ExternalVibrationScale.ScaleLevel.SCALE_HIGH; // 1 + static final int SCALE_VERY_HIGH = ExternalVibrationScale.ScaleLevel.SCALE_VERY_HIGH; // 2 + static final float ADAPTIVE_SCALE_NONE = 1f; // Scale factors for each level. private static final float SCALE_FACTOR_VERY_LOW = 0.6f; @@ -52,6 +55,8 @@ final class VibrationScaler { private static final float SCALE_FACTOR_HIGH = 1.2f; private static final float SCALE_FACTOR_VERY_HIGH = 1.4f; + private static final ScaleLevel SCALE_LEVEL_NONE = new ScaleLevel(SCALE_FACTOR_NONE); + // A mapping from the intensity adjustment to the scaling to apply, where the intensity // adjustment is defined as the delta between the default intensity level and the user selected // intensity level. It's important that we apply the scaling on the delta between the two so @@ -69,7 +74,7 @@ final class VibrationScaler { mScaleLevels = new SparseArray<>(); mScaleLevels.put(SCALE_VERY_LOW, new ScaleLevel(SCALE_FACTOR_VERY_LOW)); mScaleLevels.put(SCALE_LOW, new ScaleLevel(SCALE_FACTOR_LOW)); - mScaleLevels.put(SCALE_NONE, new ScaleLevel(SCALE_FACTOR_NONE)); + mScaleLevels.put(SCALE_NONE, SCALE_LEVEL_NONE); mScaleLevels.put(SCALE_HIGH, new ScaleLevel(SCALE_FACTOR_HIGH)); mScaleLevels.put(SCALE_VERY_HIGH, new ScaleLevel(SCALE_FACTOR_VERY_HIGH)); } @@ -87,25 +92,24 @@ final class VibrationScaler { * @param usageHint one of VibrationAttributes.USAGE_* * @return one of ExternalVibrationScale.ScaleLevel.SCALE_* */ - public int getExternalVibrationScaleLevel(int usageHint) { + public int getScaleLevel(int usageHint) { int defaultIntensity = mSettingsController.getDefaultIntensity(usageHint); int currentIntensity = mSettingsController.getCurrentIntensity(usageHint); - if (currentIntensity == Vibrator.VIBRATION_INTENSITY_OFF) { // Bypassing user settings, or it has changed between checking and scaling. Use default. return SCALE_NONE; } int scaleLevel = currentIntensity - defaultIntensity; - if (scaleLevel >= SCALE_VERY_LOW && scaleLevel <= SCALE_VERY_HIGH) { return scaleLevel; - } else { - // Something about our scaling has gone wrong, so just play with no scaling. - Slog.w(TAG, "Error in scaling calculations, ended up with invalid scale level " - + scaleLevel + " for vibration with usage " + usageHint); - return SCALE_NONE; } + + // Something about our scaling has gone wrong, so just play with no scaling. + Slog.wtf(TAG, "Error in scaling calculations, ended up with invalid scale level " + + scaleLevel + " for vibration with usage " + usageHint); + + return SCALE_NONE; } /** @@ -117,11 +121,9 @@ final class VibrationScaler { * @return The adaptive haptics scale. */ public float getAdaptiveHapticsScale(int usageHint) { - if (shouldApplyAdaptiveHapticsScale(usageHint)) { - return mAdaptiveHapticsScales.get(usageHint); - } - - return 1f; // no scaling + return Flags.adaptiveHapticsEnabled() + ? mAdaptiveHapticsScales.get(usageHint, ADAPTIVE_SCALE_NONE) + : ADAPTIVE_SCALE_NONE; } /** @@ -140,21 +142,16 @@ final class VibrationScaler { return effect; } - int defaultIntensity = mSettingsController.getDefaultIntensity(usageHint); - int currentIntensity = mSettingsController.getCurrentIntensity(usageHint); - - if (currentIntensity == Vibrator.VIBRATION_INTENSITY_OFF) { - // Bypassing user settings, or it has changed between checking and scaling. Use default. - currentIntensity = defaultIntensity; - } - - int newEffectStrength = intensityToEffectStrength(currentIntensity); - ScaleLevel scaleLevel = mScaleLevels.get(currentIntensity - defaultIntensity); + int newEffectStrength = getEffectStrength(usageHint); + ScaleLevel scaleLevel = mScaleLevels.get(getScaleLevel(usageHint)); + float adaptiveScale = getAdaptiveHapticsScale(usageHint); if (scaleLevel == null) { // Something about our scaling has gone wrong, so just play with no scaling. - Slog.e(TAG, "No configured scaling level!" - + " (current=" + currentIntensity + ", default= " + defaultIntensity + ")"); + Slog.e(TAG, "No configured scaling level found! (current=" + + mSettingsController.getCurrentIntensity(usageHint) + ", default= " + + mSettingsController.getDefaultIntensity(usageHint) + ")"); + scaleLevel = SCALE_LEVEL_NONE; } VibrationEffect.Composed composedEffect = (VibrationEffect.Composed) effect; @@ -162,20 +159,11 @@ final class VibrationScaler { new ArrayList<>(composedEffect.getSegments()); int segmentCount = segments.size(); for (int i = 0; i < segmentCount; i++) { - VibrationEffectSegment segment = segments.get(i); - segment = segment.resolve(mDefaultVibrationAmplitude) - .applyEffectStrength(newEffectStrength); - if (scaleLevel != null) { - segment = segment.scale(scaleLevel.factor); - } - - // If adaptive haptics scaling is available for this usage, apply it to the segment. - if (shouldApplyAdaptiveHapticsScale(usageHint)) { - float adaptiveScale = mAdaptiveHapticsScales.get(usageHint); - segment = segment.scaleLinearly(adaptiveScale); - } - - segments.set(i, segment); + segments.set(i, + segments.get(i).resolve(mDefaultVibrationAmplitude) + .applyEffectStrength(newEffectStrength) + .scale(scaleLevel.factor) + .scaleLinearly(adaptiveScale)); } if (segments.equals(composedEffect.getSegments())) { // No segment was updated, return original effect. @@ -197,15 +185,7 @@ final class VibrationScaler { * updated effect strength */ public PrebakedSegment scale(PrebakedSegment prebaked, int usageHint) { - int currentIntensity = mSettingsController.getCurrentIntensity(usageHint); - - if (currentIntensity == Vibrator.VIBRATION_INTENSITY_OFF) { - // Bypassing user settings, or it has changed between checking and scaling. Use default. - currentIntensity = mSettingsController.getDefaultIntensity(usageHint); - } - - int newEffectStrength = intensityToEffectStrength(currentIntensity); - return prebaked.applyEffectStrength(newEffectStrength); + return prebaked.applyEffectStrength(getEffectStrength(usageHint)); } /** @@ -213,8 +193,6 @@ final class VibrationScaler { * * @param usageHint one of VibrationAttributes.USAGE_*. * @param scale The scaling factor that should be applied to vibrations of this usage. - * - * @hide */ public void updateAdaptiveHapticsScale(@VibrationAttributes.Usage int usageHint, float scale) { mAdaptiveHapticsScales.put(usageHint, scale); @@ -224,24 +202,68 @@ final class VibrationScaler { * Removes the usage from the cached adaptive haptics scales list. * * @param usageHint one of VibrationAttributes.USAGE_*. - * - * @hide */ public void removeAdaptiveHapticsScale(@VibrationAttributes.Usage int usageHint) { mAdaptiveHapticsScales.remove(usageHint); } - /** - * Removes all cached adaptive haptics scales. - * - * @hide - */ + /** Removes all cached adaptive haptics scales. */ public void clearAdaptiveHapticsScales() { mAdaptiveHapticsScales.clear(); } - private boolean shouldApplyAdaptiveHapticsScale(int usageHint) { - return Flags.adaptiveHapticsEnabled() && mAdaptiveHapticsScales.contains(usageHint); + /** Write current settings into given {@link PrintWriter}. */ + void dump(IndentingPrintWriter pw) { + pw.println("VibrationScaler:"); + pw.increaseIndent(); + pw.println("defaultVibrationAmplitude = " + mDefaultVibrationAmplitude); + + pw.println("ScaleLevels:"); + pw.increaseIndent(); + for (int i = 0; i < mScaleLevels.size(); i++) { + int scaleLevelKey = mScaleLevels.keyAt(i); + ScaleLevel scaleLevel = mScaleLevels.valueAt(i); + pw.println(scaleLevelToString(scaleLevelKey) + " = " + scaleLevel); + } + pw.decreaseIndent(); + + pw.println("AdaptiveHapticsScales:"); + pw.increaseIndent(); + for (int i = 0; i < mAdaptiveHapticsScales.size(); i++) { + int usage = mAdaptiveHapticsScales.keyAt(i); + float scale = mAdaptiveHapticsScales.valueAt(i); + pw.println(VibrationAttributes.usageToString(usage) + + " = " + String.format(Locale.ROOT, "%.2f", scale)); + } + pw.decreaseIndent(); + + pw.decreaseIndent(); + } + + /** Write current settings into given {@link ProtoOutputStream}. */ + void dump(ProtoOutputStream proto) { + proto.write(VibratorManagerServiceDumpProto.DEFAULT_VIBRATION_AMPLITUDE, + mDefaultVibrationAmplitude); + } + + @Override + public String toString() { + return "VibrationScaler{" + + "mScaleLevels=" + mScaleLevels + + ", mDefaultVibrationAmplitude=" + mDefaultVibrationAmplitude + + ", mAdaptiveHapticsScales=" + mAdaptiveHapticsScales + + '}'; + } + + private int getEffectStrength(int usageHint) { + int currentIntensity = mSettingsController.getCurrentIntensity(usageHint); + + if (currentIntensity == Vibrator.VIBRATION_INTENSITY_OFF) { + // Bypassing user settings, or it has changed between checking and scaling. Use default. + currentIntensity = mSettingsController.getDefaultIntensity(usageHint); + } + + return intensityToEffectStrength(currentIntensity); } /** Mapping of Vibrator.VIBRATION_INTENSITY_* values to {@link EffectStrength}. */ @@ -259,6 +281,17 @@ final class VibrationScaler { } } + static String scaleLevelToString(int scaleLevel) { + return switch (scaleLevel) { + case SCALE_VERY_LOW -> "VERY_LOW"; + case SCALE_LOW -> "LOW"; + case SCALE_NONE -> "NONE"; + case SCALE_HIGH -> "HIGH"; + case SCALE_VERY_HIGH -> "VERY_HIGH"; + default -> String.valueOf(scaleLevel); + }; + } + /** Represents the scale that must be applied to a vibration effect intensity. */ private static final class ScaleLevel { public final float factor; diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java index 99ce3e2fb740..5b77433fa6d9 100644 --- a/services/core/java/com/android/server/vibrator/VibrationSettings.java +++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java @@ -386,7 +386,6 @@ final class VibrationSettings { * Returns the duration, in milliseconds, that the vibrator control service will wait for new * vibration params. * @return The request vibration params timeout in milliseconds. - * @hide */ public int getRequestVibrationParamsTimeoutMs() { return mVibrationConfig.getRequestVibrationParamsTimeoutMs(); @@ -645,11 +644,16 @@ final class VibrationSettings { .append("), "); } vibrationIntensitiesString.append('}'); + String keyboardVibrationOnString = mKeyboardVibrationOn + + " (default: " + mVibrationConfig.isDefaultKeyboardVibrationEnabled() + ")"; return "VibrationSettings{" + "mVibratorConfig=" + mVibrationConfig + + ", mVibrateOn=" + mVibrateOn + + ", mKeyboardVibrationOn=" + keyboardVibrationOnString + ", mVibrateInputDevices=" + mVibrateInputDevices + ", mBatterySaverMode=" + mBatterySaverMode - + ", mVibrateOn=" + mVibrateOn + + ", mRingerMode=" + ringerModeToString(mRingerMode) + + ", mOnWirelessCharger=" + mOnWirelessCharger + ", mVibrationIntensities=" + vibrationIntensitiesString + ", mProcStatesCache=" + mUidObserver.mProcStatesCache + '}'; @@ -658,32 +662,40 @@ final class VibrationSettings { /** Write current settings into given {@link PrintWriter}. */ void dump(IndentingPrintWriter pw) { - pw.println("VibrationSettings:"); - pw.increaseIndent(); - pw.println("vibrateOn = " + mVibrateOn); - pw.println("vibrateInputDevices = " + mVibrateInputDevices); - pw.println("batterySaverMode = " + mBatterySaverMode); - pw.println("VibrationIntensities:"); + synchronized (mLock) { + pw.println("VibrationSettings:"); + pw.increaseIndent(); + pw.println("vibrateOn = " + mVibrateOn); + pw.println("keyboardVibrationOn = " + mKeyboardVibrationOn + + ", default: " + mVibrationConfig.isDefaultKeyboardVibrationEnabled()); + pw.println("vibrateInputDevices = " + mVibrateInputDevices); + pw.println("batterySaverMode = " + mBatterySaverMode); + pw.println("ringerMode = " + ringerModeToString(mRingerMode)); + pw.println("onWirelessCharger = " + mOnWirelessCharger); + pw.println("processStateCache size = " + mUidObserver.mProcStatesCache.size()); + + pw.println("VibrationIntensities:"); + pw.increaseIndent(); + for (int i = 0; i < mCurrentVibrationIntensities.size(); i++) { + int usage = mCurrentVibrationIntensities.keyAt(i); + int intensity = mCurrentVibrationIntensities.valueAt(i); + pw.println(VibrationAttributes.usageToString(usage) + " = " + + intensityToString(intensity) + + ", default: " + intensityToString(getDefaultIntensity(usage))); + } + pw.decreaseIndent(); - pw.increaseIndent(); - for (int i = 0; i < mCurrentVibrationIntensities.size(); i++) { - int usage = mCurrentVibrationIntensities.keyAt(i); - int intensity = mCurrentVibrationIntensities.valueAt(i); - pw.println(VibrationAttributes.usageToString(usage) + " = " - + intensityToString(intensity) - + ", default: " + intensityToString(getDefaultIntensity(usage))); + mVibrationConfig.dumpWithoutDefaultSettings(pw); + pw.decreaseIndent(); } - pw.decreaseIndent(); - - mVibrationConfig.dumpWithoutDefaultSettings(pw); - pw.println("processStateCache = " + mUidObserver.mProcStatesCache); - pw.decreaseIndent(); } /** Write current settings into given {@link ProtoOutputStream}. */ void dump(ProtoOutputStream proto) { synchronized (mLock) { proto.write(VibratorManagerServiceDumpProto.VIBRATE_ON, mVibrateOn); + proto.write(VibratorManagerServiceDumpProto.KEYBOARD_VIBRATION_ON, + mKeyboardVibrationOn); proto.write(VibratorManagerServiceDumpProto.LOW_POWER_MODE, mBatterySaverMode); proto.write(VibratorManagerServiceDumpProto.ALARM_INTENSITY, getCurrentIntensity(USAGE_ALARM)); @@ -723,18 +735,22 @@ final class VibrationSettings { } private static String intensityToString(int intensity) { - switch (intensity) { - case Vibrator.VIBRATION_INTENSITY_OFF: - return "OFF"; - case Vibrator.VIBRATION_INTENSITY_LOW: - return "LOW"; - case Vibrator.VIBRATION_INTENSITY_MEDIUM: - return "MEDIUM"; - case Vibrator.VIBRATION_INTENSITY_HIGH: - return "HIGH"; - default: - return "UNKNOWN INTENSITY " + intensity; - } + return switch (intensity) { + case Vibrator.VIBRATION_INTENSITY_OFF -> "OFF"; + case Vibrator.VIBRATION_INTENSITY_LOW -> "LOW"; + case Vibrator.VIBRATION_INTENSITY_MEDIUM -> "MEDIUM"; + case Vibrator.VIBRATION_INTENSITY_HIGH -> "HIGH"; + default -> "UNKNOWN INTENSITY " + intensity; + }; + } + + private static String ringerModeToString(int ringerMode) { + return switch (ringerMode) { + case AudioManager.RINGER_MODE_SILENT -> "silent"; + case AudioManager.RINGER_MODE_VIBRATE -> "vibrate"; + case AudioManager.RINGER_MODE_NORMAL -> "normal"; + default -> String.valueOf(ringerMode); + }; } @VibrationIntensity diff --git a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java index f6af9ad991ff..f510b4e8ab30 100644 --- a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java +++ b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java @@ -161,7 +161,7 @@ final class VibrationStepConductor implements IBinder.DeathRecipient { waitForVibrationParamsIfRequired(); } // Scale resolves the default amplitudes from the effect before scaling them. - mVibration.scaleEffects(mVibrationScaler::scale); + mVibration.scaleEffects(mVibrationScaler); } else { mVibration.resolveEffects(mVibrationScaler.getDefaultVibrationAmplitude()); } diff --git a/services/core/java/com/android/server/vibrator/VibratorControlService.java b/services/core/java/com/android/server/vibrator/VibratorControlService.java index 17a9e3330375..ec3d99b24656 100644 --- a/services/core/java/com/android/server/vibrator/VibratorControlService.java +++ b/services/core/java/com/android/server/vibrator/VibratorControlService.java @@ -30,6 +30,7 @@ import static android.os.VibrationAttributes.USAGE_UNKNOWN; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; +import android.content.Context; import android.frameworks.vibrator.IVibratorControlService; import android.frameworks.vibrator.IVibratorController; import android.frameworks.vibrator.ScaleParam; @@ -37,27 +38,38 @@ import android.frameworks.vibrator.VibrationParam; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; +import android.os.SystemClock; import android.os.VibrationAttributes; +import android.os.VibrationEffect; +import android.util.IndentingPrintWriter; +import android.util.IntArray; import android.util.Slog; +import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; import java.util.Objects; import java.util.concurrent.CompletableFuture; /** * Implementation of {@link IVibratorControlService} which allows the registration of * {@link IVibratorController} to set and receive vibration params. - * - * @hide */ -public final class VibratorControlService extends IVibratorControlService.Stub { +final class VibratorControlService extends IVibratorControlService.Stub { private static final String TAG = "VibratorControlService"; private static final int UNRECOGNIZED_VIBRATION_TYPE = -1; private static final int NO_SCALE = -1; + private static final SimpleDateFormat DEBUG_DATE_TIME_FORMAT = + new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); + + private final VibrationParamsRecords mVibrationParamsRecords; private final VibratorControllerHolder mVibratorControllerHolder; private final VibrationScaler mVibrationScaler; private final Object mLock; @@ -68,25 +80,32 @@ public final class VibratorControlService extends IVibratorControlService.Stub { @GuardedBy("mLock") private IBinder mRequestVibrationParamsToken; - public VibratorControlService(VibratorControllerHolder vibratorControllerHolder, - VibrationScaler vibrationScaler, VibrationSettings vibrationSettings, Object lock) { + VibratorControlService(Context context, + VibratorControllerHolder vibratorControllerHolder, VibrationScaler vibrationScaler, + VibrationSettings vibrationSettings, Object lock) { mVibratorControllerHolder = vibratorControllerHolder; mVibrationScaler = vibrationScaler; mLock = lock; mRequestVibrationParamsForUsages = vibrationSettings.getRequestVibrationParamsForUsages(); + + int dumpSizeLimit = context.getResources().getInteger( + com.android.internal.R.integer.config_previousVibrationsDumpSizeLimit); + int dumpAggregationTimeLimit = context.getResources().getInteger( + com.android.internal.R.integer + .config_previousVibrationsDumpAggregationTimeMillisLimit); + mVibrationParamsRecords = + new VibrationParamsRecords(dumpSizeLimit, dumpAggregationTimeLimit); } @Override - public void registerVibratorController(IVibratorController controller) - throws RemoteException { + public void registerVibratorController(IVibratorController controller) { synchronized (mLock) { mVibratorControllerHolder.setVibratorController(controller); } } @Override - public void unregisterVibratorController(@NonNull IVibratorController controller) - throws RemoteException { + public void unregisterVibratorController(@NonNull IVibratorController controller) { Objects.requireNonNull(controller); synchronized (mLock) { @@ -110,7 +129,7 @@ public final class VibratorControlService extends IVibratorControlService.Stub { @Override public void setVibrationParams(@SuppressLint("ArrayReturn") VibrationParam[] params, - @NonNull IVibratorController token) throws RemoteException { + @NonNull IVibratorController token) { Objects.requireNonNull(token); synchronized (mLock) { @@ -128,12 +147,12 @@ public final class VibratorControlService extends IVibratorControlService.Stub { } updateAdaptiveHapticsScales(params); + recordUpdateVibrationParams(params, /* fromRequest= */ false); } } @Override - public void clearVibrationParams(int types, @NonNull IVibratorController token) - throws RemoteException { + public void clearVibrationParams(int types, @NonNull IVibratorController token) { Objects.requireNonNull(token); synchronized (mLock) { @@ -151,13 +170,13 @@ public final class VibratorControlService extends IVibratorControlService.Stub { } updateAdaptiveHapticsScales(types, NO_SCALE); + recordClearVibrationParams(types); } } @Override public void onRequestVibrationParamsComplete( - @NonNull IBinder requestToken, @SuppressLint("ArrayReturn") VibrationParam[] result) - throws RemoteException { + @NonNull IBinder requestToken, @SuppressLint("ArrayReturn") VibrationParam[] result) { Objects.requireNonNull(requestToken); synchronized (mLock) { @@ -177,16 +196,17 @@ public final class VibratorControlService extends IVibratorControlService.Stub { updateAdaptiveHapticsScales(result); endOngoingRequestVibrationParamsLocked(/* wasCancelled= */ false); + recordUpdateVibrationParams(result, /* fromRequest= */ true); } } @Override - public int getInterfaceVersion() throws RemoteException { + public int getInterfaceVersion() { return this.VERSION; } @Override - public String getInterfaceHash() throws RemoteException { + public String getInterfaceHash() { return this.HASH; } @@ -266,6 +286,42 @@ public final class VibratorControlService extends IVibratorControlService.Stub { } } + /** Write current settings into given {@link PrintWriter}. */ + void dump(IndentingPrintWriter pw) { + boolean isVibratorControllerRegistered; + boolean hasPendingVibrationParamsRequest; + synchronized (mLock) { + isVibratorControllerRegistered = + mVibratorControllerHolder.getVibratorController() != null; + hasPendingVibrationParamsRequest = mRequestVibrationParamsFuture != null; + } + + pw.println("VibratorControlService:"); + pw.increaseIndent(); + pw.println("isVibratorControllerRegistered = " + isVibratorControllerRegistered); + pw.println("hasPendingVibrationParamsRequest = " + hasPendingVibrationParamsRequest); + + pw.println(); + pw.println("Vibration parameters update history:"); + pw.increaseIndent(); + mVibrationParamsRecords.dump(pw); + pw.decreaseIndent(); + + pw.decreaseIndent(); + } + + /** Write current settings into given {@link ProtoOutputStream}. */ + void dump(ProtoOutputStream proto) { + boolean isVibratorControllerRegistered; + synchronized (mLock) { + isVibratorControllerRegistered = + mVibratorControllerHolder.getVibratorController() != null; + } + proto.write(VibratorManagerServiceDumpProto.IS_VIBRATOR_CONTROLLER_REGISTERED, + isVibratorControllerRegistered); + mVibrationParamsRecords.dump(proto); + } + /** * Completes or cancels the vibration params request future and resets the future and token * to null. @@ -312,6 +368,33 @@ public final class VibratorControlService extends IVibratorControlService.Stub { } } + private static int[] mapFromAdaptiveVibrationTypeToVibrationUsages(int types) { + IntArray usages = new IntArray(15); + if ((ScaleParam.TYPE_ALARM & types) != 0) { + usages.add(USAGE_ALARM); + } + + if ((ScaleParam.TYPE_NOTIFICATION & types) != 0) { + usages.add(USAGE_NOTIFICATION); + usages.add(USAGE_COMMUNICATION_REQUEST); + } + + if ((ScaleParam.TYPE_RINGTONE & types) != 0) { + usages.add(USAGE_RINGTONE); + } + + if ((ScaleParam.TYPE_MEDIA & types) != 0) { + usages.add(USAGE_MEDIA); + usages.add(USAGE_UNKNOWN); + } + + if ((ScaleParam.TYPE_INTERACTIVE & types) != 0) { + usages.add(USAGE_TOUCH); + usages.add(USAGE_HARDWARE_FEEDBACK); + } + return usages.toArray(); + } + /** * Updates the adaptive haptics scales cached in {@link VibrationScaler} with the * provided params. @@ -319,7 +402,14 @@ public final class VibratorControlService extends IVibratorControlService.Stub { * @param params the new vibration params. */ private void updateAdaptiveHapticsScales(@Nullable VibrationParam[] params) { + if (params == null) { + return; + } for (VibrationParam param : params) { + if (param.getTag() != VibrationParam.scale) { + Slog.e(TAG, "Unsupported vibration param: " + param); + continue; + } ScaleParam scaleParam = param.getScale(); updateAdaptiveHapticsScales(scaleParam.typesMask, scaleParam.scale); } @@ -333,27 +423,8 @@ public final class VibratorControlService extends IVibratorControlService.Stub { * @param scale The scaling factor that should be applied to the vibrations. */ private void updateAdaptiveHapticsScales(int types, float scale) { - if ((ScaleParam.TYPE_ALARM & types) != 0) { - updateOrRemoveAdaptiveHapticsScale(USAGE_ALARM, scale); - } - - if ((ScaleParam.TYPE_NOTIFICATION & types) != 0) { - updateOrRemoveAdaptiveHapticsScale(USAGE_NOTIFICATION, scale); - updateOrRemoveAdaptiveHapticsScale(USAGE_COMMUNICATION_REQUEST, scale); - } - - if ((ScaleParam.TYPE_RINGTONE & types) != 0) { - updateOrRemoveAdaptiveHapticsScale(USAGE_RINGTONE, scale); - } - - if ((ScaleParam.TYPE_MEDIA & types) != 0) { - updateOrRemoveAdaptiveHapticsScale(USAGE_MEDIA, scale); - updateOrRemoveAdaptiveHapticsScale(USAGE_UNKNOWN, scale); - } - - if ((ScaleParam.TYPE_INTERACTIVE & types) != 0) { - updateOrRemoveAdaptiveHapticsScale(USAGE_TOUCH, scale); - updateOrRemoveAdaptiveHapticsScale(USAGE_HARDWARE_FEEDBACK, scale); + for (int usage : mapFromAdaptiveVibrationTypeToVibrationUsages(types)) { + updateOrRemoveAdaptiveHapticsScale(usage, scale); } } @@ -375,4 +446,136 @@ public final class VibratorControlService extends IVibratorControlService.Stub { mVibrationScaler.updateAdaptiveHapticsScale(usageHint, scale); } + + private void recordUpdateVibrationParams(@Nullable VibrationParam[] params, + boolean fromRequest) { + if (params == null) { + return; + } + VibrationParamsRecords.Operation operation = + fromRequest ? VibrationParamsRecords.Operation.PULL + : VibrationParamsRecords.Operation.PUSH; + long createTime = SystemClock.uptimeMillis(); + for (VibrationParam param : params) { + if (param.getTag() != VibrationParam.scale) { + Slog.w(TAG, "Unsupported vibration param ignored from dumpsys records: " + param); + continue; + } + ScaleParam scaleParam = param.getScale(); + mVibrationParamsRecords.add(new VibrationScaleParamRecord(operation, createTime, + scaleParam.typesMask, scaleParam.scale)); + } + } + + private void recordClearVibrationParams(int typesMask) { + long createTime = SystemClock.uptimeMillis(); + mVibrationParamsRecords.add(new VibrationScaleParamRecord( + VibrationParamsRecords.Operation.CLEAR, createTime, typesMask, NO_SCALE)); + } + + /** + * Keep records of {@link VibrationParam} values received by this service from a registered + * {@link VibratorController} and provide debug information for this service. + */ + private static final class VibrationParamsRecords + extends GroupedAggregatedLogRecords<VibrationScaleParamRecord> { + + /** The type of operations on vibration parameters that the service is recording. */ + enum Operation { + PULL, PUSH, CLEAR + }; + + VibrationParamsRecords(int sizeLimit, int aggregationTimeLimit) { + super(sizeLimit, aggregationTimeLimit); + } + + @Override + synchronized void dumpGroupHeader(IndentingPrintWriter pw, int paramType) { + if (paramType == VibrationParam.scale) { + pw.println("SCALE:"); + } else { + pw.println("UNKNOWN:"); + } + } + + @Override + synchronized long findGroupKeyProtoFieldId(int usage) { + return VibratorManagerServiceDumpProto.PREVIOUS_VIBRATION_PARAMS; + } + } + + /** + * Record for a single {@link Vibration.DebugInfo}, that can be grouped by usage and aggregated + * by UID, {@link VibrationAttributes} and {@link VibrationEffect}. + */ + private static final class VibrationScaleParamRecord + implements GroupedAggregatedLogRecords.SingleLogRecord { + + private final VibrationParamsRecords.Operation mOperation; + private final long mCreateTime; + private final int mTypesMask; + private final float mScale; + + VibrationScaleParamRecord(VibrationParamsRecords.Operation operation, long createTime, + int typesMask, float scale) { + mOperation = operation; + mCreateTime = createTime; + mTypesMask = typesMask; + mScale = scale; + } + + @Override + public int getGroupKey() { + return VibrationParam.scale; + } + + @Override + public long getCreateUptimeMs() { + return mCreateTime; + } + + @Override + public boolean mayAggregate(GroupedAggregatedLogRecords.SingleLogRecord record) { + if (!(record instanceof VibrationScaleParamRecord param)) { + return false; + } + return mTypesMask == param.mTypesMask && mOperation == param.mOperation; + } + + @Override + public void dump(IndentingPrintWriter pw) { + String line = String.format(Locale.ROOT, + "%s | %6s | scale: %5s | typesMask: %6s | usages: %s", + DEBUG_DATE_TIME_FORMAT.format(new Date(mCreateTime)), + mOperation.name().toLowerCase(Locale.ROOT), + (mScale == NO_SCALE) ? "" : String.format(Locale.ROOT, "%.2f", mScale), + Long.toBinaryString(mTypesMask), createVibrationUsagesString()); + pw.println(line); + } + + @Override + public void dump(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(VibrationParamProto.CREATE_TIME, mCreateTime); + proto.write(VibrationParamProto.IS_FROM_REQUEST, + mOperation == VibrationParamsRecords.Operation.PULL); + + final long scaleToken = proto.start(VibrationParamProto.SCALE); + proto.write(VibrationScaleParamProto.TYPES_MASK, mTypesMask); + proto.write(VibrationScaleParamProto.SCALE, mScale); + proto.end(scaleToken); + + proto.end(token); + } + + private String createVibrationUsagesString() { + StringBuilder sb = new StringBuilder(); + int[] usages = mapFromAdaptiveVibrationTypeToVibrationUsages(mTypesMask); + for (int i = 0; i < usages.length; i++) { + if (i > 0) sb.append(", "); + sb.append(VibrationAttributes.usageToString(usages[i])); + } + return sb.toString(); + } + } } diff --git a/services/core/java/com/android/server/vibrator/VibratorController.java b/services/core/java/com/android/server/vibrator/VibratorController.java index f5d4d1e3926b..6710d02bee90 100644 --- a/services/core/java/com/android/server/vibrator/VibratorController.java +++ b/services/core/java/com/android/server/vibrator/VibratorController.java @@ -17,7 +17,6 @@ package com.android.server.vibrator; import android.annotation.Nullable; -import android.annotation.Nullable; import android.hardware.vibrator.IVibrator; import android.os.Binder; import android.os.IVibratorStateListener; @@ -354,13 +353,13 @@ final class VibratorController { } void dump(IndentingPrintWriter pw) { - pw.println("VibratorController:"); + pw.println("Vibrator (id=" + mVibratorInfo.getId() + "):"); pw.increaseIndent(); pw.println("isVibrating = " + mIsVibrating); pw.println("isUnderExternalControl = " + mIsUnderExternalControl); pw.println("currentAmplitude = " + mCurrentAmplitude); pw.println("vibratorInfoLoadSuccessful = " + mVibratorInfoLoadSuccessful); - pw.println("vibratorStateListenerCount = " + pw.println("vibratorStateListener size = " + mVibratorStateListeners.getRegisteredCallbackCount()); mVibratorInfo.dump(pw); pw.decreaseIndent(); diff --git a/services/core/java/com/android/server/vibrator/VibratorControllerHolder.java b/services/core/java/com/android/server/vibrator/VibratorControllerHolder.java index 79a99b3ee2ff..b49fb85ecf3f 100644 --- a/services/core/java/com/android/server/vibrator/VibratorControllerHolder.java +++ b/services/core/java/com/android/server/vibrator/VibratorControllerHolder.java @@ -24,8 +24,6 @@ import android.util.Slog; /** * Holder class for {@link IVibratorController}. - * - * @hide */ public final class VibratorControllerHolder implements IBinder.DeathRecipient { private static final String TAG = "VibratorControllerHolder"; diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java index 78e0ebbb53fa..c1bf0393fc85 100644 --- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java +++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java @@ -16,7 +16,6 @@ package com.android.server.vibrator; -import static android.os.ExternalVibrationScale.ScaleLevel.SCALE_MUTE; import static android.os.VibrationEffect.VibrationParameter.targetAmplitude; import static android.os.VibrationEffect.VibrationParameter.targetFrequency; @@ -84,7 +83,6 @@ import java.lang.ref.WeakReference; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedList; import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; @@ -217,7 +215,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { mVibrationSettings = new VibrationSettings(mContext, mHandler); mVibrationScaler = new VibrationScaler(mContext, mVibrationSettings); - mVibratorControlService = new VibratorControlService( + mVibratorControlService = new VibratorControlService(mContext, injector.createVibratorControllerHolder(), mVibrationScaler, mVibrationSettings, mLock); mInputDeviceDelegate = new InputDeviceDelegate(mContext, mHandler); @@ -416,14 +414,14 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } @Override // Binder call - public void performHapticFeedback( - int uid, int deviceId, String opPkg, int constant, boolean always, String reason) { + public void performHapticFeedback(int uid, int deviceId, String opPkg, int constant, + boolean always, String reason, boolean fromIme) { // Note that the `performHapticFeedback` method does not take a token argument from the // caller, and instead, uses this service as the token. This is to mitigate performance // impact that would otherwise be caused due to marshal latency. Haptic feedback effects are // short-lived, so we don't need to cancel when the process dies. performHapticFeedbackInternal( - uid, deviceId, opPkg, constant, always, reason, /* token= */ this); + uid, deviceId, opPkg, constant, always, reason, /* token= */ this, fromIme); } /** @@ -435,7 +433,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Nullable HalVibration performHapticFeedbackInternal( int uid, int deviceId, String opPkg, int constant, boolean always, String reason, - IBinder token) { + IBinder token, boolean fromIme) { HapticFeedbackVibrationProvider hapticVibrationProvider = getHapticVibrationProvider(); if (hapticVibrationProvider == null) { Slog.w(TAG, "performHapticFeedback; haptic vibration provider not ready."); @@ -449,7 +447,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { CombinedVibration combinedVibration = CombinedVibration.createParallel(effect); VibrationAttributes attrs = hapticVibrationProvider.getVibrationAttributesForHapticFeedback( - constant, /* bypassVibrationIntensitySetting= */ always); + constant, /* bypassVibrationIntensitySetting= */ always, fromIme); VibratorFrameworkStatsLogger.logPerformHapticsFeedbackIfKeyboard(uid, constant); return vibrateWithoutPermissionCheck(uid, deviceId, opPkg, combinedVibration, attrs, "performHapticFeedback: " + reason, token); @@ -639,13 +637,16 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } IndentingPrintWriter pw = new IndentingPrintWriter(w, /* singleIndent= */ " "); synchronized (mLock) { - pw.println("Vibrator Manager Service:"); + pw.println("VibratorManagerService:"); pw.increaseIndent(); mVibrationSettings.dump(pw); pw.println(); - pw.println("VibratorControllers:"); + mVibrationScaler.dump(pw); + pw.println(); + + pw.println("Vibrators:"); pw.increaseIndent(); for (int i = 0; i < mVibrators.size(); i++) { mVibrators.valueAt(i).dump(pw); @@ -686,6 +687,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { pw.println(); pw.println(); mVibratorManagerRecords.dump(pw); + + pw.println(); + pw.println(); + mVibratorControlService.dump(pw); } private void dumpProto(FileDescriptor fd) { @@ -695,6 +700,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } synchronized (mLock) { mVibrationSettings.dump(proto); + mVibrationScaler.dump(proto); if (mCurrentVibration != null) { mCurrentVibration.getVibration().getDebugInfo().dump(proto, VibratorManagerServiceDumpProto.CURRENT_VIBRATION); @@ -716,6 +722,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { isUnderExternalControl); } mVibratorManagerRecords.dump(proto); + mVibratorControlService.dump(proto); proto.flush(); } @@ -887,7 +894,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if (!vib.callerInfo.attrs.isFlagSet( VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)) { // Scale resolves the default amplitudes from the effect before scaling them. - vib.scaleEffects(mVibrationScaler::scale); + vib.scaleEffects(mVibrationScaler); } else { vib.resolveEffects(mVibrationScaler.getDefaultVibrationAmplitude()); } @@ -1663,7 +1670,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { public Vibration.DebugInfo getDebugInfo() { return new Vibration.DebugInfo(mStatus, stats, /* playedEffect= */ null, - /* originalEffect= */ null, scale.scaleLevel, callerInfo); + /* originalEffect= */ null, scale.scaleLevel, scale.adaptiveHapticsScale, + callerInfo); } public VibrationStats.StatsInfo getStatsInfo(long completionUptimeMillis) { @@ -1739,8 +1747,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { int aggregationTimeLimit) { mAggregatedVibrationHistory = new VibrationRecords(aggregationSizeLimit, aggregationTimeLimit); - mRecentVibrations = new VibrationRecords( - recentVibrationSizeLimit, /* aggregationTimeLimit= */ 0); + // Recent vibrations are not aggregated, to help debugging issues that just happened. + mRecentVibrations = + new VibrationRecords(recentVibrationSizeLimit, /* aggregationTimeLimit= */ 0); } synchronized void record(HalVibration vib) { @@ -1752,9 +1761,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } private synchronized void record(Vibration.DebugInfo info) { - AggregatedVibrationRecord removedRecord = mRecentVibrations.record(info); - if (removedRecord != null) { - mAggregatedVibrationHistory.record(removedRecord.mLatestVibration); + GroupedAggregatedLogRecords.AggregatedLogRecord<VibrationRecord> droppedRecord = + mRecentVibrations.add(new VibrationRecord(info)); + if (droppedRecord != null) { + // Move dropped record from recent list to aggregated history list. + mAggregatedVibrationHistory.add(droppedRecord.getLatest()); } } @@ -1763,9 +1774,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { pw.increaseIndent(); mRecentVibrations.dump(pw); pw.decreaseIndent(); + pw.println(); pw.println(); - pw.println("Aggregated vibration history:"); pw.increaseIndent(); mAggregatedVibrationHistory.dump(pw); @@ -1778,127 +1789,75 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } /** Keep records of vibrations played and provide debug information for this service. */ - private static final class VibrationRecords { - private final SparseArray<LinkedList<AggregatedVibrationRecord>> mVibrations = - new SparseArray<>(); - private final int mSizeLimit; - private final int mAggregationTimeLimit; + private static final class VibrationRecords + extends GroupedAggregatedLogRecords<VibrationRecord> { VibrationRecords(int sizeLimit, int aggregationTimeLimit) { - mSizeLimit = sizeLimit; - mAggregationTimeLimit = aggregationTimeLimit; + super(sizeLimit, aggregationTimeLimit); } - synchronized AggregatedVibrationRecord record(Vibration.DebugInfo info) { - int usage = info.mCallerInfo.attrs.getUsage(); - if (!mVibrations.contains(usage)) { - mVibrations.put(usage, new LinkedList<>()); - } - LinkedList<AggregatedVibrationRecord> records = mVibrations.get(usage); - if (mAggregationTimeLimit > 0 && !records.isEmpty()) { - AggregatedVibrationRecord lastRecord = records.getLast(); - if (lastRecord.mayAggregate(info, mAggregationTimeLimit)) { - lastRecord.record(info); - return null; - } - } - AggregatedVibrationRecord removedRecord = null; - if (records.size() > mSizeLimit) { - removedRecord = records.removeFirst(); - } - records.addLast(new AggregatedVibrationRecord(info)); - return removedRecord; - } - - synchronized void dump(IndentingPrintWriter pw) { - for (int i = 0; i < mVibrations.size(); i++) { - pw.println(VibrationAttributes.usageToString(mVibrations.keyAt(i)) + ":"); - pw.increaseIndent(); - for (AggregatedVibrationRecord info : mVibrations.valueAt(i)) { - info.dump(pw); - } - pw.decreaseIndent(); - pw.println(); - } - } - - synchronized void dump(ProtoOutputStream proto) { - for (int i = 0; i < mVibrations.size(); i++) { - long fieldId; - switch (mVibrations.keyAt(i)) { - case VibrationAttributes.USAGE_RINGTONE: - fieldId = VibratorManagerServiceDumpProto.PREVIOUS_RING_VIBRATIONS; - break; - case VibrationAttributes.USAGE_NOTIFICATION: - fieldId = VibratorManagerServiceDumpProto.PREVIOUS_NOTIFICATION_VIBRATIONS; - break; - case VibrationAttributes.USAGE_ALARM: - fieldId = VibratorManagerServiceDumpProto.PREVIOUS_ALARM_VIBRATIONS; - break; - default: - fieldId = VibratorManagerServiceDumpProto.PREVIOUS_VIBRATIONS; - } - for (AggregatedVibrationRecord info : mVibrations.valueAt(i)) { - if (info.mLatestVibration.mPlayedEffect == null) { - // External vibrations are reported separately in the dump proto - info.dump(proto, - VibratorManagerServiceDumpProto.PREVIOUS_EXTERNAL_VIBRATIONS); - } else { - info.dump(proto, fieldId); - } - } - } + @Override + void dumpGroupHeader(IndentingPrintWriter pw, int usage) { + pw.println(VibrationAttributes.usageToString(usage) + ":"); } - synchronized void dumpOnSingleField(ProtoOutputStream proto, long fieldId) { - for (int i = 0; i < mVibrations.size(); i++) { - for (AggregatedVibrationRecord info : mVibrations.valueAt(i)) { - info.dump(proto, fieldId); - } - } + @Override + long findGroupKeyProtoFieldId(int usage) { + return switch (usage) { + case VibrationAttributes.USAGE_RINGTONE -> + VibratorManagerServiceDumpProto.PREVIOUS_RING_VIBRATIONS; + case VibrationAttributes.USAGE_NOTIFICATION -> + VibratorManagerServiceDumpProto.PREVIOUS_NOTIFICATION_VIBRATIONS; + case VibrationAttributes.USAGE_ALARM -> + VibratorManagerServiceDumpProto.PREVIOUS_ALARM_VIBRATIONS; + default -> + VibratorManagerServiceDumpProto.PREVIOUS_VIBRATIONS; + }; } } /** - * Record that keeps the last {@link Vibration.DebugInfo} played, aggregating close vibrations - * from the same uid that have the same {@link VibrationAttributes} and {@link VibrationEffect}. + * Record for a single {@link Vibration.DebugInfo}, that can be grouped by usage and aggregated + * by UID, {@link VibrationAttributes} and {@link VibrationEffect}. */ - private static final class AggregatedVibrationRecord { - private final Vibration.DebugInfo mFirstVibration; - private Vibration.DebugInfo mLatestVibration; - private int mVibrationCount; + private static final class VibrationRecord + implements GroupedAggregatedLogRecords.SingleLogRecord { + private final Vibration.DebugInfo mInfo; - AggregatedVibrationRecord(Vibration.DebugInfo info) { - mLatestVibration = mFirstVibration = info; - mVibrationCount = 1; + VibrationRecord(Vibration.DebugInfo info) { + mInfo = info; } - synchronized boolean mayAggregate(Vibration.DebugInfo info, long timeLimit) { - return Objects.equals(mLatestVibration.mCallerInfo.uid, info.mCallerInfo.uid) - && Objects.equals(mLatestVibration.mCallerInfo.attrs, info.mCallerInfo.attrs) - && Objects.equals(mLatestVibration.mPlayedEffect, info.mPlayedEffect) - && Math.abs(mLatestVibration.mCreateTime - info.mCreateTime) < timeLimit; + @Override + public int getGroupKey() { + return mInfo.mCallerInfo.attrs.getUsage(); } - synchronized void record(Vibration.DebugInfo vib) { - mLatestVibration = vib; - mVibrationCount++; + @Override + public long getCreateUptimeMs() { + return mInfo.mCreateTime; } - synchronized void dump(IndentingPrintWriter pw) { - mFirstVibration.dumpCompact(pw); - if (mVibrationCount == 1) { - return; - } - if (mVibrationCount > 2) { - pw.println( - "-> Skipping " + (mVibrationCount - 2) + " aggregated vibrations, latest:"); + @Override + public boolean mayAggregate(GroupedAggregatedLogRecords.SingleLogRecord record) { + if (!(record instanceof VibrationRecord)) { + return false; } - mLatestVibration.dumpCompact(pw); + Vibration.DebugInfo info = ((VibrationRecord) record).mInfo; + return mInfo.mCallerInfo.uid == info.mCallerInfo.uid + && Objects.equals(mInfo.mCallerInfo.attrs, info.mCallerInfo.attrs) + && Objects.equals(mInfo.mPlayedEffect, info.mPlayedEffect); } - synchronized void dump(ProtoOutputStream proto, long fieldId) { - mLatestVibration.dump(proto, fieldId); + @Override + public void dump(IndentingPrintWriter pw) { + // Prints a compact version of each vibration request for dumpsys. + mInfo.dumpCompact(pw); + } + + @Override + public void dump(ProtoOutputStream proto, long fieldId) { + mInfo.dump(proto, fieldId); } } @@ -2001,7 +1960,6 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override public ExternalVibrationScale onExternalVibrationStart(ExternalVibration vib) { - if (!hasExternalControlCapability()) { return SCALE_MUTE; } @@ -2085,10 +2043,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } mCurrentExternalVibration = vibHolder; vibHolder.linkToDeath(); - vibHolder.scale.scaleLevel = mVibrationScaler.getExternalVibrationScaleLevel( - attrs.getUsage()); - vibHolder.scale.adaptiveHapticsScale = mVibrationScaler.getAdaptiveHapticsScale( - attrs.getUsage()); + vibHolder.scale.scaleLevel = mVibrationScaler.getScaleLevel(attrs.getUsage()); + vibHolder.scale.adaptiveHapticsScale = + mVibrationScaler.getAdaptiveHapticsScale(attrs.getUsage()); } if (waitForCompletion) { @@ -2300,7 +2257,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { HalVibration vib = performHapticFeedbackInternal(Binder.getCallingUid(), Context.DEVICE_ID_DEFAULT, SHELL_PACKAGE_NAME, constant, /* always= */ commonOptions.force, /* reason= */ commonOptions.description, - deathBinder); + deathBinder, false /* fromIme */); maybeWaitOnVibration(vib, commonOptions); return 0; diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 90cff3950047..92fde18233a9 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1476,7 +1476,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } - private void scheduleConfigurationChanged(Configuration config) { + private void scheduleConfigurationChanged(@NonNull Configuration config, + @NonNull ActivityWindowInfo activityWindowInfo) { if (!attachedToProcess()) { ProtoLog.w(WM_DEBUG_CONFIGURATION, "Can't report activity configuration " + "update - client not running, activityRecord=%s", this); @@ -1487,7 +1488,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A + "config: %s", this, config); mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), - ActivityConfigurationChangeItem.obtain(token, config)); + ActivityConfigurationChangeItem.obtain(token, config, activityWindowInfo)); } catch (RemoteException e) { // If process died, whatever. } @@ -9785,7 +9786,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // configurations because there are cases (like moving a task to the root pinned task) where // the combine configurations are equal, but would otherwise differ in the override config mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration()); - if (getConfiguration().equals(mTmpConfig) && !displayChanged) { + final ActivityWindowInfo newActivityWindowInfo = getActivityWindowInfo(); + final boolean isActivityWindowInfoChanged = Flags.activityWindowInfoFlag() + && !mLastReportedActivityWindowInfo.equals(newActivityWindowInfo); + if (!displayChanged && !isActivityWindowInfoChanged + && getConfiguration().equals(mTmpConfig)) { ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration & display " + "unchanged in %s", this); return true; @@ -9800,7 +9805,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Update last reported values. final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration(); - final ActivityWindowInfo newActivityWindowInfo = getActivityWindowInfo(); setLastReportedConfiguration(getProcessGlobalConfiguration(), newMergedOverrideConfig); setLastReportedActivityWindowInfo(newActivityWindowInfo); @@ -9823,7 +9827,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig, newActivityWindowInfo); } else { - scheduleConfigurationChanged(newMergedOverrideConfig); + scheduleConfigurationChanged(newMergedOverrideConfig, newActivityWindowInfo); } notifyDisplayCompatPolicyAboutConfigurationChange( mLastReportedConfiguration.getMergedConfiguration(), mTmpConfig); @@ -9891,7 +9895,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig, newActivityWindowInfo); } else { - scheduleConfigurationChanged(newMergedOverrideConfig); + scheduleConfigurationChanged(newMergedOverrideConfig, newActivityWindowInfo); } notifyDisplayCompatPolicyAboutConfigurationChange( mLastReportedConfiguration.getMergedConfiguration(), mTmpConfig); diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java index 8717098ff8e8..a914c0712319 100644 --- a/services/core/java/com/android/server/wm/ContentRecorder.java +++ b/services/core/java/com/android/server/wm/ContentRecorder.java @@ -650,6 +650,14 @@ final class ContentRecorder implements WindowContainerListener { if (isCurrentlyRecording() && mLastRecordedBounds != null) { mMediaProjectionManager.notifyActiveProjectionCapturedContentVisibilityChanged( isVisibleRequested); + + if (mContentRecordingSession.getContentToRecord() == RECORD_CONTENT_TASK) { + // If capturing a task, then the toggle visibility of the recorded surface to match + // visibility of the task, so we don't capture any mid-transition frames + mRecordedWindowContainer.getSyncTransaction() + .setVisibility(mRecordedSurface, isVisibleRequested); + mRecordedWindowContainer.scheduleAnimation(); + } } } diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index cd968067e289..fa76774a604f 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -520,11 +520,37 @@ class InsetsSourceProvider { updateVisibility(); mControl = new InsetsSourceControl(mSource.getId(), mSource.getType(), leash, mClientVisible, surfacePosition, getInsetsHint()); + mStateController.notifySurfaceTransactionReady(this, getSurfaceTransactionId(leash), true); ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "InsetsSource Control %s for target %s", mControl, mControlTarget); } + private long getSurfaceTransactionId(SurfaceControl leash) { + // Here returns mNativeObject (long) as the ID instead of the leash itself so that + // InsetsStateController won't keep referencing the leash unexpectedly. + return leash != null ? leash.mNativeObject : 0; + } + + /** + * This is called when the surface transaction of the leash initialization has been committed. + * + * @param id Indicates which transaction is committed so that stale callbacks can be dropped. + */ + void onSurfaceTransactionCommitted(long id) { + if (mIsLeashReadyForDispatching) { + return; + } + if (mControl == null) { + return; + } + if (id != getSurfaceTransactionId(mControl.getLeash())) { + return; + } + mIsLeashReadyForDispatching = true; + mStateController.notifySurfaceTransactionReady(this, 0, false); + } + void startSeamlessRotation() { if (!mSeamlessRotating) { mSeamlessRotating = true; @@ -545,10 +571,6 @@ class InsetsSourceProvider { return true; } - void onSurfaceTransactionApplied() { - mIsLeashReadyForDispatching = true; - } - void setClientVisible(boolean clientVisible) { if (mClientVisible == clientVisible) { return; @@ -733,6 +755,7 @@ class InsetsSourceProvider { public void onAnimationCancelled(SurfaceControl animationLeash) { if (mAdapter == this) { mStateController.notifyControlRevoked(mControlTarget, InsetsSourceProvider.this); + mStateController.notifySurfaceTransactionReady(InsetsSourceProvider.this, 0, false); mControl = null; mControlTarget = null; mAdapter = null; diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index 6b9fcf411ce1..ba578f642429 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -34,6 +34,7 @@ import android.os.Trace; import android.util.ArrayMap; import android.util.ArraySet; import android.util.SparseArray; +import android.util.SparseLongArray; import android.util.proto.ProtoOutputStream; import android.view.InsetsSource; import android.view.InsetsSourceControl; @@ -58,6 +59,7 @@ class InsetsStateController { private final DisplayContent mDisplayContent; private final SparseArray<InsetsSourceProvider> mProviders = new SparseArray<>(); + private final SparseLongArray mSurfaceTransactionIds = new SparseLongArray(); private final ArrayMap<InsetsControlTarget, ArrayList<InsetsSourceProvider>> mControlTargetProvidersMap = new ArrayMap<>(); private final SparseArray<InsetsControlTarget> mIdControlTargetMap = new SparseArray<>(); @@ -360,14 +362,32 @@ class InsetsStateController { notifyPendingInsetsControlChanged(); } + void notifySurfaceTransactionReady(InsetsSourceProvider provider, long id, boolean ready) { + if (ready) { + mSurfaceTransactionIds.put(provider.getSource().getId(), id); + } else { + mSurfaceTransactionIds.delete(provider.getSource().getId()); + } + } + private void notifyPendingInsetsControlChanged() { if (mPendingControlChanged.isEmpty()) { return; } + final int size = mSurfaceTransactionIds.size(); + final SparseLongArray surfaceTransactionIds = new SparseLongArray(size); + for (int i = 0; i < size; i++) { + surfaceTransactionIds.append( + mSurfaceTransactionIds.keyAt(i), mSurfaceTransactionIds.valueAt(i)); + } mDisplayContent.mWmService.mAnimator.addAfterPrepareSurfacesRunnable(() -> { - for (int i = mProviders.size() - 1; i >= 0; i--) { - final InsetsSourceProvider provider = mProviders.valueAt(i); - provider.onSurfaceTransactionApplied(); + for (int i = 0; i < size; i++) { + final int sourceId = surfaceTransactionIds.keyAt(i); + final InsetsSourceProvider provider = mProviders.get(sourceId); + if (provider == null) { + continue; + } + provider.onSurfaceTransactionCommitted(surfaceTransactionIds.valueAt(i)); } final ArraySet<InsetsControlTarget> newControlTargets = new ArraySet<>(); int displayId = mDisplayContent.getDisplayId(); diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 908cbd340236..30134d815fa6 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -336,19 +336,19 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override - public boolean performHapticFeedback(int effectId, boolean always) { + public boolean performHapticFeedback(int effectId, boolean always, boolean fromIme) { final long ident = Binder.clearCallingIdentity(); try { return mService.mPolicy.performHapticFeedback(mUid, mPackageName, - effectId, always, null); + effectId, always, null, fromIme); } finally { Binder.restoreCallingIdentity(ident); } } @Override - public void performHapticFeedbackAsync(int effectId, boolean always) { - performHapticFeedback(effectId, always); + public void performHapticFeedbackAsync(int effectId, boolean always, boolean fromIme) { + performHapticFeedback(effectId, always, fromIme); } /* Drag/drop */ diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index b43a4540bbde..5e7f1cbdd06e 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -28,6 +28,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.content.Context; +import android.os.HandlerExecutor; import android.os.Trace; import android.util.Slog; import android.util.TimeUtils; @@ -69,6 +70,8 @@ public class WindowAnimator { private Choreographer mChoreographer; + private final HandlerExecutor mExecutor; + /** * Indicates whether we have an animation frame callback scheduled, which will happen at * vsync-app and then schedule the animation tick at the right time (vsync-sf). @@ -80,8 +83,7 @@ public class WindowAnimator { * A list of runnable that need to be run after {@link WindowContainer#prepareSurfaces} is * executed and the corresponding transaction is closed and applied. */ - private final ArrayList<Runnable> mAfterPrepareSurfacesRunnables = new ArrayList<>(); - private boolean mInExecuteAfterPrepareSurfacesRunnables; + private ArrayList<Runnable> mAfterPrepareSurfacesRunnables = new ArrayList<>(); private final SurfaceControl.Transaction mTransaction; @@ -92,6 +94,7 @@ public class WindowAnimator { mTransaction = service.mTransactionFactory.get(); service.mAnimationHandler.runWithScissors( () -> mChoreographer = Choreographer.getSfInstance(), 0 /* timeout */); + mExecutor = new HandlerExecutor(service.mAnimationHandler); mAnimationFrameCallback = frameTimeNs -> { synchronized (mService.mGlobalLock) { @@ -197,6 +200,19 @@ public class WindowAnimator { updateRunningExpensiveAnimationsLegacy(); } + final ArrayList<Runnable> afterPrepareSurfacesRunnables = mAfterPrepareSurfacesRunnables; + if (!afterPrepareSurfacesRunnables.isEmpty()) { + mAfterPrepareSurfacesRunnables = new ArrayList<>(); + mTransaction.addTransactionCommittedListener(mExecutor, () -> { + synchronized (mService.mGlobalLock) { + // Traverse in order they were added. + for (int i = 0, size = afterPrepareSurfacesRunnables.size(); i < size; i++) { + afterPrepareSurfacesRunnables.get(i).run(); + } + afterPrepareSurfacesRunnables.clear(); + } + }); + } Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "applyTransaction"); mTransaction.apply(); Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); @@ -204,7 +220,6 @@ public class WindowAnimator { ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate"); mService.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); - executeAfterPrepareSurfacesRunnables(); if (DEBUG_WINDOW_TRACE) { Slog.i(TAG, "!!! animate: exit" @@ -286,34 +301,10 @@ public class WindowAnimator { /** * Adds a runnable to be executed after {@link WindowContainer#prepareSurfaces} is called and - * the corresponding transaction is closed and applied. + * the corresponding transaction is closed, applied, and committed. */ void addAfterPrepareSurfacesRunnable(Runnable r) { - // If runnables are already being handled in executeAfterPrepareSurfacesRunnable, then just - // immediately execute the runnable passed in. - if (mInExecuteAfterPrepareSurfacesRunnables) { - r.run(); - return; - } - mAfterPrepareSurfacesRunnables.add(r); scheduleAnimation(); } - - void executeAfterPrepareSurfacesRunnables() { - - // Don't even think about to start recursing! - if (mInExecuteAfterPrepareSurfacesRunnables) { - return; - } - mInExecuteAfterPrepareSurfacesRunnables = true; - - // Traverse in order they were added. - final int size = mAfterPrepareSurfacesRunnables.size(); - for (int i = 0; i < size; i++) { - mAfterPrepareSurfacesRunnables.get(i).run(); - } - mAfterPrepareSurfacesRunnables.clear(); - mInExecuteAfterPrepareSurfacesRunnables = false; - } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index c93cc074aa3d..7e06129832a8 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6706,7 +6706,7 @@ public class WindowManagerService extends IWindowManager.Stub private void dumpLogStatus(PrintWriter pw) { pw.println("WINDOW MANAGER LOGGING (dumpsys window logging)"); - if (android.tracing.Flags.perfettoProtolog()) { + if (android.tracing.Flags.perfettoProtologTracing()) { pw.println("Deprecated legacy command. Use Perfetto commands instead."); return; } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index a7a28c282ff9..18ac0e748536 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2041,6 +2041,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (!isVisible()) { return; } + final WallpaperWindowToken wallpaperToken = mToken.asWallpaperToken(); + if (wallpaperToken != null) { + if (wallpaperToken.hasVisibleNotDrawnWallpaper()) { + outWaitingForDrawn.add(this); + } + return; + } if (mActivityRecord != null) { if (!mActivityRecord.isVisibleRequested()) return; if (mActivityRecord.allDrawn) { diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java index 424d50434010..6d5fc80b8d1e 100644 --- a/services/core/java/com/android/server/wm/WindowTracing.java +++ b/services/core/java/com/android/server/wm/WindowTracing.java @@ -155,13 +155,13 @@ class WindowTracing { logAndPrintln(pw, "Stop tracing to " + mTraceFile + ". Waiting for traces to flush."); writeTraceToFileLocked(); logAndPrintln(pw, "Trace written to " + mTraceFile + "."); - if (!android.tracing.Flags.perfettoProtolog()) { + if (!android.tracing.Flags.perfettoProtologTracing()) { ((LegacyProtoLogImpl) mProtoLog).stopProtoLog(pw, true); } logAndPrintln(pw, "Start tracing to " + mTraceFile + "."); mBuffer.resetBuffer(); mEnabled = mEnabledLockFree = true; - if (!android.tracing.Flags.perfettoProtolog()) { + if (!android.tracing.Flags.perfettoProtologTracing()) { ((LegacyProtoLogImpl) mProtoLog).startProtoLog(pw); } } diff --git a/services/core/jni/com_android_server_accessibility_BrailleDisplayConnection.cpp b/services/core/jni/com_android_server_accessibility_BrailleDisplayConnection.cpp index 9a509a71cf92..c3375236098a 100644 --- a/services/core/jni/com_android_server_accessibility_BrailleDisplayConnection.cpp +++ b/services/core/jni/com_android_server_accessibility_BrailleDisplayConnection.cpp @@ -40,7 +40,7 @@ constexpr int UNIQ_SIZE_MAX = 64; } // anonymous namespace static jint com_android_server_accessibility_BrailleDisplayConnection_getHidrawDescSize( - JNIEnv* env, jobject thiz, int fd) { + JNIEnv* env, jclass /*clazz*/, int fd) { int size = 0; if (ioctl(fd, HIDIOCGRDESCSIZE, &size) < 0) { return -1; @@ -49,7 +49,7 @@ static jint com_android_server_accessibility_BrailleDisplayConnection_getHidrawD } static jbyteArray com_android_server_accessibility_BrailleDisplayConnection_getHidrawDesc( - JNIEnv* env, jobject thiz, int fd, int descSize) { + JNIEnv* env, jclass /*clazz*/, int fd, int descSize) { struct hidraw_report_descriptor desc; desc.size = descSize; if (ioctl(fd, HIDIOCGRDESC, &desc) < 0) { @@ -63,9 +63,8 @@ static jbyteArray com_android_server_accessibility_BrailleDisplayConnection_getH return result; } -static jstring com_android_server_accessibility_BrailleDisplayConnection_getHidrawUniq(JNIEnv* env, - jobject thiz, - int fd) { +static jstring com_android_server_accessibility_BrailleDisplayConnection_getHidrawUniq( + JNIEnv* env, jclass /*clazz*/, int fd) { char buf[UNIQ_SIZE_MAX]; if (ioctl(fd, HIDIOCGRAWUNIQ(UNIQ_SIZE_MAX), buf) < 0) { return nullptr; @@ -74,9 +73,8 @@ static jstring com_android_server_accessibility_BrailleDisplayConnection_getHidr return env->NewStringUTF(buf); } -static jint com_android_server_accessibility_BrailleDisplayConnection_getHidrawBusType(JNIEnv* env, - jobject thiz, - int fd) { +static jint com_android_server_accessibility_BrailleDisplayConnection_getHidrawBusType( + JNIEnv* env, jclass /*clazz*/, int fd) { struct hidraw_devinfo info; if (ioctl(fd, HIDIOCGRAWINFO, &info) < 0) { return -1; diff --git a/services/fakes/java/com/android/server/example/BlueManagerService.java b/services/fakes/java/com/android/server/example/BlueManagerService.java new file mode 100644 index 000000000000..8e3c8d73df9c --- /dev/null +++ b/services/fakes/java/com/android/server/example/BlueManagerService.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.example; + +import android.content.Context; +import android.os.Binder; +import android.ravenwood.example.BlueManager; + +import com.android.server.SystemService; + +public class BlueManagerService extends Binder { + public static class Lifecycle extends SystemService { + private BlueManagerService mService; + + public Lifecycle(Context context) { + super(context); + } + + @Override + public void onStart() { + mService = new BlueManagerService(); + publishBinderService(BlueManager.SERVICE_NAME, mService); + } + } + + @Override + public String getInterfaceDescriptor() { + return "blue"; + } +} diff --git a/services/fakes/java/com/android/server/example/RedManagerService.java b/services/fakes/java/com/android/server/example/RedManagerService.java new file mode 100644 index 000000000000..e0be7337698d --- /dev/null +++ b/services/fakes/java/com/android/server/example/RedManagerService.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.example; + +import android.content.Context; +import android.os.Binder; +import android.os.IBinder; +import android.os.RemoteException; +import android.ravenwood.example.BlueManager; +import android.ravenwood.example.RedManager; + +import com.android.server.SystemService; + +import java.util.List; + +public class RedManagerService extends Binder { + private IBinder mBlueService; + + public static class Lifecycle extends SystemService { + private RedManagerService mService; + + public Lifecycle(Context context) { + super(context, List.of(BlueManager.class)); + } + + @Override + public void onStart() { + mService = new RedManagerService(); + publishBinderService(RedManager.SERVICE_NAME, mService); + } + + @Override + public void onBootPhase(int phase) { + if (phase == PHASE_SYSTEM_SERVICES_READY) { + mService.mBlueService = getBinderService(BlueManager.SERVICE_NAME); + } + } + } + + @Override + public String getInterfaceDescriptor() { + try { + // Obtain the answer from dependency, but then augment it to prove that the answer + // was channeled through us + return mBlueService.getInterfaceDescriptor() + "+red"; + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } +} diff --git a/services/tests/VpnTests/Android.bp b/services/tests/VpnTests/Android.bp new file mode 100644 index 000000000000..64a9a3b4f119 --- /dev/null +++ b/services/tests/VpnTests/Android.bp @@ -0,0 +1,39 @@ +//######################################################################## +// Build FrameworksVpnTests package +//######################################################################## +package { + default_team: "trendy_team_fwk_core_networking", + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "Android-Apache-2.0" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["Android-Apache-2.0"], +} + +android_test { + name: "FrameworksVpnTests", + srcs: [ + "java/**/*.java", + "java/**/*.kt", + ], + + defaults: ["framework-connectivity-test-defaults"], + test_suites: ["device-tests"], + static_libs: [ + "androidx.test.rules", + "frameworks-base-testutils", + "framework-protos", + "mockito-target-minus-junit4", + "net-tests-utils", + "platform-test-annotations", + "services.core", + "cts-net-utils", + "service-connectivity-tiramisu-pre-jarjar", + ], + libs: [ + "android.test.runner", + "android.test.base", + "android.test.mock", + ], +} diff --git a/services/tests/VpnTests/AndroidManifest.xml b/services/tests/VpnTests/AndroidManifest.xml new file mode 100644 index 000000000000..d884084f2eb7 --- /dev/null +++ b/services/tests/VpnTests/AndroidManifest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.frameworks.tests.vpn"> + <application> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation + android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.frameworks.tests.vpn" + android:label="Frameworks VPN Tests" /> +</manifest>
\ No newline at end of file diff --git a/services/tests/VpnTests/AndroidTest.xml b/services/tests/VpnTests/AndroidTest.xml new file mode 100644 index 000000000000..ebeeac7d269b --- /dev/null +++ b/services/tests/VpnTests/AndroidTest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<configuration description="Runs VPN Tests."> + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="test-file-name" value="FrameworksVpnTests.apk" /> + </target_preparer> + + <option name="test-tag" value="FrameworksVpnTests" /> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="com.android.frameworks.tests.vpn" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> + </test> +</configuration>
\ No newline at end of file diff --git a/services/tests/VpnTests/OWNERS b/services/tests/VpnTests/OWNERS new file mode 100644 index 000000000000..45ea251a02e4 --- /dev/null +++ b/services/tests/VpnTests/OWNERS @@ -0,0 +1,2 @@ +set noparent +file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
\ No newline at end of file diff --git a/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java b/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java new file mode 100644 index 000000000000..ecc70e3669d6 --- /dev/null +++ b/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java @@ -0,0 +1,400 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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; + +import static com.android.testutils.ContextUtils.mockService; +import static com.android.testutils.MiscAsserts.assertThrows; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.annotation.UserIdInt; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.ConnectivityManager; +import android.net.INetd; +import android.net.Uri; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.INetworkManagementService; +import android.os.Looper; +import android.os.UserHandle; +import android.os.UserManager; +import android.security.Credentials; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import com.android.internal.net.VpnProfile; +import com.android.server.connectivity.Vpn; +import com.android.server.connectivity.VpnProfileStore; +import com.android.server.net.LockdownVpnTracker; +import com.android.testutils.HandlerUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class VpnManagerServiceTest extends VpnTestBase { + private static final String CONTEXT_ATTRIBUTION_TAG = "VPN_MANAGER"; + + private static final int TIMEOUT_MS = 2_000; + + @Mock Context mContext; + @Mock Context mContextWithoutAttributionTag; + @Mock Context mSystemContext; + @Mock Context mUserAllContext; + private HandlerThread mHandlerThread; + @Mock private Vpn mVpn; + @Mock private INetworkManagementService mNms; + @Mock private ConnectivityManager mCm; + @Mock private UserManager mUserManager; + @Mock private INetd mNetd; + @Mock private PackageManager mPackageManager; + @Mock private VpnProfileStore mVpnProfileStore; + @Mock private LockdownVpnTracker mLockdownVpnTracker; + + private VpnManagerServiceDependencies mDeps; + private VpnManagerService mService; + private BroadcastReceiver mUserPresentReceiver; + private BroadcastReceiver mIntentReceiver; + private final String mNotMyVpnPkg = "com.not.my.vpn"; + + class VpnManagerServiceDependencies extends VpnManagerService.Dependencies { + @Override + public HandlerThread makeHandlerThread() { + return mHandlerThread; + } + + @Override + public INetworkManagementService getINetworkManagementService() { + return mNms; + } + + @Override + public INetd getNetd() { + return mNetd; + } + + @Override + public Vpn createVpn(Looper looper, Context context, INetworkManagementService nms, + INetd netd, @UserIdInt int userId) { + return mVpn; + } + + @Override + public VpnProfileStore getVpnProfileStore() { + return mVpnProfileStore; + } + + @Override + public LockdownVpnTracker createLockDownVpnTracker(Context context, Handler handler, + Vpn vpn, VpnProfile profile) { + return mLockdownVpnTracker; + } + + @Override + public @UserIdInt int getMainUserId() { + return UserHandle.USER_SYSTEM; + } + } + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mHandlerThread = new HandlerThread("TestVpnManagerService"); + mDeps = new VpnManagerServiceDependencies(); + + // The attribution tag is a dependency for IKE library to collect VPN metrics correctly + // and thus should not be changed without updating the IKE code. + doReturn(mContext) + .when(mContextWithoutAttributionTag) + .createAttributionContext(CONTEXT_ATTRIBUTION_TAG); + + doReturn(mUserAllContext).when(mContext).createContextAsUser(UserHandle.ALL, 0); + doReturn(mSystemContext).when(mContext).createContextAsUser(UserHandle.SYSTEM, 0); + doReturn(mPackageManager).when(mContext).getPackageManager(); + setMockedPackages(mPackageManager, sPackages); + + mockService(mContext, ConnectivityManager.class, Context.CONNECTIVITY_SERVICE, mCm); + mockService(mContext, UserManager.class, Context.USER_SERVICE, mUserManager); + doReturn(SYSTEM_USER).when(mUserManager).getUserInfo(eq(SYSTEM_USER_ID)); + + mService = new VpnManagerService(mContextWithoutAttributionTag, mDeps); + mService.systemReady(); + + final ArgumentCaptor<BroadcastReceiver> intentReceiverCaptor = + ArgumentCaptor.forClass(BroadcastReceiver.class); + final ArgumentCaptor<BroadcastReceiver> userPresentReceiverCaptor = + ArgumentCaptor.forClass(BroadcastReceiver.class); + verify(mSystemContext).registerReceiver( + userPresentReceiverCaptor.capture(), any(), any(), any()); + verify(mUserAllContext, times(2)).registerReceiver( + intentReceiverCaptor.capture(), any(), any(), any()); + mUserPresentReceiver = userPresentReceiverCaptor.getValue(); + mIntentReceiver = intentReceiverCaptor.getValue(); + + // Add user to create vpn in mVpn + onUserStarted(SYSTEM_USER_ID); + assertNotNull(mService.mVpns.get(SYSTEM_USER_ID)); + } + + @Test + public void testUpdateAppExclusionList() { + // Start vpn + mService.startVpnProfile(TEST_VPN_PKG); + verify(mVpn).startVpnProfile(eq(TEST_VPN_PKG)); + + // Remove package due to package replaced. + onPackageRemoved(PKGS[0], PKG_UIDS[0], true /* isReplacing */); + verify(mVpn, never()).refreshPlatformVpnAppExclusionList(); + + // Add package due to package replaced. + onPackageAdded(PKGS[0], PKG_UIDS[0], true /* isReplacing */); + verify(mVpn, never()).refreshPlatformVpnAppExclusionList(); + + // Remove package + onPackageRemoved(PKGS[0], PKG_UIDS[0], false /* isReplacing */); + verify(mVpn).refreshPlatformVpnAppExclusionList(); + + // Add the package back + onPackageAdded(PKGS[0], PKG_UIDS[0], false /* isReplacing */); + verify(mVpn, times(2)).refreshPlatformVpnAppExclusionList(); + } + + @Test + public void testStartVpnProfileFromDiffPackage() { + assertThrows( + SecurityException.class, () -> mService.startVpnProfile(mNotMyVpnPkg)); + } + + @Test + public void testStopVpnProfileFromDiffPackage() { + assertThrows(SecurityException.class, () -> mService.stopVpnProfile(mNotMyVpnPkg)); + } + + @Test + public void testGetProvisionedVpnProfileStateFromDiffPackage() { + assertThrows(SecurityException.class, () -> + mService.getProvisionedVpnProfileState(mNotMyVpnPkg)); + } + + @Test + public void testGetProvisionedVpnProfileState() { + mService.getProvisionedVpnProfileState(TEST_VPN_PKG); + verify(mVpn).getProvisionedVpnProfileState(TEST_VPN_PKG); + } + + private Intent buildIntent(String action, String packageName, int userId, int uid, + boolean isReplacing) { + final Intent intent = new Intent(action); + intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); + intent.putExtra(Intent.EXTRA_UID, uid); + intent.putExtra(Intent.EXTRA_REPLACING, isReplacing); + if (packageName != null) { + intent.setData(Uri.fromParts("package" /* scheme */, packageName, null /* fragment */)); + } + + return intent; + } + + private void sendIntent(Intent intent) { + sendIntent(mIntentReceiver, mContext, intent); + } + + private void sendIntent(BroadcastReceiver receiver, Context context, Intent intent) { + final Handler h = mHandlerThread.getThreadHandler(); + + // Send in handler thread. + h.post(() -> receiver.onReceive(context, intent)); + HandlerUtils.waitForIdle(mHandlerThread, TIMEOUT_MS); + } + + private void onUserStarted(int userId) { + sendIntent(buildIntent(Intent.ACTION_USER_STARTED, + null /* packageName */, userId, -1 /* uid */, false /* isReplacing */)); + } + + private void onUserUnlocked(int userId) { + sendIntent(buildIntent(Intent.ACTION_USER_UNLOCKED, + null /* packageName */, userId, -1 /* uid */, false /* isReplacing */)); + } + + private void onUserStopped(int userId) { + sendIntent(buildIntent(Intent.ACTION_USER_STOPPED, + null /* packageName */, userId, -1 /* uid */, false /* isReplacing */)); + } + + private void onLockDownReset() { + sendIntent(buildIntent(LockdownVpnTracker.ACTION_LOCKDOWN_RESET, null /* packageName */, + UserHandle.USER_SYSTEM, -1 /* uid */, false /* isReplacing */)); + } + + private void onPackageAdded(String packageName, int userId, int uid, boolean isReplacing) { + sendIntent(buildIntent(Intent.ACTION_PACKAGE_ADDED, packageName, userId, uid, isReplacing)); + } + + private void onPackageAdded(String packageName, int uid, boolean isReplacing) { + onPackageAdded(packageName, UserHandle.USER_SYSTEM, uid, isReplacing); + } + + private void onPackageRemoved(String packageName, int userId, int uid, boolean isReplacing) { + sendIntent(buildIntent(Intent.ACTION_PACKAGE_REMOVED, packageName, userId, uid, + isReplacing)); + } + + private void onPackageRemoved(String packageName, int uid, boolean isReplacing) { + onPackageRemoved(packageName, UserHandle.USER_SYSTEM, uid, isReplacing); + } + + @Test + public void testReceiveIntentFromNonHandlerThread() { + assertThrows(IllegalStateException.class, () -> + mIntentReceiver.onReceive(mContext, buildIntent(Intent.ACTION_PACKAGE_REMOVED, + PKGS[0], UserHandle.USER_SYSTEM, PKG_UIDS[0], true /* isReplacing */))); + + assertThrows(IllegalStateException.class, () -> + mUserPresentReceiver.onReceive(mContext, new Intent(Intent.ACTION_USER_PRESENT))); + } + + private void setupLockdownVpn(String packageName) { + final byte[] profileTag = packageName.getBytes(StandardCharsets.UTF_8); + doReturn(profileTag).when(mVpnProfileStore).get(Credentials.LOCKDOWN_VPN); + } + + private void setupVpnProfile(String profileName) { + final VpnProfile profile = new VpnProfile(profileName); + profile.name = profileName; + profile.server = "192.0.2.1"; + profile.dnsServers = "8.8.8.8"; + profile.type = VpnProfile.TYPE_IPSEC_XAUTH_PSK; + final byte[] encodedProfile = profile.encode(); + doReturn(encodedProfile).when(mVpnProfileStore).get(Credentials.VPN + profileName); + } + + @Test + public void testUserPresent() { + // Verify that LockDownVpnTracker is not created. + verify(mLockdownVpnTracker, never()).init(); + + setupLockdownVpn(TEST_VPN_PKG); + setupVpnProfile(TEST_VPN_PKG); + + // mUserPresentReceiver only registers ACTION_USER_PRESENT intent and does no verification + // on action, so an empty intent is enough. + sendIntent(mUserPresentReceiver, mSystemContext, new Intent()); + + verify(mLockdownVpnTracker).init(); + verify(mSystemContext).unregisterReceiver(mUserPresentReceiver); + verify(mUserAllContext, never()).unregisterReceiver(any()); + } + + @Test + public void testUpdateLockdownVpn() { + setupLockdownVpn(TEST_VPN_PKG); + onUserUnlocked(SYSTEM_USER_ID); + + // Will not create lockDownVpnTracker w/o valid profile configured in the keystore + verify(mLockdownVpnTracker, never()).init(); + + setupVpnProfile(TEST_VPN_PKG); + + // Remove the user from mVpns + onUserStopped(SYSTEM_USER_ID); + onUserUnlocked(SYSTEM_USER_ID); + verify(mLockdownVpnTracker, never()).init(); + + // Add user back + onUserStarted(SYSTEM_USER_ID); + verify(mLockdownVpnTracker).init(); + + // Trigger another update. The existing LockDownVpnTracker should be shut down and + // initialize another one. + onUserUnlocked(SYSTEM_USER_ID); + verify(mLockdownVpnTracker).shutdown(); + verify(mLockdownVpnTracker, times(2)).init(); + } + + @Test + public void testLockdownReset() { + // Init LockdownVpnTracker + setupLockdownVpn(TEST_VPN_PKG); + setupVpnProfile(TEST_VPN_PKG); + onUserUnlocked(SYSTEM_USER_ID); + verify(mLockdownVpnTracker).init(); + + onLockDownReset(); + verify(mLockdownVpnTracker).reset(); + } + + @Test + public void testLockdownResetWhenLockdownVpnTrackerIsNotInit() { + setupLockdownVpn(TEST_VPN_PKG); + setupVpnProfile(TEST_VPN_PKG); + + onLockDownReset(); + + // LockDownVpnTracker is not created. Lockdown reset will not take effect. + verify(mLockdownVpnTracker, never()).reset(); + } + + @Test + public void testIsVpnLockdownEnabled() { + // Vpn is created but the VPN lockdown is not enabled. + assertFalse(mService.isVpnLockdownEnabled(SYSTEM_USER_ID)); + + // Set lockdown for the SYSTEM_USER_ID VPN. + doReturn(true).when(mVpn).getLockdown(); + assertTrue(mService.isVpnLockdownEnabled(SYSTEM_USER_ID)); + + // Even lockdown is enabled but no Vpn is created for SECONDARY_USER. + assertFalse(mService.isVpnLockdownEnabled(SECONDARY_USER.id)); + } + + @Test + public void testGetVpnLockdownAllowlist() { + doReturn(null).when(mVpn).getLockdownAllowlist(); + assertNull(mService.getVpnLockdownAllowlist(SYSTEM_USER_ID)); + + final List<String> expected = List.of(PKGS); + doReturn(expected).when(mVpn).getLockdownAllowlist(); + assertEquals(expected, mService.getVpnLockdownAllowlist(SYSTEM_USER_ID)); + + // Even lockdown is enabled but no Vpn is created for SECONDARY_USER. + assertNull(mService.getVpnLockdownAllowlist(SECONDARY_USER.id)); + } +} diff --git a/services/tests/VpnTests/java/com/android/server/VpnTestBase.java b/services/tests/VpnTests/java/com/android/server/VpnTestBase.java new file mode 100644 index 000000000000..6113872e213f --- /dev/null +++ b/services/tests/VpnTests/java/com/android/server/VpnTestBase.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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; + +import static android.content.pm.UserInfo.FLAG_ADMIN; +import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE; +import static android.content.pm.UserInfo.FLAG_PRIMARY; +import static android.content.pm.UserInfo.FLAG_RESTRICTED; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doAnswer; + +import android.content.pm.PackageManager; +import android.content.pm.UserInfo; +import android.os.Process; +import android.os.UserHandle; +import android.util.ArrayMap; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** Common variables or methods shared between VpnTest and VpnManagerServiceTest. */ +public class VpnTestBase { + protected static final String TEST_VPN_PKG = "com.testvpn.vpn"; + /** + * Names and UIDs for some fake packages. Important points: + * - UID is ordered increasing. + * - One pair of packages have consecutive UIDs. + */ + protected static final String[] PKGS = {"com.example", "org.example", "net.example", "web.vpn"}; + protected static final int[] PKG_UIDS = {10066, 10077, 10078, 10400}; + // Mock packages + protected static final Map<String, Integer> sPackages = new ArrayMap<>(); + static { + for (int i = 0; i < PKGS.length; i++) { + sPackages.put(PKGS[i], PKG_UIDS[i]); + } + sPackages.put(TEST_VPN_PKG, Process.myUid()); + } + + // Mock users + protected static final int SYSTEM_USER_ID = 0; + protected static final UserInfo SYSTEM_USER = new UserInfo(0, "system", UserInfo.FLAG_PRIMARY); + protected static final UserInfo PRIMARY_USER = new UserInfo(27, "Primary", + FLAG_ADMIN | FLAG_PRIMARY); + protected static final UserInfo SECONDARY_USER = new UserInfo(15, "Secondary", FLAG_ADMIN); + protected static final UserInfo RESTRICTED_PROFILE_A = new UserInfo(40, "RestrictedA", + FLAG_RESTRICTED); + protected static final UserInfo RESTRICTED_PROFILE_B = new UserInfo(42, "RestrictedB", + FLAG_RESTRICTED); + protected static final UserInfo MANAGED_PROFILE_A = new UserInfo(45, "ManagedA", + FLAG_MANAGED_PROFILE); + static { + RESTRICTED_PROFILE_A.restrictedProfileParentId = PRIMARY_USER.id; + RESTRICTED_PROFILE_B.restrictedProfileParentId = SECONDARY_USER.id; + MANAGED_PROFILE_A.profileGroupId = PRIMARY_USER.id; + } + + // Populate a fake packageName-to-UID mapping. + protected void setMockedPackages(PackageManager mockPm, final Map<String, Integer> packages) { + try { + doAnswer(invocation -> { + final String appName = (String) invocation.getArguments()[0]; + final int userId = (int) invocation.getArguments()[1]; + + final Integer appId = packages.get(appName); + if (appId == null) { + throw new PackageManager.NameNotFoundException(appName); + } + + return UserHandle.getUid(userId, appId); + }).when(mockPm).getPackageUidAsUser(anyString(), anyInt()); + } catch (Exception e) { + } + } + + protected List<Integer> toList(int[] arr) { + return Arrays.stream(arr).boxed().collect(Collectors.toList()); + } +} diff --git a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java new file mode 100644 index 000000000000..9115f952b724 --- /dev/null +++ b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java @@ -0,0 +1,3293 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.connectivity; + +import static android.Manifest.permission.BIND_VPN_SERVICE; +import static android.Manifest.permission.CONTROL_VPN; +import static android.content.pm.PackageManager.PERMISSION_DENIED; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback; +import static android.net.ConnectivityDiagnosticsManager.DataStallReport; +import static android.net.ConnectivityManager.NetworkCallback; +import static android.net.INetd.IF_STATE_DOWN; +import static android.net.INetd.IF_STATE_UP; +import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static android.net.RouteInfo.RTN_UNREACHABLE; +import static android.net.VpnManager.TYPE_VPN_PLATFORM; +import static android.net.cts.util.IkeSessionTestUtils.CHILD_PARAMS; +import static android.net.cts.util.IkeSessionTestUtils.TEST_IDENTITY; +import static android.net.cts.util.IkeSessionTestUtils.TEST_KEEPALIVE_TIMEOUT_UNSET; +import static android.net.cts.util.IkeSessionTestUtils.getTestIkeSessionParams; +import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_MOBIKE; +import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_AUTO; +import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_NONE; +import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_UDP; +import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_AUTO; +import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_IPV4; +import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_IPV6; +import static android.os.UserHandle.PER_USER_RANGE; +import static android.telephony.CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL; +import static android.telephony.CarrierConfigManager.KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; +import static android.telephony.CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT; + +import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU; +import static com.android.server.connectivity.Vpn.AUTOMATIC_KEEPALIVE_DELAY_SECONDS; +import static com.android.server.connectivity.Vpn.DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC; +import static com.android.server.connectivity.Vpn.DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; +import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_AUTO; +import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_IPV4_UDP; +import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_IPV6_ESP; +import static com.android.server.connectivity.Vpn.PREFERRED_IKE_PROTOCOL_IPV6_UDP; +import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor; +import static com.android.testutils.MiscAsserts.assertThrows; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.longThat; +import static org.mockito.Mockito.after; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.annotation.NonNull; +import android.annotation.UserIdInt; +import android.app.AppOpsManager; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.content.pm.UserInfo; +import android.content.res.Resources; +import android.net.ConnectivityDiagnosticsManager; +import android.net.ConnectivityManager; +import android.net.INetd; +import android.net.Ikev2VpnProfile; +import android.net.InetAddresses; +import android.net.InterfaceConfigurationParcel; +import android.net.IpPrefix; +import android.net.IpSecConfig; +import android.net.IpSecManager; +import android.net.IpSecTransform; +import android.net.IpSecTunnelInterfaceResponse; +import android.net.LinkAddress; +import android.net.LinkProperties; +import android.net.Network; +import android.net.NetworkAgent; +import android.net.NetworkAgentConfig; +import android.net.NetworkCapabilities; +import android.net.NetworkInfo.DetailedState; +import android.net.RouteInfo; +import android.net.TelephonyNetworkSpecifier; +import android.net.UidRangeParcel; +import android.net.VpnManager; +import android.net.VpnProfileState; +import android.net.VpnService; +import android.net.VpnTransportInfo; +import android.net.ipsec.ike.ChildSessionCallback; +import android.net.ipsec.ike.ChildSessionConfiguration; +import android.net.ipsec.ike.IkeFqdnIdentification; +import android.net.ipsec.ike.IkeSessionCallback; +import android.net.ipsec.ike.IkeSessionConfiguration; +import android.net.ipsec.ike.IkeSessionConnectionInfo; +import android.net.ipsec.ike.IkeSessionParams; +import android.net.ipsec.ike.IkeTrafficSelector; +import android.net.ipsec.ike.IkeTunnelConnectionParams; +import android.net.ipsec.ike.exceptions.IkeException; +import android.net.ipsec.ike.exceptions.IkeNetworkLostException; +import android.net.ipsec.ike.exceptions.IkeNonProtocolException; +import android.net.ipsec.ike.exceptions.IkeProtocolException; +import android.net.ipsec.ike.exceptions.IkeTimeoutException; +import android.net.vcn.VcnTransportInfo; +import android.net.wifi.WifiInfo; +import android.os.Build.VERSION_CODES; +import android.os.Bundle; +import android.os.INetworkManagementService; +import android.os.ParcelFileDescriptor; +import android.os.PersistableBundle; +import android.os.PowerWhitelistManager; +import android.os.Process; +import android.os.UserHandle; +import android.os.UserManager; +import android.os.test.TestLooper; +import android.provider.Settings; +import android.security.Credentials; +import android.telephony.CarrierConfigManager; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; +import android.util.ArrayMap; +import android.util.ArraySet; +import android.util.Pair; +import android.util.Range; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; + +import com.android.internal.R; +import com.android.internal.net.LegacyVpnInfo; +import com.android.internal.net.VpnConfig; +import com.android.internal.net.VpnProfile; +import com.android.internal.util.HexDump; +import com.android.internal.util.IndentingPrintWriter; +import com.android.server.DeviceIdleInternal; +import com.android.server.IpSecService; +import com.android.server.VpnTestBase; +import com.android.server.vcn.util.PersistableBundleUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.AdditionalAnswers; +import org.mockito.Answers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.StringWriter; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Tests for {@link Vpn}. + * + * Build, install and run with: + * runtest frameworks-net -c com.android.server.connectivity.VpnTest + */ +@RunWith(AndroidJUnit4.class) +@SmallTest +public class VpnTest extends VpnTestBase { + private static final String TAG = "VpnTest"; + + static final Network EGRESS_NETWORK = new Network(101); + static final String EGRESS_IFACE = "wlan0"; + private static final String TEST_VPN_CLIENT = "2.4.6.8"; + private static final String TEST_VPN_SERVER = "1.2.3.4"; + private static final String TEST_VPN_IDENTITY = "identity"; + private static final byte[] TEST_VPN_PSK = "psk".getBytes(); + + private static final int IP4_PREFIX_LEN = 32; + private static final int IP6_PREFIX_LEN = 64; + private static final int MIN_PORT = 0; + private static final int MAX_PORT = 65535; + + private static final InetAddress TEST_VPN_CLIENT_IP = + InetAddresses.parseNumericAddress(TEST_VPN_CLIENT); + private static final InetAddress TEST_VPN_SERVER_IP = + InetAddresses.parseNumericAddress(TEST_VPN_SERVER); + private static final InetAddress TEST_VPN_CLIENT_IP_2 = + InetAddresses.parseNumericAddress("192.0.2.200"); + private static final InetAddress TEST_VPN_SERVER_IP_2 = + InetAddresses.parseNumericAddress("192.0.2.201"); + private static final InetAddress TEST_VPN_INTERNAL_IP = + InetAddresses.parseNumericAddress("198.51.100.10"); + private static final InetAddress TEST_VPN_INTERNAL_IP6 = + InetAddresses.parseNumericAddress("2001:db8::1"); + private static final InetAddress TEST_VPN_INTERNAL_DNS = + InetAddresses.parseNumericAddress("8.8.8.8"); + private static final InetAddress TEST_VPN_INTERNAL_DNS6 = + InetAddresses.parseNumericAddress("2001:4860:4860::8888"); + + private static final IkeTrafficSelector IN_TS = + new IkeTrafficSelector(MIN_PORT, MAX_PORT, TEST_VPN_INTERNAL_IP, TEST_VPN_INTERNAL_IP); + private static final IkeTrafficSelector IN_TS6 = + new IkeTrafficSelector( + MIN_PORT, MAX_PORT, TEST_VPN_INTERNAL_IP6, TEST_VPN_INTERNAL_IP6); + private static final IkeTrafficSelector OUT_TS = + new IkeTrafficSelector(MIN_PORT, MAX_PORT, + InetAddresses.parseNumericAddress("0.0.0.0"), + InetAddresses.parseNumericAddress("255.255.255.255")); + private static final IkeTrafficSelector OUT_TS6 = + new IkeTrafficSelector( + MIN_PORT, + MAX_PORT, + InetAddresses.parseNumericAddress("::"), + InetAddresses.parseNumericAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); + + private static final Network TEST_NETWORK = new Network(Integer.MAX_VALUE); + private static final Network TEST_NETWORK_2 = new Network(Integer.MAX_VALUE - 1); + private static final String TEST_IFACE_NAME = "TEST_IFACE"; + private static final int TEST_TUNNEL_RESOURCE_ID = 0x2345; + private static final long TEST_TIMEOUT_MS = 500L; + private static final long TIMEOUT_CROSSTHREAD_MS = 20_000L; + private static final String PRIMARY_USER_APP_EXCLUDE_KEY = + "VPNAPPEXCLUDED_27_com.testvpn.vpn"; + static final String PKGS_BYTES = getPackageByteString(List.of(PKGS)); + private static final Range<Integer> PRIMARY_USER_RANGE = uidRangeForUser(PRIMARY_USER.id); + private static final int TEST_KEEPALIVE_TIMER = 800; + private static final int TEST_SUB_ID = 1234; + private static final String TEST_MCCMNC = "12345"; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; + @Mock private UserManager mUserManager; + @Mock private PackageManager mPackageManager; + @Mock private INetworkManagementService mNetService; + @Mock private INetd mNetd; + @Mock private AppOpsManager mAppOps; + @Mock private NotificationManager mNotificationManager; + @Mock private Vpn.SystemServices mSystemServices; + @Mock private Vpn.IkeSessionWrapper mIkeSessionWrapper; + @Mock private Vpn.Ikev2SessionCreator mIkev2SessionCreator; + @Mock private Vpn.VpnNetworkAgentWrapper mMockNetworkAgent; + @Mock private ConnectivityManager mConnectivityManager; + @Mock private ConnectivityDiagnosticsManager mCdm; + @Mock private TelephonyManager mTelephonyManager; + @Mock private TelephonyManager mTmPerSub; + @Mock private CarrierConfigManager mConfigManager; + @Mock private SubscriptionManager mSubscriptionManager; + @Mock private IpSecService mIpSecService; + @Mock private VpnProfileStore mVpnProfileStore; + private final TestExecutor mExecutor; + @Mock DeviceIdleInternal mDeviceIdleInternal; + private final VpnProfile mVpnProfile; + + @Captor private ArgumentCaptor<Collection<Range<Integer>>> mUidRangesCaptor; + + private IpSecManager mIpSecManager; + private TestDeps mTestDeps; + + public static class TestExecutor extends ScheduledThreadPoolExecutor { + public static final long REAL_DELAY = -1; + + // For the purposes of the test, run all scheduled tasks after 10ms to save + // execution time, unless overridden by the specific test. Set to REAL_DELAY + // to actually wait for the delay specified by the real call to schedule(). + public long delayMs = 10; + // If this is true, execute() will call the runnable inline. This is useful because + // super.execute() calls schedule(), which messes with checks that scheduled() is + // called a given number of times. + public boolean executeDirect = false; + + public TestExecutor() { + super(1); + } + + @Override + public void execute(final Runnable command) { + // See |executeDirect| for why this is necessary. + if (executeDirect) { + command.run(); + } else { + super.execute(command); + } + } + + @Override + public ScheduledFuture<?> schedule(final Runnable command, final long delay, + TimeUnit unit) { + if (0 == delay || delayMs == REAL_DELAY) { + // super.execute() calls schedule() with 0, so use the real delay if it's 0. + return super.schedule(command, delay, unit); + } else { + return super.schedule(command, delayMs, TimeUnit.MILLISECONDS); + } + } + } + + public VpnTest() throws Exception { + // Build an actual VPN profile that is capable of being converted to and from an + // Ikev2VpnProfile + final Ikev2VpnProfile.Builder builder = + new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY); + builder.setAuthPsk(TEST_VPN_PSK); + builder.setBypassable(true /* isBypassable */); + mExecutor = spy(new TestExecutor()); + mVpnProfile = builder.build().toVpnProfile(); + } + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mIpSecManager = new IpSecManager(mContext, mIpSecService); + mTestDeps = spy(new TestDeps()); + doReturn(IPV6_MIN_MTU) + .when(mTestDeps) + .calculateVpnMtu(any(), anyInt(), anyInt(), anyBoolean()); + doReturn(1500).when(mTestDeps).getJavaNetworkInterfaceMtu(any(), anyInt()); + + when(mContext.getPackageManager()).thenReturn(mPackageManager); + setMockedPackages(sPackages); + + when(mContext.getPackageName()).thenReturn(TEST_VPN_PKG); + when(mContext.getOpPackageName()).thenReturn(TEST_VPN_PKG); + mockService(UserManager.class, Context.USER_SERVICE, mUserManager); + mockService(AppOpsManager.class, Context.APP_OPS_SERVICE, mAppOps); + mockService(NotificationManager.class, Context.NOTIFICATION_SERVICE, mNotificationManager); + mockService(ConnectivityManager.class, Context.CONNECTIVITY_SERVICE, mConnectivityManager); + mockService(IpSecManager.class, Context.IPSEC_SERVICE, mIpSecManager); + mockService(ConnectivityDiagnosticsManager.class, Context.CONNECTIVITY_DIAGNOSTICS_SERVICE, + mCdm); + mockService(TelephonyManager.class, Context.TELEPHONY_SERVICE, mTelephonyManager); + mockService(CarrierConfigManager.class, Context.CARRIER_CONFIG_SERVICE, mConfigManager); + mockService(SubscriptionManager.class, Context.TELEPHONY_SUBSCRIPTION_SERVICE, + mSubscriptionManager); + doReturn(mTmPerSub).when(mTelephonyManager).createForSubscriptionId(anyInt()); + when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)) + .thenReturn(Resources.getSystem().getString( + R.string.config_customVpnAlwaysOnDisconnectedDialogComponent)); + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)) + .thenReturn(true); + + // Used by {@link Notification.Builder} + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT; + when(mContext.getApplicationInfo()).thenReturn(applicationInfo); + when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) + .thenReturn(applicationInfo); + + doNothing().when(mNetService).registerObserver(any()); + + // Deny all appops by default. + when(mAppOps.noteOpNoThrow(anyString(), anyInt(), anyString(), any(), any())) + .thenReturn(AppOpsManager.MODE_IGNORED); + + // Setup IpSecService + final IpSecTunnelInterfaceResponse tunnelResp = + new IpSecTunnelInterfaceResponse( + IpSecManager.Status.OK, TEST_TUNNEL_RESOURCE_ID, TEST_IFACE_NAME); + when(mIpSecService.createTunnelInterface(any(), any(), any(), any(), any())) + .thenReturn(tunnelResp); + doReturn(new LinkProperties()).when(mConnectivityManager).getLinkProperties(any()); + + // The unit test should know what kind of permission it needs and set the permission by + // itself, so set the default value of Context#checkCallingOrSelfPermission to + // PERMISSION_DENIED. + doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(any()); + + // Set up mIkev2SessionCreator and mExecutor + resetIkev2SessionCreator(mIkeSessionWrapper); + } + + private void resetIkev2SessionCreator(Vpn.IkeSessionWrapper ikeSession) { + reset(mIkev2SessionCreator); + when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any())) + .thenReturn(ikeSession); + } + + private <T> void mockService(Class<T> clazz, String name, T service) { + doReturn(service).when(mContext).getSystemService(name); + doReturn(name).when(mContext).getSystemServiceName(clazz); + if (mContext.getSystemService(clazz).getClass().equals(Object.class)) { + // Test is using mockito-extended (mContext uses Answers.RETURNS_DEEP_STUBS and returned + // a mock object on a final method) + doCallRealMethod().when(mContext).getSystemService(clazz); + } + } + + private Set<Range<Integer>> rangeSet(Range<Integer> ... ranges) { + final Set<Range<Integer>> range = new ArraySet<>(); + for (Range<Integer> r : ranges) range.add(r); + + return range; + } + + private static Range<Integer> uidRangeForUser(int userId) { + return new Range<Integer>(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1); + } + + private Range<Integer> uidRange(int start, int stop) { + return new Range<Integer>(start, stop); + } + + private static String getPackageByteString(List<String> packages) { + try { + return HexDump.toHexString( + PersistableBundleUtils.toDiskStableBytes(PersistableBundleUtils.fromList( + packages, PersistableBundleUtils.STRING_SERIALIZER)), + true /* upperCase */); + } catch (IOException e) { + return null; + } + } + + @Test + public void testRestrictedProfilesAreAddedToVpn() { + setMockedUsers(PRIMARY_USER, SECONDARY_USER, RESTRICTED_PROFILE_A, RESTRICTED_PROFILE_B); + + final Vpn vpn = createVpn(PRIMARY_USER.id); + + // Assume the user can have restricted profiles. + doReturn(true).when(mUserManager).canHaveRestrictedProfile(); + final Set<Range<Integer>> ranges = + vpn.createUserAndRestrictedProfilesRanges(PRIMARY_USER.id, null, null); + + assertEquals(rangeSet(PRIMARY_USER_RANGE, uidRangeForUser(RESTRICTED_PROFILE_A.id)), + ranges); + } + + @Test + public void testManagedProfilesAreNotAddedToVpn() { + setMockedUsers(PRIMARY_USER, MANAGED_PROFILE_A); + + final Vpn vpn = createVpn(PRIMARY_USER.id); + final Set<Range<Integer>> ranges = vpn.createUserAndRestrictedProfilesRanges( + PRIMARY_USER.id, null, null); + + assertEquals(rangeSet(PRIMARY_USER_RANGE), ranges); + } + + @Test + public void testAddUserToVpnOnlyAddsOneUser() { + setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A, MANAGED_PROFILE_A); + + final Vpn vpn = createVpn(PRIMARY_USER.id); + final Set<Range<Integer>> ranges = new ArraySet<>(); + vpn.addUserToRanges(ranges, PRIMARY_USER.id, null, null); + + assertEquals(rangeSet(PRIMARY_USER_RANGE), ranges); + } + + @Test + public void testUidAllowAndDenylist() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + final Range<Integer> user = PRIMARY_USER_RANGE; + final int userStart = user.getLower(); + final int userStop = user.getUpper(); + final String[] packages = {PKGS[0], PKGS[1], PKGS[2]}; + + // Allowed list + final Set<Range<Integer>> allow = vpn.createUserAndRestrictedProfilesRanges(PRIMARY_USER.id, + Arrays.asList(packages), null /* disallowedApplications */); + assertEquals(rangeSet( + uidRange(userStart + PKG_UIDS[0], userStart + PKG_UIDS[0]), + uidRange(userStart + PKG_UIDS[1], userStart + PKG_UIDS[2]), + uidRange(Process.toSdkSandboxUid(userStart + PKG_UIDS[0]), + Process.toSdkSandboxUid(userStart + PKG_UIDS[0])), + uidRange(Process.toSdkSandboxUid(userStart + PKG_UIDS[1]), + Process.toSdkSandboxUid(userStart + PKG_UIDS[2]))), + allow); + + // Denied list + final Set<Range<Integer>> disallow = + vpn.createUserAndRestrictedProfilesRanges(PRIMARY_USER.id, + null /* allowedApplications */, Arrays.asList(packages)); + assertEquals(rangeSet( + uidRange(userStart, userStart + PKG_UIDS[0] - 1), + uidRange(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), + /* Empty range between UIDS[1] and UIDS[2], should be excluded, */ + uidRange(userStart + PKG_UIDS[2] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), + uidRange(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), + Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), + uidRange(Process.toSdkSandboxUid(userStart + PKG_UIDS[2] + 1), userStop)), + disallow); + } + + private void verifyPowerSaveTempWhitelistApp(String packageName) { + verify(mDeviceIdleInternal, timeout(TEST_TIMEOUT_MS)).addPowerSaveTempWhitelistApp( + anyInt(), eq(packageName), anyLong(), anyInt(), eq(false), + eq(PowerWhitelistManager.REASON_VPN), eq("VpnManager event")); + } + + @Test + public void testGetAlwaysAndOnGetLockDown() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + + // Default state. + assertFalse(vpn.getAlwaysOn()); + assertFalse(vpn.getLockdown()); + + // Set always-on without lockdown. + assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, Collections.emptyList())); + assertTrue(vpn.getAlwaysOn()); + assertFalse(vpn.getLockdown()); + + // Set always-on with lockdown. + assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, Collections.emptyList())); + assertTrue(vpn.getAlwaysOn()); + assertTrue(vpn.getLockdown()); + + // Remove always-on configuration. + assertTrue(vpn.setAlwaysOnPackage(null, false, Collections.emptyList())); + assertFalse(vpn.getAlwaysOn()); + assertFalse(vpn.getLockdown()); + } + + @Test + public void testAlwaysOnWithoutLockdown() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + assertTrue(vpn.setAlwaysOnPackage( + PKGS[1], false /* lockdown */, null /* lockdownAllowlist */)); + verify(mConnectivityManager, never()).setRequireVpnForUids(anyBoolean(), any()); + + assertTrue(vpn.setAlwaysOnPackage( + null /* packageName */, false /* lockdown */, null /* lockdownAllowlist */)); + verify(mConnectivityManager, never()).setRequireVpnForUids(anyBoolean(), any()); + } + + @Test + public void testLockdownChangingPackage() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + final Range<Integer> user = PRIMARY_USER_RANGE; + final int userStart = user.getLower(); + final int userStop = user.getUpper(); + // Set always-on without lockdown. + assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false, null)); + + // Set always-on with lockdown. + assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true, null)); + verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), userStop) + })); + + // Switch to another app. + assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true, null)); + verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), userStop) + })); + verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart, userStart + PKG_UIDS[3] - 1), + new UidRangeParcel(userStart + PKG_UIDS[3] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[3] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[3] + 1), userStop) + })); + } + + @Test + public void testLockdownAllowlist() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + final Range<Integer> user = PRIMARY_USER_RANGE; + final int userStart = user.getLower(); + final int userStop = user.getUpper(); + // Set always-on with lockdown and allow app PKGS[2] from lockdown. + assertTrue(vpn.setAlwaysOnPackage( + PKGS[1], true, Collections.singletonList(PKGS[2]))); + verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[2] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[1]) - 1), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[2] + 1), userStop) + })); + // Change allowed app list to PKGS[3]. + assertTrue(vpn.setAlwaysOnPackage( + PKGS[1], true, Collections.singletonList(PKGS[3]))); + verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart + PKG_UIDS[2] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[2] + 1), userStop) + })); + verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1), + new UidRangeParcel(userStart + PKG_UIDS[3] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), + Process.toSdkSandboxUid(userStart + PKG_UIDS[3] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[3] + 1), userStop) + })); + + // Change the VPN app. + assertTrue(vpn.setAlwaysOnPackage( + PKGS[0], true, Collections.singletonList(PKGS[3]))); + verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, userStart + PKG_UIDS[3] - 1), + new UidRangeParcel(userStart + PKG_UIDS[3] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), + Process.toSdkSandboxUid(userStart + PKG_UIDS[3] - 1)) + })); + verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart, userStart + PKG_UIDS[0] - 1), + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1), + new UidRangeParcel(userStart + PKG_UIDS[3] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), + Process.toSdkSandboxUid(userStart + PKG_UIDS[3] - 1)) + })); + + // Remove the list of allowed packages. + assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null)); + verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[3] - 1), + new UidRangeParcel(userStart + PKG_UIDS[3] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), + Process.toSdkSandboxUid(userStart + PKG_UIDS[3] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[3] + 1), userStop) + })); + verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), userStop), + })); + + // Add the list of allowed packages. + assertTrue(vpn.setAlwaysOnPackage( + PKGS[0], true, Collections.singletonList(PKGS[1]))); + verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), userStop), + })); + verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), + Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), userStop) + })); + + // Try allowing a package with a comma, should be rejected. + assertFalse(vpn.setAlwaysOnPackage( + PKGS[0], true, Collections.singletonList("a.b,c.d"))); + + // Pass a non-existent packages in the allowlist, they (and only they) should be ignored. + // allowed package should change from PGKS[1] to PKGS[2]. + assertTrue(vpn.setAlwaysOnPackage( + PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app"))); + verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[1] - 1), + new UidRangeParcel(userStart + PKG_UIDS[1] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), + Process.toSdkSandboxUid(userStart + PKG_UIDS[1] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[1] + 1), userStop) + })); + verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(new UidRangeParcel[] { + new UidRangeParcel(userStart + PKG_UIDS[0] + 1, userStart + PKG_UIDS[2] - 1), + new UidRangeParcel(userStart + PKG_UIDS[2] + 1, + Process.toSdkSandboxUid(userStart + PKG_UIDS[0] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[0] + 1), + Process.toSdkSandboxUid(userStart + PKG_UIDS[2] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(userStart + PKG_UIDS[2] + 1), userStop) + })); + } + + @Test + public void testLockdownSystemUser() throws Exception { + final Vpn vpn = createVpn(SYSTEM_USER_ID); + + // Uid 0 is always excluded and PKG_UIDS[1] is the uid of the VPN. + final List<Integer> excludedUids = new ArrayList<>(List.of(0, PKG_UIDS[1])); + final List<Range<Integer>> ranges = makeVpnUidRange(SYSTEM_USER_ID, excludedUids); + + // Set always-on with lockdown. + assertTrue(vpn.setAlwaysOnPackage( + PKGS[1], true /* lockdown */, null /* lockdownAllowlist */)); + verify(mConnectivityManager).setRequireVpnForUids(true, ranges); + + // Disable always-on with lockdown. + assertTrue(vpn.setAlwaysOnPackage( + null /* packageName */, false /* lockdown */, null /* lockdownAllowlist */)); + verify(mConnectivityManager).setRequireVpnForUids(false, ranges); + + // Set always-on with lockdown and allow the app PKGS[2]. + excludedUids.add(PKG_UIDS[2]); + final List<Range<Integer>> ranges2 = makeVpnUidRange(SYSTEM_USER_ID, excludedUids); + assertTrue(vpn.setAlwaysOnPackage( + PKGS[1], true /* lockdown */, Collections.singletonList(PKGS[2]))); + verify(mConnectivityManager).setRequireVpnForUids(true, ranges2); + + // Disable always-on with lockdown. + assertTrue(vpn.setAlwaysOnPackage( + null /* packageName */, false /* lockdown */, null /* lockdownAllowlist */)); + verify(mConnectivityManager).setRequireVpnForUids(false, ranges2); + } + + @Test + public void testLockdownRuleRepeatability() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] { + new UidRangeParcel(PRIMARY_USER_RANGE.getLower(), PRIMARY_USER_RANGE.getUpper())}; + // Given legacy lockdown is already enabled, + vpn.setLockdown(true); + verify(mConnectivityManager, times(1)).setRequireVpnForUids(true, + toRanges(primaryUserRangeParcel)); + + // Enabling legacy lockdown twice should do nothing. + vpn.setLockdown(true); + verify(mConnectivityManager, times(1)).setRequireVpnForUids(anyBoolean(), any()); + + // And disabling should remove the rules exactly once. + vpn.setLockdown(false); + verify(mConnectivityManager, times(1)).setRequireVpnForUids(false, + toRanges(primaryUserRangeParcel)); + + // Removing the lockdown again should have no effect. + vpn.setLockdown(false); + verify(mConnectivityManager, times(2)).setRequireVpnForUids(anyBoolean(), any()); + } + + private ArrayList<Range<Integer>> toRanges(UidRangeParcel[] ranges) { + ArrayList<Range<Integer>> rangesArray = new ArrayList<>(ranges.length); + for (int i = 0; i < ranges.length; i++) { + rangesArray.add(new Range<>(ranges[i].start, ranges[i].stop)); + } + return rangesArray; + } + + @Test + public void testLockdownRuleReversibility() throws Exception { + doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN); + final Vpn vpn = createVpn(PRIMARY_USER.id); + final UidRangeParcel[] entireUser = { + new UidRangeParcel(PRIMARY_USER_RANGE.getLower(), PRIMARY_USER_RANGE.getUpper()) + }; + final UidRangeParcel[] exceptPkg0 = { + new UidRangeParcel(entireUser[0].start, entireUser[0].start + PKG_UIDS[0] - 1), + new UidRangeParcel(entireUser[0].start + PKG_UIDS[0] + 1, + Process.toSdkSandboxUid(entireUser[0].start + PKG_UIDS[0] - 1)), + new UidRangeParcel(Process.toSdkSandboxUid(entireUser[0].start + PKG_UIDS[0] + 1), + entireUser[0].stop), + }; + + final InOrder order = inOrder(mConnectivityManager); + + // Given lockdown is enabled with no package (legacy VPN), + vpn.setLockdown(true); + order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(entireUser)); + + // When a new VPN package is set the rules should change to cover that package. + vpn.prepare(null, PKGS[0], VpnManager.TYPE_VPN_SERVICE); + order.verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(entireUser)); + order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(exceptPkg0)); + + // When that VPN package is unset, everything should be undone again in reverse. + vpn.prepare(null, VpnConfig.LEGACY_VPN, VpnManager.TYPE_VPN_SERVICE); + order.verify(mConnectivityManager).setRequireVpnForUids(false, toRanges(exceptPkg0)); + order.verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(entireUser)); + } + + @Test + public void testOnUserAddedAndRemoved_restrictedUser() throws Exception { + final InOrder order = inOrder(mMockNetworkAgent); + final Vpn vpn = createVpn(PRIMARY_USER.id); + final Set<Range<Integer>> initialRange = rangeSet(PRIMARY_USER_RANGE); + // Note since mVpnProfile is a Ikev2VpnProfile, this starts an IkeV2VpnRunner. + startLegacyVpn(vpn, mVpnProfile); + // Set an initial Uid range and mock the network agent + vpn.mNetworkCapabilities.setUids(initialRange); + vpn.mNetworkAgent = mMockNetworkAgent; + + // Add the restricted user + setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A); + vpn.onUserAdded(RESTRICTED_PROFILE_A.id); + // Expect restricted user range to be added to the NetworkCapabilities. + final Set<Range<Integer>> expectRestrictedRange = + rangeSet(PRIMARY_USER_RANGE, uidRangeForUser(RESTRICTED_PROFILE_A.id)); + assertEquals(expectRestrictedRange, vpn.mNetworkCapabilities.getUids()); + order.verify(mMockNetworkAgent).doSendNetworkCapabilities( + argThat(nc -> expectRestrictedRange.equals(nc.getUids()))); + + // Remove the restricted user + vpn.onUserRemoved(RESTRICTED_PROFILE_A.id); + // Expect restricted user range to be removed from the NetworkCapabilities. + assertEquals(initialRange, vpn.mNetworkCapabilities.getUids()); + order.verify(mMockNetworkAgent).doSendNetworkCapabilities( + argThat(nc -> initialRange.equals(nc.getUids()))); + } + + @Test + public void testOnUserAddedAndRemoved_restrictedUserLockdown() throws Exception { + final UidRangeParcel[] primaryUserRangeParcel = new UidRangeParcel[] { + new UidRangeParcel(PRIMARY_USER_RANGE.getLower(), PRIMARY_USER_RANGE.getUpper())}; + final Range<Integer> restrictedUserRange = uidRangeForUser(RESTRICTED_PROFILE_A.id); + final UidRangeParcel[] restrictedUserRangeParcel = new UidRangeParcel[] { + new UidRangeParcel(restrictedUserRange.getLower(), restrictedUserRange.getUpper())}; + final Vpn vpn = createVpn(PRIMARY_USER.id); + + // Set lockdown calls setRequireVpnForUids + vpn.setLockdown(true); + verify(mConnectivityManager).setRequireVpnForUids(true, toRanges(primaryUserRangeParcel)); + + // Add the restricted user + doReturn(true).when(mUserManager).canHaveRestrictedProfile(); + setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A); + vpn.onUserAdded(RESTRICTED_PROFILE_A.id); + + // Expect restricted user range to be added. + verify(mConnectivityManager).setRequireVpnForUids(true, + toRanges(restrictedUserRangeParcel)); + + // Mark as partial indicates that the user is removed, mUserManager.getAliveUsers() does not + // return the restricted user but it is still returned in mUserManager.getUserInfo(). + RESTRICTED_PROFILE_A.partial = true; + // Remove the restricted user + vpn.onUserRemoved(RESTRICTED_PROFILE_A.id); + verify(mConnectivityManager).setRequireVpnForUids(false, + toRanges(restrictedUserRangeParcel)); + // reset to avoid affecting other tests since RESTRICTED_PROFILE_A is static. + RESTRICTED_PROFILE_A.partial = false; + } + + @Test + public void testOnUserAddedAndRemoved_restrictedUserAlwaysOn() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + + // setAlwaysOnPackage() calls setRequireVpnForUids() + assertTrue(vpn.setAlwaysOnPackage( + PKGS[0], true /* lockdown */, null /* lockdownAllowlist */)); + final List<Integer> excludedUids = List.of(PKG_UIDS[0]); + final List<Range<Integer>> primaryRanges = + makeVpnUidRange(PRIMARY_USER.id, excludedUids); + verify(mConnectivityManager).setRequireVpnForUids(true, primaryRanges); + + // Add the restricted user + doReturn(true).when(mUserManager).canHaveRestrictedProfile(); + setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A); + vpn.onUserAdded(RESTRICTED_PROFILE_A.id); + + final List<Range<Integer>> restrictedRanges = + makeVpnUidRange(RESTRICTED_PROFILE_A.id, excludedUids); + // Expect restricted user range to be added. + verify(mConnectivityManager).setRequireVpnForUids(true, restrictedRanges); + + // Mark as partial indicates that the user is removed, mUserManager.getAliveUsers() does not + // return the restricted user but it is still returned in mUserManager.getUserInfo(). + RESTRICTED_PROFILE_A.partial = true; + // Remove the restricted user + vpn.onUserRemoved(RESTRICTED_PROFILE_A.id); + verify(mConnectivityManager).setRequireVpnForUids(false, restrictedRanges); + + // reset to avoid affecting other tests since RESTRICTED_PROFILE_A is static. + RESTRICTED_PROFILE_A.partial = false; + } + + @Test + public void testPrepare_throwSecurityExceptionWhenGivenPackageDoesNotBelongToTheCaller() + throws Exception { + mTestDeps.mIgnoreCallingUidChecks = false; + final Vpn vpn = createVpn(); + assertThrows(SecurityException.class, + () -> vpn.prepare("com.not.vpn.owner", null, VpnManager.TYPE_VPN_SERVICE)); + assertThrows(SecurityException.class, + () -> vpn.prepare(null, "com.not.vpn.owner", VpnManager.TYPE_VPN_SERVICE)); + assertThrows(SecurityException.class, + () -> vpn.prepare("com.not.vpn.owner1", "com.not.vpn.owner2", + VpnManager.TYPE_VPN_SERVICE)); + } + + @Test + public void testPrepare_bothOldPackageAndNewPackageAreNull() throws Exception { + final Vpn vpn = createVpn(); + assertTrue(vpn.prepare(null, null, VpnManager.TYPE_VPN_SERVICE)); + + } + + @Test + public void testPrepare_legacyVpnWithoutControlVpn() + throws Exception { + doThrow(new SecurityException("no CONTROL_VPN")).when(mContext) + .enforceCallingOrSelfPermission(eq(CONTROL_VPN), any()); + final Vpn vpn = createVpn(); + assertThrows(SecurityException.class, + () -> vpn.prepare(null, VpnConfig.LEGACY_VPN, VpnManager.TYPE_VPN_SERVICE)); + + // CONTROL_VPN can be held by the caller or another system server process - both are + // allowed. Just checking for `enforceCallingPermission` may not be sufficient. + verify(mContext, never()).enforceCallingPermission(eq(CONTROL_VPN), any()); + } + + @Test + public void testPrepare_legacyVpnWithControlVpn() + throws Exception { + doNothing().when(mContext).enforceCallingOrSelfPermission(eq(CONTROL_VPN), any()); + final Vpn vpn = createVpn(); + assertTrue(vpn.prepare(null, VpnConfig.LEGACY_VPN, VpnManager.TYPE_VPN_SERVICE)); + + // CONTROL_VPN can be held by the caller or another system server process - both are + // allowed. Just checking for `enforceCallingPermission` may not be sufficient. + verify(mContext, never()).enforceCallingPermission(eq(CONTROL_VPN), any()); + } + + @Test + public void testIsAlwaysOnPackageSupported() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + + ApplicationInfo appInfo = new ApplicationInfo(); + when(mPackageManager.getApplicationInfoAsUser(eq(PKGS[0]), anyInt(), eq(PRIMARY_USER.id))) + .thenReturn(appInfo); + + ServiceInfo svcInfo = new ServiceInfo(); + ResolveInfo resInfo = new ResolveInfo(); + resInfo.serviceInfo = svcInfo; + when(mPackageManager.queryIntentServicesAsUser(any(), eq(PackageManager.GET_META_DATA), + eq(PRIMARY_USER.id))) + .thenReturn(Collections.singletonList(resInfo)); + + // null package name should return false + assertFalse(vpn.isAlwaysOnPackageSupported(null)); + + // Pre-N apps are not supported + appInfo.targetSdkVersion = VERSION_CODES.M; + assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0])); + + // N+ apps are supported by default + appInfo.targetSdkVersion = VERSION_CODES.N; + assertTrue(vpn.isAlwaysOnPackageSupported(PKGS[0])); + + // Apps that opt out explicitly are not supported + appInfo.targetSdkVersion = VERSION_CODES.CUR_DEVELOPMENT; + Bundle metaData = new Bundle(); + metaData.putBoolean(VpnService.SERVICE_META_DATA_SUPPORTS_ALWAYS_ON, false); + svcInfo.metaData = metaData; + assertFalse(vpn.isAlwaysOnPackageSupported(PKGS[0])); + } + + @Test + public void testNotificationShownForAlwaysOnApp() throws Exception { + final UserHandle userHandle = UserHandle.of(PRIMARY_USER.id); + final Vpn vpn = createVpn(PRIMARY_USER.id); + setMockedUsers(PRIMARY_USER); + + final InOrder order = inOrder(mNotificationManager); + + // Don't show a notification for regular disconnected states. + vpn.updateState(DetailedState.DISCONNECTED, TAG); + order.verify(mNotificationManager, atLeastOnce()).cancel(anyString(), anyInt()); + + // Start showing a notification for disconnected once always-on. + vpn.setAlwaysOnPackage(PKGS[0], false, null); + order.verify(mNotificationManager).notify(anyString(), anyInt(), any()); + + // Stop showing the notification once connected. + vpn.updateState(DetailedState.CONNECTED, TAG); + order.verify(mNotificationManager).cancel(anyString(), anyInt()); + + // Show the notification if we disconnect again. + vpn.updateState(DetailedState.DISCONNECTED, TAG); + order.verify(mNotificationManager).notify(anyString(), anyInt(), any()); + + // Notification should be cleared after unsetting always-on package. + vpn.setAlwaysOnPackage(null, false, null); + order.verify(mNotificationManager).cancel(anyString(), anyInt()); + } + + /** + * The profile name should NOT change between releases for backwards compatibility + * + * <p>If this is changed between releases, the {@link Vpn#getVpnProfilePrivileged()} method MUST + * be updated to ensure backward compatibility. + */ + @Test + public void testGetProfileNameForPackage() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + setMockedUsers(PRIMARY_USER); + + final String expected = Credentials.PLATFORM_VPN + PRIMARY_USER.id + "_" + TEST_VPN_PKG; + assertEquals(expected, vpn.getProfileNameForPackage(TEST_VPN_PKG)); + } + + private Vpn createVpn(String... grantedOps) throws Exception { + return createVpn(PRIMARY_USER, grantedOps); + } + + private Vpn createVpn(UserInfo user, String... grantedOps) throws Exception { + final Vpn vpn = createVpn(user.id); + setMockedUsers(user); + + for (final String opStr : grantedOps) { + when(mAppOps.noteOpNoThrow(opStr, Process.myUid(), TEST_VPN_PKG, + null /* attributionTag */, null /* message */)) + .thenReturn(AppOpsManager.MODE_ALLOWED); + } + + return vpn; + } + + private void checkProvisionVpnProfile(Vpn vpn, boolean expectedResult, String... checkedOps) { + assertEquals(expectedResult, vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile)); + + // The profile should always be stored, whether or not consent has been previously granted. + verify(mVpnProfileStore) + .put( + eq(vpn.getProfileNameForPackage(TEST_VPN_PKG)), + eq(mVpnProfile.encode())); + + for (final String checkedOpStr : checkedOps) { + verify(mAppOps).noteOpNoThrow(checkedOpStr, Process.myUid(), TEST_VPN_PKG, + null /* attributionTag */, null /* message */); + } + } + + @Test + public void testProvisionVpnProfileNoIpsecTunnels() throws Exception { + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)) + .thenReturn(false); + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + + try { + checkProvisionVpnProfile( + vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + fail("Expected exception due to missing feature"); + } catch (UnsupportedOperationException expected) { + } + } + + private String startVpnForVerifyAppExclusionList(Vpn vpn) throws Exception { + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(mVpnProfile.encode()); + when(mVpnProfileStore.get(PRIMARY_USER_APP_EXCLUDE_KEY)) + .thenReturn(HexDump.hexStringToByteArray(PKGS_BYTES)); + final String sessionKey = vpn.startVpnProfile(TEST_VPN_PKG); + final Set<Range<Integer>> uidRanges = vpn.createUserAndRestrictedProfilesRanges( + PRIMARY_USER.id, null /* allowedApplications */, Arrays.asList(PKGS)); + verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); + clearInvocations(mConnectivityManager); + verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); + vpn.mNetworkAgent = mMockNetworkAgent; + + return sessionKey; + } + + private Vpn prepareVpnForVerifyAppExclusionList() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + startVpnForVerifyAppExclusionList(vpn); + + return vpn; + } + + @Test + public void testSetAndGetAppExclusionList() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + final String sessionKey = startVpnForVerifyAppExclusionList(vpn); + verify(mVpnProfileStore, never()).put(eq(PRIMARY_USER_APP_EXCLUDE_KEY), any()); + vpn.setAppExclusionList(TEST_VPN_PKG, Arrays.asList(PKGS)); + verify(mVpnProfileStore) + .put(eq(PRIMARY_USER_APP_EXCLUDE_KEY), + eq(HexDump.hexStringToByteArray(PKGS_BYTES))); + final Set<Range<Integer>> uidRanges = vpn.createUserAndRestrictedProfilesRanges( + PRIMARY_USER.id, null /* allowedApplications */, Arrays.asList(PKGS)); + verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); + assertEquals(uidRanges, vpn.mNetworkCapabilities.getUids()); + assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG)); + } + + @Test + public void testRefreshPlatformVpnAppExclusionList_updatesExcludedUids() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + final String sessionKey = startVpnForVerifyAppExclusionList(vpn); + vpn.setAppExclusionList(TEST_VPN_PKG, Arrays.asList(PKGS)); + final Set<Range<Integer>> uidRanges = vpn.createUserAndRestrictedProfilesRanges( + PRIMARY_USER.id, null /* allowedApplications */, Arrays.asList(PKGS)); + verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); + verify(mMockNetworkAgent).doSendNetworkCapabilities(any()); + assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG)); + + reset(mMockNetworkAgent); + + // Remove one of the package + List<Integer> newExcludedUids = toList(PKG_UIDS); + newExcludedUids.remove((Integer) PKG_UIDS[0]); + Set<Range<Integer>> newUidRanges = makeVpnUidRangeSet(PRIMARY_USER.id, newExcludedUids); + sPackages.remove(PKGS[0]); + vpn.refreshPlatformVpnAppExclusionList(); + + // List in keystore is not changed, but UID for the removed packages is no longer exempted. + assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG)); + assertEquals(newUidRanges, vpn.mNetworkCapabilities.getUids()); + ArgumentCaptor<NetworkCapabilities> ncCaptor = + ArgumentCaptor.forClass(NetworkCapabilities.class); + verify(mMockNetworkAgent).doSendNetworkCapabilities(ncCaptor.capture()); + assertEquals(newUidRanges, ncCaptor.getValue().getUids()); + verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), eq(newUidRanges)); + + reset(mMockNetworkAgent); + + // Add the package back + newExcludedUids.add(PKG_UIDS[0]); + newUidRanges = makeVpnUidRangeSet(PRIMARY_USER.id, newExcludedUids); + sPackages.put(PKGS[0], PKG_UIDS[0]); + vpn.refreshPlatformVpnAppExclusionList(); + + // List in keystore is not changed and the uid list should be updated in the net cap. + assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG)); + assertEquals(newUidRanges, vpn.mNetworkCapabilities.getUids()); + verify(mMockNetworkAgent).doSendNetworkCapabilities(ncCaptor.capture()); + assertEquals(newUidRanges, ncCaptor.getValue().getUids()); + + // The uidRange is the same as the original setAppExclusionList so this is the second call + verify(mConnectivityManager, times(2)) + .setVpnDefaultForUids(eq(sessionKey), eq(newUidRanges)); + } + + private List<Range<Integer>> makeVpnUidRange(int userId, List<Integer> excludedAppIdList) { + final SortedSet<Integer> list = new TreeSet<>(); + + final int userBase = userId * UserHandle.PER_USER_RANGE; + for (int appId : excludedAppIdList) { + final int uid = UserHandle.getUid(userId, appId); + list.add(uid); + if (Process.isApplicationUid(uid)) { + list.add(Process.toSdkSandboxUid(uid)); // Add Sdk Sandbox UID + } + } + + final int minUid = userBase; + final int maxUid = userBase + UserHandle.PER_USER_RANGE - 1; + final List<Range<Integer>> ranges = new ArrayList<>(); + + // Iterate the list to create the ranges between each uid. + int start = minUid; + for (int uid : list) { + if (uid == start) { + start++; + } else { + ranges.add(new Range<>(start, uid - 1)); + start = uid + 1; + } + } + + // Create the range between last uid and max uid. + if (start <= maxUid) { + ranges.add(new Range<>(start, maxUid)); + } + + return ranges; + } + + private Set<Range<Integer>> makeVpnUidRangeSet(int userId, List<Integer> excludedAppIdList) { + return new ArraySet<>(makeVpnUidRange(userId, excludedAppIdList)); + } + + @Test + public void testSetAndGetAppExclusionListRestrictedUser() throws Exception { + final Vpn vpn = prepareVpnForVerifyAppExclusionList(); + + // Mock it to restricted profile + when(mUserManager.getUserInfo(anyInt())).thenReturn(RESTRICTED_PROFILE_A); + + // Restricted users cannot configure VPNs + assertThrows(SecurityException.class, + () -> vpn.setAppExclusionList(TEST_VPN_PKG, new ArrayList<>())); + + assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG)); + } + + @Test + public void testProvisionVpnProfilePreconsented() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + + checkProvisionVpnProfile( + vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + } + + @Test + public void testProvisionVpnProfileNotPreconsented() throws Exception { + final Vpn vpn = createVpn(); + + // Expect that both the ACTIVATE_VPN and ACTIVATE_PLATFORM_VPN were tried, but the caller + // had neither. + checkProvisionVpnProfile(vpn, false /* expectedResult */, + AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, AppOpsManager.OPSTR_ACTIVATE_VPN); + } + + @Test + public void testProvisionVpnProfileVpnServicePreconsented() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_VPN); + + checkProvisionVpnProfile(vpn, true /* expectedResult */, AppOpsManager.OPSTR_ACTIVATE_VPN); + } + + @Test + public void testProvisionVpnProfileTooLarge() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + + final VpnProfile bigProfile = new VpnProfile(""); + bigProfile.name = new String(new byte[Vpn.MAX_VPN_PROFILE_SIZE_BYTES + 1]); + + try { + vpn.provisionVpnProfile(TEST_VPN_PKG, bigProfile); + fail("Expected IAE due to profile size"); + } catch (IllegalArgumentException expected) { + } + } + + @Test + public void testProvisionVpnProfileRestrictedUser() throws Exception { + final Vpn vpn = + createVpn( + RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + + try { + vpn.provisionVpnProfile(TEST_VPN_PKG, mVpnProfile); + fail("Expected SecurityException due to restricted user"); + } catch (SecurityException expected) { + } + } + + @Test + public void testDeleteVpnProfile() throws Exception { + final Vpn vpn = createVpn(); + + vpn.deleteVpnProfile(TEST_VPN_PKG); + + verify(mVpnProfileStore) + .remove(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); + } + + @Test + public void testDeleteVpnProfileRestrictedUser() throws Exception { + final Vpn vpn = + createVpn( + RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + + try { + vpn.deleteVpnProfile(TEST_VPN_PKG); + fail("Expected SecurityException due to restricted user"); + } catch (SecurityException expected) { + } + } + + @Test + public void testGetVpnProfilePrivileged() throws Exception { + final Vpn vpn = createVpn(); + + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(new VpnProfile("").encode()); + + vpn.getVpnProfilePrivileged(TEST_VPN_PKG); + + verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); + } + + private void verifyPlatformVpnIsActivated(String packageName) { + verify(mAppOps).noteOpNoThrow( + eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), + eq(Process.myUid()), + eq(packageName), + eq(null) /* attributionTag */, + eq(null) /* message */); + verify(mAppOps).startOp( + eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER), + eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), + eq(packageName), + eq(null) /* attributionTag */, + eq(null) /* message */); + } + + private void verifyPlatformVpnIsDeactivated(String packageName) { + // Add a small delay to double confirm that finishOp is only called once. + verify(mAppOps, after(100)).finishOp( + eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER), + eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), + eq(packageName), + eq(null) /* attributionTag */); + } + + @Test + public void testStartVpnProfile() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(mVpnProfile.encode()); + + vpn.startVpnProfile(TEST_VPN_PKG); + + verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); + verifyPlatformVpnIsActivated(TEST_VPN_PKG); + } + + @Test + public void testStartVpnProfileVpnServicePreconsented() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_VPN); + + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(mVpnProfile.encode()); + + vpn.startVpnProfile(TEST_VPN_PKG); + + // Verify that the ACTIVATE_VPN appop was checked, but no error was thrown. + verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(), + TEST_VPN_PKG, null /* attributionTag */, null /* message */); + } + + @Test + public void testStartVpnProfileNotConsented() throws Exception { + final Vpn vpn = createVpn(); + + try { + vpn.startVpnProfile(TEST_VPN_PKG); + fail("Expected failure due to no user consent"); + } catch (SecurityException expected) { + } + + // Verify both appops were checked. + verify(mAppOps) + .noteOpNoThrow( + eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), + eq(Process.myUid()), + eq(TEST_VPN_PKG), + eq(null) /* attributionTag */, + eq(null) /* message */); + verify(mAppOps).noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_VPN, Process.myUid(), + TEST_VPN_PKG, null /* attributionTag */, null /* message */); + + // Keystore should never have been accessed. + verify(mVpnProfileStore, never()).get(any()); + } + + @Test + public void testStartVpnProfileMissingProfile() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))).thenReturn(null); + + try { + vpn.startVpnProfile(TEST_VPN_PKG); + fail("Expected failure due to missing profile"); + } catch (IllegalArgumentException expected) { + } + + verify(mVpnProfileStore).get(vpn.getProfileNameForPackage(TEST_VPN_PKG)); + verify(mAppOps) + .noteOpNoThrow( + eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), + eq(Process.myUid()), + eq(TEST_VPN_PKG), + eq(null) /* attributionTag */, + eq(null) /* message */); + } + + @Test + public void testStartVpnProfileRestrictedUser() throws Exception { + final Vpn vpn = createVpn(RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + + try { + vpn.startVpnProfile(TEST_VPN_PKG); + fail("Expected SecurityException due to restricted user"); + } catch (SecurityException expected) { + } + } + + @Test + public void testStopVpnProfileRestrictedUser() throws Exception { + final Vpn vpn = createVpn(RESTRICTED_PROFILE_A, AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + + try { + vpn.stopVpnProfile(TEST_VPN_PKG); + fail("Expected SecurityException due to restricted user"); + } catch (SecurityException expected) { + } + } + + @Test + public void testStartOpAndFinishOpWillBeCalledWhenPlatformVpnIsOnAndOff() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(mVpnProfile.encode()); + vpn.startVpnProfile(TEST_VPN_PKG); + verifyPlatformVpnIsActivated(TEST_VPN_PKG); + // Add a small delay to make sure that startOp is only called once. + verify(mAppOps, after(100).times(1)).startOp( + eq(AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER), + eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), + eq(TEST_VPN_PKG), + eq(null) /* attributionTag */, + eq(null) /* message */); + // Check that the startOp is not called with OPSTR_ESTABLISH_VPN_SERVICE. + verify(mAppOps, never()).startOp( + eq(AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE), + eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), + eq(TEST_VPN_PKG), + eq(null) /* attributionTag */, + eq(null) /* message */); + vpn.stopVpnProfile(TEST_VPN_PKG); + verifyPlatformVpnIsDeactivated(TEST_VPN_PKG); + } + + @Test + public void testStartOpWithSeamlessHandover() throws Exception { + // Create with SYSTEM_USER so that establish() will match the user ID when checking + // against Binder.getCallerUid + final Vpn vpn = createVpn(SYSTEM_USER, AppOpsManager.OPSTR_ACTIVATE_VPN); + assertTrue(vpn.prepare(TEST_VPN_PKG, null, VpnManager.TYPE_VPN_SERVICE)); + final VpnConfig config = new VpnConfig(); + config.user = "VpnTest"; + config.addresses.add(new LinkAddress("192.0.2.2/32")); + config.mtu = 1450; + final ResolveInfo resolveInfo = new ResolveInfo(); + final ServiceInfo serviceInfo = new ServiceInfo(); + serviceInfo.permission = BIND_VPN_SERVICE; + resolveInfo.serviceInfo = serviceInfo; + when(mPackageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo); + when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); + vpn.establish(config); + verify(mAppOps, times(1)).startOp( + eq(AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE), + eq(Process.myUid()), + eq(TEST_VPN_PKG), + eq(null) /* attributionTag */, + eq(null) /* message */); + // Call establish() twice with the same config, it should match seamless handover case and + // startOp() shouldn't be called again. + vpn.establish(config); + verify(mAppOps, times(1)).startOp( + eq(AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE), + eq(Process.myUid()), + eq(TEST_VPN_PKG), + eq(null) /* attributionTag */, + eq(null) /* message */); + } + + private void verifyVpnManagerEvent(String sessionKey, String category, int errorClass, + int errorCode, String[] packageName, @NonNull VpnProfileState... profileState) { + final Context userContext = + mContext.createContextAsUser(UserHandle.of(PRIMARY_USER.id), 0 /* flags */); + final ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); + + final int verifyTimes = profileState.length; + verify(userContext, timeout(TEST_TIMEOUT_MS).times(verifyTimes)) + .startService(intentArgumentCaptor.capture()); + + for (int i = 0; i < verifyTimes; i++) { + final Intent intent = intentArgumentCaptor.getAllValues().get(i); + assertEquals(packageName[i], intent.getPackage()); + assertEquals(sessionKey, intent.getStringExtra(VpnManager.EXTRA_SESSION_KEY)); + final Set<String> categories = intent.getCategories(); + assertTrue(categories.contains(category)); + assertEquals(1, categories.size()); + assertEquals(errorClass, + intent.getIntExtra(VpnManager.EXTRA_ERROR_CLASS, -1 /* defaultValue */)); + assertEquals(errorCode, + intent.getIntExtra(VpnManager.EXTRA_ERROR_CODE, -1 /* defaultValue */)); + // CATEGORY_EVENT_DEACTIVATED_BY_USER & CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED won't + // send NetworkCapabilities & LinkProperties to VPN app. + // For ERROR_CODE_NETWORK_LOST, the NetworkCapabilities & LinkProperties of underlying + // network will be cleared. So the VPN app will receive null for those 2 extra values. + if (category.equals(VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER) + || category.equals(VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED) + || errorCode == VpnManager.ERROR_CODE_NETWORK_LOST) { + assertNull(intent.getParcelableExtra( + VpnManager.EXTRA_UNDERLYING_NETWORK_CAPABILITIES)); + assertNull(intent.getParcelableExtra(VpnManager.EXTRA_UNDERLYING_LINK_PROPERTIES)); + } else { + assertNotNull(intent.getParcelableExtra( + VpnManager.EXTRA_UNDERLYING_NETWORK_CAPABILITIES)); + assertNotNull(intent.getParcelableExtra( + VpnManager.EXTRA_UNDERLYING_LINK_PROPERTIES)); + } + + assertEquals(profileState[i], intent.getParcelableExtra( + VpnManager.EXTRA_VPN_PROFILE_STATE, VpnProfileState.class)); + } + reset(userContext); + } + + private void verifyDeactivatedByUser(String sessionKey, String[] packageName) { + // CATEGORY_EVENT_DEACTIVATED_BY_USER is not an error event, so both of errorClass and + // errorCode won't be set. + verifyVpnManagerEvent(sessionKey, VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER, + -1 /* errorClass */, -1 /* errorCode */, packageName, + // VPN NetworkAgnet does not switch to CONNECTED in the test, and the state is not + // important here. Verify that the state as it is, i.e. CONNECTING state. + new VpnProfileState(VpnProfileState.STATE_CONNECTING, + sessionKey, false /* alwaysOn */, false /* lockdown */)); + } + + private void verifyAlwaysOnStateChanged(String[] packageName, VpnProfileState... profileState) { + verifyVpnManagerEvent(null /* sessionKey */, + VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */, + -1 /* errorCode */, packageName, profileState); + } + + @Test + public void testVpnManagerEventForUserDeactivated() throws Exception { + // For security reasons, Vpn#prepare() will check that oldPackage and newPackage are either + // null or the package of the caller. This test will call Vpn#prepare() to pretend the old + // VPN is replaced by a new one. But only Settings can change to some other packages, and + // this is checked with CONTROL_VPN so simulate holding CONTROL_VPN in order to pass the + // security checks. + doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN); + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(mVpnProfile.encode()); + + // Test the case that the user deactivates the vpn in vpn app. + final String sessionKey1 = vpn.startVpnProfile(TEST_VPN_PKG); + verifyPlatformVpnIsActivated(TEST_VPN_PKG); + vpn.stopVpnProfile(TEST_VPN_PKG); + verifyPlatformVpnIsDeactivated(TEST_VPN_PKG); + verifyPowerSaveTempWhitelistApp(TEST_VPN_PKG); + reset(mDeviceIdleInternal); + verifyDeactivatedByUser(sessionKey1, new String[] {TEST_VPN_PKG}); + reset(mAppOps); + + // Test the case that the user chooses another vpn and the original one is replaced. + final String sessionKey2 = vpn.startVpnProfile(TEST_VPN_PKG); + verifyPlatformVpnIsActivated(TEST_VPN_PKG); + vpn.prepare(TEST_VPN_PKG, "com.new.vpn" /* newPackage */, TYPE_VPN_PLATFORM); + verifyPlatformVpnIsDeactivated(TEST_VPN_PKG); + verifyPowerSaveTempWhitelistApp(TEST_VPN_PKG); + reset(mDeviceIdleInternal); + verifyDeactivatedByUser(sessionKey2, new String[] {TEST_VPN_PKG}); + } + + @Test + public void testVpnManagerEventForAlwaysOnChanged() throws Exception { + // Calling setAlwaysOnPackage() needs to hold CONTROL_VPN. + doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN); + final Vpn vpn = createVpn(PRIMARY_USER.id); + // Enable VPN always-on for PKGS[1]. + assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false /* lockdown */, + null /* lockdownAllowlist */)); + verifyPowerSaveTempWhitelistApp(PKGS[1]); + reset(mDeviceIdleInternal); + verifyAlwaysOnStateChanged(new String[] {PKGS[1]}, + new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, + null /* sessionKey */, true /* alwaysOn */, false /* lockdown */)); + + // Enable VPN lockdown for PKGS[1]. + assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true /* lockdown */, + null /* lockdownAllowlist */)); + verifyPowerSaveTempWhitelistApp(PKGS[1]); + reset(mDeviceIdleInternal); + verifyAlwaysOnStateChanged(new String[] {PKGS[1]}, + new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, + null /* sessionKey */, true /* alwaysOn */, true /* lockdown */)); + + // Disable VPN lockdown for PKGS[1]. + assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false /* lockdown */, + null /* lockdownAllowlist */)); + verifyPowerSaveTempWhitelistApp(PKGS[1]); + reset(mDeviceIdleInternal); + verifyAlwaysOnStateChanged(new String[] {PKGS[1]}, + new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, + null /* sessionKey */, true /* alwaysOn */, false /* lockdown */)); + + // Disable VPN always-on. + assertTrue(vpn.setAlwaysOnPackage(null, false /* lockdown */, + null /* lockdownAllowlist */)); + verifyPowerSaveTempWhitelistApp(PKGS[1]); + reset(mDeviceIdleInternal); + verifyAlwaysOnStateChanged(new String[] {PKGS[1]}, + new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, + null /* sessionKey */, false /* alwaysOn */, false /* lockdown */)); + + // Enable VPN always-on for PKGS[1] again. + assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false /* lockdown */, + null /* lockdownAllowlist */)); + verifyPowerSaveTempWhitelistApp(PKGS[1]); + reset(mDeviceIdleInternal); + verifyAlwaysOnStateChanged(new String[] {PKGS[1]}, + new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, + null /* sessionKey */, true /* alwaysOn */, false /* lockdown */)); + + // Enable VPN always-on for PKGS[2]. + assertTrue(vpn.setAlwaysOnPackage(PKGS[2], false /* lockdown */, + null /* lockdownAllowlist */)); + verifyPowerSaveTempWhitelistApp(PKGS[2]); + reset(mDeviceIdleInternal); + // PKGS[1] is replaced with PKGS[2]. + // Pass 2 VpnProfileState objects to verifyVpnManagerEvent(), the first one is sent to + // PKGS[1] to notify PKGS[1] that the VPN always-on is disabled, the second one is sent to + // PKGS[2] to notify PKGS[2] that the VPN always-on is enabled. + verifyAlwaysOnStateChanged(new String[] {PKGS[1], PKGS[2]}, + new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, + null /* sessionKey */, false /* alwaysOn */, false /* lockdown */), + new VpnProfileState(VpnProfileState.STATE_DISCONNECTED, + null /* sessionKey */, true /* alwaysOn */, false /* lockdown */)); + } + + @Test + public void testReconnectVpnManagerVpnWithAlwaysOnEnabled() throws Exception { + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(mVpnProfile.encode()); + vpn.startVpnProfile(TEST_VPN_PKG); + verifyPlatformVpnIsActivated(TEST_VPN_PKG); + + // Enable VPN always-on for TEST_VPN_PKG. + assertTrue(vpn.setAlwaysOnPackage(TEST_VPN_PKG, false /* lockdown */, + null /* lockdownAllowlist */)); + + // Reset to verify next startVpnProfile. + reset(mAppOps); + + vpn.stopVpnProfile(TEST_VPN_PKG); + + // Reconnect the vpn with different package will cause exception. + assertThrows(SecurityException.class, () -> vpn.startVpnProfile(PKGS[0])); + + // Reconnect the vpn again with the vpn always on package w/o exception. + vpn.startVpnProfile(TEST_VPN_PKG); + verifyPlatformVpnIsActivated(TEST_VPN_PKG); + } + + @Test + public void testLockdown_enableDisableWhileConnected() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); + + final InOrder order = inOrder(mTestDeps); + order.verify(mTestDeps, timeout(TIMEOUT_CROSSTHREAD_MS)) + .newNetworkAgent(any(), any(), any(), any(), any(), any(), + argThat(config -> config.allowBypass), any(), any()); + + // Make VPN lockdown. + assertTrue(vpnSnapShot.vpn.setAlwaysOnPackage(TEST_VPN_PKG, true /* lockdown */, + null /* lockdownAllowlist */)); + + order.verify(mTestDeps, timeout(TIMEOUT_CROSSTHREAD_MS)) + .newNetworkAgent(any(), any(), any(), any(), any(), any(), + argThat(config -> !config.allowBypass), any(), any()); + + // Disable lockdown. + assertTrue(vpnSnapShot.vpn.setAlwaysOnPackage(TEST_VPN_PKG, false /* lockdown */, + null /* lockdownAllowlist */)); + + order.verify(mTestDeps, timeout(TIMEOUT_CROSSTHREAD_MS)) + .newNetworkAgent(any(), any(), any(), any(), any(), any(), + argThat(config -> config.allowBypass), any(), any()); + } + + @Test + public void testSetPackageAuthorizationVpnService() throws Exception { + final Vpn vpn = createVpn(); + + assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_SERVICE)); + verify(mAppOps) + .setMode( + eq(AppOpsManager.OPSTR_ACTIVATE_VPN), + eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), + eq(TEST_VPN_PKG), + eq(AppOpsManager.MODE_ALLOWED)); + } + + @Test + public void testSetPackageAuthorizationPlatformVpn() throws Exception { + final Vpn vpn = createVpn(); + + assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, TYPE_VPN_PLATFORM)); + verify(mAppOps) + .setMode( + eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), + eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), + eq(TEST_VPN_PKG), + eq(AppOpsManager.MODE_ALLOWED)); + } + + @Test + public void testSetPackageAuthorizationRevokeAuthorization() throws Exception { + final Vpn vpn = createVpn(); + + assertTrue(vpn.setPackageAuthorization(TEST_VPN_PKG, VpnManager.TYPE_VPN_NONE)); + verify(mAppOps) + .setMode( + eq(AppOpsManager.OPSTR_ACTIVATE_VPN), + eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), + eq(TEST_VPN_PKG), + eq(AppOpsManager.MODE_IGNORED)); + verify(mAppOps) + .setMode( + eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), + eq(UserHandle.getUid(PRIMARY_USER.id, Process.myUid())), + eq(TEST_VPN_PKG), + eq(AppOpsManager.MODE_IGNORED)); + } + + private NetworkCallback triggerOnAvailableAndGetCallback() throws Exception { + return triggerOnAvailableAndGetCallback(new NetworkCapabilities.Builder().build()); + } + + private NetworkCallback triggerOnAvailableAndGetCallback( + @NonNull final NetworkCapabilities caps) throws Exception { + final ArgumentCaptor<NetworkCallback> networkCallbackCaptor = + ArgumentCaptor.forClass(NetworkCallback.class); + verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)) + .registerSystemDefaultNetworkCallback(networkCallbackCaptor.capture(), any()); + + // onAvailable() will trigger onDefaultNetworkChanged(), so NetdUtils#setInterfaceUp will be + // invoked. Set the return value of INetd#interfaceGetCfg to prevent NullPointerException. + final InterfaceConfigurationParcel config = new InterfaceConfigurationParcel(); + config.flags = new String[] {IF_STATE_DOWN}; + when(mNetd.interfaceGetCfg(anyString())).thenReturn(config); + final NetworkCallback cb = networkCallbackCaptor.getValue(); + cb.onAvailable(TEST_NETWORK); + // Trigger onCapabilitiesChanged() and onLinkPropertiesChanged() so the test can verify that + // if NetworkCapabilities and LinkProperties of underlying network will be sent/cleared or + // not. + // See verifyVpnManagerEvent(). + cb.onCapabilitiesChanged(TEST_NETWORK, caps); + cb.onLinkPropertiesChanged(TEST_NETWORK, new LinkProperties()); + return cb; + } + + private void verifyInterfaceSetCfgWithFlags(String flag) throws Exception { + // Add a timeout for waiting for interfaceSetCfg to be called. + verify(mNetd, timeout(TEST_TIMEOUT_MS)).interfaceSetCfg(argThat( + config -> Arrays.asList(config.flags).contains(flag))); + } + + private void doTestPlatformVpnWithException(IkeException exception, + String category, int errorType, int errorCode) throws Exception { + final ArgumentCaptor<IkeSessionCallback> captor = + ArgumentCaptor.forClass(IkeSessionCallback.class); + + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(mVpnProfile.encode()); + + doReturn(new NetworkCapabilities()).when(mConnectivityManager) + .getRedactedNetworkCapabilitiesForPackage(any(), anyInt(), anyString()); + doReturn(new LinkProperties()).when(mConnectivityManager) + .getRedactedLinkPropertiesForPackage(any(), anyInt(), anyString()); + + final String sessionKey = vpn.startVpnProfile(TEST_VPN_PKG); + final Set<Range<Integer>> uidRanges = rangeSet(PRIMARY_USER_RANGE); + // This is triggered by Ikev2VpnRunner constructor. + verify(mConnectivityManager, times(1)).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); + final NetworkCallback cb = triggerOnAvailableAndGetCallback(); + + verifyInterfaceSetCfgWithFlags(IF_STATE_UP); + + // Wait for createIkeSession() to be called before proceeding in order to ensure consistent + // state + verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS)) + .createIkeSession(any(), any(), any(), any(), captor.capture(), any()); + // This is triggered by Vpn#startOrMigrateIkeSession(). + verify(mConnectivityManager, times(2)).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); + reset(mIkev2SessionCreator); + // For network lost case, the process should be triggered by calling onLost(), which is the + // same process with the real case. + if (errorCode == VpnManager.ERROR_CODE_NETWORK_LOST) { + cb.onLost(TEST_NETWORK); + verify(mExecutor, atLeastOnce()).schedule(any(Runnable.class), anyLong(), any()); + } else { + final IkeSessionCallback ikeCb = captor.getValue(); + mExecutor.execute(() -> ikeCb.onClosedWithException(exception)); + } + + verifyPowerSaveTempWhitelistApp(TEST_VPN_PKG); + reset(mDeviceIdleInternal); + verifyVpnManagerEvent(sessionKey, category, errorType, errorCode, + // VPN NetworkAgnet does not switch to CONNECTED in the test, and the state is not + // important here. Verify that the state as it is, i.e. CONNECTING state. + new String[] {TEST_VPN_PKG}, new VpnProfileState(VpnProfileState.STATE_CONNECTING, + sessionKey, false /* alwaysOn */, false /* lockdown */)); + if (errorType == VpnManager.ERROR_CLASS_NOT_RECOVERABLE) { + verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), + eq(Collections.EMPTY_LIST)); + verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)) + .unregisterNetworkCallback(eq(cb)); + } else if (errorType == VpnManager.ERROR_CLASS_RECOVERABLE + // Vpn won't retry when there is no usable underlying network. + && errorCode != VpnManager.ERROR_CODE_NETWORK_LOST) { + int retryIndex = 0; + // First failure occurred above. + final IkeSessionCallback retryCb = verifyRetryAndGetNewIkeCb(retryIndex++); + // Trigger 2 more failures to let the retry delay increase to 5s. + mExecutor.execute(() -> retryCb.onClosedWithException(exception)); + final IkeSessionCallback retryCb2 = verifyRetryAndGetNewIkeCb(retryIndex++); + mExecutor.execute(() -> retryCb2.onClosedWithException(exception)); + final IkeSessionCallback retryCb3 = verifyRetryAndGetNewIkeCb(retryIndex++); + + // setVpnDefaultForUids may be called again but the uidRanges should not change. + verify(mConnectivityManager, atLeast(2)).setVpnDefaultForUids(eq(sessionKey), + mUidRangesCaptor.capture()); + final List<Collection<Range<Integer>>> capturedUidRanges = + mUidRangesCaptor.getAllValues(); + for (int i = 2; i < capturedUidRanges.size(); i++) { + // Assert equals no order. + assertTrue( + "uid ranges should not be modified. Expected: " + uidRanges + + ", actual: " + capturedUidRanges.get(i), + capturedUidRanges.get(i).containsAll(uidRanges) + && capturedUidRanges.get(i).size() == uidRanges.size()); + } + + // A fourth failure will cause the retry delay to be greater than 5s. + mExecutor.execute(() -> retryCb3.onClosedWithException(exception)); + verifyRetryAndGetNewIkeCb(retryIndex++); + + // The VPN network preference will be cleared when the retry delay is greater than 5s. + verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), + eq(Collections.EMPTY_LIST)); + } + } + + private IkeSessionCallback verifyRetryAndGetNewIkeCb(int retryIndex) { + final ArgumentCaptor<IkeSessionCallback> ikeCbCaptor = + ArgumentCaptor.forClass(IkeSessionCallback.class); + + // Verify retry is scheduled + final long expectedDelayMs = mTestDeps.getNextRetryDelayMs(retryIndex); + verify(mExecutor, timeout(TEST_TIMEOUT_MS)).schedule(any(Runnable.class), + eq(expectedDelayMs), eq(TimeUnit.MILLISECONDS)); + + verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS + expectedDelayMs)) + .createIkeSession(any(), any(), any(), any(), ikeCbCaptor.capture(), any()); + + // Forget the mIkev2SessionCreator#createIkeSession call and mExecutor#schedule call + // for the next retry verification + resetIkev2SessionCreator(mIkeSessionWrapper); + + return ikeCbCaptor.getValue(); + } + + @Test + public void testStartPlatformVpnAuthenticationFailed() throws Exception { + final IkeProtocolException exception = mock(IkeProtocolException.class); + final int errorCode = IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED; + when(exception.getErrorType()).thenReturn(errorCode); + doTestPlatformVpnWithException(exception, + VpnManager.CATEGORY_EVENT_IKE_ERROR, VpnManager.ERROR_CLASS_NOT_RECOVERABLE, + errorCode); + } + + @Test + public void testStartPlatformVpnFailedWithRecoverableError() throws Exception { + final IkeProtocolException exception = mock(IkeProtocolException.class); + final int errorCode = IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE; + when(exception.getErrorType()).thenReturn(errorCode); + doTestPlatformVpnWithException(exception, + VpnManager.CATEGORY_EVENT_IKE_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, errorCode); + } + + @Test + public void testStartPlatformVpnFailedWithUnknownHostException() throws Exception { + final IkeNonProtocolException exception = mock(IkeNonProtocolException.class); + final UnknownHostException unknownHostException = new UnknownHostException(); + final int errorCode = VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST; + when(exception.getCause()).thenReturn(unknownHostException); + doTestPlatformVpnWithException(exception, + VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, + errorCode); + } + + @Test + public void testStartPlatformVpnFailedWithIkeTimeoutException() throws Exception { + final IkeNonProtocolException exception = mock(IkeNonProtocolException.class); + final IkeTimeoutException ikeTimeoutException = + new IkeTimeoutException("IkeTimeoutException"); + final int errorCode = VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT; + when(exception.getCause()).thenReturn(ikeTimeoutException); + doTestPlatformVpnWithException(exception, + VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, + errorCode); + } + + @Test + public void testStartPlatformVpnFailedWithIkeNetworkLostException() throws Exception { + final IkeNetworkLostException exception = new IkeNetworkLostException( + new Network(100)); + doTestPlatformVpnWithException(exception, + VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, + VpnManager.ERROR_CODE_NETWORK_LOST); + } + + @Test + public void testStartPlatformVpnFailedWithIOException() throws Exception { + final IkeNonProtocolException exception = mock(IkeNonProtocolException.class); + final IOException ioException = new IOException(); + final int errorCode = VpnManager.ERROR_CODE_NETWORK_IO; + when(exception.getCause()).thenReturn(ioException); + doTestPlatformVpnWithException(exception, + VpnManager.CATEGORY_EVENT_NETWORK_ERROR, VpnManager.ERROR_CLASS_RECOVERABLE, + errorCode); + } + + @Test + public void testStartPlatformVpnIllegalArgumentExceptionInSetup() throws Exception { + when(mIkev2SessionCreator.createIkeSession(any(), any(), any(), any(), any(), any())) + .thenThrow(new IllegalArgumentException()); + final Vpn vpn = startLegacyVpn(createVpn(PRIMARY_USER.id), mVpnProfile); + final NetworkCallback cb = triggerOnAvailableAndGetCallback(); + + verifyInterfaceSetCfgWithFlags(IF_STATE_UP); + + // Wait for createIkeSession() to be called before proceeding in order to ensure consistent + // state + verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb)); + assertEquals(LegacyVpnInfo.STATE_FAILED, vpn.getLegacyVpnInfo().state); + } + + @Test + public void testVpnManagerEventWillNotBeSentToSettingsVpn() throws Exception { + startLegacyVpn(createVpn(PRIMARY_USER.id), mVpnProfile); + triggerOnAvailableAndGetCallback(); + + verifyInterfaceSetCfgWithFlags(IF_STATE_UP); + + final IkeNonProtocolException exception = mock(IkeNonProtocolException.class); + final IkeTimeoutException ikeTimeoutException = + new IkeTimeoutException("IkeTimeoutException"); + when(exception.getCause()).thenReturn(ikeTimeoutException); + + final ArgumentCaptor<IkeSessionCallback> captor = + ArgumentCaptor.forClass(IkeSessionCallback.class); + verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS)) + .createIkeSession(any(), any(), any(), any(), captor.capture(), any()); + final IkeSessionCallback ikeCb = captor.getValue(); + ikeCb.onClosedWithException(exception); + + final Context userContext = + mContext.createContextAsUser(UserHandle.of(PRIMARY_USER.id), 0 /* flags */); + verify(userContext, never()).startService(any()); + } + + private void setAndVerifyAlwaysOnPackage(Vpn vpn, int uid, boolean lockdownEnabled) { + assertTrue(vpn.setAlwaysOnPackage(TEST_VPN_PKG, lockdownEnabled, null)); + + verify(mVpnProfileStore).get(eq(vpn.getProfileNameForPackage(TEST_VPN_PKG))); + verify(mAppOps).setMode( + eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN), eq(uid), eq(TEST_VPN_PKG), + eq(AppOpsManager.MODE_ALLOWED)); + + verify(mSystemServices).settingsSecurePutStringForUser( + eq(Settings.Secure.ALWAYS_ON_VPN_APP), eq(TEST_VPN_PKG), eq(PRIMARY_USER.id)); + verify(mSystemServices).settingsSecurePutIntForUser( + eq(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN), eq(lockdownEnabled ? 1 : 0), + eq(PRIMARY_USER.id)); + verify(mSystemServices).settingsSecurePutStringForUser( + eq(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST), eq(""), eq(PRIMARY_USER.id)); + } + + @Test + public void testSetAndStartAlwaysOnVpn() throws Exception { + final Vpn vpn = createVpn(PRIMARY_USER.id); + setMockedUsers(PRIMARY_USER); + + // UID checks must return a different UID; otherwise it'll be treated as already prepared. + final int uid = Process.myUid() + 1; + when(mPackageManager.getPackageUidAsUser(eq(TEST_VPN_PKG), anyInt())) + .thenReturn(uid); + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(mVpnProfile.encode()); + + setAndVerifyAlwaysOnPackage(vpn, uid, false); + assertTrue(vpn.startAlwaysOnVpn()); + + // TODO: Test the Ikev2VpnRunner started up properly. Relies on utility methods added in + // a subsequent CL. + } + + private Vpn startLegacyVpn(final Vpn vpn, final VpnProfile vpnProfile) throws Exception { + setMockedUsers(PRIMARY_USER); + vpn.startLegacyVpn(vpnProfile); + return vpn; + } + + private IkeSessionConnectionInfo createIkeConnectInfo() { + return new IkeSessionConnectionInfo(TEST_VPN_CLIENT_IP, TEST_VPN_SERVER_IP, TEST_NETWORK); + } + + private IkeSessionConnectionInfo createIkeConnectInfo_2() { + return new IkeSessionConnectionInfo( + TEST_VPN_CLIENT_IP_2, TEST_VPN_SERVER_IP_2, TEST_NETWORK_2); + } + + private IkeSessionConfiguration createIkeConfig( + IkeSessionConnectionInfo ikeConnectInfo, boolean isMobikeEnabled) { + final IkeSessionConfiguration.Builder builder = + new IkeSessionConfiguration.Builder(ikeConnectInfo); + + if (isMobikeEnabled) { + builder.addIkeExtension(EXTENSION_TYPE_MOBIKE); + } + + return builder.build(); + } + + private ChildSessionConfiguration createChildConfig() { + return new ChildSessionConfiguration.Builder( + Arrays.asList(IN_TS, IN_TS6), Arrays.asList(OUT_TS, OUT_TS6)) + .addInternalAddress(new LinkAddress(TEST_VPN_INTERNAL_IP, IP4_PREFIX_LEN)) + .addInternalAddress(new LinkAddress(TEST_VPN_INTERNAL_IP6, IP6_PREFIX_LEN)) + .addInternalDnsServer(TEST_VPN_INTERNAL_DNS) + .addInternalDnsServer(TEST_VPN_INTERNAL_DNS6) + .build(); + } + + private IpSecTransform createIpSecTransform() { + return new IpSecTransform(mContext, new IpSecConfig()); + } + + private void verifyApplyTunnelModeTransforms(int expectedTimes) throws Exception { + verify(mIpSecService, times(expectedTimes)).applyTunnelModeTransform( + eq(TEST_TUNNEL_RESOURCE_ID), eq(IpSecManager.DIRECTION_IN), + anyInt(), anyString()); + verify(mIpSecService, times(expectedTimes)).applyTunnelModeTransform( + eq(TEST_TUNNEL_RESOURCE_ID), eq(IpSecManager.DIRECTION_OUT), + anyInt(), anyString()); + } + + private Pair<IkeSessionCallback, ChildSessionCallback> verifyCreateIkeAndCaptureCbs() + throws Exception { + final ArgumentCaptor<IkeSessionCallback> ikeCbCaptor = + ArgumentCaptor.forClass(IkeSessionCallback.class); + final ArgumentCaptor<ChildSessionCallback> childCbCaptor = + ArgumentCaptor.forClass(ChildSessionCallback.class); + + verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS)).createIkeSession( + any(), any(), any(), any(), ikeCbCaptor.capture(), childCbCaptor.capture()); + + return new Pair<>(ikeCbCaptor.getValue(), childCbCaptor.getValue()); + } + + private static class PlatformVpnSnapshot { + public final Vpn vpn; + public final NetworkCallback nwCb; + public final IkeSessionCallback ikeCb; + public final ChildSessionCallback childCb; + + PlatformVpnSnapshot(Vpn vpn, NetworkCallback nwCb, + IkeSessionCallback ikeCb, ChildSessionCallback childCb) { + this.vpn = vpn; + this.nwCb = nwCb; + this.ikeCb = ikeCb; + this.childCb = childCb; + } + } + + private PlatformVpnSnapshot verifySetupPlatformVpn(IkeSessionConfiguration ikeConfig) + throws Exception { + return verifySetupPlatformVpn(ikeConfig, true); + } + + private PlatformVpnSnapshot verifySetupPlatformVpn( + IkeSessionConfiguration ikeConfig, boolean mtuSupportsIpv6) throws Exception { + return verifySetupPlatformVpn(mVpnProfile, ikeConfig, mtuSupportsIpv6); + } + + private PlatformVpnSnapshot verifySetupPlatformVpn(VpnProfile vpnProfile, + IkeSessionConfiguration ikeConfig, boolean mtuSupportsIpv6) throws Exception { + return verifySetupPlatformVpn(vpnProfile, ikeConfig, + new NetworkCapabilities.Builder().build() /* underlying network caps */, + mtuSupportsIpv6, false /* areLongLivedTcpConnectionsExpensive */); + } + + private PlatformVpnSnapshot verifySetupPlatformVpn(VpnProfile vpnProfile, + IkeSessionConfiguration ikeConfig, + @NonNull final NetworkCapabilities underlyingNetworkCaps, + boolean mtuSupportsIpv6, + boolean areLongLivedTcpConnectionsExpensive) throws Exception { + if (!mtuSupportsIpv6) { + doReturn(IPV6_MIN_MTU - 1).when(mTestDeps).calculateVpnMtu(any(), anyInt(), anyInt(), + anyBoolean()); + } + + doReturn(mMockNetworkAgent).when(mTestDeps) + .newNetworkAgent( + any(), any(), anyString(), any(), any(), any(), any(), any(), any()); + doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork(); + + final Vpn vpn = createVpn(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN); + when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG))) + .thenReturn(vpnProfile.encode()); + + final String sessionKey = vpn.startVpnProfile(TEST_VPN_PKG); + final Set<Range<Integer>> uidRanges = Collections.singleton(PRIMARY_USER_RANGE); + verify(mConnectivityManager).setVpnDefaultForUids(eq(sessionKey), eq(uidRanges)); + final NetworkCallback nwCb = triggerOnAvailableAndGetCallback(underlyingNetworkCaps); + // There are 4 interactions with the executor. + // - Network available + // - LP change + // - NC change + // - schedule() calls in scheduleStartIkeSession() + // The first 3 calls are triggered from Executor.execute(). The execute() will also call to + // schedule() with 0 delay. Verify the exact interaction here so that it won't cause flakes + // in the follow-up flow. + verify(mExecutor, timeout(TEST_TIMEOUT_MS).times(4)) + .schedule(any(Runnable.class), anyLong(), any()); + reset(mExecutor); + + // Mock the setup procedure by firing callbacks + final Pair<IkeSessionCallback, ChildSessionCallback> cbPair = + verifyCreateIkeAndCaptureCbs(); + final IkeSessionCallback ikeCb = cbPair.first; + final ChildSessionCallback childCb = cbPair.second; + + ikeCb.onOpened(ikeConfig); + childCb.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_IN); + childCb.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_OUT); + childCb.onOpened(createChildConfig()); + + // Verification VPN setup + verifyApplyTunnelModeTransforms(1); + + ArgumentCaptor<LinkProperties> lpCaptor = ArgumentCaptor.forClass(LinkProperties.class); + ArgumentCaptor<NetworkCapabilities> ncCaptor = + ArgumentCaptor.forClass(NetworkCapabilities.class); + ArgumentCaptor<NetworkAgentConfig> nacCaptor = + ArgumentCaptor.forClass(NetworkAgentConfig.class); + verify(mTestDeps).newNetworkAgent( + any(), any(), anyString(), ncCaptor.capture(), lpCaptor.capture(), + any(), nacCaptor.capture(), any(), any()); + verify(mIkeSessionWrapper).setUnderpinnedNetwork(TEST_NETWORK); + // Check LinkProperties + final LinkProperties lp = lpCaptor.getValue(); + final List<RouteInfo> expectedRoutes = + new ArrayList<>( + Arrays.asList( + new RouteInfo( + new IpPrefix(Inet4Address.ANY, 0), + null /* gateway */, + TEST_IFACE_NAME, + RouteInfo.RTN_UNICAST))); + final List<LinkAddress> expectedAddresses = + new ArrayList<>( + Arrays.asList(new LinkAddress(TEST_VPN_INTERNAL_IP, IP4_PREFIX_LEN))); + final List<InetAddress> expectedDns = new ArrayList<>(Arrays.asList(TEST_VPN_INTERNAL_DNS)); + + if (mtuSupportsIpv6) { + expectedRoutes.add( + new RouteInfo( + new IpPrefix(Inet6Address.ANY, 0), + null /* gateway */, + TEST_IFACE_NAME, + RouteInfo.RTN_UNICAST)); + expectedAddresses.add(new LinkAddress(TEST_VPN_INTERNAL_IP6, IP6_PREFIX_LEN)); + expectedDns.add(TEST_VPN_INTERNAL_DNS6); + } else { + expectedRoutes.add( + new RouteInfo( + new IpPrefix(Inet6Address.ANY, 0), + null /* gateway */, + TEST_IFACE_NAME, + RTN_UNREACHABLE)); + } + + assertEquals(expectedRoutes, lp.getRoutes()); + assertEquals(expectedAddresses, lp.getLinkAddresses()); + assertEquals(expectedDns, lp.getDnsServers()); + + // Check NetworkCapabilities + assertEquals(Arrays.asList(TEST_NETWORK), ncCaptor.getValue().getUnderlyingNetworks()); + + // Check if allowBypass is set or not. + assertTrue(nacCaptor.getValue().isBypassableVpn()); + // Check if extra info for VPN is set. + assertTrue(nacCaptor.getValue().getLegacyExtraInfo().contains(TEST_VPN_PKG)); + final VpnTransportInfo info = (VpnTransportInfo) ncCaptor.getValue().getTransportInfo(); + assertTrue(info.isBypassable()); + assertEquals(areLongLivedTcpConnectionsExpensive, + info.areLongLivedTcpConnectionsExpensive()); + return new PlatformVpnSnapshot(vpn, nwCb, ikeCb, childCb); + } + + @Test + public void testStartPlatformVpn() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); + vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); + verify(mConnectivityManager).setVpnDefaultForUids(anyString(), eq(Collections.EMPTY_LIST)); + } + + @Test + public void testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerNoTimer() throws Exception { + doTestMigrateIkeSession_FromIkeTunnConnParams( + false /* isAutomaticIpVersionSelectionEnabled */, + true /* isAutomaticNattKeepaliveTimerEnabled */, + TEST_KEEPALIVE_TIMEOUT_UNSET /* keepaliveInProfile */, + ESP_IP_VERSION_AUTO /* ipVersionInProfile */, + ESP_ENCAP_TYPE_AUTO /* encapTypeInProfile */); + } + + @Test + public void testMigrateIkeSession_FromIkeTunnConnParams_AutoTimerTimerSet() throws Exception { + doTestMigrateIkeSession_FromIkeTunnConnParams( + false /* isAutomaticIpVersionSelectionEnabled */, + true /* isAutomaticNattKeepaliveTimerEnabled */, + TEST_KEEPALIVE_TIMER /* keepaliveInProfile */, + ESP_IP_VERSION_AUTO /* ipVersionInProfile */, + ESP_ENCAP_TYPE_AUTO /* encapTypeInProfile */); + } + + @Test + public void testMigrateIkeSession_FromIkeTunnConnParams_AutoIp() throws Exception { + doTestMigrateIkeSession_FromIkeTunnConnParams( + true /* isAutomaticIpVersionSelectionEnabled */, + false /* isAutomaticNattKeepaliveTimerEnabled */, + TEST_KEEPALIVE_TIMEOUT_UNSET /* keepaliveInProfile */, + ESP_IP_VERSION_AUTO /* ipVersionInProfile */, + ESP_ENCAP_TYPE_AUTO /* encapTypeInProfile */); + } + + @Test + public void testMigrateIkeSession_FromIkeTunnConnParams_AssignedIpProtocol() throws Exception { + doTestMigrateIkeSession_FromIkeTunnConnParams( + false /* isAutomaticIpVersionSelectionEnabled */, + false /* isAutomaticNattKeepaliveTimerEnabled */, + TEST_KEEPALIVE_TIMEOUT_UNSET /* keepaliveInProfile */, + ESP_IP_VERSION_IPV4 /* ipVersionInProfile */, + ESP_ENCAP_TYPE_UDP /* encapTypeInProfile */); + } + + @Test + public void testMigrateIkeSession_FromNotIkeTunnConnParams_AutoTimer() throws Exception { + doTestMigrateIkeSession_FromNotIkeTunnConnParams( + false /* isAutomaticIpVersionSelectionEnabled */, + true /* isAutomaticNattKeepaliveTimerEnabled */); + } + + @Test + public void testMigrateIkeSession_FromNotIkeTunnConnParams_AutoIp() throws Exception { + doTestMigrateIkeSession_FromNotIkeTunnConnParams( + true /* isAutomaticIpVersionSelectionEnabled */, + false /* isAutomaticNattKeepaliveTimerEnabled */); + } + + private void doTestMigrateIkeSession_FromNotIkeTunnConnParams( + boolean isAutomaticIpVersionSelectionEnabled, + boolean isAutomaticNattKeepaliveTimerEnabled) throws Exception { + final Ikev2VpnProfile ikeProfile = + new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY) + .setAuthPsk(TEST_VPN_PSK) + .setBypassable(true /* isBypassable */) + .setAutomaticNattKeepaliveTimerEnabled(isAutomaticNattKeepaliveTimerEnabled) + .setAutomaticIpVersionSelectionEnabled(isAutomaticIpVersionSelectionEnabled) + .build(); + + final int expectedKeepalive = isAutomaticNattKeepaliveTimerEnabled + ? AUTOMATIC_KEEPALIVE_DELAY_SECONDS + : DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT; + doTestMigrateIkeSession(ikeProfile.toVpnProfile(), + expectedKeepalive, + ESP_IP_VERSION_AUTO /* expectedIpVersion */, + ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, + new NetworkCapabilities.Builder().build()); + } + + private Ikev2VpnProfile makeIkeV2VpnProfile( + boolean isAutomaticIpVersionSelectionEnabled, + boolean isAutomaticNattKeepaliveTimerEnabled, + int keepaliveInProfile, + int ipVersionInProfile, + int encapTypeInProfile) { + // TODO: Update helper function in IkeSessionTestUtils to support building IkeSessionParams + // with IP version and encap type when mainline-prod branch support these two APIs. + final IkeSessionParams params = getTestIkeSessionParams(true /* testIpv6 */, + new IkeFqdnIdentification(TEST_IDENTITY), keepaliveInProfile); + final IkeSessionParams ikeSessionParams = new IkeSessionParams.Builder(params) + .setIpVersion(ipVersionInProfile) + .setEncapType(encapTypeInProfile) + .build(); + + final IkeTunnelConnectionParams tunnelParams = + new IkeTunnelConnectionParams(ikeSessionParams, CHILD_PARAMS); + return new Ikev2VpnProfile.Builder(tunnelParams) + .setBypassable(true) + .setAutomaticNattKeepaliveTimerEnabled(isAutomaticNattKeepaliveTimerEnabled) + .setAutomaticIpVersionSelectionEnabled(isAutomaticIpVersionSelectionEnabled) + .build(); + } + + private void doTestMigrateIkeSession_FromIkeTunnConnParams( + boolean isAutomaticIpVersionSelectionEnabled, + boolean isAutomaticNattKeepaliveTimerEnabled, + int keepaliveInProfile, + int ipVersionInProfile, + int encapTypeInProfile) throws Exception { + doTestMigrateIkeSession_FromIkeTunnConnParams(isAutomaticIpVersionSelectionEnabled, + isAutomaticNattKeepaliveTimerEnabled, keepaliveInProfile, ipVersionInProfile, + encapTypeInProfile, new NetworkCapabilities.Builder().build()); + } + + private void doTestMigrateIkeSession_FromIkeTunnConnParams( + boolean isAutomaticIpVersionSelectionEnabled, + boolean isAutomaticNattKeepaliveTimerEnabled, + int keepaliveInProfile, + int ipVersionInProfile, + int encapTypeInProfile, + @NonNull final NetworkCapabilities nc) throws Exception { + final Ikev2VpnProfile ikeProfile = makeIkeV2VpnProfile( + isAutomaticIpVersionSelectionEnabled, + isAutomaticNattKeepaliveTimerEnabled, + keepaliveInProfile, + ipVersionInProfile, + encapTypeInProfile); + + final IkeSessionParams ikeSessionParams = + ikeProfile.getIkeTunnelConnectionParams().getIkeSessionParams(); + final int expectedKeepalive = isAutomaticNattKeepaliveTimerEnabled + ? AUTOMATIC_KEEPALIVE_DELAY_SECONDS + : ikeSessionParams.getNattKeepAliveDelaySeconds(); + final int expectedIpVersion = isAutomaticIpVersionSelectionEnabled + ? ESP_IP_VERSION_AUTO + : ikeSessionParams.getIpVersion(); + final int expectedEncapType = isAutomaticIpVersionSelectionEnabled + ? ESP_ENCAP_TYPE_AUTO + : ikeSessionParams.getEncapType(); + doTestMigrateIkeSession(ikeProfile.toVpnProfile(), expectedKeepalive, + expectedIpVersion, expectedEncapType, nc); + } + + @Test + public void doTestMigrateIkeSession_Vcn() throws Exception { + final int expectedKeepalive = 2097; // Any unlikely number will do + final NetworkCapabilities vcnNc = new NetworkCapabilities.Builder() + .addTransportType(TRANSPORT_CELLULAR) + .setTransportInfo(new VcnTransportInfo(TEST_SUB_ID, expectedKeepalive)) + .build(); + final Ikev2VpnProfile ikev2VpnProfile = makeIkeV2VpnProfile( + true /* isAutomaticIpVersionSelectionEnabled */, + true /* isAutomaticNattKeepaliveTimerEnabled */, + 234 /* keepaliveInProfile */, // Should be ignored, any value will do + ESP_IP_VERSION_IPV4, // Should be ignored + ESP_ENCAP_TYPE_UDP // Should be ignored + ); + doTestMigrateIkeSession( + ikev2VpnProfile.toVpnProfile(), + expectedKeepalive, + ESP_IP_VERSION_AUTO /* expectedIpVersion */, + ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, + vcnNc); + } + + private void doTestMigrateIkeSession( + @NonNull final VpnProfile profile, + final int expectedKeepalive, + final int expectedIpVersion, + final int expectedEncapType, + @NonNull final NetworkCapabilities caps) throws Exception { + final PlatformVpnSnapshot vpnSnapShot = + verifySetupPlatformVpn(profile, + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */), + caps /* underlying network capabilities */, + false /* mtuSupportsIpv6 */, + expectedKeepalive < DEFAULT_LONG_LIVED_TCP_CONNS_EXPENSIVE_TIMEOUT_SEC); + // Simulate a new network coming up + vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); + verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt()); + + vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, caps); + // Verify MOBIKE is triggered + verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(TEST_NETWORK_2, + expectedIpVersion, expectedEncapType, expectedKeepalive); + + vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); + } + + @Test + public void testLinkPropertiesUpdateTriggerReevaluation() throws Exception { + final boolean hasV6 = true; + + mockCarrierConfig(TEST_SUB_ID, TelephonyManager.SIM_STATE_LOADED, TEST_KEEPALIVE_TIMER, + PREFERRED_IKE_PROTOCOL_IPV6_ESP); + final IkeSessionParams params = getTestIkeSessionParams(hasV6, + new IkeFqdnIdentification(TEST_IDENTITY), TEST_KEEPALIVE_TIMER); + final IkeTunnelConnectionParams tunnelParams = + new IkeTunnelConnectionParams(params, CHILD_PARAMS); + final Ikev2VpnProfile ikeProfile = new Ikev2VpnProfile.Builder(tunnelParams) + .setBypassable(true) + .setAutomaticNattKeepaliveTimerEnabled(false) + .setAutomaticIpVersionSelectionEnabled(true) + .build(); + final PlatformVpnSnapshot vpnSnapShot = + verifySetupPlatformVpn(ikeProfile.toVpnProfile(), + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */), + new NetworkCapabilities.Builder().build() /* underlying network caps */, + hasV6 /* mtuSupportsIpv6 */, + false /* areLongLivedTcpConnectionsExpensive */); + reset(mExecutor); + + // Simulate a new network coming up + final LinkProperties lp = new LinkProperties(); + lp.addLinkAddress(new LinkAddress("192.0.2.2/32")); + + // Have the executor use the real delay to make sure schedule() was called only + // once for all calls. Also, arrange for execute() not to call schedule() to avoid + // messing with the checks for schedule(). + mExecutor.delayMs = TestExecutor.REAL_DELAY; + mExecutor.executeDirect = true; + vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); + vpnSnapShot.nwCb.onCapabilitiesChanged( + TEST_NETWORK_2, new NetworkCapabilities.Builder().build()); + vpnSnapShot.nwCb.onLinkPropertiesChanged(TEST_NETWORK_2, new LinkProperties(lp)); + verify(mExecutor).schedule(any(Runnable.class), longThat(it -> it > 0), any()); + reset(mExecutor); + + final InOrder order = inOrder(mIkeSessionWrapper); + + // Verify the network is started + order.verify(mIkeSessionWrapper, timeout(TIMEOUT_CROSSTHREAD_MS)).setNetwork(TEST_NETWORK_2, + ESP_IP_VERSION_AUTO, ESP_ENCAP_TYPE_AUTO, TEST_KEEPALIVE_TIMER); + + // Send the same properties, check that no migration is scheduled + vpnSnapShot.nwCb.onLinkPropertiesChanged(TEST_NETWORK_2, new LinkProperties(lp)); + verify(mExecutor, never()).schedule(any(Runnable.class), anyLong(), any()); + + // Add v6 address, verify MOBIKE is triggered + lp.addLinkAddress(new LinkAddress("2001:db8::1/64")); + vpnSnapShot.nwCb.onLinkPropertiesChanged(TEST_NETWORK_2, new LinkProperties(lp)); + order.verify(mIkeSessionWrapper, timeout(TIMEOUT_CROSSTHREAD_MS)).setNetwork(TEST_NETWORK_2, + ESP_IP_VERSION_AUTO, ESP_ENCAP_TYPE_AUTO, TEST_KEEPALIVE_TIMER); + + // Add another v4 address, verify MOBIKE is triggered + final LinkProperties stacked = new LinkProperties(); + stacked.setInterfaceName("v4-" + lp.getInterfaceName()); + stacked.addLinkAddress(new LinkAddress("192.168.0.1/32")); + lp.addStackedLink(stacked); + vpnSnapShot.nwCb.onLinkPropertiesChanged(TEST_NETWORK_2, new LinkProperties(lp)); + order.verify(mIkeSessionWrapper, timeout(TIMEOUT_CROSSTHREAD_MS)).setNetwork(TEST_NETWORK_2, + ESP_IP_VERSION_AUTO, ESP_ENCAP_TYPE_AUTO, TEST_KEEPALIVE_TIMER); + + vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); + } + + private void mockCarrierConfig(int subId, int simStatus, int keepaliveTimer, int ikeProtocol) { + final SubscriptionInfo subscriptionInfo = mock(SubscriptionInfo.class); + doReturn(subId).when(subscriptionInfo).getSubscriptionId(); + doReturn(List.of(subscriptionInfo)).when(mSubscriptionManager) + .getActiveSubscriptionInfoList(); + + doReturn(simStatus).when(mTmPerSub).getSimApplicationState(); + doReturn(TEST_MCCMNC).when(mTmPerSub).getSimOperator(subId); + + final PersistableBundle persistableBundle = new PersistableBundle(); + persistableBundle.putInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT, keepaliveTimer); + persistableBundle.putInt(KEY_PREFERRED_IKE_PROTOCOL_INT, ikeProtocol); + // For CarrierConfigManager.isConfigForIdentifiedCarrier check + persistableBundle.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, true); + doReturn(persistableBundle).when(mConfigManager).getConfigForSubId(subId); + } + + private CarrierConfigManager.CarrierConfigChangeListener getCarrierConfigListener() { + final ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerCaptor = + ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class); + + verify(mConfigManager).registerCarrierConfigChangeListener(any(), listenerCaptor.capture()); + + return listenerCaptor.getValue(); + } + + @Test + public void testNattKeepaliveTimerFromCarrierConfig_noSubId() throws Exception { + doTestReadCarrierConfig(new NetworkCapabilities(), + TelephonyManager.SIM_STATE_LOADED, + PREFERRED_IKE_PROTOCOL_IPV4_UDP, + AUTOMATIC_KEEPALIVE_DELAY_SECONDS /* expectedKeepaliveTimer */, + ESP_IP_VERSION_AUTO /* expectedIpVersion */, + ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, + false /* expectedReadFromCarrierConfig*/, + true /* areLongLivedTcpConnectionsExpensive */); + } + + @Test + public void testNattKeepaliveTimerFromCarrierConfig_simAbsent() throws Exception { + doTestReadCarrierConfig(new NetworkCapabilities.Builder().build(), + TelephonyManager.SIM_STATE_ABSENT, + PREFERRED_IKE_PROTOCOL_IPV4_UDP, + AUTOMATIC_KEEPALIVE_DELAY_SECONDS /* expectedKeepaliveTimer */, + ESP_IP_VERSION_AUTO /* expectedIpVersion */, + ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, + false /* expectedReadFromCarrierConfig*/, + true /* areLongLivedTcpConnectionsExpensive */); + } + + @Test + public void testNattKeepaliveTimerFromCarrierConfig() throws Exception { + doTestReadCarrierConfig(createTestCellNc(), + TelephonyManager.SIM_STATE_LOADED, + PREFERRED_IKE_PROTOCOL_AUTO, + TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */, + ESP_IP_VERSION_AUTO /* expectedIpVersion */, + ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, + true /* expectedReadFromCarrierConfig*/, + false /* areLongLivedTcpConnectionsExpensive */); + } + + @Test + public void testNattKeepaliveTimerFromCarrierConfig_NotCell() throws Exception { + final NetworkCapabilities nc = new NetworkCapabilities.Builder() + .addTransportType(TRANSPORT_WIFI) + .setTransportInfo(new WifiInfo.Builder().build()) + .build(); + doTestReadCarrierConfig(nc, + TelephonyManager.SIM_STATE_LOADED, + PREFERRED_IKE_PROTOCOL_IPV4_UDP, + AUTOMATIC_KEEPALIVE_DELAY_SECONDS /* expectedKeepaliveTimer */, + ESP_IP_VERSION_AUTO /* expectedIpVersion */, + ESP_ENCAP_TYPE_AUTO /* expectedEncapType */, + false /* expectedReadFromCarrierConfig*/, + true /* areLongLivedTcpConnectionsExpensive */); + } + + @Test + public void testPreferredIpProtocolFromCarrierConfig_v4UDP() throws Exception { + doTestReadCarrierConfig(createTestCellNc(), + TelephonyManager.SIM_STATE_LOADED, + PREFERRED_IKE_PROTOCOL_IPV4_UDP, + TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */, + ESP_IP_VERSION_IPV4 /* expectedIpVersion */, + ESP_ENCAP_TYPE_UDP /* expectedEncapType */, + true /* expectedReadFromCarrierConfig*/, + false /* areLongLivedTcpConnectionsExpensive */); + } + + @Test + public void testPreferredIpProtocolFromCarrierConfig_v6ESP() throws Exception { + doTestReadCarrierConfig(createTestCellNc(), + TelephonyManager.SIM_STATE_LOADED, + PREFERRED_IKE_PROTOCOL_IPV6_ESP, + TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */, + ESP_IP_VERSION_IPV6 /* expectedIpVersion */, + ESP_ENCAP_TYPE_NONE /* expectedEncapType */, + true /* expectedReadFromCarrierConfig*/, + false /* areLongLivedTcpConnectionsExpensive */); + } + + @Test + public void testPreferredIpProtocolFromCarrierConfig_v6UDP() throws Exception { + doTestReadCarrierConfig(createTestCellNc(), + TelephonyManager.SIM_STATE_LOADED, + PREFERRED_IKE_PROTOCOL_IPV6_UDP, + TEST_KEEPALIVE_TIMER /* expectedKeepaliveTimer */, + ESP_IP_VERSION_IPV6 /* expectedIpVersion */, + ESP_ENCAP_TYPE_UDP /* expectedEncapType */, + true /* expectedReadFromCarrierConfig*/, + false /* areLongLivedTcpConnectionsExpensive */); + } + + private NetworkCapabilities createTestCellNc() { + return new NetworkCapabilities.Builder() + .addTransportType(TRANSPORT_CELLULAR) + .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() + .setSubscriptionId(TEST_SUB_ID) + .build()) + .build(); + } + + private void doTestReadCarrierConfig(NetworkCapabilities nc, int simState, int preferredIpProto, + int expectedKeepaliveTimer, int expectedIpVersion, int expectedEncapType, + boolean expectedReadFromCarrierConfig, + boolean areLongLivedTcpConnectionsExpensive) + throws Exception { + final Ikev2VpnProfile ikeProfile = + new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY) + .setAuthPsk(TEST_VPN_PSK) + .setBypassable(true /* isBypassable */) + .setAutomaticNattKeepaliveTimerEnabled(true) + .setAutomaticIpVersionSelectionEnabled(true) + .build(); + + final PlatformVpnSnapshot vpnSnapShot = + verifySetupPlatformVpn(ikeProfile.toVpnProfile(), + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */), + new NetworkCapabilities.Builder().build() /* underlying network caps */, + false /* mtuSupportsIpv6 */, + true /* areLongLivedTcpConnectionsExpensive */); + + final CarrierConfigManager.CarrierConfigChangeListener listener = + getCarrierConfigListener(); + + // Simulate a new network coming up + vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); + // Migration will not be started until receiving network capabilities change. + verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt()); + + reset(mIkeSessionWrapper); + mockCarrierConfig(TEST_SUB_ID, simState, TEST_KEEPALIVE_TIMER, preferredIpProto); + vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, nc); + verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(TEST_NETWORK_2, + expectedIpVersion, expectedEncapType, expectedKeepaliveTimer); + if (expectedReadFromCarrierConfig) { + final ArgumentCaptor<NetworkCapabilities> ncCaptor = + ArgumentCaptor.forClass(NetworkCapabilities.class); + verify(mMockNetworkAgent, timeout(TEST_TIMEOUT_MS)) + .doSendNetworkCapabilities(ncCaptor.capture()); + + final VpnTransportInfo info = + (VpnTransportInfo) ncCaptor.getValue().getTransportInfo(); + assertEquals(areLongLivedTcpConnectionsExpensive, + info.areLongLivedTcpConnectionsExpensive()); + } else { + verify(mMockNetworkAgent, never()).doSendNetworkCapabilities(any()); + } + + reset(mExecutor); + reset(mIkeSessionWrapper); + reset(mMockNetworkAgent); + + // Trigger carrier config change + listener.onCarrierConfigChanged(1 /* logicalSlotIndex */, TEST_SUB_ID, + -1 /* carrierId */, -1 /* specificCarrierId */); + verify(mIkeSessionWrapper).setNetwork(TEST_NETWORK_2, + expectedIpVersion, expectedEncapType, expectedKeepaliveTimer); + // Expect no NetworkCapabilities change. + // Call to doSendNetworkCapabilities() will not be triggered. + verify(mMockNetworkAgent, never()).doSendNetworkCapabilities(any()); + } + + @Test + public void testStartPlatformVpn_mtuDoesNotSupportIpv6() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = + verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */), + false /* mtuSupportsIpv6 */); + vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); + } + + @Test + public void testStartPlatformVpn_underlyingNetworkNotChange() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); + // Trigger update on the same network should not cause underlying network change in NC of + // the VPN network + vpnSnapShot.nwCb.onAvailable(TEST_NETWORK); + vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK, + new NetworkCapabilities.Builder() + .setSubscriptionIds(Set.of(TEST_SUB_ID)) + .build()); + // Verify setNetwork() called but no underlying network update + verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(eq(TEST_NETWORK), + eq(ESP_IP_VERSION_AUTO) /* ipVersion */, + eq(ESP_ENCAP_TYPE_AUTO) /* encapType */, + eq(DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT) /* keepaliveDelay */); + verify(mMockNetworkAgent, never()) + .doSetUnderlyingNetworks(any()); + + vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); + vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, + new NetworkCapabilities.Builder().build()); + + // A new network should trigger both setNetwork() and a underlying network update. + verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(eq(TEST_NETWORK_2), + eq(ESP_IP_VERSION_AUTO) /* ipVersion */, + eq(ESP_ENCAP_TYPE_AUTO) /* encapType */, + eq(DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT) /* keepaliveDelay */); + verify(mMockNetworkAgent).doSetUnderlyingNetworks( + Collections.singletonList(TEST_NETWORK_2)); + + vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); + } + + @Test + public void testStartPlatformVpnMobility_mobikeEnabled() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); + + // Set new MTU on a different network + final int newMtu = IPV6_MIN_MTU + 1; + doReturn(newMtu).when(mTestDeps).calculateVpnMtu(any(), anyInt(), anyInt(), anyBoolean()); + + // Mock network loss and verify a cleanup task is scheduled + vpnSnapShot.nwCb.onLost(TEST_NETWORK); + verify(mExecutor, atLeastOnce()).schedule(any(Runnable.class), anyLong(), any()); + + // Mock new network comes up and the cleanup task is cancelled + vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); + verify(mIkeSessionWrapper, never()).setNetwork(any(), anyInt(), anyInt(), anyInt()); + + vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, + new NetworkCapabilities.Builder().build()); + // Verify MOBIKE is triggered + verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).setNetwork(eq(TEST_NETWORK_2), + eq(ESP_IP_VERSION_AUTO) /* ipVersion */, + eq(ESP_ENCAP_TYPE_AUTO) /* encapType */, + eq(DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT) /* keepaliveDelay */); + // Verify mNetworkCapabilities is updated + assertEquals( + Collections.singletonList(TEST_NETWORK_2), + vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks()); + verify(mMockNetworkAgent) + .doSetUnderlyingNetworks(Collections.singletonList(TEST_NETWORK_2)); + + // Mock the MOBIKE procedure + vpnSnapShot.ikeCb.onIkeSessionConnectionInfoChanged(createIkeConnectInfo_2()); + vpnSnapShot.childCb.onIpSecTransformsMigrated( + createIpSecTransform(), createIpSecTransform()); + + verify(mIpSecService).setNetworkForTunnelInterface( + eq(TEST_TUNNEL_RESOURCE_ID), eq(TEST_NETWORK_2), anyString()); + + // Expect 2 times: one for initial setup and one for MOBIKE + verifyApplyTunnelModeTransforms(2); + + // Verify mNetworkAgent is updated + verify(mMockNetworkAgent).doSendLinkProperties(argThat(lp -> lp.getMtu() == newMtu)); + verify(mMockNetworkAgent, never()).unregister(); + // No further doSetUnderlyingNetworks interaction. The interaction count should stay one. + verify(mMockNetworkAgent, times(1)).doSetUnderlyingNetworks(any()); + vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); + } + + @Test + public void testStartPlatformVpnMobility_mobikeEnabledMtuDoesNotSupportIpv6() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = + verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); + + // Set MTU below 1280 + final int newMtu = IPV6_MIN_MTU - 1; + doReturn(newMtu).when(mTestDeps).calculateVpnMtu(any(), anyInt(), anyInt(), anyBoolean()); + + // Mock new network available & MOBIKE procedures + vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); + vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK_2, + new NetworkCapabilities.Builder().build()); + // Verify mNetworkCapabilities is updated + verify(mMockNetworkAgent, timeout(TEST_TIMEOUT_MS)) + .doSetUnderlyingNetworks(Collections.singletonList(TEST_NETWORK_2)); + assertEquals( + Collections.singletonList(TEST_NETWORK_2), + vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks()); + + vpnSnapShot.ikeCb.onIkeSessionConnectionInfoChanged(createIkeConnectInfo_2()); + vpnSnapShot.childCb.onIpSecTransformsMigrated( + createIpSecTransform(), createIpSecTransform()); + + // Verify removal of IPv6 addresses and routes triggers a network agent restart + final ArgumentCaptor<LinkProperties> lpCaptor = + ArgumentCaptor.forClass(LinkProperties.class); + verify(mTestDeps, times(2)) + .newNetworkAgent(any(), any(), anyString(), any(), lpCaptor.capture(), any(), any(), + any(), any()); + verify(mMockNetworkAgent).unregister(); + // mMockNetworkAgent is an old NetworkAgent, so it won't update LinkProperties after + // unregistering. + verify(mMockNetworkAgent, never()).doSendLinkProperties(any()); + + final LinkProperties lp = lpCaptor.getValue(); + + for (LinkAddress addr : lp.getLinkAddresses()) { + if (addr.isIpv6()) { + fail("IPv6 address found on VPN with MTU < IPv6 minimum MTU"); + } + } + + for (InetAddress dnsAddr : lp.getDnsServers()) { + if (dnsAddr instanceof Inet6Address) { + fail("IPv6 DNS server found on VPN with MTU < IPv6 minimum MTU"); + } + } + + for (RouteInfo routeInfo : lp.getRoutes()) { + if (routeInfo.getDestinationLinkAddress().isIpv6() + && !routeInfo.isIPv6UnreachableDefault()) { + fail("IPv6 route found on VPN with MTU < IPv6 minimum MTU"); + } + } + + assertEquals(newMtu, lp.getMtu()); + + vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); + } + + @Test + public void testStartPlatformVpnReestablishes_mobikeDisabled() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */)); + + // Forget the first IKE creation to be prepared to capture callbacks of the second + // IKE session + resetIkev2SessionCreator(mock(Vpn.IkeSessionWrapper.class)); + + // Mock network switch + vpnSnapShot.nwCb.onLost(TEST_NETWORK); + vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2); + // The old IKE Session will not be killed until receiving network capabilities change. + verify(mIkeSessionWrapper, never()).kill(); + + vpnSnapShot.nwCb.onCapabilitiesChanged( + TEST_NETWORK_2, new NetworkCapabilities.Builder().build()); + // Verify the old IKE Session is killed + verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS)).kill(); + + // Capture callbacks of the new IKE Session + final Pair<IkeSessionCallback, ChildSessionCallback> cbPair = + verifyCreateIkeAndCaptureCbs(); + final IkeSessionCallback ikeCb = cbPair.first; + final ChildSessionCallback childCb = cbPair.second; + + // Mock the IKE Session setup + ikeCb.onOpened(createIkeConfig(createIkeConnectInfo_2(), false /* isMobikeEnabled */)); + + childCb.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_IN); + childCb.onIpSecTransformCreated(createIpSecTransform(), IpSecManager.DIRECTION_OUT); + childCb.onOpened(createChildConfig()); + + // Expect 2 times since there have been two Session setups + verifyApplyTunnelModeTransforms(2); + + // Verify mNetworkCapabilities and mNetworkAgent are updated + assertEquals( + Collections.singletonList(TEST_NETWORK_2), + vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks()); + verify(mMockNetworkAgent) + .doSetUnderlyingNetworks(Collections.singletonList(TEST_NETWORK_2)); + + vpnSnapShot.vpn.mVpnRunner.exitVpnRunner(); + } + + private String getDump(@NonNull final Vpn vpn) { + final StringWriter sw = new StringWriter(); + final IndentingPrintWriter writer = new IndentingPrintWriter(sw, ""); + vpn.dump(writer); + writer.flush(); + return sw.toString(); + } + + private int countMatches(@NonNull final Pattern regexp, @NonNull final String string) { + final Matcher m = regexp.matcher(string); + int i = 0; + while (m.find()) ++i; + return i; + } + + @Test + public void testNCEventChanges() throws Exception { + final NetworkCapabilities.Builder ncBuilder = new NetworkCapabilities.Builder() + .addTransportType(TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_INTERNET) + .addCapability(NET_CAPABILITY_NOT_RESTRICTED) + .setLinkDownstreamBandwidthKbps(1000) + .setLinkUpstreamBandwidthKbps(500); + + final Ikev2VpnProfile ikeProfile = + new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY) + .setAuthPsk(TEST_VPN_PSK) + .setBypassable(true /* isBypassable */) + .setAutomaticNattKeepaliveTimerEnabled(true) + .setAutomaticIpVersionSelectionEnabled(true) + .build(); + + final PlatformVpnSnapshot vpnSnapShot = + verifySetupPlatformVpn(ikeProfile.toVpnProfile(), + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */), + ncBuilder.build(), false /* mtuSupportsIpv6 */, + true /* areLongLivedTcpConnectionsExpensive */); + + // Calls to onCapabilitiesChanged will be thrown to the executor for execution ; by + // default this will incur a 10ms delay before it's executed, messing with the timing + // of the log and having the checks for counts in equals() below flake. + mExecutor.executeDirect = true; + + // First nc changed triggered by verifySetupPlatformVpn + final Pattern pattern = Pattern.compile("Cap changed from", Pattern.MULTILINE); + final String stage1 = getDump(vpnSnapShot.vpn); + assertEquals(1, countMatches(pattern, stage1)); + + vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK, ncBuilder.build()); + final String stage2 = getDump(vpnSnapShot.vpn); + // Was the same caps, there should still be only 1 match + assertEquals(1, countMatches(pattern, stage2)); + + ncBuilder.setLinkDownstreamBandwidthKbps(1200) + .setLinkUpstreamBandwidthKbps(300); + vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK, ncBuilder.build()); + final String stage3 = getDump(vpnSnapShot.vpn); + // Was not an important change, should not be logged, still only 1 match + assertEquals(1, countMatches(pattern, stage3)); + + ncBuilder.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); + vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK, ncBuilder.build()); + final String stage4 = getDump(vpnSnapShot.vpn); + // Change to caps is important, should cause a new match + assertEquals(2, countMatches(pattern, stage4)); + + ncBuilder.removeCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED); + ncBuilder.setLinkDownstreamBandwidthKbps(600); + vpnSnapShot.nwCb.onCapabilitiesChanged(TEST_NETWORK, ncBuilder.build()); + final String stage5 = getDump(vpnSnapShot.vpn); + // Change to caps is important, should cause a new match even with the unimportant change + assertEquals(3, countMatches(pattern, stage5)); + } + // TODO : beef up event logs tests + + private void verifyHandlingNetworkLoss(PlatformVpnSnapshot vpnSnapShot) throws Exception { + // Forget the #sendLinkProperties during first setup. + reset(mMockNetworkAgent); + + // Mock network loss + vpnSnapShot.nwCb.onLost(TEST_NETWORK); + + // Mock the grace period expires + verify(mExecutor, atLeastOnce()).schedule(any(Runnable.class), anyLong(), any()); + + final ArgumentCaptor<LinkProperties> lpCaptor = + ArgumentCaptor.forClass(LinkProperties.class); + verify(mMockNetworkAgent, timeout(TEST_TIMEOUT_MS)) + .doSendLinkProperties(lpCaptor.capture()); + final LinkProperties lp = lpCaptor.getValue(); + + assertNull(lp.getInterfaceName()); + final List<RouteInfo> expectedRoutes = Arrays.asList( + new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null /* gateway */, + null /* iface */, RTN_UNREACHABLE), + new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /* gateway */, + null /* iface */, RTN_UNREACHABLE)); + assertEquals(expectedRoutes, lp.getRoutes()); + + verify(mMockNetworkAgent, timeout(TEST_TIMEOUT_MS)).unregister(); + } + + @Test + public void testStartPlatformVpnHandlesNetworkLoss_mobikeEnabled() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); + verifyHandlingNetworkLoss(vpnSnapShot); + } + + @Test + public void testStartPlatformVpnHandlesNetworkLoss_mobikeDisabled() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */)); + verifyHandlingNetworkLoss(vpnSnapShot); + } + + private ConnectivityDiagnosticsCallback getConnectivityDiagCallback() { + final ArgumentCaptor<ConnectivityDiagnosticsCallback> cdcCaptor = + ArgumentCaptor.forClass(ConnectivityDiagnosticsCallback.class); + verify(mCdm).registerConnectivityDiagnosticsCallback( + any(), any(), cdcCaptor.capture()); + return cdcCaptor.getValue(); + } + + private DataStallReport createDataStallReport() { + return new DataStallReport(TEST_NETWORK, 1234 /* reportTimestamp */, + 1 /* detectionMethod */, new LinkProperties(), new NetworkCapabilities(), + new PersistableBundle()); + } + + private void verifyMobikeTriggered(List<Network> expected, int retryIndex) { + // Verify retry is scheduled + final long expectedDelayMs = mTestDeps.getValidationFailRecoveryMs(retryIndex); + final ArgumentCaptor<Long> delayCaptor = ArgumentCaptor.forClass(Long.class); + verify(mExecutor, times(retryIndex + 1)).schedule( + any(Runnable.class), delayCaptor.capture(), eq(TimeUnit.MILLISECONDS)); + final List<Long> delays = delayCaptor.getAllValues(); + assertEquals(expectedDelayMs, (long) delays.get(delays.size() - 1)); + + final ArgumentCaptor<Network> networkCaptor = ArgumentCaptor.forClass(Network.class); + verify(mIkeSessionWrapper, timeout(TEST_TIMEOUT_MS + expectedDelayMs)) + .setNetwork(networkCaptor.capture(), anyInt() /* ipVersion */, + anyInt() /* encapType */, anyInt() /* keepaliveDelay */); + assertEquals(expected, Collections.singletonList(networkCaptor.getValue())); + } + + @Test + public void testDataStallInIkev2VpnMobikeDisabled() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */)); + + doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork(); + ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( + NetworkAgent.VALIDATION_STATUS_NOT_VALID); + + // Should not trigger MOBIKE if MOBIKE is not enabled + verify(mIkeSessionWrapper, never()).setNetwork(any() /* network */, + anyInt() /* ipVersion */, anyInt() /* encapType */, anyInt() /* keepaliveDelay */); + } + + @Test + public void testDataStallInIkev2VpnRecoveredByMobike() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); + + doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork(); + ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( + NetworkAgent.VALIDATION_STATUS_NOT_VALID); + // Verify MOBIKE is triggered + verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(), + 0 /* retryIndex */); + // Validation failure on VPN network should trigger a re-evaluation request for the + // underlying network. + verify(mConnectivityManager).reportNetworkConnectivity(TEST_NETWORK, false); + + reset(mIkev2SessionCreator); + reset(mExecutor); + + // Send validation status update. + // Recovered and get network validated. It should not trigger the ike session reset. + ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( + NetworkAgent.VALIDATION_STATUS_VALID); + // Verify that the retry count is reset. The mValidationFailRetryCount will not be reset + // until the executor finishes the execute() call, so wait until the all tasks are executed. + waitForIdleSerialExecutor(mExecutor, TEST_TIMEOUT_MS); + assertEquals(0, + ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).mValidationFailRetryCount); + verify(mIkev2SessionCreator, never()).createIkeSession( + any(), any(), any(), any(), any(), any()); + + reset(mIkeSessionWrapper); + reset(mExecutor); + + // Another validation fail should trigger another reportNetworkConnectivity + ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( + NetworkAgent.VALIDATION_STATUS_NOT_VALID); + verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(), + 0 /* retryIndex */); + verify(mConnectivityManager, times(2)).reportNetworkConnectivity(TEST_NETWORK, false); + } + + @Test + public void testDataStallInIkev2VpnNotRecoveredByMobike() throws Exception { + final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn( + createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */)); + + int retry = 0; + doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork(); + ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( + NetworkAgent.VALIDATION_STATUS_NOT_VALID); + verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(), + retry++); + // Validation failure on VPN network should trigger a re-evaluation request for the + // underlying network. + verify(mConnectivityManager).reportNetworkConnectivity(TEST_NETWORK, false); + reset(mIkev2SessionCreator); + + // Second validation status update. + ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( + NetworkAgent.VALIDATION_STATUS_NOT_VALID); + verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks(), + retry++); + // Call to reportNetworkConnectivity should only happen once. No further interaction. + verify(mConnectivityManager, times(1)).reportNetworkConnectivity(TEST_NETWORK, false); + + // Use real delay to verify reset session will not be performed if there is an existing + // recovery for resetting the session. + mExecutor.delayMs = TestExecutor.REAL_DELAY; + mExecutor.executeDirect = true; + // Send validation status update should result in ike session reset. + ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( + NetworkAgent.VALIDATION_STATUS_NOT_VALID); + + // Verify session reset is scheduled + long expectedDelay = mTestDeps.getValidationFailRecoveryMs(retry++); + final ArgumentCaptor<Long> delayCaptor = ArgumentCaptor.forClass(Long.class); + verify(mExecutor, times(retry)).schedule(any(Runnable.class), delayCaptor.capture(), + eq(TimeUnit.MILLISECONDS)); + final List<Long> delays = delayCaptor.getAllValues(); + assertEquals(expectedDelay, (long) delays.get(delays.size() - 1)); + // Call to reportNetworkConnectivity should only happen once. No further interaction. + verify(mConnectivityManager, times(1)).reportNetworkConnectivity(TEST_NETWORK, false); + + // Another invalid status reported should not trigger other scheduled recovery. + expectedDelay = mTestDeps.getValidationFailRecoveryMs(retry++); + ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus( + NetworkAgent.VALIDATION_STATUS_NOT_VALID); + verify(mExecutor, never()).schedule( + any(Runnable.class), eq(expectedDelay), eq(TimeUnit.MILLISECONDS)); + + // Verify that session being reset + verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS + expectedDelay)) + .createIkeSession(any(), any(), any(), any(), any(), any()); + // Call to reportNetworkConnectivity should only happen once. No further interaction. + verify(mConnectivityManager, times(1)).reportNetworkConnectivity(TEST_NETWORK, false); + } + + @Test + public void testStartLegacyVpnType() throws Exception { + setMockedUsers(PRIMARY_USER); + final Vpn vpn = createVpn(PRIMARY_USER.id); + final VpnProfile profile = new VpnProfile("testProfile" /* key */); + + profile.type = VpnProfile.TYPE_PPTP; + assertThrows(UnsupportedOperationException.class, () -> startLegacyVpn(vpn, profile)); + profile.type = VpnProfile.TYPE_L2TP_IPSEC_PSK; + assertThrows(UnsupportedOperationException.class, () -> startLegacyVpn(vpn, profile)); + } + + @Test + public void testStartLegacyVpnModifyProfile_TypePSK() throws Exception { + setMockedUsers(PRIMARY_USER); + final Vpn vpn = createVpn(PRIMARY_USER.id); + final Ikev2VpnProfile ikev2VpnProfile = + new Ikev2VpnProfile.Builder(TEST_VPN_SERVER, TEST_VPN_IDENTITY) + .setAuthPsk(TEST_VPN_PSK) + .build(); + final VpnProfile profile = ikev2VpnProfile.toVpnProfile(); + + startLegacyVpn(vpn, profile); + assertEquals(profile, ikev2VpnProfile.toVpnProfile()); + } + + private void assertTransportInfoMatches(NetworkCapabilities nc, int type) { + assertNotNull(nc); + VpnTransportInfo ti = (VpnTransportInfo) nc.getTransportInfo(); + assertNotNull(ti); + assertEquals(type, ti.getType()); + } + + // Make it public and un-final so as to spy it + public class TestDeps extends Vpn.Dependencies { + TestDeps() {} + + @Override + public boolean isCallerSystem() { + return true; + } + + @Override + public PendingIntent getIntentForStatusPanel(Context context) { + return null; + } + + @Override + public ParcelFileDescriptor adoptFd(Vpn vpn, int mtu) { + return new ParcelFileDescriptor(new FileDescriptor()); + } + + @Override + public int jniCreate(Vpn vpn, int mtu) { + // Pick a random positive number as fd to return. + return 345; + } + + @Override + public String jniGetName(Vpn vpn, int fd) { + return TEST_IFACE_NAME; + } + + @Override + public int jniSetAddresses(Vpn vpn, String interfaze, String addresses) { + if (addresses == null) return 0; + // Return the number of addresses. + return addresses.split(" ").length; + } + + @Override + public void setBlocking(FileDescriptor fd, boolean blocking) {} + + @Override + public DeviceIdleInternal getDeviceIdleInternal() { + return mDeviceIdleInternal; + } + + @Override + public long getValidationFailRecoveryMs(int retryCount) { + // Simply return retryCount as the delay seconds for retrying. + return retryCount * 100L; + } + + @Override + public ScheduledThreadPoolExecutor newScheduledThreadPoolExecutor() { + return mExecutor; + } + + public boolean mIgnoreCallingUidChecks = true; + @Override + public void verifyCallingUidAndPackage(Context context, String packageName, int userId) { + if (!mIgnoreCallingUidChecks) { + super.verifyCallingUidAndPackage(context, packageName, userId); + } + } + } + + /** + * Mock some methods of vpn object. + */ + private Vpn createVpn(@UserIdInt int userId) { + final Context asUserContext = mock(Context.class, AdditionalAnswers.delegatesTo(mContext)); + doReturn(UserHandle.of(userId)).when(asUserContext).getUser(); + when(mContext.createContextAsUser(eq(UserHandle.of(userId)), anyInt())) + .thenReturn(asUserContext); + final TestLooper testLooper = new TestLooper(); + final Vpn vpn = new Vpn(testLooper.getLooper(), mContext, mTestDeps, mNetService, + mNetd, userId, mVpnProfileStore, mSystemServices, mIkev2SessionCreator); + verify(mConnectivityManager, times(1)).registerNetworkProvider(argThat( + provider -> provider.getName().contains("VpnNetworkProvider") + )); + return vpn; + } + + /** + * Populate {@link #mUserManager} with a list of fake users. + */ + private void setMockedUsers(UserInfo... users) { + final Map<Integer, UserInfo> userMap = new ArrayMap<>(); + for (UserInfo user : users) { + userMap.put(user.id, user); + } + + /** + * @see UserManagerService#getUsers(boolean) + */ + doAnswer(invocation -> { + final ArrayList<UserInfo> result = new ArrayList<>(users.length); + for (UserInfo ui : users) { + if (ui.isEnabled() && !ui.partial) { + result.add(ui); + } + } + return result; + }).when(mUserManager).getAliveUsers(); + + doAnswer(invocation -> { + final int id = (int) invocation.getArguments()[0]; + return userMap.get(id); + }).when(mUserManager).getUserInfo(anyInt()); + } + + /** + * Populate {@link #mPackageManager} with a fake packageName-to-UID mapping. + */ + private void setMockedPackages(final Map<String, Integer> packages) { + try { + doAnswer(invocation -> { + final String appName = (String) invocation.getArguments()[0]; + final int userId = (int) invocation.getArguments()[1]; + Integer appId = packages.get(appName); + if (appId == null) throw new PackageManager.NameNotFoundException(appName); + return UserHandle.getUid(userId, appId); + }).when(mPackageManager).getPackageUidAsUser(anyString(), anyInt()); + } catch (Exception e) { + } + } +} diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java index 060f99b4317a..397d77c52f68 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java @@ -16,6 +16,8 @@ package com.android.server.display.brightness; +import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT; + import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE; import static org.junit.Assert.assertEquals; @@ -43,6 +45,7 @@ public final class BrightnessEventTest { getReason(BrightnessReason.REASON_DOZE, BrightnessReason.MODIFIER_LOW_POWER)); mBrightnessEvent.setPhysicalDisplayId("test"); mBrightnessEvent.setDisplayState(Display.STATE_ON); + mBrightnessEvent.setDisplayPolicy(POLICY_BRIGHT); mBrightnessEvent.setLux(100.0f); mBrightnessEvent.setPreThresholdLux(150.0f); mBrightnessEvent.setTime(System.currentTimeMillis()); @@ -74,11 +77,12 @@ public final class BrightnessEventTest { public void testToStringWorksAsExpected() { String actualString = mBrightnessEvent.toString(false); String expectedString = - "BrightnessEvent: disp=1, physDisp=test, displayState=ON, brt=0.6, initBrt=25.0," - + " rcmdBrt=0.6, preBrt=NaN, lux=100.0, preLux=150.0, hbmMax=0.62, hbmMode=off," - + " rbcStrength=-1, thrmMax=0.65, powerFactor=0.2, wasShortTermModelActive=true," - + " flags=, reason=doze [ low_pwr ], autoBrightness=true, strategy=" - + DISPLAY_BRIGHTNESS_STRATEGY_NAME + ", autoBrightnessMode=idle"; + "BrightnessEvent: disp=1, physDisp=test, displayState=ON, displayPolicy=BRIGHT," + + " brt=0.6, initBrt=25.0, rcmdBrt=0.6, preBrt=NaN, lux=100.0, preLux=150.0," + + " hbmMax=0.62, hbmMode=off, rbcStrength=-1, thrmMax=0.65, powerFactor=0.2," + + " wasShortTermModelActive=true, flags=, reason=doze [ low_pwr ]," + + " autoBrightness=true, strategy=" + DISPLAY_BRIGHTNESS_STRATEGY_NAME + + ", autoBrightnessMode=idle"; assertEquals(expectedString, actualString); } diff --git a/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java index d367f71de921..4a8fe416e0dd 100644 --- a/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java @@ -19,7 +19,8 @@ package com.android.server; import android.os.ServiceManager; import android.os.image.IDynamicSystemService; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; + +import androidx.test.filters.LargeTest; public class DynamicSystemServiceTest extends AndroidTestCase { private static final String TAG = "DynamicSystemServiceTests"; diff --git a/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java index aec3f451fac6..344e2c21f0a5 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java @@ -103,7 +103,7 @@ public class BrailleDisplayConnectionTest { } BrailleDisplayConnection.BrailleDisplayScanner scanner = - mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); + BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); assertThat(scanner.getHidrawNodePaths(testDir.toPath())) .containsExactly(hidrawNode0, hidrawNode1); @@ -123,7 +123,7 @@ public class BrailleDisplayConnectionTest { descriptor); BrailleDisplayConnection.BrailleDisplayScanner scanner = - mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); + BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); assertThat(scanner.getDeviceReportDescriptor(NULL_PATH)).isEqualTo(descriptor); } @@ -133,7 +133,7 @@ public class BrailleDisplayConnectionTest { when(mNativeInterface.getHidrawDescSize(anyInt())).thenReturn(0); BrailleDisplayConnection.BrailleDisplayScanner scanner = - mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); + BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); assertThat(scanner.getDeviceReportDescriptor(NULL_PATH)).isNull(); } @@ -144,7 +144,7 @@ public class BrailleDisplayConnectionTest { when(mNativeInterface.getHidrawUniq(anyInt())).thenReturn(macAddress); BrailleDisplayConnection.BrailleDisplayScanner scanner = - mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); + BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); assertThat(scanner.getUniqueId(NULL_PATH)).isEqualTo(macAddress); } @@ -155,7 +155,7 @@ public class BrailleDisplayConnectionTest { .thenReturn(BrailleDisplayConnection.BUS_USB); BrailleDisplayConnection.BrailleDisplayScanner scanner = - mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); + BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); assertThat(scanner.getDeviceBusType(NULL_PATH)) .isEqualTo(BrailleDisplayConnection.BUS_USB); @@ -167,7 +167,7 @@ public class BrailleDisplayConnectionTest { .thenReturn(BrailleDisplayConnection.BUS_BLUETOOTH); BrailleDisplayConnection.BrailleDisplayScanner scanner = - mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); + BrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface); assertThat(scanner.getDeviceBusType(NULL_PATH)) .isEqualTo(BrailleDisplayConnection.BUS_BLUETOOTH); diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index caa2e367f009..e0a99b016da9 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -70,9 +70,10 @@ import android.os.UserHandle; import android.os.UserManager; import android.test.AndroidTestCase; import android.test.mock.MockContext; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; +import androidx.test.filters.SmallTest; + import com.android.server.LocalServices; import org.mockito.ArgumentCaptor; diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java index 29a920a0386f..61ac74cc3490 100644 --- a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java @@ -21,7 +21,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; - import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -31,17 +30,16 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteStatement; import android.os.Build; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Pair; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; - import org.mockito.Mock; import org.mockito.MockitoAnnotations; diff --git a/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java b/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java index 08a65292cf20..1acb8acca71a 100644 --- a/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/adaptiveauth/AdaptiveAuthServiceTest.java @@ -24,6 +24,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOM import static com.android.server.adaptiveauth.AdaptiveAuthService.MAX_ALLOWED_FAILED_AUTH_ATTEMPTS; import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -32,9 +33,11 @@ import static org.mockito.Mockito.when; import android.app.KeyguardManager; import android.content.Context; +import android.content.pm.PackageManager; import android.hardware.biometrics.AuthenticationStateListener; import android.hardware.biometrics.BiometricManager; import android.os.RemoteException; +import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.InstrumentationRegistry; @@ -62,6 +65,7 @@ import org.mockito.MockitoAnnotations; /** * atest FrameworksServicesTests:AdaptiveAuthServiceTest */ +@Presubmit @SmallTest @RunWith(AndroidJUnit4.class) public class AdaptiveAuthServiceTest { @@ -103,6 +107,10 @@ public class AdaptiveAuthServiceTest { mSetFlagsRule.enableFlags(FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS); mContext = spy(ApplicationProvider.getApplicationContext()); + + assumeTrue("Adaptive auth is disabled on device", + !mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)); + when(mContext.getSystemService(BiometricManager.class)).thenReturn(mBiometricManager); when(mContext.getSystemService(KeyguardManager.class)).thenReturn(mKeyguardManager); diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java index 99eb047e7e37..0bf419ec242c 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java @@ -52,7 +52,6 @@ import android.platform.test.annotations.Presubmit; import android.provider.DeviceConfig; import android.provider.Settings; import android.server.wm.settings.SettingsSession; -import android.test.suitebuilder.annotation.LargeTest; import android.text.TextUtils; import android.util.KeyValueListParser; import android.util.Log; @@ -60,6 +59,7 @@ import android.util.Pair; import androidx.test.InstrumentationRegistry; import androidx.test.filters.FlakyTest; +import androidx.test.filters.LargeTest; import androidx.test.uiautomator.UiDevice; import org.junit.Before; diff --git a/services/tests/servicestests/src/com/android/server/am/ServiceRestarterTest.java b/services/tests/servicestests/src/com/android/server/am/ServiceRestarterTest.java index 4b359eb11d58..cfcb3dd56c29 100644 --- a/services/tests/servicestests/src/com/android/server/am/ServiceRestarterTest.java +++ b/services/tests/servicestests/src/com/android/server/am/ServiceRestarterTest.java @@ -38,10 +38,10 @@ import android.os.SystemClock; import android.provider.DeviceConfig; import android.provider.Settings; import android.server.wm.settings.SettingsSession; -import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import com.android.compatibility.common.util.SystemUtil; diff --git a/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java b/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java index 9acc4bd19de2..8a7815e12c8b 100644 --- a/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java +++ b/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java @@ -47,11 +47,12 @@ import android.content.pm.ShortcutServiceInternal; import android.os.Handler; import android.os.UserHandle; import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; import android.util.AtomicFile; import android.util.Xml; import android.widget.RemoteViews; +import androidx.test.filters.SmallTest; + import com.android.frameworks.servicestests.R; import com.android.internal.appwidget.IAppWidgetHost; import com.android.modules.utils.TypedXmlPullParser; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClientTest.java index 5b81277250c2..c12f13ee8cbe 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceGenerateChallengeClientTest.java @@ -25,7 +25,8 @@ import android.hardware.biometrics.face.ISession; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceGetFeatureClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceGetFeatureClientTest.java index 9d0c84edb366..5d4b04f22182 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceGetFeatureClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceGetFeatureClientTest.java @@ -28,9 +28,9 @@ import android.hardware.biometrics.face.ISession; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableContext; +import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.server.biometrics.log.BiometricContext; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClientTest.java index 1b4c01723027..a1e43fbdf7b7 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClientTest.java @@ -31,9 +31,9 @@ import android.hardware.biometrics.face.ISession; import android.hardware.face.Face; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; import androidx.annotation.NonNull; +import androidx.test.filters.SmallTest; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInternalEnumerateClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInternalEnumerateClientTest.java index 8d74fd1d56be..9845b58f79bf 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInternalEnumerateClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInternalEnumerateClientTest.java @@ -31,7 +31,8 @@ import android.hardware.face.Face; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClientTest.java index dbbd69bdd3b5..d6bc73e9f3da 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClientTest.java @@ -28,7 +28,8 @@ import android.content.Context; import android.hardware.biometrics.face.ISession; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceRevokeChallengeClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceRevokeChallengeClientTest.java index fb5502a1795d..e8cb5ad9b550 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceRevokeChallengeClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceRevokeChallengeClientTest.java @@ -25,7 +25,8 @@ import android.hardware.biometrics.face.ISession; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceSetFeatureClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceSetFeatureClientTest.java index eb8cc9c63e75..b60c845106ec 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceSetFeatureClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceSetFeatureClientTest.java @@ -27,9 +27,9 @@ import android.hardware.biometrics.face.ISession; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableContext; +import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.server.biometrics.log.BiometricContext; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapterTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapterTest.java index b9a4fb4e0939..b5d73d256f7d 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapterTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/HidlToAidlSessionAdapterTest.java @@ -16,8 +16,8 @@ package com.android.server.biometrics.sensors.face.hidl; -import static com.android.server.biometrics.sensors.face.hidl.HidlToAidlSessionAdapter.ENROLL_TIMEOUT_SEC; import static com.android.server.biometrics.sensors.face.hidl.FaceGenerateChallengeClient.CHALLENGE_TIMEOUT_SEC; +import static com.android.server.biometrics.sensors.face.hidl.HidlToAidlSessionAdapter.ENROLL_TIMEOUT_SEC; import static com.google.common.truth.Truth.assertThat; @@ -45,9 +45,9 @@ import android.hardware.keymaster.HardwareAuthToken; import android.hardware.keymaster.Timestamp; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableContext; +import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.server.biometrics.HardwareAuthTokenUtils; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClientTest.java index 840961938cb2..72b44d475bba 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGenerateChallengeClientTest.java @@ -25,7 +25,8 @@ import android.hardware.biometrics.fingerprint.ISession; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalEnumerateClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalEnumerateClientTest.java index 723f916f99c8..b5df8362b09f 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalEnumerateClientTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalEnumerateClientTest.java @@ -31,7 +31,8 @@ import android.hardware.fingerprint.Fingerprint; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricLogger; diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/HidlToAidlSessionAdapterTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/HidlToAidlSessionAdapterTest.java index d723e87a62ad..cdf1266d6a06 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/HidlToAidlSessionAdapterTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/hidl/HidlToAidlSessionAdapterTest.java @@ -28,7 +28,8 @@ import android.hardware.keymaster.HardwareAuthToken; import android.hardware.keymaster.Timestamp; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import com.android.server.biometrics.sensors.fingerprint.aidl.AidlResponseHandler; diff --git a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java index 034466383bac..28eee6644b60 100644 --- a/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/content/SyncManagerTest.java @@ -36,9 +36,9 @@ import android.content.pm.UserProperties; import android.os.Bundle; import android.os.UserManager; import android.provider.ContactsContract; -import android.test.suitebuilder.annotation.SmallTest; import androidx.test.core.app.ApplicationProvider; +import androidx.test.filters.SmallTest; import junit.framework.TestCase; diff --git a/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java index a694d5e37566..95f893bf2d17 100644 --- a/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java +++ b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java @@ -21,7 +21,8 @@ import android.content.ContentResolver; import android.os.Bundle; import android.os.PersistableBundle; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Test for SyncOperation. diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java index 5fe60d779fa6..b012aaaed3bf 100644 --- a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java @@ -16,18 +16,26 @@ package com.android.server.contentprotection; +import static android.app.admin.DevicePolicyManager.CONTENT_PROTECTION_DISABLED; +import static android.app.admin.DevicePolicyManager.CONTENT_PROTECTION_ENABLED; +import static android.app.admin.DevicePolicyManager.CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY; +import static android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED; + import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; +import android.app.admin.DevicePolicyCache; import android.app.admin.DevicePolicyManagerInternal; -import android.content.ContentResolver; import android.net.Uri; import android.os.Handler; import android.os.Looper; -import android.os.UserHandle; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.testing.TestableContentResolver; import android.testing.TestableContext; @@ -36,6 +44,9 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.server.LocalServices; + +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -78,29 +89,36 @@ public class ContentProtectionConsentManagerTest { public final TestableContext mTestableContext = new TestableContext(ApplicationProvider.getApplicationContext()); + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private final TestableContentResolver mTestableContentResolver = mTestableContext.getContentResolver(); - @Mock private ContentResolver mMockContentResolver; - @Mock private DevicePolicyManagerInternal mMockDevicePolicyManagerInternal; + @Mock private DevicePolicyCache mMockDevicePolicyCache; + + @Before + public void setup() { + setupLocalService(DevicePolicyManagerInternal.class, mMockDevicePolicyManagerInternal); + } + @Test - public void constructor_registersContentObserver() { + public void isConsentGranted_policyFlagDisabled_packageVerifierNotGranted() { + mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); ContentProtectionConsentManager manager = - createContentProtectionConsentManager(mMockContentResolver); + createContentProtectionConsentManager(VALUE_FALSE, VALUE_TRUE); + + boolean actual = manager.isConsentGranted(TEST_USER_ID); - assertThat(manager.mContentObserver).isNotNull(); - verify(mMockContentResolver) - .registerContentObserver( - URI_PACKAGE_VERIFIER_USER_CONSENT, - /* notifyForDescendants= */ false, - manager.mContentObserver, - UserHandle.USER_ALL); + assertThat(actual).isFalse(); + verifyZeroInteractions(mMockDevicePolicyManagerInternal); + verifyZeroInteractions(mMockDevicePolicyCache); } @Test - public void isConsentGranted_packageVerifierNotGranted() { + public void isConsentGranted_policyFlagEnabled_packageVerifierNotGranted() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); ContentProtectionConsentManager manager = createContentProtectionConsentManager(VALUE_FALSE, VALUE_TRUE); @@ -108,10 +126,12 @@ public class ContentProtectionConsentManagerTest { assertThat(actual).isFalse(); verifyZeroInteractions(mMockDevicePolicyManagerInternal); + verifyZeroInteractions(mMockDevicePolicyCache); } @Test - public void isConsentGranted_contentProtectionNotGranted() { + public void isConsentGranted_policyFlagDisabled_contentProtectionNotGranted() { + mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); ContentProtectionConsentManager manager = createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE); @@ -119,10 +139,52 @@ public class ContentProtectionConsentManagerTest { assertThat(actual).isFalse(); verifyZeroInteractions(mMockDevicePolicyManagerInternal); + verifyZeroInteractions(mMockDevicePolicyCache); + } + + @Test + public void isConsentGranted_policyFlagDisabled_packageVerifierGranted_userNotManaged() { + mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); + ContentProtectionConsentManager manager = + createContentProtectionConsentManager(VALUE_TRUE, VALUE_TRUE); + + boolean actual = manager.isConsentGranted(TEST_USER_ID); + + assertThat(actual).isTrue(); + verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + verifyZeroInteractions(mMockDevicePolicyCache); + } + + @Test + public void isConsentGranted_policyFlagDisabled_packageVerifierGranted_userManaged() { + mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); + when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID)) + .thenReturn(true); + ContentProtectionConsentManager manager = + createContentProtectionConsentManager(VALUE_TRUE, VALUE_TRUE); + + boolean actual = manager.isConsentGranted(TEST_USER_ID); + + assertThat(actual).isFalse(); + verifyZeroInteractions(mMockDevicePolicyCache); + } + + @Test + public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userNotManaged_contentProtectionNotGranted() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); + ContentProtectionConsentManager manager = + createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE); + + boolean actual = manager.isConsentGranted(TEST_USER_ID); + + assertThat(actual).isFalse(); + verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + verifyZeroInteractions(mMockDevicePolicyCache); } @Test - public void isConsentGranted_packageVerifierGranted_userNotManaged() { + public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userNotManaged_contentProtectionGranted() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); ContentProtectionConsentManager manager = createContentProtectionConsentManager(VALUE_TRUE, VALUE_TRUE); @@ -130,22 +192,110 @@ public class ContentProtectionConsentManagerTest { assertThat(actual).isTrue(); verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + verifyZeroInteractions(mMockDevicePolicyCache); + } + + @Test + public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userManaged_policyDisabled() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); + when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID)) + .thenReturn(true); + when(mMockDevicePolicyCache.getContentProtectionPolicy(TEST_USER_ID)) + .thenReturn(CONTENT_PROTECTION_DISABLED); + ContentProtectionConsentManager manager = + createContentProtectionConsentManager(VALUE_TRUE, VALUE_TRUE); + + boolean actual = manager.isConsentGranted(TEST_USER_ID); + + assertThat(actual).isFalse(); + verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + verify(mMockDevicePolicyCache).getContentProtectionPolicy(TEST_USER_ID); + } + + @Test + public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userManaged_policyEnabled() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); + when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID)) + .thenReturn(true); + when(mMockDevicePolicyCache.getContentProtectionPolicy(TEST_USER_ID)) + .thenReturn(CONTENT_PROTECTION_ENABLED); + ContentProtectionConsentManager manager = + createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE); + + boolean actual = manager.isConsentGranted(TEST_USER_ID); + + assertThat(actual).isTrue(); + verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + verify(mMockDevicePolicyCache).getContentProtectionPolicy(TEST_USER_ID); } @Test - public void isConsentGranted_packageVerifierGranted_userManaged() { + public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userManaged_policyNotControlled_contentProtectionGranted() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID)) .thenReturn(true); + when(mMockDevicePolicyCache.getContentProtectionPolicy(TEST_USER_ID)) + .thenReturn(CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY); ContentProtectionConsentManager manager = createContentProtectionConsentManager(VALUE_TRUE, VALUE_TRUE); boolean actual = manager.isConsentGranted(TEST_USER_ID); + assertThat(actual).isTrue(); + verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + verify(mMockDevicePolicyCache).getContentProtectionPolicy(TEST_USER_ID); + } + + @Test + public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userManaged_policyNotControlled_contentProtectionNotGranted() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); + when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID)) + .thenReturn(true); + when(mMockDevicePolicyCache.getContentProtectionPolicy(TEST_USER_ID)) + .thenReturn(CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY); + ContentProtectionConsentManager manager = + createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE); + + boolean actual = manager.isConsentGranted(TEST_USER_ID); + + assertThat(actual).isFalse(); + verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + verify(mMockDevicePolicyCache).getContentProtectionPolicy(TEST_USER_ID); + } + + @Test + public void isConsentGranted_policyFlagEnabled_packageVerifierGranted_userManaged_policyNotControlled_contentProtectionDefault() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); + when(mMockDevicePolicyManagerInternal.isUserOrganizationManaged(TEST_USER_ID)) + .thenReturn(true); + when(mMockDevicePolicyCache.getContentProtectionPolicy(TEST_USER_ID)) + .thenReturn(CONTENT_PROTECTION_NOT_CONTROLLED_BY_POLICY); + ContentProtectionConsentManager manager = + createContentProtectionConsentManager(VALUE_TRUE, VALUE_DEFAULT); + + boolean actual = manager.isConsentGranted(TEST_USER_ID); + + assertThat(actual).isTrue(); + verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + verify(mMockDevicePolicyCache).getContentProtectionPolicy(TEST_USER_ID); + } + + @Test + public void isConsentGranted_policyFlagDisabled_packageVerifierDefault() { + mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); + ContentProtectionConsentManager manager = + createContentProtectionConsentManager(VALUE_DEFAULT, VALUE_TRUE); + + boolean actual = manager.isConsentGranted(TEST_USER_ID); + assertThat(actual).isFalse(); + verifyZeroInteractions(mMockDevicePolicyManagerInternal); + verifyZeroInteractions(mMockDevicePolicyCache); } @Test - public void isConsentGranted_packageVerifierDefault() { + public void isConsentGranted_policyFlagEnabled_packageVerifierDefault() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); ContentProtectionConsentManager manager = createContentProtectionConsentManager(VALUE_DEFAULT, VALUE_TRUE); @@ -153,10 +303,12 @@ public class ContentProtectionConsentManagerTest { assertThat(actual).isFalse(); verifyZeroInteractions(mMockDevicePolicyManagerInternal); + verifyZeroInteractions(mMockDevicePolicyCache); } @Test - public void isConsentGranted_contentProtectionDefault() { + public void isConsentGranted_policyFlagDisabled_contentProtectionDefault() { + mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); ContentProtectionConsentManager manager = createContentProtectionConsentManager(VALUE_TRUE, VALUE_DEFAULT); @@ -164,57 +316,108 @@ public class ContentProtectionConsentManagerTest { assertThat(actual).isTrue(); verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + verifyZeroInteractions(mMockDevicePolicyCache); } @Test - public void contentObserver_packageVerifier() { + public void contentObserver_policyFlagDisabled_packageVerifier() { + mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); ContentProtectionConsentManager manager = - createContentProtectionConsentManager(VALUE_TRUE, VALUE_DEFAULT); + createContentProtectionConsentManager(VALUE_FALSE, VALUE_TRUE); + boolean firstActual = manager.isConsentGranted(TEST_USER_ID); + assertThat(firstActual).isFalse(); + verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt()); - notifyContentObserver( - manager, - URI_PACKAGE_VERIFIER_USER_CONSENT, - KEY_PACKAGE_VERIFIER_USER_CONSENT, - VALUE_FALSE); + putGlobalSettings(KEY_PACKAGE_VERIFIER_USER_CONSENT, VALUE_TRUE); boolean secondActual = manager.isConsentGranted(TEST_USER_ID); - - assertThat(firstActual).isTrue(); assertThat(secondActual).isFalse(); + verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt()); + + notifyContentObserver(manager, URI_PACKAGE_VERIFIER_USER_CONSENT); + boolean thirdActual = manager.isConsentGranted(TEST_USER_ID); + assertThat(thirdActual).isTrue(); verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + + verifyZeroInteractions(mMockDevicePolicyCache); } @Test - public void contentObserver_contentProtection() { + public void contentObserver_policyFlagEnabled_packageVerifier() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); ContentProtectionConsentManager manager = - createContentProtectionConsentManager(VALUE_TRUE, VALUE_DEFAULT); + createContentProtectionConsentManager(VALUE_FALSE, VALUE_TRUE); + boolean firstActual = manager.isConsentGranted(TEST_USER_ID); + assertThat(firstActual).isFalse(); + verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt()); - notifyContentObserver( - manager, - URI_CONTENT_PROTECTION_USER_CONSENT, - KEY_CONTENT_PROTECTION_USER_CONSENT, - VALUE_FALSE); + putGlobalSettings(KEY_PACKAGE_VERIFIER_USER_CONSENT, VALUE_TRUE); boolean secondActual = manager.isConsentGranted(TEST_USER_ID); + assertThat(secondActual).isFalse(); + verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt()); - assertThat(firstActual).isTrue(); + notifyContentObserver(manager, URI_PACKAGE_VERIFIER_USER_CONSENT); + boolean thirdActual = manager.isConsentGranted(TEST_USER_ID); + assertThat(thirdActual).isTrue(); + verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + + verifyZeroInteractions(mMockDevicePolicyCache); + } + + @Test + public void contentObserver_policyFlagDisabled_contentProtection() { + mSetFlagsRule.disableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); + ContentProtectionConsentManager manager = + createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE); + + boolean firstActual = manager.isConsentGranted(TEST_USER_ID); + assertThat(firstActual).isFalse(); + verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt()); + + putGlobalSettings(KEY_CONTENT_PROTECTION_USER_CONSENT, VALUE_TRUE); + boolean secondActual = manager.isConsentGranted(TEST_USER_ID); assertThat(secondActual).isFalse(); + verify(mMockDevicePolicyManagerInternal, never()).isUserOrganizationManaged(anyInt()); + + notifyContentObserver(manager, URI_CONTENT_PROTECTION_USER_CONSENT); + boolean thirdActual = manager.isConsentGranted(TEST_USER_ID); + assertThat(thirdActual).isTrue(); + verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + + verifyZeroInteractions(mMockDevicePolicyCache); + } + + @Test + public void contentObserver_policyFlagEnabled_contentProtection() { + mSetFlagsRule.enableFlags(FLAG_MANAGE_DEVICE_POLICY_ENABLED); + ContentProtectionConsentManager manager = + createContentProtectionConsentManager(VALUE_TRUE, VALUE_FALSE); + + boolean firstActual = manager.isConsentGranted(TEST_USER_ID); + assertThat(firstActual).isFalse(); verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID); + + putGlobalSettings(KEY_CONTENT_PROTECTION_USER_CONSENT, VALUE_TRUE); + boolean secondActual = manager.isConsentGranted(TEST_USER_ID); + assertThat(secondActual).isFalse(); + verify(mMockDevicePolicyManagerInternal, times(2)).isUserOrganizationManaged(TEST_USER_ID); + + notifyContentObserver(manager, URI_CONTENT_PROTECTION_USER_CONSENT); + boolean thirdActual = manager.isConsentGranted(TEST_USER_ID); + assertThat(thirdActual).isTrue(); + verify(mMockDevicePolicyManagerInternal, times(3)).isUserOrganizationManaged(TEST_USER_ID); + + verifyZeroInteractions(mMockDevicePolicyCache); } - private void notifyContentObserver( - ContentProtectionConsentManager manager, Uri uri, String key, int value) { + private void putGlobalSettings(String key, int value) { Settings.Global.putInt(mTestableContentResolver, key, value); - // Observer has to be called manually, mTestableContentResolver is not propagating - manager.mContentObserver.onChange(/* selfChange= */ false, uri, TEST_USER_ID); } - private ContentProtectionConsentManager createContentProtectionConsentManager( - ContentResolver contentResolver) { - return new ContentProtectionConsentManager( - new Handler(Looper.getMainLooper()), - contentResolver, - mMockDevicePolicyManagerInternal); + private void notifyContentObserver(ContentProtectionConsentManager manager, Uri uri) { + // Observer has to be called manually, mTestableContentResolver is not propagating + manager.mContentObserver.onChange(/* selfChange= */ false, uri, TEST_USER_ID); } private ContentProtectionConsentManager createContentProtectionConsentManager( @@ -227,6 +430,14 @@ public class ContentProtectionConsentManagerTest { mTestableContentResolver, KEY_CONTENT_PROTECTION_USER_CONSENT, valueContentProtectionUserConsent); - return createContentProtectionConsentManager(mTestableContentResolver); + return new ContentProtectionConsentManager( + new Handler(Looper.getMainLooper()), + mTestableContentResolver, + mMockDevicePolicyCache); + } + + private <T> void setupLocalService(Class<T> clazz, T service) { + LocalServices.removeServiceForTest(clazz); + LocalServices.addService(clazz, service); } } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java index 9660d6ba2f74..5f60ad93ec8b 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyConstantsTest.java @@ -17,7 +17,7 @@ package com.android.server.devicepolicy; import static com.google.common.truth.Truth.assertThat; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import org.junit.Test; diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java index d55f3796f6cb..8a9538f2374a 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java @@ -37,7 +37,8 @@ import android.os.Parcel; import android.os.SystemClock; import android.os.UserHandle; import android.os.test.TestLooper; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java index 375b52d2d5e4..e81231ad3a93 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OwnersTest.java @@ -25,8 +25,8 @@ import static com.google.common.truth.Truth.assertWithMessage; import android.content.ComponentName; import android.os.IpcDataCache; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java index d6d2b6d9abd2..07fb9fc2f509 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkManagementServiceTest.java @@ -52,9 +52,9 @@ import android.os.Process; import android.os.RemoteException; import android.os.test.FakePermissionEnforcer; import android.platform.test.annotations.Presubmit; -import android.test.suitebuilder.annotation.SmallTest; import android.util.ArrayMap; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.app.IBatteryStats; diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java index 15cd5115a49e..124970758fa5 100644 --- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java @@ -177,7 +177,6 @@ import android.telephony.SubscriptionManager; import android.telephony.SubscriptionPlan; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; -import android.test.suitebuilder.annotation.MediumTest; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; @@ -191,6 +190,7 @@ import android.util.SparseIntArray; import androidx.test.InstrumentationRegistry; import androidx.test.filters.FlakyTest; +import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.test.BroadcastInterceptingContext; @@ -2404,6 +2404,45 @@ public class NetworkPolicyManagerServiceTest { } @Test + public void testObsoleteHandleUidGone() throws Exception { + callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 51); + assertFalse(mService.isUidNetworkingBlocked(UID_A, false)); + + clearInvocations(mNetworkManager); + + // In the service, handleUidGone is only called from mUidEventHandler. Then a call to it may + // be rendered obsolete by a newer uid change posted on the handler. The latest uid state + // change is always reflected in the current UidStateChangeCallbackInfo for the uid, so to + // simulate an obsolete call for test, we directly call handleUidGone and leave the state in + // UidStateChangeCallbackInfo set by the previous call to onUidStateChanged(TOP). This call + // should then do nothing. + mService.handleUidGone(UID_A); + + verify(mNetworkManager, times(0)).setFirewallUidRule(anyInt(), anyInt(), anyInt()); + assertFalse(mService.isUidNetworkingBlocked(UID_A, false)); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE) + public void testObsoleteHandleUidChanged() throws Exception { + callAndWaitOnUidGone(UID_A); + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + + clearInvocations(mNetworkManager); + + // In the service, handleUidChanged is only called from mUidEventHandler. Then a call to it + // may be rendered obsolete by an immediate uid-gone posted on the handler. The latest uid + // state change is always reflected in the current UidStateChangeCallbackInfo for the uid, + // so to simulate an obsolete call for test, we directly call handleUidChanged and leave the + // state in UidStateChangeCallbackInfo as null as it would get removed by the previous call + // to onUidGone(). This call should then do nothing. + mService.handleUidChanged(UID_A); + + verify(mNetworkManager, times(0)).setFirewallUidRule(anyInt(), anyInt(), anyInt()); + assertTrue(mService.isUidNetworkingBlocked(UID_A, false)); + } + + @Test public void testLowPowerStandbyAllowlist() throws Exception { // Chain background is also enabled but these procstates are important enough to be exempt. callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 0); diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java index 44c464ed6adf..507b3fe62e29 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -40,13 +40,13 @@ import android.os.UserManager; import android.platform.test.annotations.Postsubmit; import android.platform.test.annotations.RequiresFlagsEnabled; import android.provider.Settings; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.MediumTest; import android.util.ArraySet; import android.util.Slog; import androidx.annotation.Nullable; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.LargeTest; +import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; diff --git a/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java b/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java index 0635cc4239f4..669eedf39342 100644 --- a/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java +++ b/services/tests/servicestests/src/com/android/server/policy/SideFpsEventHandlerTest.java @@ -32,13 +32,13 @@ import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback import android.os.Handler; import android.os.PowerManager; import android.os.test.TestLooper; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableContext; import android.testing.TestableResources; import android.view.Window; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import com.android.internal.R; diff --git a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java index ca0270deb398..db7822d32a93 100644 --- a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java +++ b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java @@ -47,7 +47,8 @@ import android.provider.DeviceConfig; import android.provider.Settings; import android.service.attention.AttentionService; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import com.android.server.wm.WindowManagerInternal; diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java index 6fffd7533df8..fe9a0e220d41 100644 --- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java +++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java @@ -29,10 +29,11 @@ import android.os.PowerSaveState; import android.provider.DeviceConfig; import android.provider.Settings.Global; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; -import android.test.suitebuilder.annotation.Suppress; import android.util.ArrayMap; +import androidx.test.filters.SmallTest; +import androidx.test.filters.Suppress; + import com.android.frameworks.servicestests.R; import com.android.internal.annotations.VisibleForTesting; import com.android.server.power.batterysaver.BatterySaverPolicy.Policy; diff --git a/services/tests/servicestests/src/com/android/server/usage/IntervalStatsTests.java b/services/tests/servicestests/src/com/android/server/usage/IntervalStatsTests.java index 517f48346b30..cb5371bfd4d1 100644 --- a/services/tests/servicestests/src/com/android/server/usage/IntervalStatsTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/IntervalStatsTests.java @@ -26,8 +26,8 @@ import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManager; import android.content.res.Configuration; import android.os.PersistableBundle; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.ArrayUtils; diff --git a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java index cd29c8057706..f3885289a977 100644 --- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java +++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java @@ -31,11 +31,11 @@ import android.app.usage.UsageStatsManager; import android.content.Context; import android.content.res.Configuration; import android.os.PersistableBundle; -import android.test.suitebuilder.annotation.SmallTest; import android.util.AtomicFile; import android.util.LongSparseArray; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java b/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java index 076d5caf5954..44d116181be5 100644 --- a/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java +++ b/services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java @@ -147,7 +147,7 @@ public class AnrTimerTest { final int n = 4; StackTraceElement[] stack = Thread.currentThread().getStackTrace(); if (stack.length < n+1) return "test"; - return stack[n].getMethodName(); + return stack[n].getClassName() + "." + stack[n].getMethodName(); } } @@ -318,8 +318,11 @@ public class AnrTimerTest { public void testDumpOutput() throws Exception { if (!AnrTimer.nativeTimersSupported()) return; + // The timers in this class are named "class.method". + final String timerName = "timer: com.android.server.utils.AnrTimerTest"; + String r1 = getDumpOutput(); - assertThat(r1).doesNotContain("timer:"); + assertThat(r1).doesNotContain(timerName); Helper helper = new Helper(2); TestArg t1 = new TestArg(1, 1); @@ -333,14 +336,14 @@ public class AnrTimerTest { String r2 = getDumpOutput(); // There are timers in the list if and only if the feature is enabled. if (mEnabled) { - assertThat(r2).contains("timer:"); + assertThat(r2).contains(timerName); } else { - assertThat(r2).doesNotContain("timer:"); + assertThat(r2).doesNotContain(timerName); } } String r3 = getDumpOutput(); - assertThat(r3).doesNotContain("timer:"); + assertThat(r3).doesNotContain(timerName); } /** diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java index 53c172a191b6..c535ec5026db 100644 --- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java @@ -31,7 +31,6 @@ import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; -import android.test.suitebuilder.annotation.MediumTest; import android.util.Base64; import android.webkit.UserPackage; import android.webkit.WebViewFactory; @@ -39,6 +38,7 @@ import android.webkit.WebViewProviderInfo; import android.webkit.WebViewProviderResponse; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; diff --git a/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java b/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java index e27bb4c8c3b6..b9ece9360980 100644 --- a/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java +++ b/services/tests/servicestests/utils/com/android/server/testutils/StubTransaction.java @@ -40,12 +40,19 @@ import java.util.concurrent.Executor; public class StubTransaction extends SurfaceControl.Transaction { private HashSet<Runnable> mWindowInfosReportedListeners = new HashSet<>(); + private HashSet<SurfaceControl.TransactionCommittedListener> mTransactionCommittedListeners = + new HashSet<>(); @Override public void apply() { for (Runnable listener : mWindowInfosReportedListeners) { listener.run(); } + for (SurfaceControl.TransactionCommittedListener listener + : mTransactionCommittedListeners) { + listener.onTransactionCommitted(); + } + mTransactionCommittedListeners.clear(); } @Override @@ -239,6 +246,9 @@ public class StubTransaction extends SurfaceControl.Transaction { @Override public SurfaceControl.Transaction addTransactionCommittedListener(Executor executor, SurfaceControl.TransactionCommittedListener listener) { + SurfaceControl.TransactionCommittedListener listenerInner = + () -> executor.execute(listener::onTransactionCommitted); + mTransactionCommittedListeners.add(listenerInner); return this; } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/AlertRateLimiterTest.java b/services/tests/uiservicestests/src/com/android/server/notification/AlertRateLimiterTest.java index dc7f118628b7..f229fd9bb221 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/AlertRateLimiterTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/AlertRateLimiterTest.java @@ -20,8 +20,7 @@ import static com.android.server.notification.AlertRateLimiter.ALLOWED_ALERT_INT import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; -import android.test.suitebuilder.annotation.SmallTest; - +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java index 8bc027d50a3b..39ff9cc75fc2 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java @@ -33,8 +33,8 @@ import android.os.UserHandle; import android.os.UserManager; import android.platform.test.flag.junit.SetFlagsRule; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BadgeExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BadgeExtractorTest.java index ce6939a9beeb..2f5c96c36a41 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BadgeExtractorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BadgeExtractorTest.java @@ -35,8 +35,8 @@ import android.graphics.drawable.Icon; import android.media.session.MediaSession; import android.os.UserHandle; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java index 9dffed20afea..b5bc610f82ea 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BubbleExtractorTest.java @@ -48,8 +48,8 @@ import android.content.pm.ShortcutInfo; import android.os.SystemClock; import android.os.UserHandle; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java index 8622488f820e..517dcb4f21f6 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -74,12 +74,12 @@ import android.os.Vibrator; import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.IAccessibilityManager; import android.view.accessibility.IAccessibilityManagerClient; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.logging.InstanceIdSequence; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java index 3797dbb97213..bfbc81ccfe39 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java @@ -29,9 +29,11 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; @@ -103,8 +105,10 @@ public class DefaultDeviceEffectsApplierTest { mContext.addMockSystemService(ColorDisplayManager.class, mColorDisplayManager); mContext.addMockSystemService(UiModeManager.class, mUiModeManager); mContext.addMockSystemService(WallpaperManager.class, mWallpaperManager); + when(mWallpaperManager.isWallpaperSupported()).thenReturn(true); mApplier = new DefaultDeviceEffectsApplier(mContext); + verify(mWallpaperManager).isWallpaperSupported(); } @Test @@ -187,6 +191,26 @@ public class DefaultDeviceEffectsApplierTest { } @Test + public void apply_disabledWallpaperService_dimWallpaperNotApplied() { + mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API); + WallpaperManager disabledWallpaperService = mock(WallpaperManager.class); + when(mWallpaperManager.isWallpaperSupported()).thenReturn(false); + mContext.addMockSystemService(WallpaperManager.class, disabledWallpaperService); + mApplier = new DefaultDeviceEffectsApplier(mContext); + verify(mWallpaperManager).isWallpaperSupported(); + + ZenDeviceEffects effects = new ZenDeviceEffects.Builder() + .setShouldSuppressAmbientDisplay(true) + .setShouldDimWallpaper(true) + .setShouldDisplayGrayscale(true) + .setShouldUseNightMode(true) + .build(); + mApplier.apply(effects, UPDATE_ORIGIN_USER); + + verifyNoMoreInteractions(mWallpaperManager); + } + + @Test public void apply_someEffects_onlyThoseEffectsApplied() { mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GlobalSortKeyComparatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GlobalSortKeyComparatorTest.java index 5041779840b3..d3e1b902cea0 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/GlobalSortKeyComparatorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/GlobalSortKeyComparatorTest.java @@ -22,8 +22,8 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.os.UserHandle; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java index f0779144ad18..1194973b4cad 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java @@ -57,9 +57,9 @@ import android.os.UserHandle; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; import android.util.ArrayMap; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.R; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java index ffc0dcdca5fc..a11d3f4a8d2c 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ImportanceExtractorTest.java @@ -16,9 +16,6 @@ package com.android.server.notification; import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.app.Notification; @@ -27,8 +24,8 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.os.UserHandle; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java index e75afccfdfdf..a1c24f1f27bf 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java @@ -34,10 +34,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; - -import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.ArgumentMatchers.anyString; @@ -84,13 +83,13 @@ import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Pair; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.IAccessibilityManager; import android.view.accessibility.IAccessibilityManagerClient; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags; @@ -103,10 +102,6 @@ import com.android.server.lights.LightsManager; import com.android.server.lights.LogicalLight; import com.android.server.pm.PackageManagerService; -import java.util.List; -import java.util.Objects; - -import java.util.Set; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -118,6 +113,10 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.verification.VerificationMode; +import java.util.List; +import java.util.Objects; +import java.util.Set; + @SmallTest @RunWith(AndroidJUnit4.class) @SuppressLint("GuardedBy") diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java index 7b16500928a0..5aecac2cab78 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java @@ -50,8 +50,8 @@ import android.os.Vibrator; import android.provider.Settings; import android.service.notification.StatusBarNotification; import android.telecom.TelecomManager; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryFilterTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryFilterTest.java index 10bfcf12c89f..6faa89970bf7 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryFilterTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryFilterTest.java @@ -20,9 +20,9 @@ import static com.google.common.truth.Truth.assertThat; import android.app.NotificationHistory; import android.app.NotificationHistory.HistoricalNotification; import android.graphics.drawable.Icon; -import android.test.suitebuilder.annotation.SmallTest; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryProtoHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryProtoHelperTest.java index 6eaf5462a6ec..b234c3ea44c0 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryProtoHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryProtoHelperTest.java @@ -20,10 +20,10 @@ import static com.google.common.truth.Truth.assertThat; import android.app.NotificationHistory; import android.app.NotificationHistory.HistoricalNotification; import android.graphics.drawable.Icon; -import android.test.suitebuilder.annotation.SmallTest; import android.text.TextUtils; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java index bf850cfe04db..8fad01a7541d 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java @@ -56,8 +56,8 @@ import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationRankingUpdate; import android.service.notification.SnoozeCriterion; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 715c9d4081b2..e3ea55a67e71 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -87,10 +87,10 @@ import static android.service.notification.Adjustment.KEY_CONTEXTUAL_ACTIONS; import static android.service.notification.Adjustment.KEY_IMPORTANCE; import static android.service.notification.Adjustment.KEY_TEXT_REPLIES; import static android.service.notification.Adjustment.KEY_USER_SENTIMENT; -import static android.service.notification.Flags.FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS; import static android.service.notification.Condition.SOURCE_CONTEXT; import static android.service.notification.Condition.SOURCE_USER_ACTION; import static android.service.notification.Condition.STATE_TRUE; +import static android.service.notification.Flags.FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS; import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING; import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS; import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING; @@ -247,7 +247,6 @@ import android.service.notification.ZenModeConfig; import android.service.notification.ZenPolicy; import android.telecom.TelecomManager; import android.telephony.TelephonyManager; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; @@ -263,6 +262,7 @@ import android.util.Xml; import android.widget.RemoteViews; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; @@ -14334,6 +14334,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) + @EnableCompatChanges(NotificationManagerService.MANAGE_GLOBAL_ZEN_VIA_IMPLICIT_RULES) public void requestInterruptionFilterFromListener_fromApp_doesNotSetGlobalZen() throws Exception { mService.setCallerIsNormalPackage(); @@ -14351,6 +14352,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) + @EnableCompatChanges(NotificationManagerService.MANAGE_GLOBAL_ZEN_VIA_IMPLICIT_RULES) public void requestInterruptionFilterFromListener_fromSystem_setsGlobalZen() throws Exception { mService.isSystemUid = true; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java index 0222bfbf8605..b42df77270ee 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java @@ -22,7 +22,6 @@ import static junit.framework.Assert.assertSame; import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -43,12 +42,12 @@ import android.os.Handler; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.UserHandle; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; -import android.testing.TestableContext; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; +import androidx.test.filters.SmallTest; + import com.android.server.UiServiceTestCase; import org.junit.Before; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotifyingAppTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotifyingAppTest.java index 0c6283116594..30e851f0423c 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotifyingAppTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotifyingAppTest.java @@ -20,8 +20,8 @@ import static junit.framework.Assert.assertTrue; import android.os.Parcel; import android.service.notification.NotifyingApp; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java index 2f52d5c48b6b..2d591ba0b98b 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java @@ -43,9 +43,9 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.ParceledListSlice; import android.permission.IPermissionManager; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Pair; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 8b557789195a..78fb5705d5ac 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -115,7 +115,6 @@ import android.provider.Settings.Global; import android.provider.Settings.Secure; import android.service.notification.ConversationChannelWrapper; import android.service.notification.nano.RankingHelperProto; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableContentResolver; import android.text.format.DateUtils; import android.util.ArrayMap; @@ -128,6 +127,7 @@ import android.util.Xml; import android.util.proto.ProtoOutputStream; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java index 4217881495b1..d2c6028dea45 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java @@ -43,10 +43,10 @@ import android.os.Build; import android.os.UserHandle; import android.os.Vibrator; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableContentResolver; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java index 131aaa0d4ea7..65ed7b6e622d 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/RateEstimatorTest.java @@ -19,8 +19,7 @@ import static com.google.common.truth.Truth.assertThat; import static java.util.concurrent.TimeUnit.HOURS; -import android.test.suitebuilder.annotation.SmallTest; - +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java index 81c573d8fb1e..70910b108fe9 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java @@ -54,7 +54,6 @@ import android.os.UserManager; import android.permission.PermissionManager; import android.telecom.TelecomManager; import android.telephony.TelephonyManager; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; @@ -63,6 +62,7 @@ import android.util.AtomicFile; import android.util.Pair; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import com.android.internal.config.sysui.TestableFlagResolver; import com.android.internal.logging.InstanceIdSequence; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java index 9ad007d6a840..7b4229f62709 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleCalendarTest.java @@ -23,9 +23,9 @@ import static org.junit.Assert.assertTrue; import android.service.notification.ScheduleCalendar; import android.service.notification.ZenModeConfig; -import android.test.suitebuilder.annotation.SmallTest; import androidx.test.filters.FlakyTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java index 11cb150651aa..a4fb16dc1adc 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java @@ -36,9 +36,9 @@ import android.content.pm.ShortcutServiceInternal; import android.os.UserHandle; import android.os.UserManager; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableLooper; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; 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 1e3b7282e2f7..dcd56e07f0d2 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/SnoozeHelperTest.java @@ -44,10 +44,10 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.os.UserHandle; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; import android.util.IntArray; import android.util.Xml; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.modules.utils.TypedXmlPullParser; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java index 0564a73bf3fc..cb4422235ea4 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java @@ -45,11 +45,11 @@ import android.os.Bundle; import android.os.UserManager; import android.provider.ContactsContract; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; import android.text.SpannableString; import android.util.ArraySet; import android.util.LruCache; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/VibratorHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/VibratorHelperTest.java index f135d16ea3b8..0993bec42c6a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/VibratorHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/VibratorHelperTest.java @@ -24,8 +24,8 @@ import static org.mockito.Mockito.when; import android.os.VibrationEffect; import android.os.Vibrator; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/VisibilityExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/VisibilityExtractorTest.java index 3998129659c6..6084153cf430 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/VisibilityExtractorTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/VisibilityExtractorTest.java @@ -18,17 +18,11 @@ package com.android.server.notification; import static android.app.Notification.VISIBILITY_PRIVATE; import static android.app.Notification.VISIBILITY_SECRET; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; -import static android.app.NotificationManager.IMPORTANCE_HIGH; -import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; -import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE; -import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS; import static android.app.NotificationManager.VISIBILITY_NO_OVERRIDE; import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS; import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS; import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; import static org.mockito.Mockito.when; @@ -36,15 +30,11 @@ import android.app.ActivityManager; import android.app.Notification; import android.app.Notification.Builder; import android.app.NotificationChannel; -import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; -import android.content.Intent; -import android.graphics.drawable.Icon; -import android.media.session.MediaSession; import android.os.UserHandle; import android.service.notification.StatusBarNotification; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java index 7d6e12cf7cb4..b997f5d9a2a0 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java @@ -51,11 +51,12 @@ import android.service.notification.StatusBarNotification; import android.service.notification.ZenModeConfig; import android.service.notification.ZenPolicy; import android.telephony.TelephonyManager; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.ArraySet; +import androidx.test.filters.SmallTest; + import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.util.NotificationMessagingUtil; import com.android.server.UiServiceTestCase; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index 8c2fd1013056..495e01a640de 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -22,6 +22,7 @@ import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ACTIVATED; import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_DEACTIVATED; import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_DISABLED; import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ENABLED; +import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_UNKNOWN; import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS; import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL; import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE; @@ -108,6 +109,7 @@ import android.app.AutomaticZenRule; import android.app.Flags; import android.app.NotificationManager; import android.app.NotificationManager.Policy; +import android.app.compat.CompatChanges; import android.content.ComponentName; import android.content.ContentResolver; import android.content.pm.ActivityInfo; @@ -141,7 +143,6 @@ import android.service.notification.ZenModeConfig.ScheduleInfo; import android.service.notification.ZenModeConfig.ZenRule; import android.service.notification.ZenModeDiff; import android.service.notification.ZenPolicy; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestWithLooperRule; import android.testing.TestableLooper; import android.util.ArrayMap; @@ -150,6 +151,8 @@ import android.util.StatsEvent; import android.util.StatsEventTestUtils; import android.util.Xml; +import androidx.test.filters.SmallTest; + import com.android.internal.R; import com.android.internal.config.sysui.TestableFlagResolver; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; @@ -4673,7 +4676,11 @@ public class ZenModeHelperTest extends UiServiceTestCase { UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); - assertEquals(AUTOMATIC_RULE_STATUS_ACTIVATED, actualStatus[0]); + if (CompatChanges.isChangeEnabled(ZenModeHelper.SEND_ACTIVATION_AZR_STATUSES)) { + assertEquals(AUTOMATIC_RULE_STATUS_ACTIVATED, actualStatus[0]); + } else { + assertEquals(AUTOMATIC_RULE_STATUS_UNKNOWN, actualStatus[0]); + } } @Test @@ -4714,7 +4721,11 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, "", Process.SYSTEM_UID); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); - assertEquals(AUTOMATIC_RULE_STATUS_DEACTIVATED, actualStatus[1]); + if (CompatChanges.isChangeEnabled(ZenModeHelper.SEND_ACTIVATION_AZR_STATUSES)) { + assertEquals(AUTOMATIC_RULE_STATUS_DEACTIVATED, actualStatus[1]); + } else { + assertEquals(AUTOMATIC_RULE_STATUS_UNKNOWN, actualStatus[1]); + } } @Test @@ -4753,10 +4764,14 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.setAutomaticZenRuleState(createdId, new Condition(zenRule.getConditionId(), "", STATE_FALSE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + UPDATE_ORIGIN_APP, Process.SYSTEM_UID); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); - assertEquals(AUTOMATIC_RULE_STATUS_DEACTIVATED, actualStatus[1]); + if (CompatChanges.isChangeEnabled(ZenModeHelper.SEND_ACTIVATION_AZR_STATUSES)) { + assertEquals(AUTOMATIC_RULE_STATUS_DEACTIVATED, actualStatus[1]); + } else { + assertEquals(AUTOMATIC_RULE_STATUS_UNKNOWN, actualStatus[1]); + } } @Test diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenPolicyTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenPolicyTest.java index 3a88294a0fa1..6433b76defc3 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenPolicyTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenPolicyTest.java @@ -26,8 +26,8 @@ import android.os.Parcel; import android.platform.test.flag.junit.SetFlagsRule; import android.service.notification.ZenPolicy; import android.service.notification.nano.DNDPolicyProto; -import android.test.suitebuilder.annotation.SmallTest; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.UiServiceTestCase; diff --git a/services/tests/vibrator/src/com/android/server/vibrator/GroupedAggregatedLogRecordsTest.java b/services/tests/vibrator/src/com/android/server/vibrator/GroupedAggregatedLogRecordsTest.java new file mode 100644 index 000000000000..038f1db32d18 --- /dev/null +++ b/services/tests/vibrator/src/com/android/server/vibrator/GroupedAggregatedLogRecordsTest.java @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.vibrator; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import android.util.IndentingPrintWriter; +import android.util.proto.ProtoOutputStream; + +import com.android.server.vibrator.GroupedAggregatedLogRecords.AggregatedLogRecord; +import com.android.server.vibrator.GroupedAggregatedLogRecords.SingleLogRecord; + +import org.junit.Test; + +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class GroupedAggregatedLogRecordsTest { + + private static final int AGGREGATION_TIME_LIMIT = 1000; + private static final int NO_AGGREGATION_TIME_LIMIT = 0; + private static final long PROTO_FIELD_ID = 1; + private static final int GROUP_1 = 1; + private static final int GROUP_2 = 2; + private static final int KEY_1 = 1; + private static final int KEY_2 = 2; + + private static final IndentingPrintWriter WRITER = new IndentingPrintWriter(new StringWriter()); + private static final ProtoOutputStream PROTO_OUTPUT_STREAM = new ProtoOutputStream(); + + private final List<TestSingleLogRecord> mTestRecords = new ArrayList<>(); + + @Test + public void record_noAggregation_keepsIndividualRecords() { + int sizeLimit = 10; + long createTime = 100; + TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords( + sizeLimit, NO_AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID); + + for (int i = 0; i < sizeLimit; i++) { + assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime++))).isNull(); + } + + dumpRecords(records); + assertGroupHeadersWrittenOnce(records, GROUP_1); + assertRecordsInRangeWrittenOnce(0, sizeLimit); + } + + @Test + public void record_sizeLimit_dropsOldestEntriesForNewOnes() { + long createTime = 100; + TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords( + /* sizeLimit= */ 2, NO_AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID); + + TestSingleLogRecord firstRecord = createRecord(GROUP_1, KEY_1, createTime++); + assertThat(records.add(firstRecord)).isNull(); + assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime++))).isNull(); + + // Adding third record drops first record + AggregatedLogRecord<TestSingleLogRecord> droppedRecord = + records.add(createRecord(GROUP_1, KEY_1, createTime++)); + assertThat(droppedRecord).isNotNull(); + assertThat(droppedRecord.getLatest()).isEqualTo(firstRecord); + + dumpRecords(records); + assertGroupHeadersWrittenOnce(records, GROUP_1); + assertRecordsInRangeNotWritten(0, 1); // First record not written + assertRecordsInRangeWrittenOnce(1, 3); // All newest records written + } + + @Test + public void record_timeAggregation_aggregatesCloseRecordAndPrintsOnlyFirstAndLast() { + long createTime = 100; + TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords( + /* sizeLimit= */ 1, AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID); + + // No record dropped, all aggregated in a single entry + assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime))).isNull(); + assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime + 1))).isNull(); + assertThat(records.add(createRecord(GROUP_1, KEY_1, + createTime + AGGREGATION_TIME_LIMIT - 2))).isNull(); + assertThat(records.add(createRecord(GROUP_1, KEY_1, + createTime + AGGREGATION_TIME_LIMIT - 1))).isNull(); + + dumpRecords(records); + assertGroupHeadersWrittenOnce(records, GROUP_1); + assertRecordsInRangeWrittenOnce(0, 1); // Writes first record + assertRecordsInRangeNotWritten(1, 3); // Skips aggregated records in between + assertRecordsInRangeWrittenOnce(3, 4); // Writes last record + } + + @Test + public void record_differentGroups_recordsKeptSeparate() { + long createTime = 100; + TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords( + /* sizeLimit= */ 1, AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID); + + // No record dropped, all kept in separate aggregated lists + assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime++))).isNull(); + assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime++))).isNull(); + assertThat(records.add(createRecord(GROUP_2, KEY_2, createTime++))).isNull(); + assertThat(records.add(createRecord(GROUP_2, KEY_2, createTime++))).isNull(); + + dumpRecords(records); + assertGroupHeadersWrittenOnce(records, GROUP_1, GROUP_2); + assertRecordsInRangeWrittenOnce(0, 4); + } + + @Test + public void record_sameGroupDifferentAggregationKeys_recordsNotAggregated() { + long createTime = 100; + TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords( + /* sizeLimit= */ 1, AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID); + + assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime++))).isNull(); + + // Second record on same group with different key not aggregated, drops first record + AggregatedLogRecord<TestSingleLogRecord> droppedRecord = + records.add(createRecord(GROUP_1, KEY_2, createTime++)); + assertThat(droppedRecord).isNotNull(); + assertThat(droppedRecord.getLatest()).isEqualTo(mTestRecords.getFirst()); + + dumpRecords(records); + assertGroupHeadersWrittenOnce(records, GROUP_1); + assertRecordsInRangeNotWritten(0, 1); // Skips first record that was dropped + assertRecordsInRangeWrittenOnce(1, 2); // Writes last record + } + + @Test + public void record_sameGroupAndAggregationKeysDistantTimes_recordsNotAggregated() { + long createTime = 100; + TestGroupedAggregatedLogRecords records = new TestGroupedAggregatedLogRecords( + /* sizeLimit= */ 1, AGGREGATION_TIME_LIMIT, PROTO_FIELD_ID); + + assertThat(records.add(createRecord(GROUP_1, KEY_1, createTime))).isNull(); + + // Second record after aggregation time limit not aggregated, drops first record + AggregatedLogRecord<TestSingleLogRecord> droppedRecord = + records.add(createRecord(GROUP_1, KEY_1, createTime + AGGREGATION_TIME_LIMIT)); + assertThat(droppedRecord).isNotNull(); + assertThat(droppedRecord.getLatest()).isEqualTo(mTestRecords.getFirst()); + + dumpRecords(records); + assertGroupHeadersWrittenOnce(records, GROUP_1); + assertRecordsInRangeNotWritten(0, 1); // Skips first record that was dropped + assertRecordsInRangeWrittenOnce(1, 2); // Writes last record + } + + private TestSingleLogRecord createRecord(int groupKey, int aggregateKey, long createTime) { + TestSingleLogRecord record = new TestSingleLogRecord(groupKey, aggregateKey, createTime); + mTestRecords.add(record); + return record; + } + + private void dumpRecords(TestGroupedAggregatedLogRecords records) { + records.dump(WRITER); + records.dump(PROTO_OUTPUT_STREAM); + } + + private void assertGroupHeadersWrittenOnce(TestGroupedAggregatedLogRecords records, + int... groupKeys) { + assertThat(records.dumpGroupKeys).containsExactlyElementsIn( + Arrays.stream(groupKeys).boxed().toList()); + } + + private void assertRecordsInRangeWrittenOnce(int startIndexInclusive, int endIndexExclusive) { + for (int i = startIndexInclusive; i < endIndexExclusive; i++) { + assertWithMessage("record index=" + i).that(mTestRecords.get(i).dumpTextCount) + .isEqualTo(1); + assertWithMessage("record index=" + i).that(mTestRecords.get(i).dumpProtoFieldIds) + .containsExactly(PROTO_FIELD_ID); + } + } + + private void assertRecordsInRangeNotWritten(int startIndexInclusive, int endIndexExclusive) { + for (int i = startIndexInclusive; i < endIndexExclusive; i++) { + assertWithMessage("record index=" + i).that(mTestRecords.get(i).dumpTextCount) + .isEqualTo(0); + assertWithMessage("record index=" + i).that(mTestRecords.get(i).dumpProtoFieldIds) + .isEmpty(); + } + } + + private static final class TestGroupedAggregatedLogRecords + extends GroupedAggregatedLogRecords<TestSingleLogRecord> { + + public final List<Integer> dumpGroupKeys = new ArrayList<>(); + + private final long mProtoFieldId; + + TestGroupedAggregatedLogRecords(int sizeLimit, int aggregationTimeLimitMs, + long protoFieldId) { + super(sizeLimit, aggregationTimeLimitMs); + mProtoFieldId = protoFieldId; + } + + @Override + void dumpGroupHeader(IndentingPrintWriter pw, int groupKey) { + dumpGroupKeys.add(groupKey); + } + + @Override + long findGroupKeyProtoFieldId(int groupKey) { + return mProtoFieldId; + } + } + + private static final class TestSingleLogRecord implements SingleLogRecord { + public final List<Long> dumpProtoFieldIds = new ArrayList<>(); + public int dumpTextCount = 0; + + private final int mGroupKey; + private final int mAggregateKey; + private final long mCreateTime; + + TestSingleLogRecord(int groupKey, int aggregateKey, long createTime) { + mGroupKey = groupKey; + mAggregateKey = aggregateKey; + mCreateTime = createTime; + } + + @Override + public int getGroupKey() { + return mGroupKey; + } + + @Override + public long getCreateUptimeMs() { + return mCreateTime; + } + + @Override + public boolean mayAggregate(SingleLogRecord record) { + if (record instanceof TestSingleLogRecord param) { + return mAggregateKey == param.mAggregateKey; + } + return false; + } + + @Override + public void dump(IndentingPrintWriter pw) { + dumpTextCount++; + } + + @Override + public void dump(ProtoOutputStream proto, long fieldId) { + dumpProtoFieldIds.add(fieldId); + } + } +} diff --git a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java index 3d0dca0de87e..e3d45967848a 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java @@ -17,9 +17,11 @@ package com.android.server.vibrator; import static android.os.VibrationAttributes.CATEGORY_KEYBOARD; +import static android.os.VibrationAttributes.CATEGORY_UNKNOWN; import static android.os.VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY; import static android.os.VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF; import static android.os.VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE; +import static android.os.VibrationAttributes.USAGE_TOUCH; import static android.os.VibrationEffect.Composition.PRIMITIVE_CLICK; import static android.os.VibrationEffect.Composition.PRIMITIVE_TICK; import static android.os.VibrationEffect.EFFECT_CLICK; @@ -285,7 +287,8 @@ public class HapticFeedbackVibrationProviderTest { HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations(); VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( - SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ false); + SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ false, + false /* fromIme*/); assertThat(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)).isFalse(); } @@ -295,7 +298,7 @@ public class HapticFeedbackVibrationProviderTest { HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations(); VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( - SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ true); + SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ true, false /* fromIme*/); assertThat(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)).isTrue(); } @@ -307,7 +310,7 @@ public class HapticFeedbackVibrationProviderTest { for (int effectId : SCROLL_FEEDBACK_CONSTANTS) { VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( - effectId, /* bypassVibrationIntensitySetting= */ false); + effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/); assertWithMessage("Expected FLAG_BYPASS_INTERRUPTION_POLICY for effect " + effectId) .that(attrs.isFlagSet(FLAG_BYPASS_INTERRUPTION_POLICY)).isTrue(); } @@ -320,40 +323,59 @@ public class HapticFeedbackVibrationProviderTest { for (int effectId : SCROLL_FEEDBACK_CONSTANTS) { VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( - effectId, /* bypassVibrationIntensitySetting= */ false); + effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/); assertWithMessage("Expected no FLAG_BYPASS_INTERRUPTION_POLICY for effect " + effectId) .that(attrs.isFlagSet(FLAG_BYPASS_INTERRUPTION_POLICY)).isFalse(); } } @Test - public void testVibrationAttribute_keyboardCategoryOff_notUseKeyboardCategory() { + public void testVibrationAttribute_keyboardCategoryOff_isIme_notUseKeyboardCategory() { mSetFlagsRule.disableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations(); for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) { VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( - effectId, /* bypassVibrationIntensitySetting= */ false); + effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/); + assertWithMessage("Expected USAGE_TOUCH for effect " + effectId) + .that(attrs.getUsage()).isEqualTo(USAGE_TOUCH); assertWithMessage("Expected no CATEGORY_KEYBOARD for effect " + effectId) - .that(attrs.getCategory()).isEqualTo(0); + .that(attrs.getCategory()).isEqualTo(CATEGORY_UNKNOWN); } } @Test - public void testVibrationAttribute_keyboardCategoryOn_useKeyboardCategory() { + public void testVibrationAttribute_keyboardCategoryOn_notIme_notUseKeyboardCategory() { mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations(); for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) { VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( - effectId, /* bypassVibrationIntensitySetting= */ false); + effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/); + assertWithMessage("Expected USAGE_TOUCH for effect " + effectId) + .that(attrs.getUsage()).isEqualTo(USAGE_TOUCH); + assertWithMessage("Expected CATEGORY_KEYBOARD for effect " + effectId) + .that(attrs.getCategory()).isEqualTo(CATEGORY_UNKNOWN); + } + } + + @Test + public void testVibrationAttribute_keyboardCategoryOn_isIme_useKeyboardCategory() { + mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); + HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations(); + + for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) { + VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( + effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/); + assertWithMessage("Expected USAGE_TOUCH for effect " + effectId) + .that(attrs.getUsage()).isEqualTo(USAGE_TOUCH); assertWithMessage("Expected CATEGORY_KEYBOARD for effect " + effectId) .that(attrs.getCategory()).isEqualTo(CATEGORY_KEYBOARD); } } @Test - public void testVibrationAttribute_noFixAmplitude_keyboardCategoryOn_noBypassIntensityScale() { + public void testVibrationAttribute_noFixAmplitude_notBypassIntensityScale() { mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); mockVibratorPrimitiveSupport(PRIMITIVE_CLICK, PRIMITIVE_TICK); mockKeyboardVibrationFixedAmplitude(-1); @@ -361,7 +383,23 @@ public class HapticFeedbackVibrationProviderTest { for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) { VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( - effectId, /* bypassVibrationIntensitySetting= */ false); + effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/); + assertWithMessage("Expected no FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE for effect " + + effectId) + .that(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)).isFalse(); + } + } + + @Test + public void testVibrationAttribute_notIme_notBypassIntensityScale() { + mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); + mockVibratorPrimitiveSupport(PRIMITIVE_CLICK, PRIMITIVE_TICK); + mockKeyboardVibrationFixedAmplitude(KEYBOARD_VIBRATION_FIXED_AMPLITUDE); + HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations(); + + for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) { + VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( + effectId, /* bypassVibrationIntensitySetting= */ false, false /* fromIme*/); assertWithMessage("Expected no FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE for effect " + effectId) .that(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)).isFalse(); @@ -369,7 +407,7 @@ public class HapticFeedbackVibrationProviderTest { } @Test - public void testVibrationAttribute_fixAmplitude_keyboardCategoryOn_bypassIntensityScale() { + public void testVibrationAttribute_fixAmplitude_isIme_bypassIntensityScale() { mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); mockVibratorPrimitiveSupport(PRIMITIVE_CLICK, PRIMITIVE_TICK); mockKeyboardVibrationFixedAmplitude(KEYBOARD_VIBRATION_FIXED_AMPLITUDE); @@ -377,7 +415,7 @@ public class HapticFeedbackVibrationProviderTest { for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) { VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( - effectId, /* bypassVibrationIntensitySetting= */ false); + effectId, /* bypassVibrationIntensitySetting= */ false, true /* fromIme*/); assertWithMessage("Expected FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE for effect " + effectId) .that(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_SCALE)).isTrue(); diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationScalerTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationScalerTest.java index 3e59878f9e1e..b2644350dfdd 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationScalerTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationScalerTest.java @@ -117,32 +117,32 @@ public class VibrationScalerTest { } @Test - public void testGetExternalVibrationScale() { + public void testGetScaleLevel() { setDefaultIntensity(USAGE_TOUCH, Vibrator.VIBRATION_INTENSITY_LOW); setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_HIGH); assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_VERY_HIGH, - mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH)); + mVibrationScaler.getScaleLevel(USAGE_TOUCH)); setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_MEDIUM); assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_HIGH, - mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH)); + mVibrationScaler.getScaleLevel(USAGE_TOUCH)); setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_LOW); assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_NONE, - mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH)); + mVibrationScaler.getScaleLevel(USAGE_TOUCH)); setDefaultIntensity(USAGE_TOUCH, VIBRATION_INTENSITY_MEDIUM); assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_LOW, - mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH)); + mVibrationScaler.getScaleLevel(USAGE_TOUCH)); setDefaultIntensity(USAGE_TOUCH, VIBRATION_INTENSITY_HIGH); assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_VERY_LOW, - mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH)); + mVibrationScaler.getScaleLevel(USAGE_TOUCH)); setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF); // Vibration setting being bypassed will use default setting and not scale. assertEquals(ExternalVibrationScale.ScaleLevel.SCALE_NONE, - mVibrationScaler.getExternalVibrationScaleLevel(USAGE_TOUCH)); + mVibrationScaler.getScaleLevel(USAGE_TOUCH)); } @Test diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java index 0d5bf95d959d..3799abc100c9 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java @@ -38,10 +38,10 @@ import android.frameworks.vibrator.ScaleParam; import android.os.Binder; import android.os.Handler; import android.os.IBinder; -import android.os.RemoteException; import android.os.test.TestLooper; import android.util.SparseArray; +import androidx.test.InstrumentationRegistry; import androidx.test.core.app.ApplicationProvider; import com.android.internal.util.ArrayUtils; @@ -86,20 +86,20 @@ public class VibratorControlServiceTest { ApplicationProvider.getApplicationContext(), new Handler(testLooper.getLooper())); mFakeVibratorController = new FakeVibratorController(mTestLooper.getLooper()); - mVibratorControlService = new VibratorControlService(new VibratorControllerHolder(), + mVibratorControlService = new VibratorControlService( + InstrumentationRegistry.getContext(), new VibratorControllerHolder(), mMockVibrationScaler, mVibrationSettings, mLock); } @Test - public void testRegisterVibratorController() throws RemoteException { + public void testRegisterVibratorController() { mVibratorControlService.registerVibratorController(mFakeVibratorController); assertThat(mFakeVibratorController.isLinkedToDeath).isTrue(); } @Test - public void testUnregisterVibratorController_providingTheRegisteredController_performsRequest() - throws RemoteException { + public void testUnregisterVibratorController_providingRegisteredController_performsRequest() { mVibratorControlService.registerVibratorController(mFakeVibratorController); mVibratorControlService.unregisterVibratorController(mFakeVibratorController); @@ -108,8 +108,7 @@ public class VibratorControlServiceTest { } @Test - public void testUnregisterVibratorController_providingAnInvalidController_ignoresRequest() - throws RemoteException { + public void testUnregisterVibratorController_providingAnInvalidController_ignoresRequest() { FakeVibratorController controller1 = new FakeVibratorController(mTestLooper.getLooper()); FakeVibratorController controller2 = new FakeVibratorController(mTestLooper.getLooper()); mVibratorControlService.registerVibratorController(controller1); @@ -120,8 +119,7 @@ public class VibratorControlServiceTest { } @Test - public void testOnRequestVibrationParamsComplete_cachesAdaptiveHapticsScalesCorrectly() - throws RemoteException { + public void testOnRequestVibrationParamsComplete_cachesAdaptiveHapticsScalesCorrectly() { mVibratorControlService.registerVibratorController(mFakeVibratorController); int timeoutInMillis = 10; CompletableFuture<Void> future = @@ -148,8 +146,7 @@ public class VibratorControlServiceTest { } @Test - public void testOnRequestVibrationParamsComplete_withIncorrectToken_ignoresRequest() - throws RemoteException, InterruptedException { + public void testOnRequestVibrationParamsComplete_withIncorrectToken_ignoresRequest() { mVibratorControlService.registerVibratorController(mFakeVibratorController); int timeoutInMillis = 10; CompletableFuture<Void> unusedFuture = @@ -167,8 +164,7 @@ public class VibratorControlServiceTest { } @Test - public void testSetVibrationParams_cachesAdaptiveHapticsScalesCorrectly() - throws RemoteException { + public void testSetVibrationParams_cachesAdaptiveHapticsScalesCorrectly() { mVibratorControlService.registerVibratorController(mFakeVibratorController); SparseArray<Float> vibrationScales = new SparseArray<>(); vibrationScales.put(ScaleParam.TYPE_ALARM, 0.7f); @@ -187,8 +183,7 @@ public class VibratorControlServiceTest { } @Test - public void testSetVibrationParams_withUnregisteredController_ignoresRequest() - throws RemoteException { + public void testSetVibrationParams_withUnregisteredController_ignoresRequest() { SparseArray<Float> vibrationScales = new SparseArray<>(); vibrationScales.put(ScaleParam.TYPE_ALARM, 0.7f); vibrationScales.put(ScaleParam.TYPE_NOTIFICATION, 0.4f); @@ -201,8 +196,7 @@ public class VibratorControlServiceTest { } @Test - public void testClearVibrationParams_clearsCachedAdaptiveHapticsScales() - throws RemoteException { + public void testClearVibrationParams_clearsCachedAdaptiveHapticsScales() { mVibratorControlService.registerVibratorController(mFakeVibratorController); int types = buildVibrationTypesMask(ScaleParam.TYPE_ALARM, ScaleParam.TYPE_NOTIFICATION); @@ -216,8 +210,7 @@ public class VibratorControlServiceTest { } @Test - public void testClearVibrationParams_withUnregisteredController_ignoresRequest() - throws RemoteException { + public void testClearVibrationParams_withUnregisteredController_ignoresRequest() { mVibratorControlService.clearVibrationParams(ScaleParam.TYPE_ALARM, mFakeVibratorController); @@ -225,8 +218,7 @@ public class VibratorControlServiceTest { } @Test - public void testRequestVibrationParams_createsFutureRequestProperly() - throws RemoteException { + public void testRequestVibrationParams_createsFutureRequestProperly() { int timeoutInMillis = 10; mVibratorControlService.registerVibratorController(mFakeVibratorController); CompletableFuture<Void> future = @@ -243,8 +235,7 @@ public class VibratorControlServiceTest { } @Test - public void testShouldRequestVibrationParams_returnsTrueForVibrationsThatShouldRequestParams() - throws RemoteException { + public void testShouldRequestVibrationParams_returnsTrueForVibrationsThatShouldRequestParams() { int[] vibrations = new int[]{USAGE_ALARM, USAGE_RINGTONE, USAGE_MEDIA, USAGE_TOUCH, USAGE_NOTIFICATION, USAGE_HARDWARE_FEEDBACK, USAGE_UNKNOWN, USAGE_COMMUNICATION_REQUEST}; @@ -258,8 +249,7 @@ public class VibratorControlServiceTest { } @Test - public void testShouldRequestVibrationParams_unregisteredVibratorController_returnsFalse() - throws RemoteException { + public void testShouldRequestVibrationParams_unregisteredVibratorController_returnsFalse() { int[] vibrations = new int[]{USAGE_ALARM, USAGE_RINGTONE, USAGE_MEDIA, USAGE_TOUCH, USAGE_NOTIFICATION, USAGE_HARDWARE_FEEDBACK, USAGE_UNKNOWN, USAGE_COMMUNICATION_REQUEST}; @@ -269,7 +259,7 @@ public class VibratorControlServiceTest { } } - private int buildVibrationTypesMask(int... types) { + private static int buildVibrationTypesMask(int... types) { int typesMask = 0; for (int type : types) { typesMask |= type; diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java index d2ad61f2ba9f..1ea90f55b727 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java @@ -2526,7 +2526,7 @@ public class VibratorManagerServiceTest { int constant, boolean always) throws InterruptedException { HalVibration vib = service.performHapticFeedbackInternal(UID, Context.DEVICE_ID_DEFAULT, PACKAGE_NAME, - constant, always, "some reason", service); + constant, always, "some reason", service, false /* fromIme */); if (vib != null) { vib.waitForEnd(); } diff --git a/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorController.java b/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorController.java index 2a010f0a82a9..0cd88ef7a4b4 100644 --- a/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorController.java +++ b/services/tests/vibrator/utils/com/android/server/vibrator/FakeVibratorController.java @@ -60,11 +60,7 @@ public final class FakeVibratorController extends IVibratorController.Stub { requestTimeoutInMillis = timeoutInMillis; mHandler.post(() -> { if (mVibratorControlService != null) { - try { - mVibratorControlService.onRequestVibrationParamsComplete(token, mRequestResult); - } catch (RemoteException e) { - throw new RuntimeException(e); - } + mVibratorControlService.onRequestVibrationParamsComplete(token, mRequestResult); } }); } diff --git a/services/tests/voiceinteractiontests/Android.bp b/services/tests/voiceinteractiontests/Android.bp index 8a79fe443179..8c70851f87df 100644 --- a/services/tests/voiceinteractiontests/Android.bp +++ b/services/tests/voiceinteractiontests/Android.bp @@ -45,6 +45,7 @@ android_test { "servicestests-utils-mockito-extended", "truth", "frameworks-base-testutils", + "androidx.test.rules", ], libs: [ diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerTest.java index 35170b3516b7..a9c517ddc946 100644 --- a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerTest.java +++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger/SoundTriggerTest.java @@ -16,19 +16,20 @@ package com.android.server.soundtrigger; +import android.hardware.soundtrigger.SoundTrigger; import android.hardware.soundtrigger.SoundTrigger.ConfidenceLevel; import android.hardware.soundtrigger.SoundTrigger.Keyphrase; import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionEvent; import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra; import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel; import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent; -import android.hardware.soundtrigger.SoundTrigger; import android.media.AudioFormat; +import android.os.Binder; import android.os.Parcel; import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.SmallTest; -import android.os.Binder; + +import androidx.test.filters.LargeTest; +import androidx.test.filters.SmallTest; import java.util.Arrays; import java.util.Locale; diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml index ef197918deff..d6c51736316a 100644 --- a/services/tests/wmtests/AndroidManifest.xml +++ b/services/tests/wmtests/AndroidManifest.xml @@ -49,6 +49,8 @@ <uses-permission android:name="android.permission.MANAGE_MEDIA_PROJECTION"/> <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/> <uses-permission android:name="android.permission.MONITOR_INPUT"/> + <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS"/> + <uses-permission android:name="android.permission.MANAGE_DEFAULT_APPLICATIONS"/> <!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) --> <application android:debuggable="true" diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java index e21388e57a9e..3c02eee7772e 100644 --- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java +++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutTests.java @@ -38,6 +38,7 @@ import static android.view.KeyEvent.KEYCODE_SCREENSHOT; import static android.view.KeyEvent.KEYCODE_U; import static android.view.KeyEvent.KEYCODE_Z; +import android.app.role.RoleManager; import android.content.Intent; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; @@ -51,16 +52,19 @@ import org.junit.Test; @Presubmit @SmallTest public class ModifierShortcutTests extends ShortcutKeyTestBase { - private static final SparseArray<String> META_SHORTCUTS = new SparseArray<>(); + private static final SparseArray<String> INTENT_SHORTCUTS = new SparseArray<>(); + private static final SparseArray<String> ROLE_SHORTCUTS = new SparseArray<>(); static { - META_SHORTCUTS.append(KEYCODE_U, Intent.CATEGORY_APP_CALCULATOR); - META_SHORTCUTS.append(KEYCODE_B, Intent.CATEGORY_APP_BROWSER); - META_SHORTCUTS.append(KEYCODE_C, Intent.CATEGORY_APP_CONTACTS); - META_SHORTCUTS.append(KEYCODE_E, Intent.CATEGORY_APP_EMAIL); - META_SHORTCUTS.append(KEYCODE_K, Intent.CATEGORY_APP_CALENDAR); - META_SHORTCUTS.append(KEYCODE_M, Intent.CATEGORY_APP_MAPS); - META_SHORTCUTS.append(KEYCODE_P, Intent.CATEGORY_APP_MUSIC); - META_SHORTCUTS.append(KEYCODE_S, Intent.CATEGORY_APP_MESSAGING); + // These shortcuts should align with those defined in bookmarks.xml + INTENT_SHORTCUTS.append(KEYCODE_U, Intent.CATEGORY_APP_CALCULATOR); + INTENT_SHORTCUTS.append(KEYCODE_C, Intent.CATEGORY_APP_CONTACTS); + INTENT_SHORTCUTS.append(KEYCODE_E, Intent.CATEGORY_APP_EMAIL); + INTENT_SHORTCUTS.append(KEYCODE_K, Intent.CATEGORY_APP_CALENDAR); + INTENT_SHORTCUTS.append(KEYCODE_M, Intent.CATEGORY_APP_MAPS); + INTENT_SHORTCUTS.append(KEYCODE_P, Intent.CATEGORY_APP_MUSIC); + + ROLE_SHORTCUTS.append(KEYCODE_B, RoleManager.ROLE_BROWSER); + ROLE_SHORTCUTS.append(KEYCODE_S, RoleManager.ROLE_SMS); } private static final int ANY_DISPLAY_ID = 123; @@ -74,13 +78,21 @@ public class ModifierShortcutTests extends ShortcutKeyTestBase { */ @Test public void testMetaShortcuts() { - for (int i = 0; i < META_SHORTCUTS.size(); i++) { - final int keyCode = META_SHORTCUTS.keyAt(i); - final String category = META_SHORTCUTS.valueAt(i); + for (int i = 0; i < INTENT_SHORTCUTS.size(); i++) { + final int keyCode = INTENT_SHORTCUTS.keyAt(i); + final String category = INTENT_SHORTCUTS.valueAt(i); sendKeyCombination(new int[]{KEYCODE_META_LEFT, keyCode}, 0); mPhoneWindowManager.assertLaunchCategory(category); } + + for (int i = 0; i < ROLE_SHORTCUTS.size(); i++) { + final int keyCode = ROLE_SHORTCUTS.keyAt(i); + final String role = ROLE_SHORTCUTS.valueAt(i); + + sendKeyCombination(new int[]{KEYCODE_META_LEFT, keyCode}, 0); + mPhoneWindowManager.assertLaunchRole(role); + } } /** diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java index 1a26c451c076..0776c512b61d 100644 --- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java +++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java @@ -60,6 +60,7 @@ import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.NotificationManager; import android.app.SearchManager; +import android.app.role.RoleManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -124,6 +125,8 @@ import java.util.function.Supplier; class TestPhoneWindowManager { private static final long TEST_SINGLE_KEY_DELAY_MILLIS = SingleKeyGestureDetector.MULTI_PRESS_TIMEOUT + 1000L * HW_TIMEOUT_MULTIPLIER; + private static final String TEST_BROWSER_ROLE_PACKAGE_NAME = "com.browser"; + private static final String TEST_SMS_ROLE_PACKAGE_NAME = "com.sms"; private PhoneWindowManager mPhoneWindowManager; private Context mContext; @@ -151,6 +154,7 @@ class TestPhoneWindowManager { @Mock private UserManagerInternal mUserManagerInternal; @Mock private AudioManagerInternal mAudioManagerInternal; @Mock private SearchManager mSearchManager; + @Mock private RoleManager mRoleManager; @Mock private Display mDisplay; @Mock private DisplayRotation mDisplayRotation; @@ -180,6 +184,9 @@ class TestPhoneWindowManager { private boolean mIsTalkBackEnabled; private boolean mIsTalkBackShortcutGestureEnabled; + private Intent mBrowserIntent; + private Intent mSmsIntent; + private int mKeyEventPolicyFlags = FLAG_INTERACTIVE; private class TestTalkbackShortcutController extends TalkbackShortcutController { @@ -290,6 +297,7 @@ class TestPhoneWindowManager { doReturn(mSensorPrivacyManager).when(mContext).getSystemService( eq(SensorPrivacyManager.class)); doReturn(mSearchManager).when(mContext).getSystemService(eq(SearchManager.class)); + doReturn(mRoleManager).when(mContext).getSystemService(eq(RoleManager.class)); doReturn(false).when(mPackageManager).hasSystemFeature(any()); try { doThrow(new PackageManager.NameNotFoundException("test")).when(mPackageManager) @@ -360,6 +368,21 @@ class TestPhoneWindowManager { doReturn(interceptionInfo) .when(mWindowManagerInternal).getKeyInterceptionInfoFromToken(any()); + doReturn(true).when(mRoleManager).isRoleAvailable(eq(RoleManager.ROLE_BROWSER)); + doReturn(true).when(mRoleManager).isRoleAvailable(eq(RoleManager.ROLE_SMS)); + doReturn(TEST_BROWSER_ROLE_PACKAGE_NAME).when(mRoleManager).getDefaultApplication( + eq(RoleManager.ROLE_BROWSER)); + doReturn(TEST_SMS_ROLE_PACKAGE_NAME).when(mRoleManager).getDefaultApplication( + eq(RoleManager.ROLE_SMS)); + mBrowserIntent = new Intent(Intent.ACTION_MAIN); + mBrowserIntent.setPackage(TEST_BROWSER_ROLE_PACKAGE_NAME); + mSmsIntent = new Intent(Intent.ACTION_MAIN); + mSmsIntent.setPackage(TEST_SMS_ROLE_PACKAGE_NAME); + doReturn(mBrowserIntent).when(mPackageManager).getLaunchIntentForPackage( + eq(TEST_BROWSER_ROLE_PACKAGE_NAME)); + doReturn(mSmsIntent).when(mPackageManager).getLaunchIntentForPackage( + eq(TEST_SMS_ROLE_PACKAGE_NAME)); + Mockito.reset(mContext); } @@ -670,6 +693,29 @@ class TestPhoneWindowManager { Mockito.reset(mContext); } + void assertLaunchRole(String role) { + mTestLooper.dispatchAll(); + ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); + try { + verify(mContext).startActivityAsUser(intentCaptor.capture(), any()); + switch (role) { + case RoleManager.ROLE_BROWSER: + Assert.assertEquals(intentCaptor.getValue(), mBrowserIntent); + break; + case RoleManager.ROLE_SMS: + Assert.assertEquals(intentCaptor.getValue(), mSmsIntent); + break; + default: + throw new AssertionError("Role " + role + " not supported in tests."); + } + } catch (Throwable t) { + throw new AssertionError("failed to assert " + role, t); + } + // Reset verifier for next call. + Mockito.reset(mContext); + } + + void assertShowRecentApps() { mTestLooper.dispatchAll(); verify(mStatusBarManagerInternal).showRecentApps(anyBoolean()); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 67c528cf40ae..09e7b9141e04 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -527,7 +527,8 @@ public class ActivityRecordTests extends WindowTestsBase { // The configuration change is still sent to the activity, even if it doesn't relaunch. final ActivityConfigurationChangeItem expected = - ActivityConfigurationChangeItem.obtain(activity.token, newConfig); + ActivityConfigurationChangeItem.obtain(activity.token, newConfig, + activity.getActivityWindowInfo()); verify(mClientLifecycleManager).scheduleTransactionItem( eq(activity.app.getThread()), eq(expected)); } @@ -599,7 +600,8 @@ public class ActivityRecordTests extends WindowTestsBase { final Configuration currentConfig = activity.getConfiguration(); assertEquals(expectedOrientation, currentConfig.orientation); final ActivityConfigurationChangeItem expected = - ActivityConfigurationChangeItem.obtain(activity.token, currentConfig); + ActivityConfigurationChangeItem.obtain(activity.token, currentConfig, + activity.getActivityWindowInfo()); verify(mClientLifecycleManager).scheduleTransactionItem(activity.app.getThread(), expected); verify(displayRotation).onSetRequestedOrientation(); } @@ -818,7 +820,7 @@ public class ActivityRecordTests extends WindowTestsBase { final ActivityConfigurationChangeItem expected = ActivityConfigurationChangeItem.obtain(activity.token, - activity.getConfiguration()); + activity.getConfiguration(), activity.getActivityWindowInfo()); verify(mClientLifecycleManager).scheduleTransactionItem( activity.app.getThread(), expected); } finally { diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java index 0c1fbf3cb3d7..1a1fe95756d7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java @@ -94,6 +94,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { public void setUp() throws Exception { assumeFalse(WindowManagerService.sEnableShellTransitions); mAppTransitionController = new AppTransitionController(mWm, mDisplayContent); + mWm.mAnimator.ready(); } @Test @@ -855,7 +856,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // Animation run by the remote handler. assertTrue(remoteAnimationRunner.isAnimationStarted()); @@ -886,7 +887,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(openingActivity, closingActivity, null /* changingTaskFragment */); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // Animation is not run by the remote handler because the activity is filling the Task. assertFalse(remoteAnimationRunner.isAnimationStarted()); @@ -921,7 +922,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(openingActivity, closingActivity, null /* changingTaskFragment */); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // Animation run by the remote handler. assertTrue(remoteAnimationRunner.isAnimationStarted()); @@ -946,7 +947,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // Animation run by the remote handler. assertTrue(remoteAnimationRunner.isAnimationStarted()); @@ -973,7 +974,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment1); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // Animation run by the remote handler. assertTrue(remoteAnimationRunner.isAnimationStarted()); @@ -997,7 +998,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // Animation not run by the remote handler. assertFalse(remoteAnimationRunner.isAnimationStarted()); @@ -1024,7 +1025,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // Animation should not run by the remote handler when there are non-embedded activities of // different UID. @@ -1051,7 +1052,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // Animation should not run by the remote handler when there is wallpaper in the transition. assertFalse(remoteAnimationRunner.isAnimationStarted()); @@ -1085,7 +1086,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(activity1, null /* closingActivity */, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // The animation will be animated remotely by client and all activities are input disabled // for untrusted animation. @@ -1136,7 +1137,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // The animation will be animated remotely by client and all activities are input disabled // for untrusted animation. @@ -1178,7 +1179,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { // Prepare and start transition. prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); // The animation will be animated remotely by client, but input should not be dropped for // fully trusted. diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java index 2085d6140f68..1f15ec3be3a8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java @@ -371,6 +371,7 @@ public class InsetsStateControllerTest extends WindowTestsBase { mDisplayContent.getInsetsPolicy().updateBarControlTarget(app); mDisplayContent.getInsetsPolicy().showTransient(statusBars(), true /* isGestureOnSystemBar */); + mWm.mAnimator.ready(); waitUntilWindowAnimatorIdle(); assertTrue(mDisplayContent.getInsetsPolicy().isTransient(statusBars())); diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java index 11d9629cf25e..a1638019359b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java @@ -43,7 +43,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -113,6 +112,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { runWithScissors(mWm.mH, () -> mHandler = new TestHandler(null, mClock), 0); mController = new RemoteAnimationController(mWm, mDisplayContent, mAdapter, mHandler, false /*isActivityEmbedding*/); + mWm.mAnimator.ready(); } private WindowState createAppOverlayWindow() { @@ -136,7 +136,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = @@ -168,7 +168,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = @@ -290,7 +290,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = @@ -336,7 +336,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { task.applyAnimationUnchecked(null /* lp */, true /* enter */, TRANSIT_OLD_TASK_OPEN, false /* isVoiceInteraction */, null /* sources */); mController.goodToGo(TRANSIT_OLD_TASK_OPEN); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); try { @@ -363,7 +363,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback); mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = @@ -417,7 +417,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback); mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = @@ -471,7 +471,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback); mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = @@ -526,7 +526,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = @@ -559,7 +559,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = @@ -595,7 +595,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); mController.goodToGo(TRANSIT_OLD_KEYGUARD_GOING_AWAY); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = @@ -645,7 +645,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); mController.goodToGo(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor<RemoteAnimationTarget[]> wallpapersCaptor = @@ -782,7 +782,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mDisplayContent.applySurfaceChangesTransaction(); mController.goodToGo(TRANSIT_OLD_TASK_OPEN); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_OPEN), any(), any(), any(), any()); @@ -810,7 +810,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); mController.goodToGo(transit); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); + waitUntilWindowAnimatorIdle(); return adapter; } diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java index a8f6fe86c823..7ab093d0ae13 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -546,7 +546,7 @@ public class SystemServicesTestRule implements TestRule { // This makes sure all previous messages in the handler are fully processed vs. just popping // them from the message queue. final AtomicBoolean currentMessagesProcessed = new AtomicBoolean(false); - wm.mAnimator.getChoreographer().postFrameCallback(time -> { + wm.mAnimator.addAfterPrepareSurfacesRunnable(() -> { synchronized (currentMessagesProcessed) { currentMessagesProcessed.set(true); currentMessagesProcessed.notifyAll(); diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java index 7551b1650ad0..1233686a4b48 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java @@ -265,7 +265,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy { @Override public boolean performHapticFeedback(int uid, String packageName, int effectId, - boolean always, String reason) { + boolean always, String reason, boolean fromIme) { return false; } diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index 0f2c62d3d09b..2da352d43290 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -48,6 +48,7 @@ import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; import android.os.Binder; import android.os.Bundle; +import android.os.Looper; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.UserHandle; @@ -65,6 +66,7 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.internal.util.dump.DualDumpOutputStream; +import com.android.internal.widget.LockPatternUtils; import com.android.server.FgThread; import com.android.server.SystemServerInitThreadPool; import com.android.server.SystemService; @@ -151,6 +153,7 @@ public class UsbService extends IUsbManager.Stub { private final UsbPermissionManager mPermissionManager; static final int PACKAGE_MONITOR_OPERATION_ID = 1; + static final int STRONG_AUTH_OPERATION_ID = 2; /** * The user id of the current user. There might be several profiles (with separate user ids) * per user. @@ -272,6 +275,10 @@ public class UsbService extends IUsbManager.Stub { if (android.hardware.usb.flags.Flags.enableUsbDataSignalStaking()) { new PackageUninstallMonitor() .register(mContext, UserHandle.ALL, BackgroundThread.getHandler()); + + new LockPatternUtils(mContext) + .registerStrongAuthTracker(new StrongAuthTracker(mContext, + BackgroundThread.getHandler().getLooper())); } } @@ -1408,4 +1415,33 @@ public class UsbService extends IUsbManager.Stub { } } } + + /** + * Implements a callback within StrongAuthTracker to disable USB data signaling + * when the device enters lockdown mode. This likely involves updating a state + * that controls USB data behavior. + */ + private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker { + private boolean mLockdownModeStatus; + + StrongAuthTracker(Context context, Looper looper) { + super(context, looper); + } + + @Override + public synchronized void onStrongAuthRequiredChanged(int userId) { + + boolean lockDownTriggeredByUser = (getStrongAuthForUser(userId) + & STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0; + //if it goes into the same lockdown status, no change is needed + if (mLockdownModeStatus == lockDownTriggeredByUser) { + return; + } + mLockdownModeStatus = lockDownTriggeredByUser; + for (UsbPort port: mPortManager.getPorts()) { + enableUsbData(port.getId(), !lockDownTriggeredByUser, STRONG_AUTH_OPERATION_ID, + new IUsbOperationInternal.Default()); + } + } + } } diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java index b3db2dea4a27..862aff9be9ce 100644 --- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java +++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java @@ -31,12 +31,11 @@ import static android.hardware.soundtrigger.SoundTrigger.STATUS_OK; import static android.provider.Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY; import static android.provider.Settings.Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT; -import static com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent.Type; -import static com.android.server.utils.EventLogger.Event.ALOGW; - import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import static com.android.server.soundtrigger.DeviceStateHandler.DeviceStateListener; import static com.android.server.soundtrigger.DeviceStateHandler.SoundTriggerDeviceState; +import static com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent.Type; +import static com.android.server.utils.EventLogger.Event.ALOGW; import android.Manifest; import android.annotation.NonNull; @@ -94,8 +93,8 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.SparseArray; import android.util.Slog; +import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.ISoundTriggerService; @@ -105,19 +104,17 @@ import com.android.server.SoundTriggerInternal; import com.android.server.SystemService; import com.android.server.soundtrigger.SoundTriggerEvent.ServiceEvent; import com.android.server.soundtrigger.SoundTriggerEvent.SessionEvent; -import com.android.server.utils.EventLogger.Event; import com.android.server.utils.EventLogger; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; -import java.util.function.Consumer; -import java.util.List; -import java.util.Set; import java.util.Deque; +import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.TreeMap; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -126,6 +123,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; import java.util.stream.Collectors; /** @@ -257,6 +255,11 @@ public class SoundTriggerService extends SystemService { publishLocalService(SoundTriggerInternal.class, mLocalSoundTriggerService); } + private boolean hasCalling() { + return mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_TELEPHONY_CALLING); + } + @Override public void onBootPhase(int phase) { Slog.d(TAG, "onBootPhase: " + phase + " : " + isSafeMode()); @@ -282,11 +285,13 @@ public class SoundTriggerService extends SystemService { // Do so after registering the listener so we ensure that we don't drop any events mDeviceStateHandler.onPowerModeChanged(powerManager.getSoundTriggerPowerSaveMode()); - // PhoneCallStateHandler initializes the original call state - mPhoneCallStateHandler = new PhoneCallStateHandler( - mContext.getSystemService(SubscriptionManager.class), - mContext.getSystemService(TelephonyManager.class), - mDeviceStateHandler); + if (hasCalling()) { + // PhoneCallStateHandler initializes the original call state + mPhoneCallStateHandler = new PhoneCallStateHandler( + mContext.getSystemService(SubscriptionManager.class), + mContext.getSystemService(TelephonyManager.class), + mDeviceStateHandler); + } } mMiddlewareService = ISoundTriggerMiddlewareService.Stub.asInterface( ServiceManager.waitForService(Context.SOUND_TRIGGER_MIDDLEWARE_SERVICE)); diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index aef7158fd613..1e1dd00b8df5 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -181,10 +181,8 @@ public class VoiceInteractionManagerService extends SystemService { LocalServices.getService(ActivityManagerInternal.class)); mAtmInternal = Objects.requireNonNull( LocalServices.getService(ActivityTaskManagerInternal.class)); - mWmInternal = Objects.requireNonNull( - LocalServices.getService(WindowManagerInternal.class)); - mDpmInternal = Objects.requireNonNull( - LocalServices.getService(DevicePolicyManagerInternal.class)); + mWmInternal = LocalServices.getService(WindowManagerInternal.class); + mDpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class); LegacyPermissionManagerInternal permissionManagerInternal = LocalServices.getService( LegacyPermissionManagerInternal.class); permissionManagerInternal.setVoiceInteractionPackagesProvider( @@ -2750,11 +2748,17 @@ public class VoiceInteractionManagerService extends SystemService { if (isAssistDataAllowed) { visiblePackageNames.add(record.getComponentName().getPackageName()); } - if (mDpmInternal.isUserOrganizationManaged(record.getUserId())) { + if (mDpmInternal != null + && mDpmInternal.isUserOrganizationManaged(record.getUserId())) { isManagedProfileVisible = true; } } - final ScreenCapture.ScreenshotHardwareBuffer shb = mWmInternal.takeAssistScreenshot(); + final ScreenCapture.ScreenshotHardwareBuffer shb; + if (mWmInternal != null) { + shb = mWmInternal.takeAssistScreenshot(); + } else { + shb = null; + } final Bitmap bm = shb != null ? shb.asBitmap() : null; // Now that everything is fetched, putting it in the launchIntent. if (bm != null) { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 626a2e574881..88acbabc0e0f 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -8435,7 +8435,7 @@ public class TelephonyManager { * In addition to the {@link Manifest.permission#MODIFY_PHONE_STATE} permission, callers of this * API must also be listed in the device configuration as an authorized app in * {@code packages/services/Telephony/res/values/config.xml} under the - * {@code config_number_verification_package_name} key. + * {@code platform_number_verification_package} key. * * @hide * @param range The range of phone numbers the caller expects a phone call from. @@ -15023,7 +15023,7 @@ public class TelephonyManager { @FlaggedApi(android.permission.flags.Flags.FLAG_GET_EMERGENCY_ROLE_HOLDER_API_ENABLED) @NonNull @SystemApi - public String getEmergencyAssistancePackage() { + public String getEmergencyAssistancePackageName() { if (!isEmergencyAssistanceEnabled() || !isVoiceCapable()) { throw new IllegalStateException("isEmergencyAssistanceEnabled() is false or device" + " not voice capable."); @@ -18535,7 +18535,7 @@ public class TelephonyManager { * @hide */ @SystemApi - @FlaggedApi(com.android.server.telecom.flags.Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) + @FlaggedApi(com.android.server.telecom.flags.Flags.FLAG_GET_LAST_KNOWN_CELL_IDENTITY) @RequiresPermission(allOf = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_LAST_KNOWN_CELL_ID}) public @Nullable CellIdentity getLastKnownCellIdentity() { diff --git a/test-runner/src/android/test/InstrumentationTestRunner.java b/test-runner/src/android/test/InstrumentationTestRunner.java index 07e3f8736cc8..b2a8847039c7 100644 --- a/test-runner/src/android/test/InstrumentationTestRunner.java +++ b/test-runner/src/android/test/InstrumentationTestRunner.java @@ -16,9 +16,7 @@ package android.test; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.SmallTest; -import com.android.internal.util.Predicate; +import static android.test.suitebuilder.TestPredicates.hasAnnotation; import android.app.Activity; import android.app.Instrumentation; @@ -29,16 +27,11 @@ import android.test.suitebuilder.TestMethod; import android.test.suitebuilder.TestPredicates; import android.test.suitebuilder.TestSuiteBuilder; import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.PrintStream; -import java.lang.annotation.Annotation; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; +import com.android.internal.util.Predicate; import junit.framework.AssertionFailedError; import junit.framework.Test; @@ -49,7 +42,14 @@ import junit.framework.TestSuite; import junit.runner.BaseTestRunner; import junit.textui.ResultPrinter; -import static android.test.suitebuilder.TestPredicates.hasAnnotation; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.PrintStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; /** * An {@link Instrumentation} that runs various types of {@link junit.framework.TestCase}s against diff --git a/test-runner/src/android/test/suitebuilder/TestPredicates.java b/test-runner/src/android/test/suitebuilder/TestPredicates.java index 616d1a972612..faf31fdc5350 100644 --- a/test-runner/src/android/test/suitebuilder/TestPredicates.java +++ b/test-runner/src/android/test/suitebuilder/TestPredicates.java @@ -19,7 +19,9 @@ package android.test.suitebuilder; import android.test.InstrumentationTestCase; import android.test.suitebuilder.annotation.Smoke; import android.test.suitebuilder.annotation.Suppress; + import com.android.internal.util.Predicate; + import java.lang.annotation.Annotation; /** diff --git a/test-runner/tests/src/android/test/AndroidTestRunnerTest.java b/test-runner/tests/src/android/test/AndroidTestRunnerTest.java index 67235480fa6d..bd6c04bca4d0 100644 --- a/test-runner/tests/src/android/test/AndroidTestRunnerTest.java +++ b/test-runner/tests/src/android/test/AndroidTestRunnerTest.java @@ -19,15 +19,15 @@ package android.test; import android.test.mock.MockContext; import android.test.suitebuilder.annotation.SmallTest; -import java.util.ArrayList; -import junit.framework.TestCase; import junit.framework.AssertionFailedError; import junit.framework.Test; -import junit.framework.TestSuite; +import junit.framework.TestCase; import junit.framework.TestListener; +import junit.framework.TestSuite; -import java.util.List; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; /** * Unit tests for {@link AndroidTestRunner} diff --git a/tests/CoreTests/android/Android.bp b/tests/CoreTests/android/Android.bp index e2f194b04437..97a6e5fd4d1b 100644 --- a/tests/CoreTests/android/Android.bp +++ b/tests/CoreTests/android/Android.bp @@ -16,5 +16,8 @@ android_test { "android.test.base.stubs", ], sdk_version: "current", - static_libs: ["junit"], + static_libs: [ + "junit", + "androidx.test.rules", + ], } diff --git a/tests/CoreTests/android/core/RequestAPITest.java b/tests/CoreTests/android/core/RequestAPITest.java index 206f228c3804..2d420d30b299 100644 --- a/tests/CoreTests/android/core/RequestAPITest.java +++ b/tests/CoreTests/android/core/RequestAPITest.java @@ -19,10 +19,11 @@ package android.core; import android.net.http.RequestHandle; import android.net.http.RequestQueue; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.Suppress; import android.util.Log; import android.webkit.CookieSyncManager; +import androidx.test.filters.Suppress; + import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.HashMap; diff --git a/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java b/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java index d6e2861c03a7..cc0255d4140a 100644 --- a/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java +++ b/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java @@ -15,6 +15,14 @@ */ package android.gameperformance; +import android.annotation.NonNull; +import android.app.Activity; +import android.os.Bundle; +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; + +import androidx.test.filters.SmallTest; + import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -22,18 +30,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; -import android.annotation.NonNull; -import android.app.Activity; -import android.content.Context; -import android.graphics.PixelFormat; -import android.os.Build; -import android.os.Bundle; -import android.os.Debug; -import android.os.Trace; -import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.Log; - public class GamePerformanceTest extends ActivityInstrumentationTestCase2<GamePerformanceActivity> { private final static String TAG = "GamePerformanceTest"; diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java index b9f1738f9bb7..a96389046d6a 100644 --- a/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java +++ b/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java @@ -37,7 +37,7 @@ import perfetto.protos.ProtologConfig; public class PerfettoDataSourceTest { @Before public void before() { - assumeTrue(android.tracing.Flags.perfettoProtolog()); + assumeTrue(android.tracing.Flags.perfettoProtologTracing()); } @Test diff --git a/tests/SurfaceComposition/Android.bp b/tests/SurfaceComposition/Android.bp index f5aba8f5a2f2..a02662fb912e 100644 --- a/tests/SurfaceComposition/Android.bp +++ b/tests/SurfaceComposition/Android.bp @@ -32,7 +32,10 @@ android_test { enabled: false, }, srcs: ["src/**/*.java"], - static_libs: ["junit"], + static_libs: [ + "junit", + "androidx.test.rules", + ], libs: [ "android.test.runner.stubs", "android.test.base.stubs", diff --git a/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java index 261ea2ec866d..f82585c02c08 100644 --- a/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java +++ b/tests/SurfaceComposition/src/android/surfacecomposition/SurfaceCompositionTest.java @@ -22,9 +22,10 @@ import android.os.Bundle; import android.surfacecomposition.SurfaceCompositionMeasuringActivity.AllocationScore; import android.surfacecomposition.SurfaceCompositionMeasuringActivity.CompositorScore; import android.test.ActivityInstrumentationTestCase2; -import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; +import androidx.test.filters.SmallTest; + public class SurfaceCompositionTest extends ActivityInstrumentationTestCase2<SurfaceCompositionMeasuringActivity> { private final static String TAG = "SurfaceCompositionTest"; diff --git a/tests/permission/Android.bp b/tests/permission/Android.bp index d06809b209a0..b02f410c733e 100644 --- a/tests/permission/Android.bp +++ b/tests/permission/Android.bp @@ -20,6 +20,7 @@ android_test { "androidx.test.runner", "junit", "platform-test-annotations", + "androidx.test.rules", ], platform_apis: true, test_suites: ["device-tests"], diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java index 5fb23b0ad507..99ca9c084b54 100644 --- a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java @@ -21,7 +21,8 @@ import android.app.ActivityTaskManager; import android.app.IActivityManager; import android.content.res.Configuration; import android.os.RemoteException; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import junit.framework.TestCase; diff --git a/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java b/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java index 299d8d003d9c..0c9d447a3ac1 100644 --- a/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java @@ -19,7 +19,8 @@ package com.android.framework.permission.tests; import android.app.PackageInstallObserver; import android.content.pm.PackageManager; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; /** * Verify PackageManager api's that require specific permissions. diff --git a/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java index 41727431bd5e..2fa0b2164835 100644 --- a/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java +++ b/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java @@ -18,7 +18,8 @@ package com.android.framework.permission.tests; import android.telephony.SmsManager; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import java.util.ArrayList; diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java index 330bc84d7a76..e67fd6702f7b 100644 --- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java @@ -23,9 +23,10 @@ import android.os.Binder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; -import android.test.suitebuilder.annotation.SmallTest; import android.view.IWindowManager; +import androidx.test.filters.SmallTest; + import junit.framework.TestCase; /** diff --git a/tests/testables/tests/src/android/testing/TestableLooperTest.java b/tests/testables/tests/src/android/testing/TestableLooperTest.java index a02eb6b176dc..fd5c4caca484 100644 --- a/tests/testables/tests/src/android/testing/TestableLooperTest.java +++ b/tests/testables/tests/src/android/testing/TestableLooperTest.java @@ -30,10 +30,11 @@ import static org.mockito.Mockito.when; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableLooper.MessageHandler; import android.testing.TestableLooper.RunWithLooper; +import androidx.test.filters.SmallTest; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/tests/testables/tests/src/android/testing/TestableResourcesTest.java b/tests/testables/tests/src/android/testing/TestableResourcesTest.java index dd4325c59aa2..77916944eeea 100644 --- a/tests/testables/tests/src/android/testing/TestableResourcesTest.java +++ b/tests/testables/tests/src/android/testing/TestableResourcesTest.java @@ -21,9 +21,9 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import android.content.res.Resources; -import android.test.suitebuilder.annotation.SmallTest; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import com.android.testables.R; diff --git a/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java b/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java index 0333d514343d..f3f429a39c3c 100644 --- a/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java +++ b/tests/testables/tests/src/android/testing/TestableSettingsProviderTest.java @@ -20,9 +20,9 @@ import android.content.ContentResolver; import android.provider.Settings; import android.provider.Settings.Global; import android.provider.Settings.Secure; -import android.test.suitebuilder.annotation.SmallTest; import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; diff --git a/tests/utils/testutils/tests/Android.bp b/tests/utils/testutils/tests/Android.bp index b901b1802383..8104280cdd5e 100644 --- a/tests/utils/testutils/tests/Android.bp +++ b/tests/utils/testutils/tests/Android.bp @@ -31,6 +31,7 @@ android_test { "androidx.test.runner", "mockito-target-minus-junit4", "frameworks-base-testutils", + "androidx.test.rules", ], libs: [ diff --git a/tests/utils/testutils/tests/src/android/os/test/TestLooperTest.java b/tests/utils/testutils/tests/src/android/os/test/TestLooperTest.java index c72e20ccc5ba..6205b98d4e79 100644 --- a/tests/utils/testutils/tests/src/android/os/test/TestLooperTest.java +++ b/tests/utils/testutils/tests/src/android/os/test/TestLooperTest.java @@ -28,7 +28,8 @@ import static org.mockito.Mockito.spy; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.test.suitebuilder.annotation.SmallTest; + +import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Rule; diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt index 83e09bf7043e..fd7474b55fa6 100644 --- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt +++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/SubclassFilter.kt @@ -20,7 +20,7 @@ import com.android.hoststubgen.asm.toJvmClassName /** * Filter to apply a policy to classes extending or implementing a class, - * either directly or indirectly. (with a breadth first search.) + * either directly or indirectly. * * The policy won't apply to the super class itself. */ @@ -42,7 +42,7 @@ class SubclassFilter( } /** - * Find a policy for a class with a breadth-first search. + * Find a policy for a class. */ private fun findPolicyForClass(className: String): FilterPolicyWithReason? { val cn = classes.findClass(className) ?: return null diff --git a/tools/protologtool/src/com/android/protolog/tool/Constants.kt b/tools/protologtool/src/com/android/protolog/tool/Constants.kt index aa3e00f2f4db..4a93de916826 100644 --- a/tools/protologtool/src/com/android/protolog/tool/Constants.kt +++ b/tools/protologtool/src/com/android/protolog/tool/Constants.kt @@ -18,7 +18,7 @@ package com.android.protolog.tool object Constants { const val NAME = "protologtool" - const val VERSION = "1.0.0" + const val VERSION = "2.0.0" const val IS_ENABLED_METHOD = "isEnabled" const val ENUM_VALUES_METHOD = "values" } |