diff options
218 files changed, 4358 insertions, 1038 deletions
diff --git a/api/current.txt b/api/current.txt index 1c60efa62be3..ee89c591fd40 100644 --- a/api/current.txt +++ b/api/current.txt @@ -29939,7 +29939,7 @@ package android.net.wifi { method public java.util.List<android.net.wifi.ScanResult> getScanResults(); method public int getWifiState(); method public boolean is5GHzBandSupported(); - method public boolean isDeviceToApRttSupported(); + method @Deprecated public boolean isDeviceToApRttSupported(); method public boolean isEasyConnectSupported(); method public boolean isEnhancedPowerReportingSupported(); method public boolean isOweSupported(); @@ -35683,6 +35683,7 @@ package android.os.storage { method public String getMountedObbPath(String); method @NonNull public android.os.storage.StorageVolume getPrimaryStorageVolume(); method @Nullable public android.os.storage.StorageVolume getStorageVolume(java.io.File); + method @NonNull public android.os.storage.StorageVolume getStorageVolume(@NonNull android.net.Uri); method @NonNull public java.util.List<android.os.storage.StorageVolume> getStorageVolumes(); method @NonNull public java.util.UUID getUuidForPath(@NonNull java.io.File) throws java.io.IOException; method public boolean isAllocationSupported(@NonNull java.io.FileDescriptor); @@ -38609,13 +38610,13 @@ package android.provider { public static final class MediaStore.Images.Media implements android.provider.MediaStore.Images.ImageColumns { ctor public MediaStore.Images.Media(); - method public static android.graphics.Bitmap getBitmap(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException, java.io.IOException; + method @Deprecated public static android.graphics.Bitmap getBitmap(android.content.ContentResolver, android.net.Uri) throws java.io.FileNotFoundException, java.io.IOException; method public static android.net.Uri getContentUri(String); - method public static String insertImage(android.content.ContentResolver, String, String, String) throws java.io.FileNotFoundException; - method public static String insertImage(android.content.ContentResolver, android.graphics.Bitmap, String, String); - method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[]); - method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[], String, String); - method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String); + method @Deprecated public static String insertImage(android.content.ContentResolver, String, String, String) throws java.io.FileNotFoundException; + method @Deprecated public static String insertImage(android.content.ContentResolver, android.graphics.Bitmap, String, String); + method @Deprecated public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[]); + method @Deprecated public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[], String, String); + method @Deprecated public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[], String, String[], String); field public static final String CONTENT_TYPE = "vnd.android.cursor.dir/image"; field public static final String DEFAULT_SORT_ORDER = "bucket_display_name"; field public static final android.net.Uri EXTERNAL_CONTENT_URI; @@ -38684,7 +38685,7 @@ package android.provider { public static final class MediaStore.Video { ctor public MediaStore.Video(); - method public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[]); + method @Deprecated public static android.database.Cursor query(android.content.ContentResolver, android.net.Uri, String[]); field public static final String DEFAULT_SORT_ORDER = "_display_name"; } diff --git a/api/system-current.txt b/api/system-current.txt index 128ee99c27ad..13ba78e7f629 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3496,6 +3496,18 @@ package android.media { method public android.media.AudioRecord.Builder setSessionId(int) throws java.lang.IllegalArgumentException; } + public class HwAudioSource { + method public void start(); + method public void stop(); + } + + public static class HwAudioSource.Builder { + ctor public HwAudioSource.Builder(); + method @NonNull public android.media.HwAudioSource build(); + method @NonNull public android.media.HwAudioSource.Builder setAudioAttributes(@NonNull android.media.AudioAttributes); + method @NonNull public android.media.HwAudioSource.Builder setAudioDeviceInfo(@NonNull android.media.AudioDeviceInfo); + } + public final class MediaRecorder.AudioSource { field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT) public static final int ECHO_REFERENCE = 1997; // 0x7cd field @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD) public static final int HOTWORD = 1999; // 0x7cf @@ -4642,7 +4654,7 @@ package android.net.wifi { method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState(); - method public boolean isDeviceToDeviceRttSupported(); + method @Deprecated public boolean isDeviceToDeviceRttSupported(); method public boolean isPortableHotspotSupported(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled(); method public boolean isWifiScannerSupported(); @@ -6288,6 +6300,8 @@ package android.service.autofill.augmented { ctor public AugmentedAutofillService(); method protected final void dump(java.io.FileDescriptor, java.io.PrintWriter, String[]); method protected void dump(@NonNull java.io.PrintWriter, @NonNull String[]); + method public void onConnected(); + method public void onDisconnected(); method public void onFillRequest(@NonNull android.service.autofill.augmented.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.augmented.FillController, @NonNull android.service.autofill.augmented.FillCallback); field public static final String SERVICE_INTERFACE = "android.service.autofill.augmented.AugmentedAutofillService"; } diff --git a/api/test-current.txt b/api/test-current.txt index 01678b1c1066..f84e4ad80288 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -2057,6 +2057,8 @@ package android.service.autofill.augmented { ctor public AugmentedAutofillService(); method protected final void dump(java.io.FileDescriptor, java.io.PrintWriter, String[]); method protected void dump(@NonNull java.io.PrintWriter, @NonNull String[]); + method public void onConnected(); + method public void onDisconnected(); method public void onFillRequest(@NonNull android.service.autofill.augmented.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.augmented.FillController, @NonNull android.service.autofill.augmented.FillCallback); field public static final String SERVICE_INTERFACE = "android.service.autofill.augmented.AugmentedAutofillService"; } diff --git a/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl b/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl index ea7274f3ea58..4a66715ad2b8 100644 --- a/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl +++ b/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl @@ -24,6 +24,7 @@ interface IIdmap2 { const int POLICY_SYSTEM_PARTITION = 0x00000002; const int POLICY_VENDOR_PARTITION = 0x00000004; const int POLICY_PRODUCT_PARTITION = 0x00000008; + const int POLICY_SIGNATURE = 0x00000010; @utf8InCpp String getIdmapPath(@utf8InCpp String overlayApkPath, int userId); boolean removeIdmap(@utf8InCpp String overlayApkPath, int userId); diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp index 99b5f0ff3c2d..ec498ffb393c 100644 --- a/cmds/idmap2/libidmap2/Idmap.cpp +++ b/cmds/idmap2/libidmap2/Idmap.cpp @@ -284,7 +284,7 @@ std::unique_ptr<const Idmap> Idmap::FromBinaryStream(std::istream& stream, bool CheckOverlayable(const LoadedPackage& target_package, const utils::OverlayManifestInfo& overlay_info, - const PolicyBitmask& fulfilled_polices, const ResourceId& resid) { + const PolicyBitmask& fulfilled_policies, const ResourceId& resid) { const OverlayableInfo* overlayable_info = target_package.GetOverlayableInfo(resid); if (overlayable_info == nullptr) { // If the resource does not have an overlayable definition, allow the resource to be overlaid. @@ -299,7 +299,7 @@ bool CheckOverlayable(const LoadedPackage& target_package, } // Enforce policy restrictions if the resource is declared as overlayable. - return (overlayable_info->policy_flags & fulfilled_polices) != 0; + return (overlayable_info->policy_flags & fulfilled_policies) != 0; } std::unique_ptr<const Idmap> Idmap::FromApkAssets( diff --git a/cmds/idmap2/libidmap2/Policies.cpp b/cmds/idmap2/libidmap2/Policies.cpp index 0f87ef0c4ea9..6649288dfa41 100644 --- a/cmds/idmap2/libidmap2/Policies.cpp +++ b/cmds/idmap2/libidmap2/Policies.cpp @@ -35,6 +35,7 @@ const std::map<android::StringPiece, PolicyFlags> kStringToFlag = { {"product", PolicyFlags::POLICY_PRODUCT_PARTITION}, {"system", PolicyFlags::POLICY_SYSTEM_PARTITION}, {"vendor", PolicyFlags::POLICY_VENDOR_PARTITION}, + {"signature", PolicyFlags::POLICY_SIGNATURE}, }; } // namespace diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp index 0e0e25f4f0f3..9a0412efbde4 100644 --- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp +++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp @@ -129,28 +129,31 @@ TEST(BinaryStreamVisitorTests, CreateIdmapFromApkAssetsInteropWithLoadedIdmap) { success = LoadedIdmap::Lookup(header, 0x0008, &entry); // string/policy_system_vendor ASSERT_FALSE(success); - success = LoadedIdmap::Lookup(header, 0x0009, &entry); // string/str1 + success = LoadedIdmap::Lookup(header, 0x0009, &entry); // string/policy_signature + ASSERT_FALSE(success); + + success = LoadedIdmap::Lookup(header, 0x000a, &entry); // string/str1 ASSERT_TRUE(success); ASSERT_EQ(entry, 0x0000); - success = LoadedIdmap::Lookup(header, 0x000a, &entry); // string/str2 + success = LoadedIdmap::Lookup(header, 0x000b, &entry); // string/str2 ASSERT_FALSE(success); - success = LoadedIdmap::Lookup(header, 0x000b, &entry); // string/str3 + success = LoadedIdmap::Lookup(header, 0x000c, &entry); // string/str3 ASSERT_TRUE(success); ASSERT_EQ(entry, 0x0001); - success = LoadedIdmap::Lookup(header, 0x000c, &entry); // string/str4 + success = LoadedIdmap::Lookup(header, 0x000d, &entry); // string/str4 ASSERT_TRUE(success); ASSERT_EQ(entry, 0x0002); - success = LoadedIdmap::Lookup(header, 0x000d, &entry); // string/x + success = LoadedIdmap::Lookup(header, 0x000e, &entry); // string/x ASSERT_FALSE(success); - success = LoadedIdmap::Lookup(header, 0x000e, &entry); // string/y + success = LoadedIdmap::Lookup(header, 0x000f, &entry); // string/y ASSERT_FALSE(success); - success = LoadedIdmap::Lookup(header, 0x000f, &entry); // string/z + success = LoadedIdmap::Lookup(header, 0x0010, &entry); // string/z ASSERT_FALSE(success); } diff --git a/cmds/idmap2/tests/FileUtilsTests.cpp b/cmds/idmap2/tests/FileUtilsTests.cpp index 8514e12e8c17..2e85eb6215d1 100644 --- a/cmds/idmap2/tests/FileUtilsTests.cpp +++ b/cmds/idmap2/tests/FileUtilsTests.cpp @@ -39,12 +39,13 @@ TEST(FileUtilsTests, FindFilesFindEverythingNonRecursive) { [](unsigned char type ATTRIBUTE_UNUSED, const std::string& path ATTRIBUTE_UNUSED) -> bool { return true; }); ASSERT_THAT(v, NotNull()); - ASSERT_EQ(v->size(), 6U); + ASSERT_EQ(v->size(), 7U); ASSERT_EQ(std::set<std::string>(v->begin(), v->end()), std::set<std::string>({ root + "/.", root + "/..", root + "/overlay", root + "/target", + root + "/signature-overlay", root + "/system-overlay", root + "/system-overlay-invalid", })); @@ -56,15 +57,22 @@ TEST(FileUtilsTests, FindFilesFindApkFilesRecursive) { return type == DT_REG && path.size() > 4 && path.compare(path.size() - 4, 4, ".apk") == 0; }); ASSERT_THAT(v, NotNull()); - ASSERT_EQ(v->size(), 9U); + ASSERT_EQ(v->size(), 10U); ASSERT_EQ( std::set<std::string>(v->begin(), v->end()), std::set<std::string>( - {root + "/target/target.apk", root + "/target/target-no-overlayable.apk", - root + "/overlay/overlay.apk", root + "/overlay/overlay-no-name.apk", - root + "/overlay/overlay-no-name-static.apk", root + "/overlay/overlay-static-1.apk", - root + "/overlay/overlay-static-2.apk", root + "/system-overlay/system-overlay.apk", - root + "/system-overlay-invalid/system-overlay-invalid.apk"})); + { + root + "/target/target.apk", + root + "/target/target-no-overlayable.apk", + root + "/overlay/overlay.apk", + root + "/overlay/overlay-no-name.apk", + root + "/overlay/overlay-no-name-static.apk", + root + "/overlay/overlay-static-1.apk", + root + "/overlay/overlay-static-2.apk", + root + "/signature-overlay/signature-overlay.apk", + root + "/system-overlay/system-overlay.apk", + root + "/system-overlay-invalid/system-overlay-invalid.apk" + })); } TEST(FileUtilsTests, ReadFile) { diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp index 1216f9ec736a..a6a2ada76712 100644 --- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp +++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp @@ -132,9 +132,9 @@ TEST_F(Idmap2BinaryTests, Dump) { ASSERT_THAT(result, NotNull()); ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; ASSERT_NE(result->stdout.find("0x7f010000 -> 0x7f010000 integer/int1"), std::string::npos); - ASSERT_NE(result->stdout.find("0x7f020009 -> 0x7f020000 string/str1"), std::string::npos); - ASSERT_NE(result->stdout.find("0x7f02000b -> 0x7f020001 string/str3"), std::string::npos); - ASSERT_NE(result->stdout.find("0x7f02000c -> 0x7f020002 string/str4"), std::string::npos); + ASSERT_NE(result->stdout.find("0x7f02000a -> 0x7f020000 string/str1"), std::string::npos); + ASSERT_NE(result->stdout.find("0x7f02000c -> 0x7f020001 string/str3"), std::string::npos); + ASSERT_NE(result->stdout.find("0x7f02000d -> 0x7f020002 string/str4"), std::string::npos); ASSERT_EQ(result->stdout.find("00000210: 007f target package id"), std::string::npos); // clang-format off @@ -286,7 +286,7 @@ TEST_F(Idmap2BinaryTests, Lookup) { "lookup", "--idmap-path", GetIdmapPath(), "--config", "", - "--resid", "0x7f020009"}); // string/str1 + "--resid", "0x7f02000a"}); // string/str1 // clang-format on ASSERT_THAT(result, NotNull()); ASSERT_EQ(result->status, EXIT_SUCCESS) << result->stderr; diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index b40521f054af..53ec03ba3d5e 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -191,8 +191,8 @@ TEST(IdmapTests, CreateIdmapFromApkAssets) { ASSERT_THAT(idmap->GetHeader(), NotNull()); ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U); ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x01U); - ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xdd53ca29); - ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0xa71ccd77); + ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xd513ca1b); + ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x8635c2ed); ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path); ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path); ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path); @@ -217,7 +217,7 @@ TEST(IdmapTests, CreateIdmapFromApkAssets) { ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U); ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U); ASSERT_EQ(types[1]->GetEntryCount(), 4U); - ASSERT_EQ(types[1]->GetEntryOffset(), 9U); + ASSERT_EQ(types[1]->GetEntryOffset(), 10U); ASSERT_EQ(types[1]->GetEntry(0), 0x0000U); ASSERT_EQ(types[1]->GetEntry(1), kNoEntry); ASSERT_EQ(types[1]->GetEntry(2), 0x0001U); @@ -254,11 +254,76 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublic) { ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U); ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U); - ASSERT_EQ(types[0]->GetEntryCount(), 3U); + ASSERT_EQ(types[0]->GetEntryCount(), 4U); ASSERT_EQ(types[0]->GetEntryOffset(), 6U); ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_public - ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/policy_system - ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_system_vendor + ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature + ASSERT_EQ(types[0]->GetEntry(2), 0x0001U); // string/policy_system + ASSERT_EQ(types[0]->GetEntry(3), 0x0002U); // string/policy_system_vendor +} + +TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignature) { + const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); + std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); + ASSERT_THAT(target_apk, NotNull()); + + const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk"); + std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); + ASSERT_THAT(overlay_apk, NotNull()); + + uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_SIGNATURE; + + std::stringstream error; + std::unique_ptr<const Idmap> idmap = + Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, + policy_flags, /* enforce_overlayable */ true, error); + ASSERT_THAT(idmap, NotNull()); + + const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); + ASSERT_EQ(dataBlocks.size(), 1U); + + const std::unique_ptr<const IdmapData>& data = dataBlocks[0]; + + ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU); + ASSERT_EQ(data->GetHeader()->GetTypeCount(), 1U); + + const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries(); + ASSERT_EQ(types.size(), 1U); + + ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U); + ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U); + ASSERT_EQ(types[0]->GetEntryCount(), 1U); + ASSERT_EQ(types[0]->GetEntryOffset(), 7U); + ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_signature +} + +TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySignatureNotFulfilled) { + const std::string target_apk_path(GetTestDataPath() + "/target/target.apk"); + std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path); + ASSERT_THAT(target_apk, NotNull()); + + const std::string overlay_apk_path(GetTestDataPath() + "/signature-overlay/signature-overlay.apk"); + std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path); + ASSERT_THAT(overlay_apk, NotNull()); + + uint32_t policy_flags = PolicyFlags::POLICY_PUBLIC; + + std::stringstream error; + std::unique_ptr<const Idmap> idmap = + Idmap::FromApkAssets(target_apk_path, *target_apk, overlay_apk_path, *overlay_apk, + policy_flags, /* enforce_overlayable */ true, error); + ASSERT_THAT(idmap, NotNull()); + + const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData(); + ASSERT_EQ(dataBlocks.size(), 1U); + + const std::unique_ptr<const IdmapData>& data = dataBlocks[0]; + + ASSERT_EQ(data->GetHeader()->GetTargetPackageId(), 0x7fU); + ASSERT_EQ(data->GetHeader()->GetTypeCount(), 0U); + + const std::vector<std::unique_ptr<const IdmapData::TypeEntry>>& types = data->GetTypeEntries(); + ASSERT_EQ(types.size(), 0U); // can't overlay, so contains nothing } // Overlays should abide by all overlayable restrictions if enforcement of overlayable is enabled. @@ -292,11 +357,12 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) { ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U); ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U); - ASSERT_EQ(types[0]->GetEntryCount(), 3U); + ASSERT_EQ(types[0]->GetEntryCount(), 4U); ASSERT_EQ(types[0]->GetEntryOffset(), 6U); ASSERT_EQ(types[0]->GetEntry(0), 0x0003U); // string/policy_public - ASSERT_EQ(types[0]->GetEntry(1), 0x0004U); // string/policy_system - ASSERT_EQ(types[0]->GetEntry(2), 0x0005U); // string/policy_system_vendor + ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature + ASSERT_EQ(types[0]->GetEntry(2), 0x0005U); // string/policy_system + ASSERT_EQ(types[0]->GetEntry(3), 0x0006U); // string/policy_system_vendor } // Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled. @@ -330,14 +396,15 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalidIgn ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U); ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U); - ASSERT_EQ(types[0]->GetEntryCount(), 6U); + ASSERT_EQ(types[0]->GetEntryCount(), 7U); ASSERT_EQ(types[0]->GetEntryOffset(), 3U); ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/other ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_product - ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public - ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_system - ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system_vendor + ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_signature + ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_public + ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system + ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor } // The resources of APKs that do not include an overlayable declaration should not restrict what @@ -371,14 +438,15 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayable) { ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U); ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U); - ASSERT_EQ(types[0]->GetEntryCount(), 6U); + ASSERT_EQ(types[0]->GetEntryCount(), 7U); ASSERT_EQ(types[0]->GetEntryOffset(), 3U); ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/not_overlayable ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/other ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_product ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/policy_public - ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_system - ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system_vendor + ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/string/policy_signature + ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system + ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor } // The resources of APKs that do not include an overlayable declaration should not restrict what @@ -418,7 +486,7 @@ TEST(IdmapOverlayableTests, CreateIdmapFromApkAssetsNoDefinedOverlayableAndNoTar ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U); ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U); ASSERT_EQ(types[1]->GetEntryCount(), 4U); - ASSERT_EQ(types[1]->GetEntryOffset(), 9U); + ASSERT_EQ(types[1]->GetEntryOffset(), 10U); ASSERT_EQ(types[1]->GetEntry(0), 0x0000U); ASSERT_EQ(types[1]->GetEntry(1), kNoEntry); ASSERT_EQ(types[1]->GetEntry(2), 0x0001U); diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp index a5588c330d85..7ec13ed0ade7 100644 --- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp +++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp @@ -52,8 +52,8 @@ TEST(RawPrintVisitorTests, CreateRawPrintVisitor) { ASSERT_NE(stream.str().find("00000000: 504d4449 magic\n"), std::string::npos); ASSERT_NE(stream.str().find("00000004: 00000001 version\n"), std::string::npos); - ASSERT_NE(stream.str().find("00000008: dd53ca29 target crc\n"), std::string::npos); - ASSERT_NE(stream.str().find("0000000c: a71ccd77 overlay crc\n"), std::string::npos); + ASSERT_NE(stream.str().find("00000008: d513ca1b target crc\n"), std::string::npos); + ASSERT_NE(stream.str().find("0000000c: 8635c2ed overlay crc\n"), std::string::npos); ASSERT_NE(stream.str().find("0000021c: 00000000 0x7f010000 -> 0x7f010000 integer/int1\n"), std::string::npos); } diff --git a/cmds/idmap2/tests/data/overlay/build b/cmds/idmap2/tests/data/overlay/build index e60da803388b..e879f443c7b1 100644..100755 --- a/cmds/idmap2/tests/data/overlay/build +++ b/cmds/idmap2/tests/data/overlay/build @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FRAMEWORK_RES_APK="$(gettop)/out/target/common/obj/APPS/framework-res_intermediates/package-export.apk" +FRAMEWORK_RES_APK="${ANDROID_BUILD_TOP}/out/target/common/obj/APPS/framework-res_intermediates/package-export.apk" aapt2 compile --dir res -o compiled.flata diff --git a/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml b/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml new file mode 100644 index 000000000000..5dacebded529 --- /dev/null +++ b/cmds/idmap2/tests/data/signature-overlay/AndroidManifest.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<manifest + xmlns:android="http://schemas.android.com/apk/res/android" + package="test.overlay.system"> + <overlay + android:targetPackage="test.target" + android:targetName="TestResources"/> +</manifest> diff --git a/tools/aapt2/integration-tests/AutoVersionTest/Android.mk b/cmds/idmap2/tests/data/signature-overlay/build index 03cce3534a4e..fdd8301c3b7d 100644..100755 --- a/tools/aapt2/integration-tests/AutoVersionTest/Android.mk +++ b/cmds/idmap2/tests/data/signature-overlay/build @@ -1,5 +1,4 @@ -# -# Copyright (C) 2017 The Android Open Source Project +# 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. @@ -12,13 +11,16 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -LOCAL_PATH := $(call my-dir) +FRAMEWORK_RES_APK=${ANDROID_BUILD_TOP}/prebuilts/sdk/current/public/android.jar + +aapt2 compile --dir res -o compiled.flata + +aapt2 link \ + --no-resource-removal \ + -I "$FRAMEWORK_RES_APK" \ + --manifest AndroidManifest.xml \ + -o signature-overlay.apk \ + compiled.flata -include $(CLEAR_VARS) -LOCAL_USE_AAPT2 := true -LOCAL_PACKAGE_NAME := AaptAutoVersionTest -LOCAL_SDK_VERSION := current -LOCAL_MODULE_TAGS := tests -include $(BUILD_PACKAGE) +rm compiled.flata diff --git a/cmds/idmap2/tests/data/signature-overlay/res/values/values.xml b/cmds/idmap2/tests/data/signature-overlay/res/values/values.xml new file mode 100644 index 000000000000..59e7d8ed69c1 --- /dev/null +++ b/cmds/idmap2/tests/data/signature-overlay/res/values/values.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <!-- This overlay will fulfill the policy "signature". This allows it overlay the + following resources. --> + <string name="policy_signature">policy_signature</string> +</resources> diff --git a/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk Binary files differnew file mode 100644 index 000000000000..b2c490dcbb90 --- /dev/null +++ b/cmds/idmap2/tests/data/signature-overlay/signature-overlay.apk diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/build b/cmds/idmap2/tests/data/system-overlay-invalid/build index 920e1f8ad6f3..920e1f8ad6f3 100644..100755 --- a/cmds/idmap2/tests/data/system-overlay-invalid/build +++ b/cmds/idmap2/tests/data/system-overlay-invalid/build diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml index af1bea16daee..02704009d743 100644 --- a/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml +++ b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml @@ -22,6 +22,7 @@ <!-- Requests to overlay a resource that belongs to a policy the overlay does not fulfill. --> <string name="policy_product">policy_product</string> + <string name="policy_signature">policy_signature</string> <!-- Requests to overlay a resource that is not declared as overlayable. --> <string name="not_overlayable">not_overlayable</string> diff --git a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk Binary files differindex 710ed9067f69..9448939b5636 100644 --- a/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk +++ b/cmds/idmap2/tests/data/system-overlay-invalid/system-overlay-invalid.apk diff --git a/cmds/idmap2/tests/data/system-overlay/build b/cmds/idmap2/tests/data/system-overlay/build index be0d2390f535..be0d2390f535 100644..100755 --- a/cmds/idmap2/tests/data/system-overlay/build +++ b/cmds/idmap2/tests/data/system-overlay/build diff --git a/cmds/idmap2/tests/data/target/build b/cmds/idmap2/tests/data/target/build index 137ddb5ecaa1..e6df742cc9da 100644..100755 --- a/cmds/idmap2/tests/data/target/build +++ b/cmds/idmap2/tests/data/target/build @@ -17,5 +17,5 @@ aapt2 link --manifest AndroidManifest.xml -A assets -o target.apk compiled.flata rm compiled.flata aapt2 compile res/values/values.xml -o . -aapt2 link --manifest AndroidManifest.xml -A assets -o target_no_overlayable.apk values_values.arsc.flat +aapt2 link --manifest AndroidManifest.xml -A assets -o target-no-overlayable.apk values_values.arsc.flat rm values_values.arsc.flat
\ No newline at end of file diff --git a/cmds/idmap2/tests/data/target/res/values/overlayable.xml b/cmds/idmap2/tests/data/target/res/values/overlayable.xml index 02d25630546f..0bf83fa50b75 100644 --- a/cmds/idmap2/tests/data/target/res/values/overlayable.xml +++ b/cmds/idmap2/tests/data/target/res/values/overlayable.xml @@ -15,20 +15,12 @@ --> <resources> <overlayable name="TestResources"> - <!-- Publicly overlayable resources --> - <item type="string" name="a" /> - <item type="string" name="b" /> - <item type="string" name="c" /> - <item type="string" name="str1" /> - <item type="string" name="str2" /> - <item type="string" name="str3" /> - <item type="string" name="str4" /> - <item type="string" name="x" /> - <item type="string" name="y" /> - <item type="string" name="z" /> - <item type="integer" name="int1" /> - - <!-- Resources with partition restrictins --> + <!-- Resources with signature restrictions --> + <policy type="signature"> + <item type="string" name="policy_signature" /> + </policy> + + <!-- Resources with partition restrictions --> <policy type="system"> <item type="string" name="policy_system" /> </policy> @@ -41,12 +33,26 @@ <item type="string" name="policy_product" /> </policy> + <!-- Resources publicly overlayable --> <policy type="public"> <item type="string" name="policy_public" /> + <item type="string" name="a" /> + <item type="string" name="b" /> + <item type="string" name="c" /> + <item type="string" name="str1" /> + <item type="string" name="str2" /> + <item type="string" name="str3" /> + <item type="string" name="str4" /> + <item type="string" name="x" /> + <item type="string" name="y" /> + <item type="string" name="z" /> + <item type="integer" name="int1" /> </policy> </overlayable> <overlayable name="OtherResources"> - <item type="string" name="other" /> + <policy type="public"> + <item type="string" name="other" /> + </policy> </overlayable> </resources>
\ No newline at end of file diff --git a/cmds/idmap2/tests/data/target/res/values/values.xml b/cmds/idmap2/tests/data/target/res/values/values.xml index 0d337f3890a8..edd53f4c9b52 100644 --- a/cmds/idmap2/tests/data/target/res/values/values.xml +++ b/cmds/idmap2/tests/data/target/res/values/values.xml @@ -33,6 +33,7 @@ <string name="policy_system_vendor">policy_system_vendor</string> <string name="policy_product">policy_product</string> <string name="policy_public">policy_public</string> + <string name="policy_signature">policy_signature</string> <item type="string" name="other" /> </resources> diff --git a/cmds/idmap2/tests/data/target/target-no-overlayable.apk b/cmds/idmap2/tests/data/target/target-no-overlayable.apk Binary files differindex 8676cbb9dc3f..908b54a2f0c3 100644 --- a/cmds/idmap2/tests/data/target/target-no-overlayable.apk +++ b/cmds/idmap2/tests/data/target/target-no-overlayable.apk diff --git a/cmds/idmap2/tests/data/target/target.apk b/cmds/idmap2/tests/data/target/target.apk Binary files differindex ecbe87578684..da3c1aef5fba 100644 --- a/cmds/idmap2/tests/data/target/target.apk +++ b/cmds/idmap2/tests/data/target/target.apk diff --git a/core/java/android/annotation/CurrentTimeMillisLong.java b/core/java/android/annotation/CurrentTimeMillisLong.java index 9846ccee7a25..355bb5a2f960 100644 --- a/core/java/android/annotation/CurrentTimeMillisLong.java +++ b/core/java/android/annotation/CurrentTimeMillisLong.java @@ -25,12 +25,12 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; /** - * @memberDoc Value is a non-negative timestamp in the - * {@link System#currentTimeMillis()} time base. - * @paramDoc Value is a non-negative timestamp in the - * {@link System#currentTimeMillis()} time base. - * @returnDoc Value is a non-negative timestamp in the - * {@link System#currentTimeMillis()} time base. + * @memberDoc Value is a non-negative timestamp measured as the number of + * milliseconds since 1970-01-01T00:00:00Z. + * @paramDoc Value is a non-negative timestamp measured as the number of + * milliseconds since 1970-01-01T00:00:00Z. + * @returnDoc Value is a non-negative timestamp measured as the number of + * milliseconds since 1970-01-01T00:00:00Z. * @hide */ @Retention(SOURCE) diff --git a/core/java/android/annotation/CurrentTimeSecondsLong.java b/core/java/android/annotation/CurrentTimeSecondsLong.java new file mode 100644 index 000000000000..2b4ffd77ad34 --- /dev/null +++ b/core/java/android/annotation/CurrentTimeSecondsLong.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.annotation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * @memberDoc Value is a non-negative timestamp measured as the number of + * seconds since 1970-01-01T00:00:00Z. + * @paramDoc Value is a non-negative timestamp measured as the number of + * seconds since 1970-01-01T00:00:00Z. + * @returnDoc Value is a non-negative timestamp measured as the number of + * seconds since 1970-01-01T00:00:00Z. + * @hide + */ +@Retention(SOURCE) +@Target({METHOD, PARAMETER, FIELD}) +public @interface CurrentTimeSecondsLong { +} diff --git a/core/java/android/annotation/Px.java b/core/java/android/annotation/Px.java index ad99fdb7657e..cec7f80405d3 100644 --- a/core/java/android/annotation/Px.java +++ b/core/java/android/annotation/Px.java @@ -29,6 +29,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; * Denotes that a numeric parameter, field or method return value is expected * to represent a pixel dimension. * + * @memberDoc This units of this value are pixels. * @paramDoc This units of this value are pixels. * @returnDoc This units of this value are pixels. * {@hide} diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index bcbeb220bfb2..e0ae4e37765a 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -29,12 +29,17 @@ import android.content.Intent; import android.graphics.Insets; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; +import android.hardware.input.InputManager; import android.os.RemoteException; +import android.os.SystemClock; import android.os.UserHandle; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.IWindowManager; +import android.view.InputDevice; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.SurfaceSession; @@ -346,6 +351,32 @@ public class ActivityView extends ViewGroup { mSurfaceView.setVisibility(visibility); } + /** + * Injects a pair of down/up key events with keycode {@link KeyEvent#KEYCODE_BACK} to the + * virtual display. + */ + public void performBackPress() { + if (mVirtualDisplay == null) { + return; + } + final int displayId = mVirtualDisplay.getDisplay().getDisplayId(); + final InputManager im = InputManager.getInstance(); + im.injectInputEvent(createKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, displayId), + InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + im.injectInputEvent(createKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK, displayId), + InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + } + + private static KeyEvent createKeyEvent(int action, int code, int displayId) { + long when = SystemClock.uptimeMillis(); + final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */, + 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */, + KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, + InputDevice.SOURCE_KEYBOARD); + ev.setDisplayId(displayId); + return ev; + } + private void initVirtualDisplay(SurfaceSession surfaceSession) { if (mVirtualDisplay != null) { throw new IllegalStateException("Trying to initialize for the second time."); diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 3feccf507ff5..0aed981edf92 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -388,7 +388,7 @@ public class Environment { /** {@hide} */ public static File getDataStagingDirectory(String volumeUuid) { - return new File(getDataDirectory(volumeUuid), "staging"); + return new File(getDataDirectory(volumeUuid), "pkg_staging"); } /** {@hide} */ diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index ee3d35427b29..1de811792e7d 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.content.pm.ApplicationInfo; import android.net.LocalSocket; import android.net.LocalSocketAddress; +import android.provider.DeviceConfig; import android.util.Log; import android.util.Slog; @@ -66,16 +67,6 @@ public class ZygoteProcess { /** * @hide for internal use only. */ - public static final String ZYGOTE_SOCKET_NAME = "zygote"; - - /** - * @hide for internal use only. - */ - public static final String ZYGOTE_SECONDARY_SOCKET_NAME = "zygote_secondary"; - - /** - * @hide for internal use only. - */ public static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000; /** @@ -89,17 +80,12 @@ public class ZygoteProcess { /** * @hide for internal use only */ - public static final String BLASTULA_POOL_SOCKET_NAME = "blastula_pool"; - - /** - * @hide for internal use only - */ - public static final String BLASTULA_POOL_SECONDARY_SOCKET_NAME = "blastula_pool_secondary"; + private static final String LOG_TAG = "ZygoteProcess"; /** - * @hide for internal use only + * The default value for enabling the blastula pool. */ - private static final String LOG_TAG = "ZygoteProcess"; + private static final String BLASTULA_POOL_ENABLED_DEFAULT = "false"; /** * The name of the socket used to communicate with the primary zygote. @@ -110,6 +96,7 @@ public class ZygoteProcess { * The name of the secondary (alternate ABI) zygote socket. */ private final LocalSocketAddress mZygoteSecondarySocketAddress; + /** * The name of the socket used to communicate with the primary blastula pool. */ @@ -122,17 +109,21 @@ public class ZygoteProcess { public ZygoteProcess() { mZygoteSocketAddress = - new LocalSocketAddress(ZYGOTE_SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED); + new LocalSocketAddress(Zygote.PRIMARY_SOCKET_NAME, + LocalSocketAddress.Namespace.RESERVED); mZygoteSecondarySocketAddress = - new LocalSocketAddress(ZYGOTE_SECONDARY_SOCKET_NAME, + new LocalSocketAddress(Zygote.SECONDARY_SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED); mBlastulaPoolSocketAddress = - new LocalSocketAddress(BLASTULA_POOL_SOCKET_NAME, + new LocalSocketAddress(Zygote.BLASTULA_POOL_PRIMARY_SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED); mBlastulaPoolSecondarySocketAddress = - new LocalSocketAddress(BLASTULA_POOL_SECONDARY_SOCKET_NAME, + new LocalSocketAddress(Zygote.BLASTULA_POOL_SECONDARY_SOCKET_NAME, LocalSocketAddress.Namespace.RESERVED); + + // TODO (chriswailes): Uncomment when the blastula pool can be enabled. +// fetchBlastulaPoolEnabledProp(); } public ZygoteProcess(LocalSocketAddress primarySocketAddress, @@ -272,6 +263,15 @@ public class ZygoteProcess { private ZygoteState secondaryZygoteState; /** + * If the blastula pool should be created and used to start applications. + * + * Setting this value to false will disable the creation, maintenance, and use of the blastula + * pool. When the blastula pool is disabled the application lifecycle will be identical to + * previous versions of Android. + */ + private boolean mBlastulaPoolEnabled = false; + + /** * Start a new process. * * <p>If processes are enabled, a new process is created and the @@ -327,6 +327,14 @@ public class ZygoteProcess { @Nullable String sandboxId, boolean useBlastulaPool, @Nullable String[] zygoteArgs) { + if (fetchBlastulaPoolEnabledProp()) { + // TODO (chriswailes): Send the appropriate command to the zygotes + Log.i(LOG_TAG, "Blastula pool enabled property set to: " + mBlastulaPoolEnabled); + + // This can't be enabled yet, but we do want to test this code path. + mBlastulaPoolEnabled = false; + } + try { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, @@ -407,7 +415,7 @@ public class ZygoteProcess { Process.ProcessStartResult result = new Process.ProcessStartResult(); // TODO (chriswailes): Move branch body into separate function. - if (useBlastulaPool && Zygote.BLASTULA_POOL_ENABLED && isValidBlastulaCommand(args)) { + if (useBlastulaPool && isValidBlastulaCommand(args)) { LocalSocket blastulaSessionSocket = null; try { @@ -620,6 +628,7 @@ public class ZygoteProcess { final StringBuilder sb = new StringBuilder(); sb.append("--packages-for-uid="); + // TODO (chriswailes): Replace with String.join for (int i = 0; i < packagesForUid.length; ++i) { if (i != 0) { sb.append(','); @@ -656,11 +665,42 @@ public class ZygoteProcess { synchronized(mLock) { return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), - useBlastulaPool, + useBlastulaPool && mBlastulaPoolEnabled, argsForZygote); } } + private boolean fetchBlastulaPoolEnabledProp() { + boolean origVal = mBlastulaPoolEnabled; + + final String propertyString = + Zygote.getSystemProperty( + DeviceConfig.RuntimeNative.BLASTULA_POOL_ENABLED, + BLASTULA_POOL_ENABLED_DEFAULT); + + if (!propertyString.isEmpty()) { + mBlastulaPoolEnabled = + Zygote.getSystemPropertyBoolean( + DeviceConfig.RuntimeNative.BLASTULA_POOL_ENABLED, + Boolean.parseBoolean(BLASTULA_POOL_ENABLED_DEFAULT)); + } + + return origVal != mBlastulaPoolEnabled; + } + + private long mLastPropCheckTimestamp = 0; + + private boolean fetchBlastulaPoolEnabledPropWithMinInterval() { + final long currentTimestamp = SystemClock.elapsedRealtime(); + + if (currentTimestamp - mLastPropCheckTimestamp >= Zygote.PROPERTY_CHECK_INTERVAL) { + mLastPropCheckTimestamp = currentTimestamp; + return fetchBlastulaPoolEnabledProp(); + } + + return false; + } + /** * Closes the connections to the zygote, if they exist. */ @@ -940,7 +980,7 @@ public class ZygoteProcess { /** * Try connecting to the Zygote over and over again until we hit a time-out. - * @param socketName The name of the socket to connect to. + * @param zygoteSocketName The name of the socket to connect to. */ public static void waitForConnectionToZygote(String zygoteSocketName) { final LocalSocketAddress zygoteSocketAddress = @@ -950,7 +990,7 @@ public class ZygoteProcess { /** * Try connecting to the Zygote over and over again until we hit a time-out. - * @param address The name of the socket to connect to. + * @param zygoteSocketAddress The name of the socket to connect to. */ public static void waitForConnectionToZygote(LocalSocketAddress zygoteSocketAddress) { int numRetries = ZYGOTE_CONNECT_TIMEOUT_MS / ZYGOTE_CONNECT_RETRY_DELAY_MS; diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 43c906495cb6..15aaa946e602 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -38,6 +38,7 @@ import android.content.pm.IPackageMoveObserver; import android.content.pm.PackageManager; import android.content.res.ObbInfo; import android.content.res.ObbScanner; +import android.net.Uri; import android.os.Binder; import android.os.Environment; import android.os.FileUtils; @@ -55,6 +56,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.SystemProperties; +import android.provider.MediaStore; import android.provider.Settings; import android.sysprop.VoldProperties; import android.system.ErrnoException; @@ -1096,12 +1098,32 @@ public class StorageManager { } /** - * Return the {@link StorageVolume} that contains the given file, or {@code null} if none. + * Return the {@link StorageVolume} that contains the given file, or + * {@code null} if none. */ public @Nullable StorageVolume getStorageVolume(File file) { return getStorageVolume(getVolumeList(), file); } + /** + * Return the {@link StorageVolume} that contains the given + * {@link MediaStore} item. + */ + public @NonNull StorageVolume getStorageVolume(@NonNull Uri uri) { + final String volumeName = MediaStore.getVolumeName(uri); + switch (volumeName) { + case MediaStore.VOLUME_EXTERNAL: + return getPrimaryStorageVolume(); + default: + for (StorageVolume vol : getStorageVolumes()) { + if (Objects.equals(vol.getNormalizedUuid(), volumeName)) { + return vol; + } + } + } + throw new IllegalStateException("Unknown volume for " + uri); + } + /** {@hide} */ public static @Nullable StorageVolume getStorageVolume(File file, int userId) { return getStorageVolume(getVolumeList(userId, 0), file); diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java index 7eb03007ee6a..f6a8388a7d40 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -145,6 +145,38 @@ public final class DeviceConfig { @SystemApi public interface RuntimeNative { String NAMESPACE = "runtime_native"; + + /** + * Zygote flags. See {@link com.internal.os.Zygote}. + */ + + /** + * If {@code true}, enables the blastula pool feature. + * + * @hide for internal use only + */ + String BLASTULA_POOL_ENABLED = "blastula_pool_enabled"; + + /** + * The maximum number of processes to keep in the blastula pool. + * + * @hide for internal use only + */ + String BLASTULA_POOL_SIZE_MAX = "blastula_pool_size_max"; + + /** + * The minimum number of processes to keep in the blastula pool. + * + * @hide for internal use only + */ + String BLASTULA_POOL_SIZE_MIN = "blastula_pool_size_max"; + + /** + * The threshold used to determine if the pool should be refilled. + * + * @hide for internal use only + */ + String BLASTULA_POOL_REFILL_THRESHOLD = "blastula_refill_threshold"; } /** diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 1b10bef76067..643307eb89ae 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -17,6 +17,8 @@ package android.provider; import android.annotation.BytesLong; +import android.annotation.CurrentTimeMillisLong; +import android.annotation.CurrentTimeSecondsLong; import android.annotation.DurationMillisLong; import android.annotation.IntRange; import android.annotation.NonNull; @@ -40,7 +42,9 @@ import android.database.Cursor; import android.database.DatabaseUtils; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.ImageDecoder; import android.graphics.Point; +import android.graphics.PostProcessor; import android.media.ExifInterface; import android.net.Uri; import android.os.Bundle; @@ -78,8 +82,15 @@ import java.util.Set; import java.util.regex.Pattern; /** - * The Media provider contains meta data for all available media on both internal - * and external storage devices. + * The contract between the media provider and applications. Contains + * definitions for the supported URIs and columns. + * <p> + * The media provider provides an indexed collection of common media types, such + * as {@link Audio}, {@link Video}, and {@link Images}, from any attached + * storage devices. Each collection is organized based on the primary MIME type + * of the underlying content; for example, {@code image/*} content is indexed + * under {@link Images}. The {@link Files} collection provides a broad view + * across all collections, and does not filter by MIME type. */ public final class MediaStore { private final static String TAG = "MediaStore"; @@ -847,11 +858,11 @@ public final class MediaStore { } /** - * Common fields for most MediaProvider tables + * Common media metadata columns. */ public interface MediaColumns extends BaseColumns { /** - * Path to the file on disk. + * Path to the media item on disk. * <p> * Note that apps may not have filesystem permissions to directly access * this path. Instead of trying to open this path directly, apps should @@ -871,7 +882,7 @@ public final class MediaStore { public static final String DATA = "_data"; /** - * Hash of the file on disk. + * Hash of the media item on disk. * <p> * Contains a 20-byte binary blob which is the SHA-1 hash of the file as * persisted on disk. For performance reasons, the hash may not be @@ -890,35 +901,35 @@ public final class MediaStore { public static final String HASH = "_hash"; /** - * The size of the file in bytes + * The size of the media item. */ + @BytesLong @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String SIZE = "_size"; /** - * The display name of the file + * The display name of the media item. */ @Column(Cursor.FIELD_TYPE_STRING) public static final String DISPLAY_NAME = "_display_name"; /** - * The title of the content + * The title of the media item. */ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true) public static final String TITLE = "title"; /** - * The time the file was added to the media provider - * Units are seconds since 1970. + * The time the media item was first added. */ + @CurrentTimeSecondsLong @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String DATE_ADDED = "date_added"; /** - * The time the file was last modified - * Units are seconds since 1970. - * NOTE: This is for internal use by the media scanner. Do not modify this field. + * The time the media item was last modified. */ + @CurrentTimeSecondsLong @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String DATE_MODIFIED = "date_modified"; @@ -986,23 +997,25 @@ public final class MediaStore { public static final String IS_TRASHED = "is_trashed"; /** - * The time the file should be considered expired. Units are seconds - * since 1970. Typically only meaningful in the context of - * {@link #IS_PENDING} or {@link #IS_TRASHED}. + * The time the media item should be considered expired. Typically only + * meaningful in the context of {@link #IS_PENDING} or + * {@link #IS_TRASHED}. + * * @removed */ @Deprecated + @CurrentTimeSecondsLong @Column(Cursor.FIELD_TYPE_INTEGER) public static final String DATE_EXPIRES = "date_expires"; /** - * The width of the image/video in pixels. + * The width of the media item, in pixels. */ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String WIDTH = "width"; /** - * The height of the image/video in pixels. + * The height of the media item, in pixels. */ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String HEIGHT = "height"; @@ -1151,8 +1164,7 @@ public final class MediaStore { } /** - * Fields for master table for all media files. - * Table also contains MediaColumns._ID, DATA, SIZE and DATE_MODIFIED. + * File metadata columns. */ public interface FileColumns extends MediaColumns { /** @@ -1179,15 +1191,26 @@ public final class MediaStore { public static final String PARENT = "parent"; /** - * The MIME type of the file - * <P>Type: TEXT</P> + * The MIME type of the media item. + * <p> + * This is typically defined based on the file extension of the media + * item. However, it may be the value of the {@code format} attribute + * defined by the <em>Dublin Core Media Initiative</em> standard, + * extracted from any XMP metadata contained within this media item. + * <p class="note"> + * Note: the {@code format} attribute may be ignored if the top-level + * MIME type disagrees with the file extension. For example, it's + * reasonable for an {@code image/jpeg} file to declare a {@code format} + * of {@code image/vnd.google.panorama360+jpg}, but declaring a + * {@code format} of {@code audio/ogg} would be ignored. + * <p> + * This is a read-only column that is automatically computed. */ @Column(Cursor.FIELD_TYPE_STRING) public static final String MIME_TYPE = "mime_type"; /** - * The title of the content - * <P>Type: TEXT</P> + * The title of the media item. */ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true) public static final String TITLE = "title"; @@ -1245,10 +1268,12 @@ public final class MediaStore { public static final Point MICRO_SIZE = new Point(96, 96); } - /** Column fields for downloaded files used in {@link Downloads} table */ + /** + * Download metadata columns. + */ public interface DownloadColumns extends MediaColumns { /** - * Uri indicating where the file has been downloaded from. + * Uri indicating where the item has been downloaded from. */ @Column(Cursor.FIELD_TYPE_STRING) String DOWNLOAD_URI = "download_uri"; @@ -1422,9 +1447,12 @@ public final class MediaStore { } /** - * Contains meta data for all available images. + * Collection of all media with MIME type of {@code image/*}. */ public static final class Images { + /** + * Image metadata columns. + */ public interface ImageColumns extends MediaColumns { /** * The description of the image @@ -1473,9 +1501,9 @@ public final class MediaStore { public static final String LONGITUDE = "longitude"; /** - * The date & time that the image was taken in units - * of milliseconds since jan 1, 1970. + * The time the media item was taken. */ + @CurrentTimeMillisLong @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String DATE_TAKEN = "datetaken"; @@ -1531,16 +1559,34 @@ public final class MediaStore { } public static final class Media implements ImageColumns { + /** + * @deprecated all queries should be performed through + * {@link ContentResolver} directly, which offers modern + * features like {@link CancellationSignal}. + */ + @Deprecated public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) { return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER); } + /** + * @deprecated all queries should be performed through + * {@link ContentResolver} directly, which offers modern + * features like {@link CancellationSignal}. + */ + @Deprecated public static final Cursor query(ContentResolver cr, Uri uri, String[] projection, String where, String orderBy) { return cr.query(uri, projection, where, null, orderBy == null ? DEFAULT_SORT_ORDER : orderBy); } + /** + * @deprecated all queries should be performed through + * {@link ContentResolver} directly, which offers modern + * features like {@link CancellationSignal}. + */ + @Deprecated public static final Cursor query(ContentResolver cr, Uri uri, String[] projection, String selection, String [] selectionArgs, String orderBy) { return cr.query(uri, projection, selection, @@ -1552,9 +1598,12 @@ public final class MediaStore { * * @param cr The content resolver to use * @param url The url of the image - * @throws FileNotFoundException - * @throws IOException + * @deprecated loading of images should be performed through + * {@link ImageDecoder#createSource(ContentResolver, Uri)}, + * which offers modern features like + * {@link PostProcessor}. */ + @Deprecated public static final Bitmap getBitmap(ContentResolver cr, Uri url) throws FileNotFoundException, IOException { InputStream input = cr.openInputStream(url); @@ -1571,8 +1620,11 @@ public final class MediaStore { * @param name The name of the image * @param description The description of the image * @return The URL to the newly created image - * @throws FileNotFoundException + * @deprecated inserting of images should be performed through + * {@link MediaStore#createPending(Context, PendingParams)}, + * which offers richer control over lifecycle. */ + @Deprecated public static final String insertImage(ContentResolver cr, String imagePath, String name, String description) throws FileNotFoundException { // Check if file exists with a FileInputStream @@ -1599,7 +1651,11 @@ public final class MediaStore { * @param description The description of the image * @return The URL to the newly created image, or <code>null</code> if the image failed to be stored * for any reason. + * @deprecated inserting of images should be performed through + * {@link MediaStore#createPending(Context, PendingParams)}, + * which offers richer control over lifecycle. */ + @Deprecated public static final String insertImage(ContentResolver cr, Bitmap source, String title, String description) { ContentValues values = new ContentValues(); @@ -1694,15 +1750,33 @@ public final class MediaStore { */ @Deprecated public static class Thumbnails implements BaseColumns { + /** + * @deprecated all queries should be performed through + * {@link ContentResolver} directly, which offers modern + * features like {@link CancellationSignal}. + */ + @Deprecated public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) { return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER); } + /** + * @deprecated all queries should be performed through + * {@link ContentResolver} directly, which offers modern + * features like {@link CancellationSignal}. + */ + @Deprecated public static final Cursor queryMiniThumbnails(ContentResolver cr, Uri uri, int kind, String[] projection) { return cr.query(uri, projection, "kind = " + kind, null, DEFAULT_SORT_ORDER); } + /** + * @deprecated all queries should be performed through + * {@link ContentResolver} directly, which offers modern + * features like {@link CancellationSignal}. + */ + @Deprecated public static final Cursor queryMiniThumbnail(ContentResolver cr, long origId, int kind, String[] projection) { return cr.query(EXTERNAL_CONTENT_URI, projection, @@ -1885,11 +1959,11 @@ public final class MediaStore { } /** - * Container for all audio content. + * Collection of all media with MIME type of {@code audio/*}. */ public static final class Audio { /** - * Columns for audio file that show up in multiple tables. + * Audio metadata columns. */ public interface AudioColumns extends MediaColumns { @@ -1901,15 +1975,17 @@ public final class MediaStore { public static final String TITLE_KEY = "title_key"; /** - * The duration of the audio file, in ms + * The duration of the audio item. */ + @DurationMillisLong @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String DURATION = "duration"; /** - * The position, in ms, playback was at when playback for this file - * was last stopped. + * The position within the audio item at which playback should be + * resumed. */ + @DurationMillisLong @Column(Cursor.FIELD_TYPE_INTEGER) public static final String BOOKMARK = "bookmark"; @@ -2187,7 +2263,7 @@ public final class MediaStore { } /** - * Columns representing an audio genre + * Audio genre metadata columns. */ public interface GenresColumns { /** @@ -2290,7 +2366,7 @@ public final class MediaStore { } /** - * Columns representing a playlist + * Audio playlist metadata columns. */ public interface PlaylistsColumns { /** @@ -2321,17 +2397,16 @@ public final class MediaStore { public static final String DATA = "_data"; /** - * The time the file was added to the media provider - * Units are seconds since 1970. + * The time the media item was first added. */ + @CurrentTimeSecondsLong @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String DATE_ADDED = "date_added"; /** - * The time the file was last modified - * Units are seconds since 1970. - * NOTE: This is for internal use by the media scanner. Do not modify this field. + * The time the media item was last modified. */ + @CurrentTimeSecondsLong @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String DATE_MODIFIED = "date_modified"; } @@ -2450,7 +2525,7 @@ public final class MediaStore { } /** - * Columns representing an artist + * Audio artist metadata columns. */ public interface ArtistColumns { /** @@ -2537,7 +2612,7 @@ public final class MediaStore { } /** - * Columns representing an album + * Audio album metadata columns. */ public interface AlbumColumns { @@ -2707,6 +2782,9 @@ public final class MediaStore { } } + /** + * Collection of all media with MIME type of {@code video/*}. + */ public static final class Video { /** @@ -2714,15 +2792,25 @@ public final class MediaStore { */ public static final String DEFAULT_SORT_ORDER = MediaColumns.DISPLAY_NAME; + /** + * @deprecated all queries should be performed through + * {@link ContentResolver} directly, which offers modern + * features like {@link CancellationSignal}. + */ + @Deprecated public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) { return cr.query(uri, projection, null, null, DEFAULT_SORT_ORDER); } + /** + * Video metadata columns. + */ public interface VideoColumns extends MediaColumns { /** - * The duration of the video file, in ms + * The duration of the video item. */ + @DurationMillisLong @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String DURATION = "duration"; @@ -2799,9 +2887,9 @@ public final class MediaStore { public static final String LONGITUDE = "longitude"; /** - * The date & time that the video was taken in units - * of milliseconds since jan 1, 1970. + * The time the media item was taken. */ + @CurrentTimeMillisLong @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true) public static final String DATE_TAKEN = "datetaken"; @@ -2849,11 +2937,10 @@ public final class MediaStore { public static final String GROUP_ID = "group_id"; /** - * The bookmark for the video. Time in ms. Represents the location in the video that the - * video should start playing at the next time it is opened. If the value is null or - * out of the range 0..DURATION-1 then the video should start playing from the - * beginning. + * The position within the video item at which playback should be + * resumed. */ + @DurationMillisLong @Column(Cursor.FIELD_TYPE_INTEGER) public static final String BOOKMARK = "bookmark"; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index d925d7ee2676..a465b3271407 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -11731,6 +11731,14 @@ public final class Settings { public static final String APP_IDLE_CONSTANTS = "app_idle_constants"; /** + * Enable ART bytecode verification verifications for debuggable apps. + * 0 = disable, 1 = enable. + * @hide + */ + public static final String ART_VERIFIER_VERIFY_DEBUGGABLE = + "art_verifier_verify_debuggable"; + + /** * Power manager specific settings. * This is encoded as a key=value list, separated by commas. Ex: * @@ -12393,6 +12401,14 @@ public final class Settings { public static final String GAME_DRIVER_WHITELIST = "game_driver_whitelist"; /** + * List of libraries in sphal accessible by Game Driver + * The string is a list of library names, separated by colon. + * i.e. <lib1>:<lib2>:...:<libN> + * @hide + */ + public static final String GAME_DRIVER_SPHAL_LIBRARIES = "game_driver_sphal_libraries"; + + /** * Ordered GPU debug layer list for Vulkan * i.e. <layer1>:<layer2>:...:<layerN> * @hide diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java index 8695da237f97..ce83a57bf68b 100644 --- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java +++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java @@ -126,6 +126,14 @@ public abstract class AugmentedAutofillService extends Service { } /** + * Called when the Android system connects to service. + * + * <p>You should generally do initialization here rather than in {@link #onCreate}. + */ + public void onConnected() { + } + + /** * Asks the service to handle an "augmented" autofill request. * * <p>This method is called when the "stantard" autofill service cannot handle a request, which @@ -158,6 +166,14 @@ public abstract class AugmentedAutofillService extends Service { @NonNull FillCallback callback) { } + /** + * Called when the Android system disconnects from the service. + * + * <p> At this point this service may no longer be an active {@link AugmentedAutofillService}. + */ + public void onDisconnected() { + } + private void handleOnFillRequest(int sessionId, @NonNull IBinder client, int taskId, @NonNull ComponentName componentName, @NonNull AutofillId focusedId, @Nullable AutofillValue focusedValue, long requestTime, diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java index 630c38a734bd..172f1d8a8f20 100644 --- a/core/java/android/widget/SearchView.java +++ b/core/java/android/widget/SearchView.java @@ -2078,6 +2078,11 @@ public class SearchView extends LinearLayout implements CollapsibleActionView { return ic; } + @Override + public boolean checkInputConnectionProxy(View view) { + return view == mSearchView; + } + private void showSoftInputIfNecessary() { if (mHasPendingShowSoftInputRequest) { final InputMethodManager imm = diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 2009fd50137a..0fbd4dca700b 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -72,6 +72,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; import android.provider.DocumentsContract; +import android.provider.Downloads; import android.provider.OpenableColumns; import android.service.chooser.ChooserTarget; import android.service.chooser.ChooserTargetService; @@ -620,27 +621,39 @@ public class ChooserActivity extends ResolverActivity { } } + /** + * Wrapping the ContentResolver call to expose for easier mocking, + * and to avoid mocking Android core classes. + */ + @VisibleForTesting + public Cursor queryResolver(ContentResolver resolver, Uri uri) { + return resolver.query(uri, null, null, null, null); + } + private FileInfo extractFileInfo(Uri uri, ContentResolver resolver) { String fileName = null; boolean hasThumbnail = false; - Cursor cursor = null; - - try { - cursor = resolver.query(uri, null, null, null, null); - } catch (SecurityException e) { - Log.w(TAG, "Error loading file preview", e); - } - if (cursor != null && cursor.getCount() > 0) { - int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); - int flagsIndex = cursor.getColumnIndex(DocumentsContract.Document.COLUMN_FLAGS); + try (Cursor cursor = queryResolver(resolver, uri)) { + if (cursor != null && cursor.getCount() > 0) { + int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + int titleIndex = cursor.getColumnIndex(Downloads.Impl.COLUMN_TITLE); + int flagsIndex = cursor.getColumnIndex(DocumentsContract.Document.COLUMN_FLAGS); + + cursor.moveToFirst(); + if (nameIndex != -1) { + fileName = cursor.getString(nameIndex); + } else if (titleIndex != -1) { + fileName = cursor.getString(titleIndex); + } - cursor.moveToFirst(); - fileName = cursor.getString(nameIndex); - if (flagsIndex != -1) { - hasThumbnail = (cursor.getInt(flagsIndex) - & DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL) != 0; + if (flagsIndex != -1) { + hasThumbnail = (cursor.getInt(flagsIndex) + & DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL) != 0; + } } + } catch (SecurityException e) { + Log.w(TAG, "Error loading file preview", e); } if (TextUtils.isEmpty(fileName)) { diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java index 258d081c6ad8..d9fd3b5bd6d8 100644 --- a/core/java/com/android/internal/colorextraction/ColorExtractor.java +++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java @@ -21,7 +21,7 @@ import android.annotation.Nullable; import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; -import android.os.Trace; +import android.os.AsyncTask; import android.util.Log; import android.util.SparseArray; @@ -53,11 +53,11 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener protected WallpaperColors mLockColors; public ColorExtractor(Context context) { - this(context, new Tonal(context)); + this(context, new Tonal(context), true /* immediately */); } @VisibleForTesting - public ColorExtractor(Context context, ExtractionType extractionType) { + public ColorExtractor(Context context, ExtractionType extractionType, boolean immediately) { mContext = context; mExtractionType = extractionType; @@ -71,23 +71,48 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener } mOnColorsChangedListeners = new ArrayList<>(); - GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM); - GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK); WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class); if (wallpaperManager == null) { Log.w(TAG, "Can't listen to color changes!"); } else { wallpaperManager.addOnColorsChangedListener(this, null /* handler */); + initExtractColors(wallpaperManager, immediately); + } + } - // Initialize all gradients with the current colors - Trace.beginSection("ColorExtractor#getWallpaperColors"); + private void initExtractColors(WallpaperManager wallpaperManager, boolean immediately) { + if (immediately) { mSystemColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM); mLockColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_LOCK); - Trace.endSection(); + extractWallpaperColors(); + } else { + new LoadWallpaperColors().executeOnExecutor( + AsyncTask.THREAD_POOL_EXECUTOR, wallpaperManager); + } + } + + private class LoadWallpaperColors extends AsyncTask<WallpaperManager, Void, Void> { + private WallpaperColors mSystemColors; + private WallpaperColors mLockColors; + @Override + protected Void doInBackground(WallpaperManager... params) { + mSystemColors = params[0].getWallpaperColors(WallpaperManager.FLAG_SYSTEM); + mLockColors = params[0].getWallpaperColors(WallpaperManager.FLAG_LOCK); + return null; + } + @Override + protected void onPostExecute(Void b) { + ColorExtractor.this.mSystemColors = mSystemColors; + ColorExtractor.this.mLockColors = mLockColors; + extractWallpaperColors(); + triggerColorsChanged(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK); } + } - // Initialize all gradients with the current colors + private void extractWallpaperColors() { + GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM); + GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK); extractInto(mSystemColors, systemColors[TYPE_NORMAL], systemColors[TYPE_DARK], diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 40d78688cb4c..22884ac9e3fc 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -29,6 +29,7 @@ import android.os.IVold; import android.os.Process; import android.os.SystemProperties; import android.os.Trace; +import android.provider.DeviceConfig; import android.system.ErrnoException; import android.system.Os; import android.util.Log; @@ -129,21 +130,6 @@ public final class Zygote { public static final int BLASTULA_MANAGEMENT_MESSAGE_BYTES = 8; /** - * If the blastula pool should be created and used to start applications. - * - * Setting this value to false will disable the creation, maintenance, and use of the blastula - * pool. When the blastula pool is disabled the application lifecycle will be identical to - * previous versions of Android. - */ - public static final boolean BLASTULA_POOL_ENABLED = false; - - /** - * File descriptor used for communication between the signal handler and the ZygoteServer poll - * loop. - * */ - protected static FileDescriptor sBlastulaPoolEventFD; - - /** * An extraArg passed when a zygote process is forking a child-zygote, specifying a name * in the abstract socket namespace. This socket name is what the new child zygote * should listen for connections on. @@ -174,43 +160,39 @@ public final class Zygote { private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_"; /** - * The maximum value that the sBlastulaPoolMax variable may take. This value - * is a mirror of BLASTULA_POOL_MAX_LIMIT found in com_android_internal_os_Zygote.cpp. + * The duration to wait before re-checking Zygote related system properties. + * + * Five minutes in milliseconds. */ - static final int BLASTULA_POOL_MAX_LIMIT = 10; + public static final long PROPERTY_CHECK_INTERVAL = 300000; /** - * The minimum value that the sBlastulaPoolMin variable may take. + * @hide for internal use only */ - static final int BLASTULA_POOL_MIN_LIMIT = 1; + public static final int SOCKET_BUFFER_SIZE = 256; + + /** a prototype instance for a future List.toArray() */ + protected static final int[][] INT_ARRAY_2D = new int[0][0]; /** - * The runtime-adjustable maximum Blastula pool size. + * @hide for internal use only. */ - static int sBlastulaPoolMax = BLASTULA_POOL_MAX_LIMIT; + public static final String PRIMARY_SOCKET_NAME = "zygote"; /** - * The runtime-adjustable minimum Blastula pool size. + * @hide for internal use only. */ - static int sBlastulaPoolMin = BLASTULA_POOL_MIN_LIMIT; + public static final String SECONDARY_SOCKET_NAME = "zygote_secondary"; /** - * The runtime-adjustable value used to determine when to re-fill the - * blastula pool. The pool will be re-filled when - * (sBlastulaPoolMax - gBlastulaPoolCount) >= sBlastulaPoolRefillThreshold. + * @hide for internal use only */ - // TODO (chriswailes): This must be updated at the same time as sBlastulaPoolMax. - static int sBlastulaPoolRefillThreshold = (sBlastulaPoolMax / 2); + public static final String BLASTULA_POOL_PRIMARY_SOCKET_NAME = "blastula_pool"; /** * @hide for internal use only */ - public static final int SOCKET_BUFFER_SIZE = 256; - - private static LocalServerSocket sBlastulaPoolSocket = null; - - /** a prototype instance for a future List.toArray() */ - protected static final int[][] INT_ARRAY_2D = new int[0][0]; + public static final String BLASTULA_POOL_SECONDARY_SOCKET_NAME = "blastula_pool_secondary"; private Zygote() {} @@ -428,70 +410,47 @@ public final class Zygote { protected static native void nativeGetSocketFDs(boolean isPrimary); /** - * Initialize the blastula pool and fill it with the desired number of - * processes. - */ - protected static Runnable initBlastulaPool() { - if (BLASTULA_POOL_ENABLED) { - sBlastulaPoolEventFD = getBlastulaPoolEventFD(); - - return fillBlastulaPool(null); - } else { - return null; - } + * Returns the raw string value of a system property. + * + * Note that Device Config is not available without an application so SystemProperties is used + * instead. + * + * TODO (chriswailes): Cache the system property location in native code and then write a JNI + * function to fetch it. + */ + public static String getSystemProperty(String propertyName, String defaultValue) { + return SystemProperties.get( + String.join(".", + "persist.device_config", + DeviceConfig.RuntimeNative.NAMESPACE, + propertyName), + defaultValue); } /** - * Checks to see if the current policy says that pool should be refilled, and spawns new - * blastulas if necessary. + * Returns the value of a system property converted to a boolean using specific logic. * - * NOTE: This function doesn't need to be guarded with BLASTULA_POOL_ENABLED because it is - * only called from contexts that are only valid if the pool is enabled. + * Note that Device Config is not available without an application so SystemProperties is used + * instead. * - * @param sessionSocketRawFDs Anonymous session sockets that are currently open - * @return In the Zygote process this function will always return null; in blastula processes - * this function will return a Runnable object representing the new application that is - * passed up from blastulaMain. - */ - protected static Runnable fillBlastulaPool(int[] sessionSocketRawFDs) { - Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillBlastulaPool"); - - int blastulaPoolCount = getBlastulaPoolCount(); - - int numBlastulasToSpawn = sBlastulaPoolMax - blastulaPoolCount; - - if (blastulaPoolCount < sBlastulaPoolMin - || numBlastulasToSpawn >= sBlastulaPoolRefillThreshold) { - - // Disable some VM functionality and reset some system values - // before forking. - ZygoteHooks.preFork(); - resetNicePriority(); - - while (blastulaPoolCount++ < sBlastulaPoolMax) { - Runnable caller = forkBlastula(sessionSocketRawFDs); - - if (caller != null) { - return caller; - } - } - - // Re-enable runtime services for the Zygote. Blastula services - // are re-enabled in specializeBlastula. - ZygoteHooks.postForkCommon(); - - Log.i("zygote", "Filled the blastula pool. New blastulas: " + numBlastulasToSpawn); - } - - Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); - - return null; + * @see SystemProperties.getBoolean + * + * TODO (chriswailes): Cache the system property location in native code and then write a JNI + * function to fetch it. + */ + public static boolean getSystemPropertyBoolean(String propertyName, Boolean defaultValue) { + return SystemProperties.getBoolean( + String.join(".", + "persist.device_config", + DeviceConfig.RuntimeNative.NAMESPACE, + propertyName), + defaultValue); } /** * @return Number of blastulas currently in the pool */ - private static int getBlastulaPoolCount() { + static int getBlastulaPoolCount() { return nativeGetBlastulaPoolCount(); } @@ -501,7 +460,7 @@ public final class Zygote { * @return The event FD used for communication between the signal handler and the ZygoteServer * poll loop */ - private static FileDescriptor getBlastulaPoolEventFD() { + static FileDescriptor getBlastulaPoolEventFD() { FileDescriptor fd = new FileDescriptor(); fd.setInt$(nativeGetBlastulaPoolEventFD()); @@ -518,7 +477,8 @@ public final class Zygote { * this function will return a Runnable object representing the new application that is * passed up from blastulaMain. */ - private static Runnable forkBlastula(int[] sessionSocketRawFDs) { + static Runnable forkBlastula(LocalServerSocket blastulaPoolSocket, + int[] sessionSocketRawFDs) { FileDescriptor[] pipeFDs = null; try { @@ -532,7 +492,7 @@ public final class Zygote { if (pid == 0) { IoUtils.closeQuietly(pipeFDs[0]); - return blastulaMain(pipeFDs[1]); + return blastulaMain(blastulaPoolSocket, pipeFDs[1]); } else { // The read-end of the pipe will be closed by the native code. // See removeBlastulaTableEntry(); @@ -553,7 +513,8 @@ public final class Zygote { * of the ZygoteServer. * @return A runnable oject representing the new application. */ - static Runnable blastulaMain(FileDescriptor writePipe) { + private static Runnable blastulaMain(LocalServerSocket blastulaPoolSocket, + FileDescriptor writePipe) { final int pid = Process.myPid(); LocalSocket sessionSocket = null; @@ -563,7 +524,7 @@ public final class Zygote { while (true) { try { - sessionSocket = sBlastulaPoolSocket.accept(); + sessionSocket = blastulaPoolSocket.accept(); BufferedReader blastulaReader = new BufferedReader(new InputStreamReader(sessionSocket.getInputStream())); @@ -611,7 +572,7 @@ public final class Zygote { System.exit(-1); } finally { IoUtils.closeQuietly(sessionSocket); - IoUtils.closeQuietly(sBlastulaPoolSocket); + IoUtils.closeQuietly(blastulaPoolSocket); } try { @@ -660,7 +621,7 @@ public final class Zygote { * exception if an invalid arugment is encountered. * @param args The arguments to test */ - static void validateBlastulaCommand(ZygoteArguments args) { + private static void validateBlastulaCommand(ZygoteArguments args) { if (args.mAbiListQuery) { throw new IllegalArgumentException(BLASTULA_ERROR_PREFIX + "--query-abi-list"); } else if (args.mPidQuery) { @@ -851,20 +812,6 @@ public final class Zygote { } /** - * Creates a managed object representing the Blastula pool socket that has - * already been initialized and bound by init. - * - * TODO (chriswailes): Move the name selection logic into this function. - * - * @throws RuntimeException when open fails - */ - static void createBlastulaSocket(String socketName) { - if (BLASTULA_POOL_ENABLED && sBlastulaPoolSocket == null) { - sBlastulaPoolSocket = createManagedSocketFromInitSocket(socketName); - } - } - - /** * Creates a managed LocalServerSocket object using a file descriptor * created by an init.rc script. The init scripts that specify the * sockets name can be found in system/core/rootdir. The socket is bound diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index e132abd7e4cb..7cddf7588b28 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -755,7 +755,7 @@ public class ZygoteInit { } public static void main(String argv[]) { - ZygoteServer zygoteServer = new ZygoteServer(); + ZygoteServer zygoteServer = null; // Mark zygote start. This ensures that thread creation will throw // an error. @@ -783,7 +783,7 @@ public class ZygoteInit { RuntimeInit.enableDdms(); boolean startSystemServer = false; - String socketName = "zygote"; + String zygoteSocketName = "zygote"; String abiList = null; boolean enableLazyPreload = false; for (int i = 1; i < argv.length; i++) { @@ -794,26 +794,19 @@ public class ZygoteInit { } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { - socketName = argv[i].substring(SOCKET_NAME_ARG.length()); + zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } + final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME); + if (abiList == null) { throw new RuntimeException("No ABI list supplied."); } - // TODO (chriswailes): Wrap these three calls in a helper function? - final String blastulaSocketName = - socketName.equals(ZygoteProcess.ZYGOTE_SOCKET_NAME) - ? ZygoteProcess.BLASTULA_POOL_SOCKET_NAME - : ZygoteProcess.BLASTULA_POOL_SECONDARY_SOCKET_NAME; - - zygoteServer.createZygoteSocket(socketName); - Zygote.createBlastulaSocket(blastulaSocketName); - - Zygote.getSocketFDs(socketName.equals(ZygoteProcess.ZYGOTE_SOCKET_NAME)); + Zygote.getSocketFDs(isPrimaryZygote); // In some configurations, we avoid preloading resources and classes eagerly. // In such cases, we will preload things prior to our first fork. @@ -846,8 +839,10 @@ public class ZygoteInit { ZygoteHooks.stopZygoteNoThreadCreation(); + zygoteServer = new ZygoteServer(isPrimaryZygote); + if (startSystemServer) { - Runnable r = forkSystemServer(abiList, socketName, zygoteServer); + Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); // {@code r == null} in the parent (zygote) process, and {@code r != null} in the // child (system_server) process. @@ -857,23 +852,18 @@ public class ZygoteInit { } } - // If the return value is null then this is the zygote process - // returning to the normal control flow. If it returns a Runnable - // object then this is a blastula that has finished specializing. - caller = Zygote.initBlastulaPool(); + Log.i(TAG, "Accepting command socket connections"); - if (caller == null) { - Log.i(TAG, "Accepting command socket connections"); - - // The select loop returns early in the child process after a fork and - // loops forever in the zygote. - caller = zygoteServer.runSelectLoop(abiList); - } + // The select loop returns early in the child process after a fork and + // loops forever in the zygote. + caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { Log.e(TAG, "System zygote died with exception", ex); throw ex; } finally { - zygoteServer.closeServerSocket(); + if (zygoteServer != null) { + zygoteServer.closeServerSocket(); + } } // We're in the child process and have exited the select loop. Proceed to execute the @@ -894,8 +884,8 @@ public class ZygoteInit { } private static void waitForSecondaryZygote(String socketName) { - String otherZygoteName = ZygoteProcess.ZYGOTE_SOCKET_NAME.equals(socketName) - ? ZygoteProcess.ZYGOTE_SECONDARY_SOCKET_NAME : ZygoteProcess.ZYGOTE_SOCKET_NAME; + String otherZygoteName = Zygote.PRIMARY_SOCKET_NAME.equals(socketName) + ? Zygote.SECONDARY_SOCKET_NAME : Zygote.PRIMARY_SOCKET_NAME; ZygoteProcess.waitForConnectionToZygote(otherZygoteName); } diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java index a78c095a8deb..24269efc3f26 100644 --- a/core/java/com/android/internal/os/ZygoteServer.java +++ b/core/java/com/android/internal/os/ZygoteServer.java @@ -20,12 +20,17 @@ import static android.system.OsConstants.POLLIN; import android.net.LocalServerSocket; import android.net.LocalSocket; +import android.os.SystemClock; +import android.os.Trace; +import android.provider.DeviceConfig; import android.system.ErrnoException; import android.system.Os; import android.system.StructPollfd; import android.util.Log; import android.util.Slog; +import dalvik.system.ZygoteHooks; + import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.FileDescriptor; @@ -38,7 +43,7 @@ import java.util.ArrayList; * Provides functions to wait for commands on a UNIX domain socket, and fork * off child processes that inherit the initial state of the VM.% * - * Please see {@link ZygoteConnection.Arguments} for documentation on the + * Please see {@link ZygoteArguments} for documentation on the * client protocol. */ class ZygoteServer { @@ -46,11 +51,48 @@ class ZygoteServer { public static final String TAG = "ZygoteServer"; /** + * The maximim value that will be accepted from the BLASTULA_POOL_SIZE_MAX device property. + * is a mirror of BLASTULA_POOL_MAX_LIMIT found in com_android_internal_os_Zygote.cpp. + */ + private static final int BLASTULA_POOL_SIZE_MAX_LIMIT = 100; + + /** + * The minimum value that will be accepted from the BLASTULA_POOL_SIZE_MIN device property. + */ + private static final int BLASTULA_POOL_SIZE_MIN_LIMIT = 1; + + /** The default value used for the BLASTULA_POOL_SIZE_MAX device property */ + private static final String BLASTULA_POOL_SIZE_MAX_DEFAULT = "10"; + + /** The default value used for the BLASTULA_POOL_SIZE_MIN device property */ + private static final String BLASTULA_POOL_SIZE_MIN_DEFAULT = "1"; + + /** + * If the blastula pool should be created and used to start applications. + * + * Setting this value to false will disable the creation, maintenance, and use of the blastula + * pool. When the blastula pool is disabled the application lifecycle will be identical to + * previous versions of Android. + */ + private boolean mBlastulaPoolEnabled = false; + + /** * Listening socket that accepts new server connections. */ private LocalServerSocket mZygoteSocket; /** + * The name of the blastula socket to use if the blastula pool is enabled. + */ + private LocalServerSocket mBlastulaPoolSocket; + + /** + * File descriptor used for communication between the signal handler and the ZygoteServer poll + * loop. + * */ + private FileDescriptor mBlastulaPoolEventFD; + + /** * Whether or not mZygoteSocket's underlying FD should be closed directly. * If mZygoteSocket is created with an existing FD, closing the socket does * not close the FD and it must be closed explicitly. If the socket is created @@ -64,25 +106,55 @@ class ZygoteServer { */ private boolean mIsForkChild; - ZygoteServer() { } + /** + * The runtime-adjustable maximum Blastula pool size. + */ + private int mBlastulaPoolSizeMax = 0; - void setForkChild() { - mIsForkChild = true; + /** + * The runtime-adjustable minimum Blastula pool size. + */ + private int mBlastulaPoolSizeMin = 0; + + /** + * The runtime-adjustable value used to determine when to re-fill the + * blastula pool. The pool will be re-filled when + * (sBlastulaPoolMax - gBlastulaPoolCount) >= sBlastulaPoolRefillThreshold. + */ + private int mBlastulaPoolRefillThreshold = 0; + + ZygoteServer() { + mBlastulaPoolEventFD = null; + mZygoteSocket = null; + mBlastulaPoolSocket = null; } /** - * Creates a managed object representing the Zygote socket that has already - * been initialized and bound by init. - * - * TODO (chriswailes): Move the name selection logic into this function. + * Initialize the Zygote server with the Zygote server socket, blastula pool server socket, + * and blastula pool event FD. * - * @throws RuntimeException when open fails + * @param isPrimaryZygote If this is the primary Zygote or not. */ - void createZygoteSocket(String socketName) { - if (mZygoteSocket == null) { - mZygoteSocket = Zygote.createManagedSocketFromInitSocket(socketName); - mCloseSocketFd = true; + ZygoteServer(boolean isPrimaryZygote) { + mBlastulaPoolEventFD = Zygote.getBlastulaPoolEventFD(); + + if (isPrimaryZygote) { + mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME); + mBlastulaPoolSocket = + Zygote.createManagedSocketFromInitSocket( + Zygote.BLASTULA_POOL_PRIMARY_SOCKET_NAME); + } else { + mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME); + mBlastulaPoolSocket = + Zygote.createManagedSocketFromInitSocket( + Zygote.BLASTULA_POOL_SECONDARY_SOCKET_NAME); } + + fetchBlastulaPoolPolicyProps(); + } + + void setForkChild() { + mIsForkChild = true; } /** @@ -151,6 +223,104 @@ class ZygoteServer { return mZygoteSocket.getFileDescriptor(); } + private void fetchBlastulaPoolPolicyProps() { + final String blastulaPoolSizeMaxPropString = + Zygote.getSystemProperty( + DeviceConfig.RuntimeNative.BLASTULA_POOL_SIZE_MAX, + BLASTULA_POOL_SIZE_MAX_DEFAULT); + + if (!blastulaPoolSizeMaxPropString.isEmpty()) { + mBlastulaPoolSizeMax = + Integer.min( + Integer.parseInt(blastulaPoolSizeMaxPropString), + BLASTULA_POOL_SIZE_MAX_LIMIT); + } + + final String blastulaPoolSizeMinPropString = + Zygote.getSystemProperty( + DeviceConfig.RuntimeNative.BLASTULA_POOL_SIZE_MIN, + BLASTULA_POOL_SIZE_MIN_DEFAULT); + + if (!blastulaPoolSizeMinPropString.isEmpty()) { + mBlastulaPoolSizeMin = + Integer.max( + Integer.parseInt(blastulaPoolSizeMinPropString), + BLASTULA_POOL_SIZE_MIN_LIMIT); + } + + final String blastulaPoolRefillThresholdPropString = + Zygote.getSystemProperty( + DeviceConfig.RuntimeNative.BLASTULA_POOL_REFILL_THRESHOLD, + Integer.toString(mBlastulaPoolSizeMax / 2)); + + if (!blastulaPoolRefillThresholdPropString.isEmpty()) { + mBlastulaPoolRefillThreshold = + Integer.min( + Integer.parseInt(blastulaPoolRefillThresholdPropString), + mBlastulaPoolSizeMax); + } + + } + + private long mLastPropCheckTimestamp = 0; + + private void fetchBlastulaPoolPolicyPropsWithMinInterval() { + final long currentTimestamp = SystemClock.elapsedRealtime(); + + if (currentTimestamp - mLastPropCheckTimestamp >= Zygote.PROPERTY_CHECK_INTERVAL) { + fetchBlastulaPoolPolicyProps(); + mLastPropCheckTimestamp = currentTimestamp; + } + } + + /** + * Checks to see if the current policy says that pool should be refilled, and spawns new + * blastulas if necessary. + * + * @param sessionSocketRawFDs Anonymous session sockets that are currently open + * @return In the Zygote process this function will always return null; in blastula processes + * this function will return a Runnable object representing the new application that is + * passed up from blastulaMain. + */ + private Runnable fillBlastulaPool(int[] sessionSocketRawFDs) { + Log.i(TAG, "FDHUNT - Marker 2 - fillBlastulaPool"); + + if (mBlastulaPoolEnabled) { + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillBlastulaPool"); + + int blastulaPoolCount = Zygote.getBlastulaPoolCount(); + int numBlastulasToSpawn = mBlastulaPoolSizeMax - blastulaPoolCount; + + if (blastulaPoolCount < mBlastulaPoolSizeMin + || numBlastulasToSpawn >= mBlastulaPoolRefillThreshold) { + + // Disable some VM functionality and reset some system values + // before forking. + ZygoteHooks.preFork(); + Zygote.resetNicePriority(); + + while (blastulaPoolCount++ < mBlastulaPoolSizeMax) { + Runnable caller = Zygote.forkBlastula(mBlastulaPoolSocket, sessionSocketRawFDs); + + if (caller != null) { + return caller; + } + } + + // Re-enable runtime services for the Zygote. Blastula services + // are re-enabled in specializeBlastula. + ZygoteHooks.postForkCommon(); + + Log.i("zygote", + "Filled the blastula pool. New blastulas: " + numBlastulasToSpawn); + } + + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); + } + + return null; + } + /** * Runs the zygote process's select loop. Accepts new connections as * they happen, and reads commands from connections one spawn-request's @@ -164,6 +334,8 @@ class ZygoteServer { peers.add(null); while (true) { + fetchBlastulaPoolPolicyPropsWithMinInterval(); + int[] blastulaPipeFDs = Zygote.getBlastulaPipeFDs(); // Space for all of the socket FDs, the Blastula Pool Event FD, and @@ -181,7 +353,7 @@ class ZygoteServer { final int blastulaPoolEventFDIndex = pollIndex; pollFDs[pollIndex] = new StructPollfd(); - pollFDs[pollIndex].fd = Zygote.sBlastulaPoolEventFD; + pollFDs[pollIndex].fd = mBlastulaPoolEventFD; pollFDs[pollIndex].events = (short) POLLIN; ++pollIndex; @@ -275,6 +447,8 @@ class ZygoteServer { } else { // Either the blastula pool event FD or a blastula reporting pipe. + Log.i(TAG, "FDHUNT - Marker 1 - runSelectLoop"); + // If this is the event FD the payload will be the number of blastulas removed. // If this is a reporting pipe FD the payload will be the PID of the blastula // that was just specialized. @@ -316,7 +490,7 @@ class ZygoteServer { .mapToInt(fd -> fd.getInt$()) .toArray(); - final Runnable command = Zygote.fillBlastulaPool(sessionSocketRawFDs); + final Runnable command = fillBlastulaPool(sessionSocketRawFDs); if (command != null) { return command; diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index d69d416e8401..c45900c098b3 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -667,6 +667,11 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote) char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX]; std::string fingerprintBuf; char jdwpProviderBuf[sizeof("-XjdwpProvider:") - 1 + PROPERTY_VALUE_MAX]; + char bootImageBuf[sizeof("-Ximage:") - 1 + PROPERTY_VALUE_MAX]; + + if (parseRuntimeOption("dalvik.vm.boot-image", bootImageBuf, "-Ximage:")) { + ALOGI("Boot image: '%s'\n", bootImageBuf); + } bool checkJni = false; property_get("dalvik.vm.checkjni", propBuf, ""); diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 7b4e4ea43415..4649b5262723 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -1357,6 +1357,9 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, SetSchedulerPolicy(fail_fn); + __android_log_close(); + stats_log_close(); + const char* se_info_ptr = se_info.has_value() ? se_info.value().c_str() : nullptr; const char* nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr; diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index c9957f369473..cccb40d51722 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -453,6 +453,8 @@ message GlobalSettingsProto { optional SettingProto game_driver_blacklists = 14; // ANGLE - Show a dialog box when ANGLE is selected for the currently running PKG optional SettingProto show_angle_in_use_dialog = 15; + // Game Driver - List of libraries in sphal accessible by Game Driver + optional SettingProto game_driver_sphal_libraries = 16; } optional Gpu gpu = 59; diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 5948f2988bc4..09fb663468f5 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4291,6 +4291,13 @@ <!-- Title text to append when the display is secure. [CHAR LIMIT=30] --> <string name="display_manager_overlay_display_secure_suffix">, secure</string> + <!-- Activity starter --> + <!-- Toast message for blocking background activity starts feature running in permissive mode --> + <string name="activity_starter_block_bg_activity_starts_permissive">This background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> will be blocked in future Q builds. See go/q-bg-block.</string> + + <!-- Toast message for blocking background activity starts feature running in enforcing mode --> + <string name="activity_starter_block_bg_activity_starts_enforcing">Background activity start from <xliff:g id="packageName" example="com.example">%1$s</xliff:g> blocked. See go/q-bg-block. </string> + <!-- Keyguard strings --> <!-- Message shown in pattern unlock after some number of unsuccessful attempts --> <string name="kg_forgot_pattern_button_text">Forgot Pattern</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7ef5e022c1c4..1ebd6e931ab6 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -763,6 +763,8 @@ <java-symbol type="string" name="display_manager_hdmi_display_name" /> <java-symbol type="string" name="display_manager_overlay_display_name" /> <java-symbol type="string" name="display_manager_overlay_display_secure_suffix" /> + <java-symbol type="string" name="activity_starter_block_bg_activity_starts_permissive" /> + <java-symbol type="string" name="activity_starter_block_bg_activity_starts_enforcing" /> <java-symbol type="string" name="display_manager_overlay_display_title" /> <java-symbol type="string" name="double_tap_toast" /> <java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" /> diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index c57b609023ca..46cac7a49f13 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -122,6 +122,7 @@ public class SettingsBackupTest { Settings.Global.APP_OPS_CONSTANTS, Settings.Global.APP_STANDBY_ENABLED, Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE, + Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, Settings.Global.ASSISTED_GPS_ENABLED, Settings.Global.AUDIO_SAFE_VOLUME_STATE, Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES, @@ -494,6 +495,7 @@ public class SettingsBackupTest { Settings.Global.GAME_DRIVER_BLACKLISTS, Settings.Global.GAME_DRIVER_BLACKLIST, Settings.Global.GAME_DRIVER_WHITELIST, + Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, Settings.Global.GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX, Settings.Global.GPU_DEBUG_LAYER_APP, Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING, diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java index 7f104b1b0a14..f27f3f9ca427 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -30,6 +30,7 @@ import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -41,6 +42,7 @@ import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; +import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -651,6 +653,59 @@ public class ChooserActivityTest { onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed())); } + @Test + public void contentProviderThrowSecurityException() throws InterruptedException { + Uri uri = Uri.parse("content://com.android.frameworks.coretests/app.pdf"); + + ArrayList<Uri> uris = new ArrayList<>(); + uris.add(uri); + + Intent sendIntent = createSendUriIntentWithPreview(uris); + + List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2); + when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + + sOverrides.resolverForceException = true; + + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); + waitForIdle(); + onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed())); + onView(withId(R.id.content_preview_filename)).check(matches(withText("app.pdf"))); + onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed())); + } + + @Test + public void contentProviderReturnsNoColumns() throws InterruptedException { + Uri uri = Uri.parse("content://com.android.frameworks.coretests/app.pdf"); + + ArrayList<Uri> uris = new ArrayList<>(); + uris.add(uri); + uris.add(uri); + + Intent sendIntent = createSendUriIntentWithPreview(uris); + + List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2); + when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + + Cursor cursor = mock(Cursor.class); + when(cursor.getCount()).thenReturn(1); + Mockito.doNothing().when(cursor).close(); + when(cursor.moveToFirst()).thenReturn(true); + when(cursor.getColumnIndex(Mockito.anyString())).thenReturn(-1); + + sOverrides.resolverCursor = cursor; + + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); + waitForIdle(); + onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed())); + onView(withId(R.id.content_preview_filename)).check(matches(withText("app.pdf + 1 file"))); + onView(withId(R.id.content_preview_file_icon)).check(matches(isDisplayed())); + } + private Intent createSendTextIntent() { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java index 096b78b95fbd..57c84ff5c8ac 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java @@ -19,8 +19,10 @@ package com.android.internal.app; import static org.mockito.Mockito.mock; import android.app.usage.UsageStatsManager; +import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; +import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; import android.util.Size; @@ -97,6 +99,19 @@ public class ChooserWrapperActivity extends ChooserActivity { return sOverrides.metricsLogger; } + @Override + public Cursor queryResolver(ContentResolver resolver, Uri uri) { + if (sOverrides.resolverCursor != null) { + return sOverrides.resolverCursor; + } + + if (sOverrides.resolverForceException) { + throw new SecurityException("Test exception handling"); + } + + return super.queryResolver(resolver, uri); + } + /** * We cannot directly mock the activity created since instrumentation creates it. * <p> @@ -109,6 +124,8 @@ public class ChooserWrapperActivity extends ChooserActivity { public ResolverListController resolverListController; public Boolean isVoiceInteraction; public boolean isImageType; + public Cursor resolverCursor; + public boolean resolverForceException; public Bitmap previewThumbnail; public MetricsLogger metricsLogger; @@ -118,6 +135,8 @@ public class ChooserWrapperActivity extends ChooserActivity { createPackageManager = null; previewThumbnail = null; isImageType = false; + resolverCursor = null; + resolverForceException = false; resolverListController = mock(ResolverListController.class); metricsLogger = mock(MetricsLogger.class); } diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index 0335a7c6bd7d..793dd8d39376 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -318,6 +318,7 @@ cc_test { "tests/unit/RenderNodeDrawableTests.cpp", "tests/unit/RenderNodeTests.cpp", "tests/unit/RenderPropertiesTests.cpp", + "tests/unit/RenderThreadTests.cpp", "tests/unit/ShaderCacheTests.cpp", "tests/unit/SkiaBehaviorTests.cpp", "tests/unit/SkiaDisplayListTests.cpp", diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index fc63819120d6..bfae80f4698a 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -346,6 +346,7 @@ void RenderThread::requestVsync() { bool RenderThread::threadLoop() { setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY); + Looper::setForThread(mLooper); if (gOnStartHook) { gOnStartHook("RenderThread"); } diff --git a/libs/hwui/tests/unit/RenderThreadTests.cpp b/libs/hwui/tests/unit/RenderThreadTests.cpp new file mode 100644 index 000000000000..af8ae7841af2 --- /dev/null +++ b/libs/hwui/tests/unit/RenderThreadTests.cpp @@ -0,0 +1,29 @@ +/* + * 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. + */ + +#include <gtest/gtest.h> + +#include "tests/common/TestUtils.h" +#include <utils/Looper.h> + +using namespace android; +using namespace android::uirenderer; +using namespace android::uirenderer::renderthread; + +RENDERTHREAD_TEST(RenderThread, isLooper) { + ASSERT_TRUE(Looper::getForThread() != nullptr); +} + diff --git a/media/java/android/media/HwAudioSource.java b/media/java/android/media/HwAudioSource.java new file mode 100644 index 000000000000..8bdb8a63f470 --- /dev/null +++ b/media/java/android/media/HwAudioSource.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.media; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; + +import com.android.internal.util.Preconditions; + +/** + * The HwAudioSource represents the audio playback directly from a source audio device. + * It currently supports {@link HwAudioSource#start()} and {@link HwAudioSource#stop()} only + * corresponding to {@link AudioSystem#startAudioSource(AudioPortConfig, AudioAttributes)} + * and {@link AudioSystem#stopAudioSource(int)}. + * + * @hide + */ +@SystemApi +public class HwAudioSource extends PlayerBase { + private final AudioDeviceInfo mAudioDeviceInfo; + private final AudioAttributes mAudioAttributes; + + private int mNativeHandle; + + /** + * Class constructor for a hardware audio source based player. + * + * Use the {@link Builder} class to construct a {@link HwAudioSource} instance. + * + * @param device {@link AudioDeviceInfo} instance of the source audio device. + * @param attributes {@link AudioAttributes} instance for this player. + */ + private HwAudioSource(@NonNull AudioDeviceInfo device, @NonNull AudioAttributes attributes) { + super(attributes, AudioPlaybackConfiguration.PLAYER_TYPE_HW_SOURCE); + Preconditions.checkNotNull(device); + Preconditions.checkNotNull(attributes); + Preconditions.checkArgument(device.isSource(), "Requires a source device"); + mAudioDeviceInfo = device; + mAudioAttributes = attributes; + baseRegisterPlayer(); + } + + /** + * TODO: sets the gain on {@link #mAudioDeviceInfo}. + * + * @param muting if true, the player is to be muted, and the volume values can be ignored + * @param leftVolume the left volume to use if muting is false + * @param rightVolume the right volume to use if muting is false + */ + @Override + void playerSetVolume(boolean muting, float leftVolume, float rightVolume) { + } + + /** + * TODO: applies {@link VolumeShaper} on {@link #mAudioDeviceInfo}. + * + * @param configuration a {@code VolumeShaper.Configuration} object + * created by {@link VolumeShaper.Configuration.Builder} or + * an created from a {@code VolumeShaper} id + * by the {@link VolumeShaper.Configuration} constructor. + * @param operation a {@code VolumeShaper.Operation}. + * @return + */ + @Override + int playerApplyVolumeShaper( + @NonNull VolumeShaper.Configuration configuration, + @NonNull VolumeShaper.Operation operation) { + return 0; + } + + /** + * TODO: gets the {@link VolumeShaper} by a given id. + * + * @param id the {@code VolumeShaper} id returned from + * sending a fully specified {@code VolumeShaper.Configuration} + * through {@link #playerApplyVolumeShaper} + * @return + */ + @Override + @Nullable + VolumeShaper.State playerGetVolumeShaperState(int id) { + return new VolumeShaper.State(1f, 1f); + } + + /** + * TODO: sets the level on {@link #mAudioDeviceInfo}. + * + * @param muting + * @param level + * @return + */ + @Override + int playerSetAuxEffectSendLevel(boolean muting, float level) { + return AudioSystem.SUCCESS; + } + + @Override + void playerStart() { + start(); + } + + @Override + void playerPause() { + // Pause is equivalent to stop for hardware audio source based players. + stop(); + } + + @Override + void playerStop() { + stop(); + } + + /** + * Starts the playback from {@link AudioDeviceInfo}. + */ + public void start() { + baseStart(); + mNativeHandle = AudioSystem.startAudioSource( + mAudioDeviceInfo.getPort().activeConfig(), + mAudioAttributes); + } + + /** + * Stops the playback from {@link AudioDeviceInfo}. + */ + public void stop() { + baseStop(); + if (mNativeHandle > 0) { + AudioSystem.stopAudioSource(mNativeHandle); + mNativeHandle = 0; + } + } + + /** + * Builder class for {@link HwAudioSource} objects. + * Use this class to configure and create a <code>HwAudioSource</code> instance. + * <p>Here is an example where <code>Builder</code> is used to specify an audio + * playback directly from a source device as media usage, to be used by a new + * <code>HwAudioSource</code> instance: + * + * <pre class="prettyprint"> + * HwAudioSource player = new HwAudioSource.Builder() + * .setAudioAttributes(new AudioAttributes.Builder() + * .setUsage(AudioAttributes.USAGE_MEDIA) + * .build()) + * .setAudioDeviceInfo(device) + * .build() + * </pre> + * <p> + * If the audio attributes are not set with {@link #setAudioAttributes(AudioAttributes)}, + * attributes comprising {@link AudioAttributes#USAGE_MEDIA} will be used. + */ + public static class Builder { + private AudioAttributes mAudioAttributes; + private AudioDeviceInfo mAudioDeviceInfo; + + /** + * Constructs a new Builder with default values. + */ + public Builder() { + } + + /** + * Sets the {@link AudioAttributes}. + * @param attributes a non-null {@link AudioAttributes} instance that describes the audio + * data to be played. + * @return the same Builder instance. + */ + public @NonNull Builder setAudioAttributes(@NonNull AudioAttributes attributes) { + Preconditions.checkNotNull(attributes); + mAudioAttributes = attributes; + return this; + } + + /** + * Sets the {@link AudioDeviceInfo}. + * @param info a non-null {@link AudioDeviceInfo} instance that describes the audio + * data come from. + * @return the same Builder instance. + */ + public @NonNull Builder setAudioDeviceInfo(@NonNull AudioDeviceInfo info) { + Preconditions.checkNotNull(info); + Preconditions.checkArgument(info.isSource()); + mAudioDeviceInfo = info; + return this; + } + + /** + * Builds an {@link HwAudioSource} instance initialized with all the parameters set + * on this <code>Builder</code>. + * @return a new successfully initialized {@link HwAudioSource} instance. + */ + public @NonNull HwAudioSource build() { + Preconditions.checkNotNull(mAudioDeviceInfo); + if (mAudioAttributes == null) { + mAudioAttributes = new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_MEDIA) + .build(); + } + return new HwAudioSource(mAudioDeviceInfo, mAudioAttributes); + } + } + + /** + * Eliminate {@link #deprecateStreamTypeForPlayback(int, String, String)} in API list. + * TODO: remove this pseudo-override function + * @hide + */ + public static void deprecateStreamTypeForPlayback(int streamType, String className, + String opName) throws IllegalArgumentException { + // Do nothing. + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index c5a951ca5249..369bb9fdd9dd 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -512,32 +512,52 @@ public class CarStatusBar extends StatusBar implements } @Override + public void setLockscreenUser(int newUserId) { + super.setLockscreenUser(newUserId); + // Try to dismiss the keyguard after every user switch. + dismissKeyguardWhenUserSwitcherNotDisplayed(); + } + + @Override public void onStateChanged(int newState) { super.onStateChanged(newState); startSwitchToGuestTimerIfDrivingOnKeyguard(); - if (mFullscreenUserSwitcher == null) { - return; // Not using the full screen user switcher. - } - - if (newState == StatusBarState.FULLSCREEN_USER_SWITCHER) { - if (!mFullscreenUserSwitcher.isVisible()) { - // Current execution path continues to set state after this, thus we deffer the - // dismissal to the next execution cycle. - postDismissKeyguard(); // Dismiss the keyguard if switcher is not visible. - } + if (newState != StatusBarState.FULLSCREEN_USER_SWITCHER) { + hideUserSwitcher(); } else { - mFullscreenUserSwitcher.hide(); + dismissKeyguardWhenUserSwitcherNotDisplayed(); } } + /** Makes the full screen user switcher visible, if applicable. */ public void showUserSwitcher() { if (mFullscreenUserSwitcher != null && mState == StatusBarState.FULLSCREEN_USER_SWITCHER) { mFullscreenUserSwitcher.show(); // Makes the switcher visible. } } + private void hideUserSwitcher() { + if (mFullscreenUserSwitcher != null) { + mFullscreenUserSwitcher.hide(); + } + } + + // We automatically dismiss keyguard unless user switcher is being shown on the keyguard. + private void dismissKeyguardWhenUserSwitcherNotDisplayed() { + if (mFullscreenUserSwitcher == null) { + return; // Not using the full screen user switcher. + } + + if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER + && !mFullscreenUserSwitcher.isVisible()) { + // Current execution path continues to set state after this, thus we deffer the + // dismissal to the next execution cycle. + postDismissKeyguard(); // Dismiss the keyguard if switcher is not visible. + } + } + public void postDismissKeyguard() { mHandler.post(this::dismissKeyguard); } diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml new file mode 100644 index 000000000000..824cc6992491 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-af/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Metgeseltoestel-bestuurder"</string> + <string name="chooser_title" msgid="4958797271463138976">"Koppel met <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Koppel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> met <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml new file mode 100644 index 000000000000..5d8950467b7b --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-am/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"አጃቢ የመሣሪያ አስተዳዳሪ"</string> + <string name="chooser_title" msgid="4958797271463138976">"ከ<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ጋር አገናኝ"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ከ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> አገናኝ"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml new file mode 100644 index 000000000000..9199986d1348 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"تطبيق \"مدير الجهاز المصاحب\""</string> + <string name="chooser_title" msgid="4958797271463138976">"الربط باستخدام تطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"ربط تطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بجهاز <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml new file mode 100644 index 000000000000..2bd6d7e93d66 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-as/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"কম্পেনিয়ন ডিভাইচ মেনেজাৰ"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ৰ সৈতে লিংক কৰক"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ৰ সৈতে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> লিংক কৰক"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml new file mode 100644 index 000000000000..c992cfdc1fcc --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-az/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Kompanyon Cihaz Meneceri"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilə əlaqələndirin"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqini <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ilə əlaqələndirin"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml new file mode 100644 index 000000000000..8a388a472579 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Menadžer pridruženog uređaja"</string> + <string name="chooser_title" msgid="4958797271463138976">"Povežite sa aplikacijom <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Povežite aplikaciju <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> i uređaj <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml new file mode 100644 index 000000000000..e1b801670267 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-be/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Менеджар спадарожнай прылады"</string> + <string name="chooser_title" msgid="4958797271463138976">"Звяжыце з праграмай <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Звяжыце праграму <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> з прыладай <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml new file mode 100644 index 000000000000..8748e205d212 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Свързване с(ъс) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Свържете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> с(ъс) <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml new file mode 100644 index 000000000000..a9fb9ff3d9d1 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-এর সাথে লিঙ্ক করুন"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-এর সাথে <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> লিঙ্ক করুন"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml new file mode 100644 index 000000000000..220553cfcd30 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Prateći upravitelj uređaja"</string> + <string name="chooser_title" msgid="4958797271463138976">"Povežite se s aplikacijom <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Povežite aplikaciju <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> s uređajem <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml new file mode 100644 index 000000000000..0ad921a79dd6 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Aplicació Gestor de dispositius complementaris"</string> + <string name="chooser_title" msgid="4958797271463138976">"Enllaça amb <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Enllaça <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> amb <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml new file mode 100644 index 000000000000..ebd9cb192216 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Správce doprovodných zařízení"</string> + <string name="chooser_title" msgid="4958797271463138976">"Propojení s aplikací <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Propojení aplikace <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> se zařízením <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml new file mode 100644 index 000000000000..7601e40428c1 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-da/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Medfølgende enhedshåndtering"</string> + <string name="chooser_title" msgid="4958797271463138976">"Tilknyt <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Knyt <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> til <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml new file mode 100644 index 000000000000..b58f2c55d1af --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-de/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Begleitgerät-Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Mit <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> verknüpfen"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mit <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> verknüpfen"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml new file mode 100644 index 000000000000..2d562136849a --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-el/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Διαχείριση συνοδευτικής εφαρμογής"</string> + <string name="chooser_title" msgid="4958797271463138976">"Σύνδεση με <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Σύνδεση <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> με <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml new file mode 100644 index 000000000000..91c7643150d1 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Link with <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Link <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> with <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml new file mode 100644 index 000000000000..91c7643150d1 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Link with <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Link <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> with <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml new file mode 100644 index 000000000000..91c7643150d1 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Link with <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Link <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> with <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml new file mode 100644 index 000000000000..91c7643150d1 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Link with <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Link <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> with <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml new file mode 100644 index 000000000000..e052e61ac10b --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Link with <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Link <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> with <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml new file mode 100644 index 000000000000..0552ee7ab9f3 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Administrador de dispositivo complementario"</string> + <string name="chooser_title" msgid="4958797271463138976">"Vincular con <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Vincular <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> con <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml new file mode 100644 index 000000000000..c9e218e334f1 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-es/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Gestor de dispositivos complementario"</string> + <string name="chooser_title" msgid="4958797271463138976">"Vincular con <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Vincular <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> con <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml new file mode 100644 index 000000000000..1ac26f712a18 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-et/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Kaasseadme haldur"</string> + <string name="chooser_title" msgid="4958797271463138976">"Linkimine rakendusega <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Rakenduse <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> linkimine seadmega <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml new file mode 100644 index 000000000000..26e19792b4c6 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Gailu osagarriaren kudeatzailea"</string> + <string name="chooser_title" msgid="4958797271463138976">"Lotu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioarekin"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Lotu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> gailuarekin"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml new file mode 100644 index 000000000000..b43fe290ad04 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"مدیر دستگاه مرتبط"</string> + <string name="chooser_title" msgid="4958797271463138976">"پیوند با <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"پیوند <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> با <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml new file mode 100644 index 000000000000..fbc18f60c751 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Linkitä <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Linkitä <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ja <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml new file mode 100644 index 000000000000..05e340299aef --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Gestionnaire d\'appareil compagnon"</string> + <string name="chooser_title" msgid="4958797271463138976">"Lier à <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Lier <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml new file mode 100644 index 000000000000..881d6aaea693 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Gestionnaire d\'appareils associés"</string> + <string name="chooser_title" msgid="4958797271463138976">"Associer à l\'application <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Associer l\'application <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à l\'appareil <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml new file mode 100644 index 000000000000..6f85022a31fb --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Xestor de dispositivos complementarios"</string> + <string name="chooser_title" msgid="4958797271463138976">"Vincular con <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Vincular <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> con <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml new file mode 100644 index 000000000000..508850765cbd --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"કમ્પેનિયન ડિવાઇસ મેનેજર"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> સાથે લિંક કરો"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> સાથે લિંક કરો"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml new file mode 100644 index 000000000000..4afcb630a8ed --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"सहयोगी डिवाइस मैनेजर"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> से लिंक करें"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> से लिंक करें"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml new file mode 100644 index 000000000000..7b71939476fb --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Povežite s aplikacijom <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Povežite aplikaciju <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> s uređajem <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml new file mode 100644 index 000000000000..19920b24fe3f --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Társeszközök kezelője"</string> + <string name="chooser_title" msgid="4958797271463138976">"Összekapcsolás a(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> alkalmazással"</string> + <string name="confirmation_title" msgid="5683126664999349196">"A(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> alkalmazás és a(z) <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> eszköz összekapcsolása"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml new file mode 100644 index 000000000000..8dee4a34f3ef --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածի հետ կապում"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածի կապում <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> սարքի հետ"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml new file mode 100644 index 000000000000..efd77fe7b60f --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-in/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Pengelola Perangkat Pendamping"</string> + <string name="chooser_title" msgid="4958797271463138976">"Tautkan dengan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Tautkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dengan <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml new file mode 100644 index 000000000000..4bf94474ccb1 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-is/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Stjórnun fylgdartækja"</string> + <string name="chooser_title" msgid="4958797271463138976">"Tengjast við <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Tengja <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> við <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml new file mode 100644 index 000000000000..a602061f71f1 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-it/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Gestione dispositivi companion"</string> + <string name="chooser_title" msgid="4958797271463138976">"Collega con <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Collega <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> con <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml new file mode 100644 index 000000000000..b95fae5327ee --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"ניהול מכשיר מותאם"</string> + <string name="chooser_title" msgid="4958797271463138976">"קישור אל <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"קישור <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> אל <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml new file mode 100644 index 000000000000..8c39e701c9c6 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"コンパニオン デバイス マネージャ"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> とのリンク"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> と <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> とのリンク"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml new file mode 100644 index 000000000000..6fa899a1ac2f --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"კომპანიონი მოწყობილობების მენეჯერი"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-თან მიბმა"</string> + <string name="confirmation_title" msgid="5683126664999349196">"მიაბით ერთმანეთს <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> და <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml new file mode 100644 index 000000000000..18ab5e6f9d22 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасымен байланыстыру"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасымен және <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> құрылғысымен байланыстыру"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml new file mode 100644 index 000000000000..42efac4c0674 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-km/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"កម្មវិធីគ្រប់គ្រងឧបករណ៍ដៃគូ"</string> + <string name="chooser_title" msgid="4958797271463138976">"ភ្ជាប់ជាមួយ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"ភ្ជាប់ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ជាមួយ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml new file mode 100644 index 000000000000..e21bb02ed9ab --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"ಕಂಪ್ಯಾನಿಯನ್ ಸಾಧನ ನಿರ್ವಾಹಕರು"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ನ ಜೊತೆಗೆ ಲಿಂಕ್ ಮಾಡಿ"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಅನ್ನು <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ನ ಜೊತೆಗೆ ಲಿಂಕ್ ಮಾಡಿ"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml new file mode 100644 index 000000000000..17702f58d90a --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"부속 기기 관리자"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 연결"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>을(를) <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>에 연결"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml new file mode 100644 index 000000000000..63efea7ab046 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосу менен байланыштыруу"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосун <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> түзмөгү менен байланыштыруу"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml new file mode 100644 index 000000000000..f6375515cbe4 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"ຕົວຈັດການອຸປະກອນປະກອບ"</string> + <string name="chooser_title" msgid="4958797271463138976">"ເຊື່ອມຕໍ່ກັບ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"ເຊື່ອມຕໍ່ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ກັບ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml new file mode 100644 index 000000000000..ddaa60146267 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Susieti su pr. <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Susieti programą <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> su <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> įrenginiu"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml new file mode 100644 index 000000000000..ba8840c1645c --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Palīgierīču pārzinis"</string> + <string name="chooser_title" msgid="4958797271463138976">"Saistīšana ar lietotni <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Lietotnes <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> saistīšana ar ierīci <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml new file mode 100644 index 000000000000..4c2e41177658 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Поврзување со <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Поврзување на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> со <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml new file mode 100644 index 000000000000..950e4e4fa346 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"കമ്പാനിയൻ ഉപകരണ മാനേജർ"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ഉപയോഗിച്ച് ലിങ്ക് ചെയ്യുക"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> with <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ലിങ്ക് ചെയ്യുക"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml new file mode 100644 index 000000000000..5add54ae1505 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-тай холбох"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-г <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-тай холбох"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml new file mode 100644 index 000000000000..45348c04f6ca --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"सहयोगी डिव्हाइस व्यवस्थापक"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g><strong> सह लिंक करा"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ला <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> शी लिंक करा"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml new file mode 100644 index 000000000000..5a50f157b132 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Pengurus Peranti Rakan"</string> + <string name="chooser_title" msgid="4958797271463138976">"Paut dengan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Paut <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dengan <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml new file mode 100644 index 000000000000..3fba5ffd9b3b --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-my/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"တွဲဖက်ကိရိယာ မန်နေဂျာ"</string> + <string name="chooser_title" msgid="4958797271463138976">"<xliff:g id="APP_NAME">%1$s</xliff:g></strong> ဖြင့် ချိတ်ဆက်ရန်<strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ဖြင့် ချိတ်ဆက်ခြင်း <strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml new file mode 100644 index 000000000000..0b49f473e853 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Knytt til <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Knytt <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> til <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml new file mode 100644 index 000000000000..348104f844ab --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"सहयोगी यन्त्रको प्रबन्धक"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> सँग लिंक गर्नुहोस्"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> सँग <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई लिंक गर्नुहोस्"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml new file mode 100644 index 000000000000..12177ca92362 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Koppelen met <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> met <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> koppelen"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml new file mode 100644 index 000000000000..b5a9e1c66f29 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-or/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"ସହଯୋଗୀ ଡିଭାଇସ୍ ପରିଚାଳକ"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ସହ ଲିଙ୍କ୍ କରନ୍ତୁ"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ସହିତ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ଲିଙ୍କ୍ କରନ୍ତୁ"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml new file mode 100644 index 000000000000..70a408f6a1bb --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"ਸੰਬੰਧੀ ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਕ"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨਾਲ ਲਿੰਕ ਕਰੋ"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ਨਾਲ ਲਿੰਕ ਕਰੋ"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml new file mode 100644 index 000000000000..c622cedc990b --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Menedżer urządzeń towarzyszących"</string> + <string name="chooser_title" msgid="4958797271463138976">"Połącz z: <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Połącz: <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> z: <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000000..b18c3ad260c3 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Gerenciador de dispositivos complementar"</string> + <string name="chooser_title" msgid="4958797271463138976">"Vincular a <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Vincular <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml new file mode 100644 index 000000000000..a64c544736e9 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Gestor de dispositivos associados"</string> + <string name="chooser_title" msgid="4958797271463138976">"Associe à aplicação <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Associe a aplicação <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ao dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml new file mode 100644 index 000000000000..b18c3ad260c3 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Gerenciador de dispositivos complementar"</string> + <string name="chooser_title" msgid="4958797271463138976">"Vincular a <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Vincular <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml new file mode 100644 index 000000000000..1c7860203cc7 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Manager de dispozitiv Companion"</string> + <string name="chooser_title" msgid="4958797271463138976">"Conectați cu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Conectați <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> cu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml new file mode 100644 index 000000000000..74b91002a2d1 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Управление подключенными устройствами"</string> + <string name="chooser_title" msgid="4958797271463138976">"Подключение к приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Подключение приложения <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> к устройству <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml new file mode 100644 index 000000000000..89f4409c0158 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-si/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"සහායක උපාංග කළමනාකරු"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> සමඟ සම්බන්ධ කරන්න"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> සමඟ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> සම්බන්ධ කරන්න"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml new file mode 100644 index 000000000000..21b3b30cab32 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Správca sprievodných zariadení"</string> + <string name="chooser_title" msgid="4958797271463138976">"Prepojenie s aplikáciou <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Prepojenie <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> so zariadením <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml new file mode 100644 index 000000000000..5645fb13e5db --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Upravitelj spremljevalnih naprav"</string> + <string name="chooser_title" msgid="4958797271463138976">"Povezava z aplikacijo <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Povezava aplikacije <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> z napravo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml new file mode 100644 index 000000000000..793554f8d40d --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Menaxheri i pajisjes shoqëruese"</string> + <string name="chooser_title" msgid="4958797271463138976">"Lidh me <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Lidh <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> me <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml new file mode 100644 index 000000000000..eac68058cfa2 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Менаџер придруженог уређаја"</string> + <string name="chooser_title" msgid="4958797271463138976">"Повежите са апликацијом <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Повежите апликацију <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> и уређај <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml new file mode 100644 index 000000000000..7d2ad85ba321 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Länka med <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Länka <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> till <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml new file mode 100644 index 000000000000..8308bbd3d78a --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Kidhibiti cha Vifaa Visaidizi"</string> + <string name="chooser_title" msgid="4958797271463138976">"Unganisha na <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Ungansha <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml new file mode 100644 index 000000000000..05110374ba30 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"கம்பேனியன் சாதன நிர்வாகி"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸுடன் இணைத்தல்"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> சாதனத்துடன் இணைத்தல்"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml new file mode 100644 index 000000000000..ebcc7f5c10ec --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-te/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"సహచర పరికర మేనేజర్"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>తో లింక్ చేయండి"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> with <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>తో లింక్ చేయండి"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml new file mode 100644 index 000000000000..3240794631d7 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-th/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"ลิงก์กับ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"ลิงก์ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> กับ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml new file mode 100644 index 000000000000..444b0d80c01f --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Kasamang Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"I-link sa <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"I-link ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> sa <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml new file mode 100644 index 000000000000..9c20ed4faa71 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasına bağlan"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasını <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazına bağla"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml new file mode 100644 index 000000000000..bed8d4d26bf3 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Диспетчер супутніх пристроїв"</string> + <string name="chooser_title" msgid="4958797271463138976">"Налаштуйте зв’язок із додатком <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Зв’яжіть пристрій <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> з додатком <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml new file mode 100644 index 000000000000..e9ad738d99f7 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"ساتھی آلہ مینیجر"</string> + <string name="chooser_title" msgid="4958797271463138976">";lt;strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong&gt& سے لنک کریں"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> سے لنک کریں"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml new file mode 100644 index 000000000000..c7d82ad806de --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga ulash"</string> + <string name="confirmation_title" msgid="5683126664999349196">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> with <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ilovasiga ulash"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml new file mode 100644 index 000000000000..29e128c7a40e --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> + <string name="chooser_title" msgid="4958797271463138976">"Liên kết với <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Liên kết <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> với <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000000..8e962185ab8d --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"配套设备管理器"</string> + <string name="chooser_title" msgid="4958797271463138976">"关联 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"将 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 关联到 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml new file mode 100644 index 000000000000..dd055d0b239f --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"隨附裝置管理員"</string> + <string name="chooser_title" msgid="4958797271463138976">"使用「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>連接"</string> + <string name="confirmation_title" msgid="5683126664999349196">"連結「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>和「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml new file mode 100644 index 000000000000..2c46d599bf35 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"隨附裝置管理員"</string> + <string name="chooser_title" msgid="4958797271463138976">"與「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>連結"</string> + <string name="confirmation_title" msgid="5683126664999349196">"為「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>與<strong></strong> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> 建立連結"</string> +</resources> diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml new file mode 100644 index 000000000000..80a24ff0e225 --- /dev/null +++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2017 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4470785958457506021">"Isiphathi sedivayisi esihambisanayo"</string> + <string name="chooser_title" msgid="4958797271463138976">"Xhuma ne-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> + <string name="confirmation_title" msgid="5683126664999349196">"Xhuma ne-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> nge-<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> +</resources> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index db4b131a0f6f..81b304dc2ce4 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -724,6 +724,9 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.Global.GAME_DRIVER_BLACKLISTS, GlobalSettingsProto.Gpu.GAME_DRIVER_BLACKLISTS); + dumpSetting(s, p, + Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, + GlobalSettingsProto.Gpu.GAME_DRIVER_SPHAL_LIBRARIES); p.end(gpuToken); final long hdmiToken = p.start(GlobalSettingsProto.HDMI); diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bubble_preview.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bubble_preview.png Binary files differdeleted file mode 100644 index 67f072f54795..000000000000 --- a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bubble_preview.png +++ /dev/null diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/stretch_preview.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/stretch_preview.png Binary files differdeleted file mode 100644 index 63927bc4deaf..000000000000 --- a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/stretch_preview.png +++ /dev/null diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_preview.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_preview.png Binary files differdeleted file mode 100644 index a538149ca3d8..000000000000 --- a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_preview.png +++ /dev/null diff --git a/packages/SystemUI/res/layout-land/global_actions_grid.xml b/packages/SystemUI/res/layout-land/global_actions_grid.xml index 911b661d48eb..480f5235f75a 100644 --- a/packages/SystemUI/res/layout-land/global_actions_grid.xml +++ b/packages/SystemUI/res/layout-land/global_actions_grid.xml @@ -29,10 +29,10 @@ android:layoutDirection="ltr" android:layout_marginTop="@dimen/global_actions_grid_side_margin" android:translationZ="@dimen/global_actions_translate" - android:paddingLeft="@dimen/global_actions_grid_top_padding" - android:paddingRight="@dimen/global_actions_grid_bottom_padding" - android:paddingTop="@dimen/global_actions_grid_left_padding" - android:paddingBottom="@dimen/global_actions_grid_right_padding" + android:paddingLeft="@dimen/global_actions_grid_horizontal_padding" + android:paddingRight="@dimen/global_actions_grid_horizontal_padding" + android:paddingTop="@dimen/global_actions_grid_vertical_padding" + android:paddingBottom="@dimen/global_actions_grid_vertical_padding" android:background="?android:attr/colorBackgroundFloating" > <LinearLayout @@ -61,17 +61,18 @@ <!-- For separated items--> <LinearLayout android:id="@+id/separated_button" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/global_actions_grid_side_margin" android:layout_marginBottom="@dimen/global_actions_grid_side_margin" - android:paddingTop="@dimen/global_actions_grid_left_padding" - android:paddingLeft="@dimen/global_actions_grid_top_padding" - android:paddingBottom="@dimen/global_actions_grid_right_padding" - android:paddingRight="@dimen/global_actions_grid_bottom_padding" + android:paddingLeft="@dimen/global_actions_grid_horizontal_padding" + android:paddingRight="@dimen/global_actions_grid_horizontal_padding" + android:paddingTop="@dimen/global_actions_grid_vertical_padding" + android:paddingBottom="@dimen/global_actions_grid_vertical_padding" android:orientation="horizontal" android:layoutDirection="ltr" android:background="?android:attr/colorBackgroundFloating" + android:gravity="center" android:translationZ="@dimen/global_actions_translate" /> diff --git a/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml b/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml index 669be1b40567..4f868263226d 100644 --- a/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml +++ b/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml @@ -23,17 +23,18 @@ <LinearLayout android:id="@+id/separated_button" android:layout_gravity="top|left" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/global_actions_grid_side_margin" android:layout_marginBottom="@dimen/global_actions_grid_side_margin" - android:paddingTop="@dimen/global_actions_grid_left_padding" - android:paddingLeft="@dimen/global_actions_grid_top_padding" - android:paddingBottom="@dimen/global_actions_grid_right_padding" - android:paddingRight="@dimen/global_actions_grid_bottom_padding" + android:paddingLeft="@dimen/global_actions_grid_horizontal_padding" + android:paddingRight="@dimen/global_actions_grid_horizontal_padding" + android:paddingTop="@dimen/global_actions_grid_vertical_padding" + android:paddingBottom="@dimen/global_actions_grid_vertical_padding" android:orientation="horizontal" android:layoutDirection="rtl" android:background="?android:attr/colorBackgroundFloating" + android:gravity="center" android:translationZ="@dimen/global_actions_translate" /> @@ -44,12 +45,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" - android:layout_marginTop="@dimen/global_actions_grid_side_margin" + android:layout_marginBottom="@dimen/global_actions_grid_side_margin" android:translationZ="@dimen/global_actions_translate" - android:paddingLeft="@dimen/global_actions_grid_top_padding" - android:paddingRight="@dimen/global_actions_grid_bottom_padding" - android:paddingTop="@dimen/global_actions_grid_left_padding" - android:paddingBottom="@dimen/global_actions_grid_right_padding" + android:paddingLeft="@dimen/global_actions_grid_horizontal_padding" + android:paddingRight="@dimen/global_actions_grid_horizontal_padding" + android:paddingTop="@dimen/global_actions_grid_vertical_padding" + android:paddingBottom="@dimen/global_actions_grid_vertical_padding" android:background="?android:attr/colorBackgroundFloating" > <LinearLayout diff --git a/packages/SystemUI/res/layout/global_actions_grid.xml b/packages/SystemUI/res/layout/global_actions_grid.xml index 1b56fa089281..729e96ebc22e 100644 --- a/packages/SystemUI/res/layout/global_actions_grid.xml +++ b/packages/SystemUI/res/layout/global_actions_grid.xml @@ -23,15 +23,16 @@ <LinearLayout android:id="@+id/separated_button" android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:layout_marginLeft="@dimen/global_actions_grid_side_margin" android:layout_marginRight="@dimen/global_actions_grid_side_margin" - android:paddingTop="@dimen/global_actions_grid_top_padding" - android:paddingLeft="@dimen/global_actions_grid_left_padding" - android:paddingBottom="@dimen/global_actions_grid_bottom_padding" - android:paddingRight="@dimen/global_actions_grid_right_padding" + android:paddingLeft="@dimen/global_actions_grid_horizontal_padding" + android:paddingRight="@dimen/global_actions_grid_horizontal_padding" + android:paddingTop="@dimen/global_actions_grid_vertical_padding" + android:paddingBottom="@dimen/global_actions_grid_vertical_padding" android:orientation="vertical" android:background="?android:attr/colorBackgroundFloating" + android:gravity="center" android:translationZ="@dimen/global_actions_translate" /> @@ -44,10 +45,10 @@ android:layoutDirection="rtl" android:layout_marginRight="@dimen/global_actions_grid_side_margin" android:translationZ="@dimen/global_actions_translate" - android:paddingLeft="@dimen/global_actions_grid_left_padding" - android:paddingRight="@dimen/global_actions_grid_right_padding" - android:paddingTop="@dimen/global_actions_grid_top_padding" - android:paddingBottom="@dimen/global_actions_grid_bottom_padding" + android:paddingLeft="@dimen/global_actions_grid_horizontal_padding" + android:paddingRight="@dimen/global_actions_grid_horizontal_padding" + android:paddingTop="@dimen/global_actions_grid_vertical_padding" + android:paddingBottom="@dimen/global_actions_grid_vertical_padding" android:background="?android:attr/colorBackgroundFloating" > <LinearLayout diff --git a/packages/SystemUI/res/layout/global_actions_grid_item.xml b/packages/SystemUI/res/layout/global_actions_grid_item.xml index a8938390690f..5dee09dac947 100644 --- a/packages/SystemUI/res/layout/global_actions_grid_item.xml +++ b/packages/SystemUI/res/layout/global_actions_grid_item.xml @@ -18,46 +18,43 @@ work around this for now with LinearLayouts. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="72dp" - android:layout_height="72dp" - android:gravity="center" + android:layout_width="@dimen/global_actions_grid_item_width" + android:layout_height="@dimen/global_actions_grid_item_height" + android:gravity="top|center_horizontal" android:orientation="vertical" android:layout_marginTop="@dimen/global_actions_grid_item_vertical_margin" android:layout_marginBottom="@dimen/global_actions_grid_item_vertical_margin" android:layout_marginLeft="@dimen/global_actions_grid_item_side_margin" android:layout_marginRight="@dimen/global_actions_grid_item_side_margin" - android:paddingEnd="4dip" - android:paddingStart="4dip"> - +> <ImageView android:id="@*android:id/icon" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_gravity="center" + android:layout_width="@dimen/global_actions_grid_item_icon_width" + android:layout_height="@dimen/global_actions_grid_item_icon_height" + android:layout_marginTop="@dimen/global_actions_grid_item_icon_top_margin" + android:layout_marginBottom="@dimen/global_actions_grid_item_icon_bottom_margin" + android:layout_marginLeft="@dimen/global_actions_grid_item_icon_side_margin" + android:layout_marginRight="@dimen/global_actions_grid_item_icon_side_margin" android:scaleType="center" android:alpha="?android:attr/primaryContentAlpha" /> <TextView android:id="@*android:id/message" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="top|center_horizontal" - android:paddingTop="10dp" android:gravity="center" - android:textSize="12sp" + android:textSize="12dp" android:textAppearance="?android:attr/textAppearanceSmall" - android:singleLine="true" /> <TextView + android:visibility="gone" android:id="@*android:id/status" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="top|center_horizontal" android:gravity="center" android:textColor="?android:attr/textColorTertiary" android:textAppearance="?android:attr/textAppearanceSmall" - android:singleLine="true" /> </LinearLayout> diff --git a/packages/SystemUI/res/layout/home_handle.xml b/packages/SystemUI/res/layout/home_handle.xml new file mode 100644 index 000000000000..48ea5c47bc7c --- /dev/null +++ b/packages/SystemUI/res/layout/home_handle.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2019 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<com.android.systemui.statusbar.phone.NavigationHandle + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/home_handle" + android:layout_width="@dimen/navigation_handle_width" + android:layout_height="match_parent" + android:layout_weight="0" + /> + diff --git a/packages/SystemUI/res/values-sw320dp-land/dimens.xml b/packages/SystemUI/res/values-sw320dp-land/dimens.xml new file mode 100644 index 000000000000..2ec5abd673cb --- /dev/null +++ b/packages/SystemUI/res/values-sw320dp-land/dimens.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2019 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<resources> + + <!-- Global actions grid --> + <dimen name="global_actions_grid_vertical_padding">3dp</dimen> + <dimen name="global_actions_grid_horizontal_padding">0dp</dimen> + + <dimen name="global_actions_grid_item_side_margin">4dp</dimen> + <dimen name="global_actions_grid_item_vertical_margin">5dp</dimen> + +</resources> + diff --git a/packages/SystemUI/res/values-sw320dp/dimens.xml b/packages/SystemUI/res/values-sw320dp/dimens.xml new file mode 100644 index 000000000000..0c2b1cc5e679 --- /dev/null +++ b/packages/SystemUI/res/values-sw320dp/dimens.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2019 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<resources> + + <!-- Global actions grid --> + <dimen name="global_actions_grid_container_bottom_margin">16dp</dimen> + + <dimen name="global_actions_grid_vertical_padding">0dp</dimen> + <dimen name="global_actions_grid_horizontal_padding">3dp</dimen> + + <dimen name="global_actions_grid_item_side_margin">5dp</dimen> + <dimen name="global_actions_grid_item_vertical_margin">4dp</dimen> + <dimen name="global_actions_grid_item_width">64dp</dimen> + <dimen name="global_actions_grid_item_height">64dp</dimen> + + <dimen name="global_actions_grid_item_icon_width">18dp</dimen> + <dimen name="global_actions_grid_item_icon_height">18dp</dimen> + <dimen name="global_actions_grid_item_icon_top_margin">12dp</dimen> + <dimen name="global_actions_grid_item_icon_side_margin">22dp</dimen> + <dimen name="global_actions_grid_item_icon_bottom_margin">4dp</dimen> + +</resources> + diff --git a/packages/SystemUI/res/values-sw410dp-land/dimens.xml b/packages/SystemUI/res/values-sw410dp-land/dimens.xml new file mode 100644 index 000000000000..61ba2d02da9e --- /dev/null +++ b/packages/SystemUI/res/values-sw410dp-land/dimens.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2019 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<resources> + + <!-- Global actions grid --> + <dimen name="global_actions_grid_vertical_padding">4dp</dimen> + <dimen name="global_actions_grid_horizontal_padding">8dp</dimen> + + <dimen name="global_actions_grid_item_side_margin">8dp</dimen> + <dimen name="global_actions_grid_item_vertical_margin">12dp</dimen> + +</resources> + diff --git a/packages/SystemUI/res/values-sw410dp/dimens.xml b/packages/SystemUI/res/values-sw410dp/dimens.xml index 5ce65241c9ca..4197eb2519fa 100644 --- a/packages/SystemUI/res/values-sw410dp/dimens.xml +++ b/packages/SystemUI/res/values-sw410dp/dimens.xml @@ -21,4 +21,22 @@ for different hardware and product builds. --> <resources> <dimen name="qs_detail_items_padding_top">16dp</dimen> + + <!-- Global actions grid --> + <dimen name="global_actions_grid_container_bottom_margin">16dp</dimen> + + <dimen name="global_actions_grid_vertical_padding">8dp</dimen> + <dimen name="global_actions_grid_horizontal_padding">4dp</dimen> + + <dimen name="global_actions_grid_item_side_margin">12dp</dimen> + <dimen name="global_actions_grid_item_vertical_margin">8dp</dimen> + <dimen name="global_actions_grid_item_width">72dp</dimen> + <dimen name="global_actions_grid_item_height">72dp</dimen> + + <dimen name="global_actions_grid_item_icon_width">24dp</dimen> + <dimen name="global_actions_grid_item_icon_height">24dp</dimen> + <dimen name="global_actions_grid_item_icon_top_margin">16dp</dimen> + <dimen name="global_actions_grid_item_icon_side_margin">24dp</dimen> + <dimen name="global_actions_grid_item_icon_bottom_margin">4dp</dimen> + </resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 76eb85eb4695..4396a42929ba 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -325,6 +325,7 @@ <!-- Nav bar button default ordering/layout --> <string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string> <string name="config_navBarLayoutQuickstep" translatable="false">back[1.7WC];home;contextual[1.7WC]</string> + <string name="config_navBarLayoutHandle" translatable="false">";home_handle;"</string> <bool name="quick_settings_show_full_alarm">false</bool> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 1c7ee3667c16..d4903cc12f29 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -33,6 +33,11 @@ <!-- size of the dead zone when touches have recently occurred elsewhere on screen --> <dimen name="navigation_bar_deadzone_size_max">32dp</dimen> + <!-- dimensions for the navigation bar handle --> + <dimen name="navigation_handle_width">180dp</dimen> + <dimen name="navigation_handle_radius">2dp</dimen> + <dimen name="navigation_handle_bottom">8dp</dimen> + <!-- Height of notification icons in the status bar --> <dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen> @@ -841,26 +846,15 @@ <dimen name="default_gear_space">18dp</dimen> <dimen name="cell_overlay_padding">18dp</dimen> + <!-- Global actions power menu --> <dimen name="global_actions_panel_width">120dp</dimen> - - <dimen name="global_actions_grid_container_bottom_margin">16dp</dimen> - - <dimen name="global_actions_grid_side_margin">4dp</dimen> - <dimen name="global_actions_grid_separated_panel_width">104dp</dimen> - <dimen name="global_actions_grid_top_padding">8dp</dimen> - <dimen name="global_actions_grid_bottom_padding">8dp</dimen> - <dimen name="global_actions_grid_left_padding">4dp</dimen> - <dimen name="global_actions_grid_right_padding">4dp</dimen> - - <dimen name="global_actions_grid_item_side_margin">12dp</dimen> - <dimen name="global_actions_grid_item_vertical_margin">8dp</dimen> - <dimen name="global_actions_top_padding">120dp</dimen> - <dimen name="global_actions_padding">12dp</dimen> - <dimen name="global_actions_translate">9dp</dimen> + <!-- Global actions grid layout --> + <dimen name="global_actions_grid_side_margin">4dp</dimen> + <!-- The maximum offset in either direction that elements are moved horizontally to prevent burn-in on AOD. --> <dimen name="burn_in_prevention_offset_x">8dp</dimen> diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java index 078108d658ee..c5dc3244d0a3 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java @@ -16,42 +16,59 @@ package com.android.keyguard.clock; import android.annotation.Nullable; +import android.app.WallpaperManager; import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; import android.os.Handler; import android.os.Looper; import android.provider.Settings; +import android.util.ArrayMap; +import android.util.DisplayMetrics; import android.view.LayoutInflater; +import android.view.View; +import android.view.View.MeasureSpec; import androidx.annotation.VisibleForTesting; +import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.R; +import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManager.DockEventListener; import com.android.systemui.plugins.ClockPlugin; -import com.android.systemui.statusbar.policy.ExtensionController; -import com.android.systemui.statusbar.policy.ExtensionController.Extension; +import com.android.systemui.util.InjectionInflationController; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; +import java.util.Map; +import java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Singleton; /** - * Manages custom clock faces. + * Manages custom clock faces for AOD and lock screen. */ @Singleton public final class ClockManager { - private final ContentResolver mContentResolver; - private final List<ClockInfo> mClockInfos = new ArrayList<>(); /** + * Map from expected value stored in settings to supplier of custom clock face. + */ + private final Map<String, Supplier<ClockPlugin>> mClocks = new ArrayMap<>(); + @Nullable private ClockPlugin mCurrentClock; + + private final ContentResolver mContentResolver; + private final SettingsWrapper mSettingsWrapper; + /** * Observe settings changes to know when to switch the clock face. */ private final ContentObserver mContentObserver = @@ -59,24 +76,9 @@ public final class ClockManager { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); - if (mClockExtension != null) { - mClockExtension.reload(); - } + reload(); } }; - private final ExtensionController mExtensionController; - /** - * Used to select between plugin or default implementations of ClockPlugin interface. - */ - private Extension<ClockPlugin> mClockExtension; - /** - * Consumer that accepts the a new ClockPlugin implementation when the Extension reloads. - */ - private final Consumer<ClockPlugin> mClockPluginConsumer = this::setClockPlugin; - /** - * Supplier of default ClockPlugin implementation. - */ - private final DefaultClockSupplier mDefaultClockSupplier; /** * Observe changes to dock state to know when to switch the clock face. */ @@ -84,25 +86,38 @@ public final class ClockManager { new DockEventListener() { @Override public void onEvent(int event) { - final boolean isDocked = (event == DockManager.STATE_DOCKED + mIsDocked = (event == DockManager.STATE_DOCKED || event == DockManager.STATE_DOCKED_HIDE); - mDefaultClockSupplier.setDocked(isDocked); - if (mClockExtension != null) { - mClockExtension.reload(); - } + reload(); } }; - @Nullable - private final DockManager mDockManager; + @Nullable private final DockManager mDockManager; + /** + * When docked, the DOCKED_CLOCK_FACE setting will be checked for the custom clock face + * to show. + */ + private boolean mIsDocked; private final List<ClockChangedListener> mListeners = new ArrayList<>(); + private final SysuiColorExtractor mColorExtractor; + private final int mWidth; + private final int mHeight; + @Inject - public ClockManager(Context context, ExtensionController extensionController, - @Nullable DockManager dockManager) { - mExtensionController = extensionController; + public ClockManager(Context context, InjectionInflationController injectionInflater, + @Nullable DockManager dockManager, SysuiColorExtractor colorExtractor) { + this(context, injectionInflater, dockManager, colorExtractor, context.getContentResolver(), + new SettingsWrapper(context.getContentResolver())); + } + + ClockManager(Context context, InjectionInflationController injectionInflater, + @Nullable DockManager dockManager, SysuiColorExtractor colorExtractor, + ContentResolver contentResolver, SettingsWrapper settingsWrapper) { mDockManager = dockManager; - mContentResolver = context.getContentResolver(); + mColorExtractor = colorExtractor; + mContentResolver = contentResolver; + mSettingsWrapper = settingsWrapper; Resources res = context.getResources(); mClockInfos.add(ClockInfo.builder() @@ -117,25 +132,35 @@ public final class ClockManager { .setTitle(res.getString(R.string.clock_title_bubble)) .setId(BubbleClockController.class.getName()) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.bubble_thumbnail)) - .setPreview(() -> BitmapFactory.decodeResource(res, R.drawable.bubble_preview)) + .setPreview(() -> getClockPreview(BubbleClockController.class.getName())) .build()); mClockInfos.add(ClockInfo.builder() .setName("stretch") .setTitle(res.getString(R.string.clock_title_stretch)) .setId(StretchAnalogClockController.class.getName()) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.stretch_thumbnail)) - .setPreview(() -> BitmapFactory.decodeResource(res, R.drawable.stretch_preview)) + .setPreview(() -> getClockPreview(StretchAnalogClockController.class.getName())) .build()); mClockInfos.add(ClockInfo.builder() .setName("type") .setTitle(res.getString(R.string.clock_title_type)) .setId(TypeClockController.class.getName()) .setThumbnail(() -> BitmapFactory.decodeResource(res, R.drawable.type_thumbnail)) - .setPreview(() -> BitmapFactory.decodeResource(res, R.drawable.type_preview)) + .setPreview(() -> getClockPreview(TypeClockController.class.getName())) .build()); - mDefaultClockSupplier = new DefaultClockSupplier(new SettingsWrapper(mContentResolver), - LayoutInflater.from(context)); + LayoutInflater layoutInflater = injectionInflater.injectable(LayoutInflater.from(context)); + mClocks.put(BubbleClockController.class.getName(), + () -> BubbleClockController.build(layoutInflater)); + mClocks.put(StretchAnalogClockController.class.getName(), + () -> StretchAnalogClockController.build(layoutInflater)); + mClocks.put(TypeClockController.class.getName(), + () -> TypeClockController.build(layoutInflater)); + + // Store the size of the display for generation of clock preview. + DisplayMetrics dm = res.getDisplayMetrics(); + mWidth = dm.widthPixels; + mHeight = dm.heightPixels; } /** @@ -146,9 +171,7 @@ public final class ClockManager { register(); } mListeners.add(listener); - if (mClockExtension != null) { - mClockExtension.reload(); - } + reload(); } /** @@ -168,7 +191,66 @@ public final class ClockManager { return mClockInfos; } - private void setClockPlugin(ClockPlugin plugin) { + /** + * Get the current clock. + * @returns current custom clock or null for default. + */ + @Nullable + ClockPlugin getCurrentClock() { + return mCurrentClock; + } + + @VisibleForTesting + boolean isDocked() { + return mIsDocked; + } + + @VisibleForTesting + ContentObserver getContentObserver() { + return mContentObserver; + } + + /** + * Generate a realistic preview of a clock face. + * @param clockId ID of clock to use for preview, should be obtained from {@link getClockInfos}. + * Returns null if clockId is not found. + */ + @Nullable + private Bitmap getClockPreview(String clockId) { + Supplier<ClockPlugin> supplier = mClocks.get(clockId); + if (supplier == null) { + return null; + } + ClockPlugin plugin = supplier.get(); + + // Use the big clock view for the preview + View clockView = plugin.getBigClockView(); + if (clockView == null) { + return null; + } + + // Initialize state of plugin before generating preview. + plugin.setDarkAmount(1f); + plugin.setTextColor(Color.WHITE); + + ColorExtractor.GradientColors colors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, + true); + plugin.setColorPalette(colors.supportsDarkText(), colors.getColorPalette()); + plugin.dozeTimeTick(); + + // Draw clock view hierarchy to canvas. + Bitmap bitmap = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + clockView.measure(MeasureSpec.makeMeasureSpec(mWidth, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(mHeight, MeasureSpec.EXACTLY)); + clockView.layout(0, 0, mWidth, mHeight); + canvas.drawColor(Color.BLACK); + clockView.draw(canvas); + + return bitmap; + } + + private void notifyClockChanged(ClockPlugin plugin) { for (int i = 0; i < mListeners.size(); i++) { // It probably doesn't make sense to supply the same plugin instances to multiple // listeners. This should be fine for now since there is only a single listener. @@ -186,11 +268,6 @@ public final class ClockManager { if (mDockManager != null) { mDockManager.addListener(mDockEventListener); } - mClockExtension = mExtensionController.newExtension(ClockPlugin.class) - .withPlugin(ClockPlugin.class) - .withCallback(mClockPluginConsumer) - .withDefault(mDefaultClockSupplier) - .build(); } private void unregister() { @@ -198,12 +275,35 @@ public final class ClockManager { if (mDockManager != null) { mDockManager.removeListener(mDockEventListener); } - mClockExtension.destroy(); } - @VisibleForTesting - boolean isDocked() { - return mDefaultClockSupplier.isDocked(); + private void reload() { + mCurrentClock = getClockPlugin(); + notifyClockChanged(mCurrentClock); + } + + private ClockPlugin getClockPlugin() { + ClockPlugin plugin = null; + if (mIsDocked) { + final String name = mSettingsWrapper.getDockedClockFace(); + if (name != null) { + Supplier<ClockPlugin> supplier = mClocks.get(name); + if (supplier != null) { + plugin = supplier.get(); + if (plugin != null) { + return plugin; + } + } + } + } + final String name = mSettingsWrapper.getLockScreenCustomClockFace(); + if (name != null) { + Supplier<ClockPlugin> supplier = mClocks.get(name); + if (supplier != null) { + plugin = supplier.get(); + } + } + return plugin; } /** diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockSupplier.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockSupplier.java deleted file mode 100644 index 7fdd2357bc8e..000000000000 --- a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockSupplier.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.keyguard.clock; - -import android.util.ArrayMap; -import android.view.LayoutInflater; - -import com.android.systemui.plugins.ClockPlugin; - -import java.util.Map; -import java.util.function.Supplier; - -/** - * Supplier that only gets an instance when a settings value matches expected value. - */ -public class DefaultClockSupplier implements Supplier<ClockPlugin> { - - private final SettingsWrapper mSettingsWrapper; - /** - * Map from expected value stored in settings to supplier of custom clock face. - */ - private final Map<String, Supplier<ClockPlugin>> mClocks = new ArrayMap<>(); - /** - * When docked, the DOCKED_CLOCK_FACE setting will be checked for the custom clock face - * to show. - */ - private boolean mIsDocked; - - /** - * Constructs a supplier that changes secure setting key against value. - * - * @param settingsWrapper Wrapper around settings used to look up the custom clock face. - * @param layoutInflater Provided to clocks as dependency to inflate clock views. - */ - public DefaultClockSupplier(SettingsWrapper settingsWrapper, LayoutInflater layoutInflater) { - mSettingsWrapper = settingsWrapper; - - mClocks.put(BubbleClockController.class.getName(), - () -> BubbleClockController.build(layoutInflater)); - mClocks.put(StretchAnalogClockController.class.getName(), - () -> StretchAnalogClockController.build(layoutInflater)); - mClocks.put(TypeClockController.class.getName(), - () -> TypeClockController.build(layoutInflater)); - } - - /** - * Sets the dock state. - * - * @param isDocked True when docked, false otherwise. - */ - public void setDocked(boolean isDocked) { - mIsDocked = isDocked; - } - - boolean isDocked() { - return mIsDocked; - } - - /** - * Get the custom clock face based on values in settings. - * - * @return Custom clock face, null if the settings value doesn't match a custom clock. - */ - @Override - public ClockPlugin get() { - ClockPlugin plugin = null; - if (mIsDocked) { - final String name = mSettingsWrapper.getDockedClockFace(); - if (name != null) { - Supplier<ClockPlugin> supplier = mClocks.get(name); - if (supplier != null) { - plugin = supplier.get(); - if (plugin != null) { - return plugin; - } - } - } - } - final String name = mSettingsWrapper.getLockScreenCustomClockFace(); - if (name != null) { - Supplier<ClockPlugin> supplier = mClocks.get(name); - if (supplier != null) { - plugin = supplier.get(); - } - } - return plugin; - } -} diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java b/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java index e35cf113c111..22753805c95e 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java @@ -37,7 +37,7 @@ public class ImageClock extends FrameLayout { private ImageView mHourHand; private ImageView mMinuteHand; - private Calendar mTime; + private final Calendar mTime = Calendar.getInstance(TimeZone.getDefault()); private String mDescFormat; private TimeZone mTimeZone; @@ -51,7 +51,6 @@ public class ImageClock extends FrameLayout { public ImageClock(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - mTime = Calendar.getInstance(); mDescFormat = ((SimpleDateFormat) DateFormat.getTimeFormat(context)).toLocalizedPattern(); } @@ -98,7 +97,7 @@ public class ImageClock extends FrameLayout { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - mTime = Calendar.getInstance(mTimeZone != null ? mTimeZone : TimeZone.getDefault()); + mTime.setTimeZone(mTimeZone != null ? mTimeZone : TimeZone.getDefault()); onTimeChanged(); } } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClock.java b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClock.java index 3c9a4f821c62..34c855bc33d3 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClock.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClock.java @@ -37,7 +37,7 @@ public class StretchAnalogClock extends View { private final Paint mHourPaint = new Paint(); private final Paint mMinutePaint = new Paint(); - private Calendar mTime; + private Calendar mTime = Calendar.getInstance(TimeZone.getDefault()); private TimeZone mTimeZone; public StretchAnalogClock(Context context) { @@ -138,7 +138,7 @@ public class StretchAnalogClock extends View { @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - mTime = Calendar.getInstance(mTimeZone != null ? mTimeZone : TimeZone.getDefault()); + mTime.setTimeZone(mTimeZone != null ? mTimeZone : TimeZone.getDefault()); onTimeChanged(); } } diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java index 6f1b59c69865..7bce3c5cb63f 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java @@ -44,7 +44,7 @@ public class TypographicClock extends TextView { private final String[] mHours; private final String[] mMinutes; private int mAccentColor; - private Calendar mTime; + private final Calendar mTime = Calendar.getInstance(TimeZone.getDefault()); private String mDescFormat; private TimeZone mTimeZone; @@ -58,7 +58,6 @@ public class TypographicClock extends TextView { public TypographicClock(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - mTime = Calendar.getInstance(); mDescFormat = ((SimpleDateFormat) DateFormat.getTimeFormat(context)).toLocalizedPattern(); mResources = context.getResources(); mHours = mResources.getStringArray(R.array.type_clock_hours); @@ -111,12 +110,13 @@ public class TypographicClock extends TextView { */ public void setClockColor(int color) { mAccentColor = color; + onTimeChanged(); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); - mTime = Calendar.getInstance(mTimeZone != null ? mTimeZone : TimeZone.getDefault()); + mTime.setTimeZone(mTimeZone != null ? mTimeZone : TimeZone.getDefault()); onTimeChanged(); } } diff --git a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java index 00ff518ce212..8c49d56ae348 100644 --- a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java +++ b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java @@ -151,7 +151,10 @@ public abstract class MultiListLayout extends LinearLayout { return null; } - interface RotationListener { + /** + * Interface to provide callbacks which trigger when this list detects a rotation. + */ + public interface RotationListener { void onRotate(int from, int to); } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index e62c77de0051..0832296b7dab 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -243,6 +243,16 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe } /** + * Directs a back gesture at the bubble stack. When opened, the current expanded bubble + * is forwarded a back key down/up pair. + */ + public void performBackPressIfNeeded() { + if (mStackView != null) { + mStackView.performBackPressIfNeeded(); + } + } + + /** * Adds or updates a bubble associated with the provided notification entry. * * @param notif the notification associated with this bubble. diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 492eadd240ed..6dee8ad846af 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -335,6 +335,14 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList updateView(); } + boolean performBackPressIfNeeded() { + if (mActivityView == null || !usingActivityView()) { + return false; + } + mActivityView.performBackPress(); + return true; + } + @Override public void onClick(View view) { if (mEntry == null) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index ed9b38b85156..eae17eea1937 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -815,4 +815,15 @@ public class BubbleStackView extends FrameLayout { getNormalizedYPosition()); } } + + /** + * Called when a back gesture should be directed to the Bubbles stack. When expanded, + * a back key down/up event pair is forwarded to the bubble Activity. + */ + boolean performBackPressIfNeeded() { + if (!isExpanded()) { + return false; + } + return mExpandedBubble.expandedView.performBackPressIfNeeded(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java index 900ea72d856c..a74c3287e1f1 100644 --- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java +++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java @@ -61,7 +61,7 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable { @VisibleForTesting public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) { - super(context, type); + super(context, type, false /* immediately */); mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context); mWpHiddenColors = new GradientColors(); diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 7c9b2864f7f2..3fa6035387c7 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -33,7 +33,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.UserInfo; -import android.content.res.Configuration; import android.database.ContentObserver; import android.graphics.Point; import android.graphics.drawable.Drawable; @@ -161,8 +160,6 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, private final ScreenshotHelper mScreenshotHelper; private final ScreenRecordHelper mScreenRecordHelper; - private int mLastRotation; - /** * @param context everything needs a context :( */ @@ -205,8 +202,6 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, mScreenshotHelper = new ScreenshotHelper(context); mScreenRecordHelper = new ScreenRecordHelper(context); - mLastRotation = RotationUtils.getRotation(mContext); - Dependency.get(ConfigurationController.class).addCallback(this); } @@ -432,15 +427,6 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, mContext.getTheme().applyStyle(mContext.getThemeResId(), true); } - @Override - public void onConfigChanged(Configuration newConfig) { - int rotation = RotationUtils.getRotation(mContext); - if (rotation != mLastRotation) { - mDialog.onRotate(); - } - mLastRotation = rotation; - } - public void destroy() { Dependency.get(ConfigurationController.class).removeCallback(this); } @@ -1540,13 +1526,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return true; } }); - } - - public void onRotate() { - if (mShowing && isGridEnabled(mContext)) { - initializeLayout(); - updateList(); - } + mGlobalActionsLayout.setRotationListener(this::onRotate); } private int getGlobalActionsLayoutId(Context context) { @@ -1703,6 +1683,13 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, public void setKeyguardShowing(boolean keyguardShowing) { mKeyguardShowing = keyguardShowing; } + + public void onRotate(int from, int to) { + if (mShowing && isGridEnabled(mContext)) { + initializeLayout(); + updateList(); + } + } } /** 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 b34907dfebf1..b65c4a5f71d8 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 @@ -125,6 +125,7 @@ public class NotificationContentInflater { private boolean mIsChildInGroup; private InflationCallback mCallback; private boolean mRedactAmbient; + private boolean mInflateSynchronously = false; private final ArrayMap<Integer, RemoteViews> mCachedContentViews = new ArrayMap<>(); public NotificationContentInflater(ExpandableNotificationRow row) { @@ -248,10 +249,20 @@ public class NotificationContentInflater { // To check if the notification has inline image and preload inline image if necessary. mRow.getImageResolver().preloadImages(sbn.getNotification()); - AsyncInflationTask task = new AsyncInflationTask(sbn, reInflateFlags, mCachedContentViews, - mRow, mIsLowPriority, mIsChildInGroup, mUsesIncreasedHeight, - mUsesIncreasedHeadsUpHeight, mRedactAmbient, mCallback, mRemoteViewClickHandler); - if (mCallback != null && mCallback.doInflateSynchronous()) { + AsyncInflationTask task = new AsyncInflationTask( + sbn, + mInflateSynchronously, + reInflateFlags, + mCachedContentViews, + mRow, + mIsLowPriority, + mIsChildInGroup, + mUsesIncreasedHeight, + mUsesIncreasedHeadsUpHeight, + mRedactAmbient, + mCallback, + mRemoteViewClickHandler); + if (mInflateSynchronously) { task.onPostExecute(task.doInBackground()); } else { task.execute(); @@ -259,13 +270,23 @@ public class NotificationContentInflater { } @VisibleForTesting - InflationProgress inflateNotificationViews(@InflationFlag int reInflateFlags, - Notification.Builder builder, Context packageContext) { + InflationProgress inflateNotificationViews( + boolean inflateSynchronously, + @InflationFlag int reInflateFlags, + Notification.Builder builder, + Context packageContext) { InflationProgress result = createRemoteViews(reInflateFlags, builder, mIsLowPriority, mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient, packageContext); - apply(result, reInflateFlags, mCachedContentViews, mRow, mRedactAmbient, - mRemoteViewClickHandler, null); + apply( + inflateSynchronously, + result, + reInflateFlags, + mCachedContentViews, + mRow, + mRedactAmbient, + mRemoteViewClickHandler, + null); return result; } @@ -348,9 +369,13 @@ public class NotificationContentInflater { return result; } - public static CancellationSignal apply(InflationProgress result, - @InflationFlag int reInflateFlags, ArrayMap<Integer, RemoteViews> cachedContentViews, - ExpandableNotificationRow row, boolean redactAmbient, + public static CancellationSignal apply( + boolean inflateSynchronously, + InflationProgress result, + @InflationFlag int reInflateFlags, + ArrayMap<Integer, RemoteViews> cachedContentViews, + ExpandableNotificationRow row, + boolean redactAmbient, RemoteViews.OnClickHandler remoteViewClickHandler, @Nullable InflationCallback callback) { NotificationContentView privateLayout = row.getPrivateLayout(); @@ -373,8 +398,8 @@ public class NotificationContentInflater { return result.newContentView; } }; - applyRemoteView(result, reInflateFlags, flag, cachedContentViews, row, redactAmbient, - isNewView, remoteViewClickHandler, callback, privateLayout, + applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, cachedContentViews, + row, redactAmbient, isNewView, remoteViewClickHandler, callback, privateLayout, privateLayout.getContractedChild(), privateLayout.getVisibleWrapper( NotificationContentView.VISIBLE_TYPE_CONTRACTED), runningInflations, applyCallback); @@ -397,9 +422,9 @@ public class NotificationContentInflater { return result.newExpandedView; } }; - applyRemoteView(result, reInflateFlags, flag, cachedContentViews, row, - redactAmbient, isNewView, remoteViewClickHandler, callback, - privateLayout, privateLayout.getExpandedChild(), + applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, + cachedContentViews, row, redactAmbient, isNewView, remoteViewClickHandler, + callback, privateLayout, privateLayout.getExpandedChild(), privateLayout.getVisibleWrapper( NotificationContentView.VISIBLE_TYPE_EXPANDED), runningInflations, applyCallback); @@ -423,9 +448,9 @@ public class NotificationContentInflater { return result.newHeadsUpView; } }; - applyRemoteView(result, reInflateFlags, flag, cachedContentViews, row, - redactAmbient, isNewView, remoteViewClickHandler, callback, - privateLayout, privateLayout.getHeadsUpChild(), + applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, + cachedContentViews, row, redactAmbient, isNewView, remoteViewClickHandler, + callback, privateLayout, privateLayout.getHeadsUpChild(), privateLayout.getVisibleWrapper( VISIBLE_TYPE_HEADSUP), runningInflations, applyCallback); @@ -448,8 +473,8 @@ public class NotificationContentInflater { return result.newPublicView; } }; - applyRemoteView(result, reInflateFlags, flag, cachedContentViews, row, - redactAmbient, isNewView, remoteViewClickHandler, callback, + applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, cachedContentViews, + row, redactAmbient, isNewView, remoteViewClickHandler, callback, publicLayout, publicLayout.getContractedChild(), publicLayout.getVisibleWrapper(NotificationContentView.VISIBLE_TYPE_CONTRACTED), runningInflations, applyCallback); @@ -472,8 +497,8 @@ public class NotificationContentInflater { return result.newAmbientView; } }; - applyRemoteView(result, reInflateFlags, flag, cachedContentViews, row, - redactAmbient, isNewView, remoteViewClickHandler, callback, + applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, cachedContentViews, + row, redactAmbient, isNewView, remoteViewClickHandler, callback, newParent, newParent.getAmbientChild(), newParent.getVisibleWrapper( NotificationContentView.VISIBLE_TYPE_AMBIENT), runningInflations, applyCallback); @@ -489,18 +514,24 @@ public class NotificationContentInflater { } @VisibleForTesting - static void applyRemoteView(final InflationProgress result, - final @InflationFlag int reInflateFlags, @InflationFlag int inflationId, + static void applyRemoteView( + boolean inflateSynchronously, + final InflationProgress result, + final @InflationFlag int reInflateFlags, + @InflationFlag int inflationId, final ArrayMap<Integer, RemoteViews> cachedContentViews, - final ExpandableNotificationRow row, final boolean redactAmbient, boolean isNewView, + final ExpandableNotificationRow row, + final boolean redactAmbient, + boolean isNewView, RemoteViews.OnClickHandler remoteViewClickHandler, @Nullable final InflationCallback callback, - NotificationContentView parentLayout, View existingView, + NotificationContentView parentLayout, + View existingView, NotificationViewWrapper existingWrapper, final HashMap<Integer, CancellationSignal> runningInflations, ApplyCallback applyCallback) { RemoteViews newContentView = applyCallback.getRemoteView(); - if (callback != null && callback.doInflateSynchronous()) { + if (inflateSynchronously) { try { if (isNewView) { View v = newContentView.apply( @@ -723,15 +754,7 @@ public class NotificationContentInflater { * @param entry the entry with the content views set * @param inflatedFlags the flags associated with the content views that were inflated */ - void onAsyncInflationFinished(NotificationEntry entry, - @InflationFlag int inflatedFlags); - - /** - * Used to disable async-ness for tests. Should only be used for tests. - */ - default boolean doInflateSynchronous() { - return false; - } + void onAsyncInflationFinished(NotificationEntry entry, @InflationFlag int inflatedFlags); } public void clearCachesAndReInflate() { @@ -739,6 +762,15 @@ public class NotificationContentInflater { inflateNotificationViews(); } + /** + * Sets whether to perform inflation on the same thread as the caller. This method should only + * be used in tests, not in production. + */ + @VisibleForTesting + void setInflateSynchronously(boolean inflateSynchronously) { + mInflateSynchronously = inflateSynchronously; + } + private static boolean canReapplyAmbient(ExpandableNotificationRow row, boolean redactAmbient) { NotificationContentView ambientView = redactAmbient ? row.getPublicLayout() : row.getPrivateLayout(); @@ -750,6 +782,7 @@ public class NotificationContentInflater { private final StatusBarNotification mSbn; private final Context mContext; + private final boolean mInflateSynchronously; private final boolean mIsLowPriority; private final boolean mIsChildInGroup; private final boolean mUsesIncreasedHeight; @@ -763,14 +796,22 @@ public class NotificationContentInflater { private RemoteViews.OnClickHandler mRemoteViewClickHandler; private CancellationSignal mCancellationSignal; - private AsyncInflationTask(StatusBarNotification notification, + private AsyncInflationTask( + StatusBarNotification notification, + boolean inflateSynchronously, @InflationFlag int reInflateFlags, - ArrayMap<Integer, RemoteViews> cachedContentViews, ExpandableNotificationRow row, - boolean isLowPriority, boolean isChildInGroup, boolean usesIncreasedHeight, - boolean usesIncreasedHeadsUpHeight, boolean redactAmbient, - InflationCallback callback, RemoteViews.OnClickHandler remoteViewClickHandler) { + ArrayMap<Integer, RemoteViews> cachedContentViews, + ExpandableNotificationRow row, + boolean isLowPriority, + boolean isChildInGroup, + boolean usesIncreasedHeight, + boolean usesIncreasedHeadsUpHeight, + boolean redactAmbient, + InflationCallback callback, + RemoteViews.OnClickHandler remoteViewClickHandler) { mRow = row; mSbn = notification; + mInflateSynchronously = inflateSynchronously; mReInflateFlags = reInflateFlags; mCachedContentViews = cachedContentViews; mContext = mRow.getContext(); @@ -817,8 +858,8 @@ public class NotificationContentInflater { @Override protected void onPostExecute(InflationProgress result) { if (mError == null) { - mCancellationSignal = apply(result, mReInflateFlags, mCachedContentViews, mRow, - mRedactAmbient, mRemoteViewClickHandler, this); + mCancellationSignal = apply(mInflateSynchronously, result, mReInflateFlags, + mCachedContentViews, mRow, mRedactAmbient, mRemoteViewClickHandler, this); } else { handleError(mError); } @@ -866,11 +907,6 @@ public class NotificationContentInflater { // try to purge unnecessary cached entries. mRow.getImageResolver().purgeCache(); } - - @Override - public boolean doInflateSynchronous() { - return mCallback != null && mCallback.doInflateSynchronous(); - } } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java index cc8adde2ed04..38df17ab52fd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java @@ -112,6 +112,9 @@ public class ContextualButtonGroup extends ButtonDispatcher { * their icons for their buttons. */ public void updateIcons() { + if (getCurrentView() == null || !getCurrentView().isAttachedToWindow()) { + return; + } for (ButtonData data : mButtonData) { data.button.updateIcon(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java index 5ccb9b294718..b622688a8ac6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java @@ -18,14 +18,12 @@ package com.android.systemui.statusbar.phone; import static com.android.systemui.statusbar.phone.NavBarTintController.DEFAULT_COLOR_ADAPT_TRANSITION_TIME; import static com.android.systemui.statusbar.phone.NavBarTintController.MIN_COLOR_ADAPT_TRANSITION_TIME; -import static com.android.systemui.statusbar.phone.NavBarTintController.NAV_COLOR_TRANSITION_TIME_SETTING; import android.animation.ValueAnimator; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; -import android.provider.Settings; import android.util.MathUtils; import android.util.TimeUtils; @@ -167,9 +165,7 @@ public class LightBarTransitionsController implements Dumpable, Callbacks, public long getTintAnimationDuration() { if (NavBarTintController.isEnabled(mContext)) { - return Math.max(Settings.Global.getInt(mContext.getContentResolver(), - NAV_COLOR_TRANSITION_TIME_SETTING, DEFAULT_COLOR_ADAPT_TRANSITION_TIME), - MIN_COLOR_ADAPT_TRANSITION_TIME); + return Math.max(DEFAULT_COLOR_ADAPT_TRANSITION_TIME, MIN_COLOR_ADAPT_TRANSITION_TIME); } return DEFAULT_TINT_ANIMATION_DURATION; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java index b4f850b033e8..cf3f89ef8788 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone; import android.content.Context; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Color; @@ -27,11 +28,13 @@ import android.os.Looper; import android.provider.Settings; import android.util.DisplayMetrics; import android.view.SurfaceControl; +import android.view.View; + +import com.android.systemui.R; public class NavBarTintController { - public static final String NAV_COLOR_TRANSITION_TIME_SETTING = "navbar_color_adapt_transition"; public static final int MIN_COLOR_ADAPT_TRANSITION_TIME = 400; - public static final int DEFAULT_COLOR_ADAPT_TRANSITION_TIME = 1500; + public static final int DEFAULT_COLOR_ADAPT_TRANSITION_TIME = 1700; private final HandlerThread mColorAdaptHandlerThread = new HandlerThread("ColorExtractThread"); private Handler mColorAdaptionHandler; @@ -42,23 +45,25 @@ public class NavBarTintController { // Passing the threshold of this luminance value will make the button black otherwise white private static final float LUMINANCE_THRESHOLD = 0.3f; - // The home button's icon is actually smaller than the button's size, the percentage will - // cut into the button's size to determine the icon size - private static final float PERCENTAGE_BUTTON_PADDING = 0.3f; - - // The distance from the home button to color sample around - private static final int COLOR_SAMPLE_MARGIN = 20; + // The margin from the bounds of the view to color sample around + private static final int COLOR_SAMPLE_MARGIN = 10; private boolean mRunning; private final NavigationBarView mNavigationBarView; private final LightBarTransitionsController mLightBarController; private final Handler mMainHandler = new Handler(Looper.getMainLooper()); + private final int mBarRadius; + private final int mBarBottom; public NavBarTintController(NavigationBarView navigationBarView, LightBarTransitionsController lightBarController) { mNavigationBarView = navigationBarView; mLightBarController = lightBarController; + + final Resources res = navigationBarView.getResources(); + mBarRadius = res.getDimensionPixelSize(R.dimen.navigation_handle_radius); + mBarBottom = res.getDimensionPixelSize(R.dimen.navigation_handle_bottom); } public void start() { @@ -91,27 +96,28 @@ public class NavBarTintController { private void updateTint() { int[] navPos = new int[2]; int[] butPos = new int[2]; - if (mNavigationBarView.getHomeButton().getCurrentView() == null) { + View view = mNavigationBarView.getHomeHandle().getCurrentView(); + if (view == null) { return; } - // Determine the area of the home icon in the larger home button - mNavigationBarView.getHomeButton().getCurrentView().getLocationInSurface(butPos); - final int navWidth = mNavigationBarView.getHomeButton().getCurrentView().getWidth(); - final int navHeight = mNavigationBarView.getHomeButton().getCurrentView().getHeight(); - final int xPadding = (int) (PERCENTAGE_BUTTON_PADDING * navWidth); - final int yPadding = (int) (PERCENTAGE_BUTTON_PADDING * navHeight); - final Rect homeButtonRect = new Rect(butPos[0] + xPadding, butPos[1] + yPadding, - navWidth + butPos[0] - xPadding, navHeight + butPos[1] - yPadding); - if (mNavigationBarView.getCurrentView() == null || homeButtonRect.isEmpty()) { + // Determine the area of the icon within its view bounds + view.getLocationInSurface(butPos); + final int navWidth = view.getWidth(); + final int navHeight = view.getHeight(); + int viewBottom = butPos[1] + navHeight - mBarBottom; + final Rect viewIconRect = new Rect(butPos[0], viewBottom - mBarRadius * 2, + butPos[0] + navWidth, viewBottom); + + if (mNavigationBarView.getCurrentView() == null || viewIconRect.isEmpty()) { scheduleColorAdaption(); return; } mNavigationBarView.getCurrentView().getLocationOnScreen(navPos); - homeButtonRect.offset(navPos[0], navPos[1]); + viewIconRect.offset(navPos[0], navPos[1]); // Apply a margin area around the button region to sample the colors, crop from screenshot - final Rect cropRect = new Rect(homeButtonRect); + final Rect cropRect = new Rect(viewIconRect); cropRect.inset(-COLOR_SAMPLE_MARGIN, -COLOR_SAMPLE_MARGIN); if (cropRect.isEmpty()) { scheduleColorAdaption(); @@ -120,8 +126,8 @@ public class NavBarTintController { // Determine the size of the home area Rect homeArea = new Rect(COLOR_SAMPLE_MARGIN, COLOR_SAMPLE_MARGIN, - homeButtonRect.width() + COLOR_SAMPLE_MARGIN, - homeButtonRect.height() + COLOR_SAMPLE_MARGIN); + viewIconRect.width() + COLOR_SAMPLE_MARGIN, + viewIconRect.height() + COLOR_SAMPLE_MARGIN); // Get the screenshot around the home button icon to determine the color DisplayMetrics mDisplayMetrics = new DisplayMetrics(); @@ -129,7 +135,8 @@ public class NavBarTintController { final Bitmap hardBitmap = SurfaceControl .screenshot(new Rect(), mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels, mNavigationBarView.getContext().getDisplay().getRotation()); - if (hardBitmap != null && cropRect.bottom <= hardBitmap.getHeight()) { + if (cropRect.bottom <= hardBitmap.getHeight() + && cropRect.left + cropRect.width() <= hardBitmap.getWidth()) { final Bitmap cropBitmap = Bitmap.createBitmap(hardBitmap, cropRect.left, cropRect.top, cropRect.width(), cropRect.height()); final Bitmap softBitmap = cropBitmap.copy(Config.ARGB_8888, false); @@ -204,6 +211,8 @@ public class NavBarTintController { public static boolean isEnabled(Context context) { return Settings.Global.getInt(context.getContentResolver(), - NavigationPrototypeController.NAV_COLOR_ADAPT_ENABLE_SETTING, 0) == 1; + NavigationPrototypeController.NAV_COLOR_ADAPT_ENABLE_SETTING, 0) == 1 + && Settings.Global.getInt(context.getContentResolver(), + NavigationPrototypeController.SHOW_HOME_HANDLE_SETTING, 0) == 1; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index 538d79717293..1eb499048db8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -445,8 +445,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback // Respect the disabled flag, no need for action as flag change callback will handle hiding if (rotateSuggestionsDisabled) return; - mNavigationBarView.getRotateSuggestionButton() - .onRotationProposal(rotation, winRotation, isValid); + View rotationButton = mNavigationBarView.getRotateSuggestionButton().getCurrentView(); + if (rotationButton != null && rotationButton.isAttachedToWindow()) { + mNavigationBarView.getRotateSuggestionButton() + .onRotationProposal(rotation, winRotation, isValid); + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java index 7c31dae2a746..c9fa89e7cb97 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java @@ -65,6 +65,7 @@ public class NavigationBarInflaterView extends FrameLayout public static final String RECENT = "recent"; public static final String NAVSPACE = "space"; public static final String CLIPBOARD = "clipboard"; + public static final String HOME_HANDLE = "home_handle"; public static final String KEY = "key"; public static final String LEFT = "left"; public static final String RIGHT = "right"; @@ -393,6 +394,8 @@ public class NavigationBarInflaterView extends FrameLayout v = inflater.inflate(R.layout.clipboard, parent, false); } else if (CONTEXTUAL.equals(button)) { v = inflater.inflate(R.layout.contextual, parent, false); + } else if (HOME_HANDLE.equals(button)) { + v = inflater.inflate(R.layout.home_handle, parent, false); } else if (button.startsWith(KEY)) { String uri = extractImage(button); int code = extractKeycode(button); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 8152206aa2ed..d6d3d0807659 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -29,6 +29,7 @@ import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION; +import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_VIEWS; import android.animation.LayoutTransition; import android.animation.LayoutTransition.TransitionListener; @@ -339,6 +340,11 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mRightEdgePanel.setDimensions(width, height); } } + + @Override + public void onHomeHandleVisiblilityChanged(boolean visible) { + showHomeHandle(visible); + } }; public NavigationBarView(Context context, AttributeSet attrs) { @@ -376,6 +382,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back)); mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home)); + mButtonDispatchers.put(R.id.home_handle, new ButtonDispatcher(R.id.home_handle)); mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps)); mButtonDispatchers.put(R.id.menu, menuButton); mButtonDispatchers.put(R.id.ime_switcher, imeSwitcherButton); @@ -573,6 +580,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav .getContextButton(R.id.rotate_suggestion); } + public ButtonDispatcher getHomeHandle() { + return mButtonDispatchers.get(R.id.home_handle); + } + public SparseArray<ButtonDispatcher> getButtonDispatchers() { return mButtonDispatchers; } @@ -855,6 +866,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav final boolean showSwipeUpUI = mOverviewProxyService.shouldShowSwipeUpUI(); if (mNavigationInflaterView != null) { + if (mPrototypeController.showHomeHandle()) { + showHomeHandle(true /* visible */); + } + // Reinflate the navbar if needed, no-op unless the swipe up state changes mNavigationInflaterView.onLikelyDefaultLayoutChange(); } @@ -899,6 +914,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav private void setWindowFlag(int flags, boolean enable) { final ViewGroup navbarView = ((ViewGroup) getParent()); + if (navbarView == null) { + return; + } WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView.getLayoutParams(); if (lp == null || enable == ((lp.flags & flags) != 0)) { return; @@ -912,6 +930,18 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav wm.updateViewLayout(navbarView, lp); } + private void showHomeHandle(boolean visible) { + mNavigationInflaterView.onTuningChanged(NAV_BAR_VIEWS, + visible ? getContext().getString(R.string.config_navBarLayoutHandle) : null); + + // Color adaption is tied with showing home handle, only avaliable if visible + if (visible) { + mColorAdaptionController.start(); + } else { + mColorAdaptionController.end(); + } + } + public void setMenuVisibility(final boolean show) { mContextualButtonGroup.setButtonVisiblity(R.id.menu, show); } @@ -1136,6 +1166,12 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav // If car mode or density changes, we need to reset the icons. updateNavButtonIcons(); } + + if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { + mColorAdaptionController.start(); + } else { + mColorAdaptionController.end(); + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java new file mode 100644 index 000000000000..968074c6af59 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone; + +import android.animation.ArgbEvaluator; +import android.annotation.ColorInt; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.ContextThemeWrapper; +import android.view.View; + +import com.android.settingslib.Utils; +import com.android.systemui.R; +import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface; + +public class NavigationHandle extends View implements ButtonInterface { + private float mDarkIntensity = -1; + + private final Paint mPaint = new Paint(); + private @ColorInt final int mLightColor; + private @ColorInt final int mDarkColor; + private final int mRadius; + private final int mBottom; + + public NavigationHandle(Context context) { + this(context, null); + } + + public NavigationHandle(Context context, AttributeSet attr) { + super(context, attr); + final Resources res = context.getResources(); + mRadius = res.getDimensionPixelSize(R.dimen.navigation_handle_radius); + mBottom = res.getDimensionPixelSize(R.dimen.navigation_handle_bottom); + + final int dualToneDarkTheme = Utils.getThemeAttr(context, R.attr.darkIconTheme); + final int dualToneLightTheme = Utils.getThemeAttr(context, R.attr.lightIconTheme); + Context lightContext = new ContextThemeWrapper(context, dualToneLightTheme); + Context darkContext = new ContextThemeWrapper(context, dualToneDarkTheme); + mLightColor = Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor); + mDarkColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor); + mPaint.setAntiAlias(true); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + // Draw that bar + int navHeight = getHeight(); + int height = mRadius * 2; + int width = getWidth(); + int y = (navHeight - mBottom - height); + canvas.drawRoundRect(mRadius, y, width - mRadius, y + height, mRadius, mRadius, mPaint); + } + + @Override + public void setImageDrawable(Drawable drawable) { + } + + @Override + public void abortCurrentGesture() { + } + + @Override + public void setVertical(boolean vertical) { + } + + @Override + public void setDarkIntensity(float intensity) { + if (mDarkIntensity != intensity) { + mPaint.setColor((int) ArgbEvaluator.getInstance().evaluate(intensity, mLightColor, + mDarkColor)); + mDarkIntensity = intensity; + invalidate(); + } + } + + @Override + public void setDelayTouchFeedback(boolean shouldDelay) { + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java index 8421e23e97b0..2c31e2cfea2e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; +import android.graphics.Point; import android.net.Uri; import android.os.Handler; import android.provider.Settings; @@ -37,12 +38,11 @@ public class NavigationPrototypeController extends ContentObserver { private static final String HIDE_HOME_BUTTON_SETTING = "quickstepcontroller_hidehome"; private static final String PROTOTYPE_ENABLED = "prototype_enabled"; - private static final String EDGE_SENSITIVITY_HEIGHT_SETTING = - "quickstepcontroller_edge_height_sensitivity"; public static final String EDGE_SENSITIVITY_WIDTH_SETTING = "quickstepcontroller_edge_width_sensitivity"; private final String GESTURE_MATCH_SETTING = "quickstepcontroller_gesture_match_map"; public static final String NAV_COLOR_ADAPT_ENABLE_SETTING = "navbar_color_adapt_enable"; + public static final String SHOW_HOME_HANDLE_SETTING = "quickstepcontroller_showhandle"; @Retention(RetentionPolicy.SOURCE) @IntDef({ACTION_DEFAULT, ACTION_QUICKSTEP, ACTION_QUICKSCRUB, ACTION_BACK, @@ -86,7 +86,7 @@ public class NavigationPrototypeController extends ContentObserver { registerObserver(GESTURE_MATCH_SETTING); registerObserver(NAV_COLOR_ADAPT_ENABLE_SETTING); registerObserver(EDGE_SENSITIVITY_WIDTH_SETTING); - registerObserver(EDGE_SENSITIVITY_HEIGHT_SETTING); + registerObserver(SHOW_HOME_HANDLE_SETTING); } /** @@ -114,20 +114,29 @@ public class NavigationPrototypeController extends ContentObserver { } else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) { mListener.onColorAdaptChanged( NavBarTintController.isEnabled(mContext)); - } else if (path.endsWith(EDGE_SENSITIVITY_WIDTH_SETTING) - || path.endsWith(EDGE_SENSITIVITY_HEIGHT_SETTING)) { + } else if (path.endsWith(EDGE_SENSITIVITY_WIDTH_SETTING)) { mListener.onEdgeSensitivityChanged(getEdgeSensitivityWidth(), getEdgeSensitivityHeight()); + } else if (path.endsWith(SHOW_HOME_HANDLE_SETTING)) { + mListener.onHomeHandleVisiblilityChanged(showHomeHandle()); } } } + /** + * @return the width for edge swipe + */ public int getEdgeSensitivityWidth() { return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 0)); } + /** + * @return full screen height + */ public int getEdgeSensitivityHeight() { - return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_HEIGHT_SETTING, 0)); + final Point size = new Point(); + mContext.getDisplay().getRealSize(size); + return size.y; } public boolean isEnabled() { @@ -149,6 +158,10 @@ public class NavigationPrototypeController extends ContentObserver { return getGlobalBool(HIDE_HOME_BUTTON_SETTING, false /* default */); } + boolean showHomeHandle() { + return getGlobalBool(SHOW_HOME_HANDLE_SETTING, false /* default */); + } + /** * Since Settings.Global cannot pass arrays, use a string to represent each character as a * gesture map to actions corresponding to {@see GestureAction}. The number is represented as: @@ -185,6 +198,7 @@ public class NavigationPrototypeController extends ContentObserver { void onGestureRemap(@GestureAction int[] actions); void onBackButtonVisibilityChanged(boolean visible); void onHomeButtonVisibilityChanged(boolean visible); + void onHomeHandleVisiblilityChanged(boolean visible); void onColorAdaptChanged(boolean enabled); void onEdgeSensitivityChanged(int width, int height); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 008eeefa8341..51ffc1dd98cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -3261,7 +3261,11 @@ public class StatusBar extends SystemUI implements DemoMode, return true; } if (mState != StatusBarState.KEYGUARD && mState != StatusBarState.SHADE_LOCKED) { - animateCollapsePanels(); + if (mNotificationPanel.canPanelBeCollapsed()) { + animateCollapsePanels(); + } else { + mBubbleController.performBackPressIfNeeded(); + } return true; } if (mKeyguardUserSwitcher != null && mKeyguardUserSwitcher.hideIfNotSimple(true)) { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java index f813ac693d42..58701e72e406 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java @@ -17,15 +17,21 @@ package com.android.keyguard.clock; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.database.ContentObserver; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; -import android.testing.LeakCheck; import android.testing.TestableLooper.RunWithLooper; +import android.view.LayoutInflater; import com.android.systemui.SysuiTestCase; +import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerFake; -import com.android.systemui.utils.leaks.FakeExtensionController; +import com.android.systemui.util.InjectionInflationController; import org.junit.After; import org.junit.Before; @@ -39,21 +45,31 @@ import org.mockito.MockitoAnnotations; @RunWithLooper public final class ClockManagerTest extends SysuiTestCase { + private static final String BUBBLE_CLOCK = BubbleClockController.class.getName(); + private static final Class<?> BUBBLE_CLOCK_CLASS = BubbleClockController.class; + private ClockManager mClockManager; - private LeakCheck mLeakCheck; - private FakeExtensionController mFakeExtensionController; + private ContentObserver mContentObserver; private DockManagerFake mFakeDockManager; + @Mock InjectionInflationController mMockInjectionInflationController; + @Mock SysuiColorExtractor mMockColorExtractor; + @Mock ContentResolver mMockContentResolver; + @Mock SettingsWrapper mMockSettingsWrapper; @Mock ClockManager.ClockChangedListener mMockListener; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mLeakCheck = new LeakCheck(); - mFakeExtensionController = new FakeExtensionController(mLeakCheck); + + LayoutInflater inflater = LayoutInflater.from(getContext()); + when(mMockInjectionInflationController.injectable(any())).thenReturn(inflater); + mFakeDockManager = new DockManagerFake(); - mClockManager = new ClockManager(getContext(), mFakeExtensionController, - mFakeDockManager); + mClockManager = new ClockManager(getContext(), mMockInjectionInflationController, + mFakeDockManager, mMockColorExtractor, mMockContentResolver, mMockSettingsWrapper); + mClockManager.addOnClockChangedListener(mMockListener); + mContentObserver = mClockManager.getContentObserver(); } @After @@ -72,4 +88,76 @@ public final class ClockManagerTest extends SysuiTestCase { mFakeDockManager.setDockEvent(DockManager.STATE_NONE); assertThat(mClockManager.isDocked()).isFalse(); } + + @Test + public void getCurrentClock_default() { + // GIVEN that settings doesn't contain any values + when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(null); + when(mMockSettingsWrapper.getDockedClockFace()).thenReturn(null); + // WHEN settings change event is fired + mContentObserver.onChange(false); + // THEN the result is null, indicated the default clock face should be used. + assertThat(mClockManager.getCurrentClock()).isNull(); + } + + @Test + public void getCurrentClock_customClock() { + // GIVEN that settings is set to the bubble clock face + when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(BUBBLE_CLOCK); + // WHEN settings change event is fired + mContentObserver.onChange(false); + // THEN the plugin is the bubble clock face. + assertThat(mClockManager.getCurrentClock()).isInstanceOf(BUBBLE_CLOCK_CLASS); + } + + @Test + public void getCurrentClock_badSettingsValue() { + // GIVEN that settings contains a value that doesn't correspond to a + // custom clock face. + when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn("bad value"); + // WHEN settings change event is fired + mContentObserver.onChange(false); + // THEN the result is null. + assertThat(mClockManager.getCurrentClock()).isNull(); + } + + @Test + public void getCurrentClock_dockedDefault() { + // WHEN dock event is fired + mFakeDockManager.setDockEvent(DockManager.STATE_DOCKED); + // THEN the result is null, indicating the default clock face. + assertThat(mClockManager.getCurrentClock()).isNull(); + } + + @Test + public void getCurrentClock_dockedCustomClock() { + // GIVEN settings is set to the bubble clock face + when(mMockSettingsWrapper.getDockedClockFace()).thenReturn(BUBBLE_CLOCK); + // WHEN dock event fires + mFakeDockManager.setDockEvent(DockManager.STATE_DOCKED); + // THEN the plugin is the bubble clock face. + assertThat(mClockManager.getCurrentClock()).isInstanceOf(BUBBLE_CLOCK_CLASS); + } + + @Test + public void getCurrentClock_badDockedSettingsValue() { + // GIVEN settings contains a value that doesn't correspond to an available clock face. + when(mMockSettingsWrapper.getDockedClockFace()).thenReturn("bad value"); + // WHEN dock event fires + mFakeDockManager.setDockEvent(DockManager.STATE_DOCKED); + // THEN the result is null. + assertThat(mClockManager.getCurrentClock()).isNull(); + } + + @Test + public void getCurrentClock_badDockedSettingsFallback() { + // GIVEN settings contains a value that doesn't correspond to an available clock face, but + // locked screen settings is set to bubble clock. + when(mMockSettingsWrapper.getDockedClockFace()).thenReturn("bad value"); + when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(BUBBLE_CLOCK); + // WHEN dock event is fired + mFakeDockManager.setDockEvent(DockManager.STATE_DOCKED); + // THEN the plugin is the bubble clock face. + assertThat(mClockManager.getCurrentClock()).isInstanceOf(BUBBLE_CLOCK_CLASS); + } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/DefaultClockSupplierTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/DefaultClockSupplierTest.java deleted file mode 100644 index 1a3b198ac0d6..000000000000 --- a/packages/SystemUI/tests/src/com/android/keyguard/clock/DefaultClockSupplierTest.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.keyguard.clock; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.when; - -import android.test.suitebuilder.annotation.SmallTest; -import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper.RunWithLooper; -import android.view.LayoutInflater; - -import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.ClockPlugin; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -@RunWithLooper -public final class DefaultClockSupplierTest extends SysuiTestCase { - - private static final String BUBBLE_CLOCK = BubbleClockController.class.getName(); - private static final Class<?> BUBBLE_CLOCK_CLASS = BubbleClockController.class; - - private DefaultClockSupplier mDefaultClockSupplier; - @Mock SettingsWrapper mMockSettingsWrapper; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mDefaultClockSupplier = new DefaultClockSupplier(mMockSettingsWrapper, - LayoutInflater.from(getContext())); - } - - @Test - public void get_default() { - // GIVEN that settings doesn't contain any values - when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(null); - when(mMockSettingsWrapper.getDockedClockFace()).thenReturn(null); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the result is null, indicated the default clock face should be used. - assertThat(plugin).isNull(); - } - - @Test - public void get_customClock() { - // GIVEN that settings is set to the bubble clock face - when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(BUBBLE_CLOCK); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the plugin is the bubble clock face. - assertThat(plugin).isInstanceOf(BUBBLE_CLOCK_CLASS); - } - - @Test - public void get_badSettingsValue() { - // GIVEN that settings contains a value that doesn't correspond to a - // custom clock face. - when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn("bad value"); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the result is null. - assertThat(plugin).isNull(); - } - - @Test - public void get_dockedDefault() { - // GIVEN docked - mDefaultClockSupplier.setDocked(true); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the result is null, indicating the default clock face. - assertThat(plugin).isNull(); - } - - @Test - public void get_dockedCustomClock() { - // GIVEN docked and settings is set to the bubble clock face - mDefaultClockSupplier.setDocked(true); - when(mMockSettingsWrapper.getDockedClockFace()).thenReturn(BUBBLE_CLOCK); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the plugin is the bubble clock face. - assertThat(plugin).isInstanceOf(BUBBLE_CLOCK_CLASS); - } - - @Test - public void get_badDockedSettingsValue() { - // GIVEN docked and settings contains a value that doesn't correspond to - // an available clock face. - mDefaultClockSupplier.setDocked(true); - when(mMockSettingsWrapper.getDockedClockFace()).thenReturn("bad value"); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the result is null. - assertThat(plugin).isNull(); - } - - @Test - public void get_badDockedSettingsFallback() { - // GIVEN docked and settings contains a value that doesn't correspond to - // an available clock face, but locked screen settings is set to bubble - // clock. - mDefaultClockSupplier.setDocked(true); - when(mMockSettingsWrapper.getDockedClockFace()).thenReturn("bad value"); - when(mMockSettingsWrapper.getLockScreenCustomClockFace()).thenReturn(BUBBLE_CLOCK); - // WHEN get is called - ClockPlugin plugin = mDefaultClockSupplier.get(); - // THEN the plugin is the bubble clock face. - assertThat(plugin).isInstanceOf(BUBBLE_CLOCK_CLASS); - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java index dfaa76a58e2d..99dc9f87520f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java @@ -99,7 +99,11 @@ public class NotificationContentInflaterTest extends SysuiTestCase { public void testIncreasedHeadsUpBeingUsed() { mNotificationInflater.setUsesIncreasedHeadsUpHeight(true); Notification.Builder builder = spy(mBuilder); - mNotificationInflater.inflateNotificationViews(FLAG_CONTENT_VIEW_ALL, builder, mContext); + mNotificationInflater.inflateNotificationViews( + false /* inflateSynchronously */, + FLAG_CONTENT_VIEW_ALL, + builder, + mContext); verify(builder).createHeadsUpContentView(true); } @@ -107,7 +111,11 @@ public class NotificationContentInflaterTest extends SysuiTestCase { public void testIncreasedHeightBeingUsed() { mNotificationInflater.setUsesIncreasedHeight(true); Notification.Builder builder = spy(mBuilder); - mNotificationInflater.inflateNotificationViews(FLAG_CONTENT_VIEW_ALL, builder, mContext); + mNotificationInflater.inflateNotificationViews( + false /* inflateSynchronously */, + FLAG_CONTENT_VIEW_ALL, + builder, + mContext); verify(builder).createContentView(true); } @@ -163,7 +171,11 @@ public class NotificationContentInflaterTest extends SysuiTestCase { new NotificationContentInflater.InflationProgress(); result.packageContext = mContext; CountDownLatch countDownLatch = new CountDownLatch(1); - NotificationContentInflater.applyRemoteView(result, FLAG_CONTENT_VIEW_EXPANDED, 0, + NotificationContentInflater.applyRemoteView( + false /* inflateSynchronously */, + result, + FLAG_CONTENT_VIEW_EXPANDED, + 0, new ArrayMap() /* cachedContentViews */, mRow, false /* redactAmbient */, true /* isNewView */, (v, p, r) -> true, new InflationCallback() { @@ -246,6 +258,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase { NotificationContentInflater inflater) throws Exception { CountDownLatch countDownLatch = new CountDownLatch(1); final ExceptionHolder exceptionHolder = new ExceptionHolder(); + inflater.setInflateSynchronously(true); inflater.setInflationCallback(new InflationCallback() { @Override public void handleInflationException(StatusBarNotification notification, @@ -265,11 +278,6 @@ public class NotificationContentInflaterTest extends SysuiTestCase { } countDownLatch.countDown(); } - - @Override - public boolean doInflateSynchronous() { - return true; - } }); block.run(); assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS)); diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java index 4254a0ba200a..2e40c1acfa2c 100644 --- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java +++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java @@ -115,8 +115,10 @@ public class WallpaperBackupAgent extends BackupAgent { // We always back up this 'empty' file to ensure that the absence of // storable wallpaper imagery still produces a non-empty backup data // stream, otherwise it'd simply be ignored in preflight. - FileOutputStream touch = new FileOutputStream(empty); - touch.close(); + if (!empty.exists()) { + FileOutputStream touch = new FileOutputStream(empty); + touch.close(); + } fullBackupFile(empty, data); SharedPreferences prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk index 1294dbbbfa87..7ce13c2f59e9 100644 --- a/packages/overlays/Android.mk +++ b/packages/overlays/Android.mk @@ -44,6 +44,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := frameworks-base-overlays-debug LOCAL_REQUIRED_MODULES := \ ExperimentNavigationBarFloatingOverlay \ + ExperimentNavigationBarVisualInsetOverlay \ ExperimentNavigationBarDefaultOverlay \ ExperimentNavigationBarSlimOverlay32 \ ExperimentNavigationBarSlimOverlay40 \ diff --git a/tools/aapt2/integration-tests/StaticLibTest/LibTwo/Android.mk b/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/Android.mk index 27a3134e6ffa..56bf51642c9d 100644 --- a/tools/aapt2/integration-tests/StaticLibTest/LibTwo/Android.mk +++ b/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/Android.mk @@ -1,11 +1,11 @@ # -# Copyright (C) 2016 The Android Open Source Project +# Copyright 2018, The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -14,15 +14,17 @@ # limitations under the License. # -LOCAL_PATH := $(call my-dir) - +LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_USE_AAPT2 := true -LOCAL_MODULE := AaptTestStaticLib_LibTwo -LOCAL_SDK_VERSION := current -LOCAL_MODULE_TAGS := tests -LOCAL_SRC_FILES := $(call all-java-files-under,src) + +LOCAL_RRO_THEME := ExperimentNavigationBarVisualInset +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res -LOCAL_SHARED_ANDROID_LIBRARIES := AaptTestStaticLib_LibOne -include $(BUILD_STATIC_JAVA_LIBRARY) +LOCAL_PACKAGE_NAME := ExperimentNavigationBarVisualInsetOverlay +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE)
\ No newline at end of file diff --git a/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/AndroidManifest.xml b/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/AndroidManifest.xml new file mode 100644 index 000000000000..3ea5dc4716ff --- /dev/null +++ b/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/AndroidManifest.xml @@ -0,0 +1,27 @@ +<!-- +/** + * Copyright (c) 2018, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.internal.experiment.navbar.type.inset" + android:versionCode="1" + android:versionName="1.0"> + <overlay android:targetPackage="android" + android:category="com.android.internal.experiment_navbar_visual_inset" + android:priority="1"/> + + <application android:label="@string/experiment_navigationbar_overlay" android:hasCode="false"/> +</manifest>
\ No newline at end of file diff --git a/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/res/values/config.xml b/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/res/values/config.xml new file mode 100644 index 000000000000..d35a744e4e59 --- /dev/null +++ b/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/res/values/config.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2018, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources> + <!-- Height of the bottom navigation / system bar. --> + <dimen name="navigation_bar_height">16dp</dimen> + <!-- Width of the navigation bar when it is placed vertically on the screen --> + <dimen name="navigation_bar_width">16dp</dimen> +</resources>
\ No newline at end of file diff --git a/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/res/values/strings.xml b/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/res/values/strings.xml new file mode 100644 index 000000000000..84dfcb76706b --- /dev/null +++ b/packages/overlays/ExperimentNavigationBarVisualInsetOverlay/res/values/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2018, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Name of overlay [CHAR LIMIT=64] --> + <string name="experiment_navigationbar_overlay" translatable="false">Visual Inset Navigation Bar</string> +</resources>
\ No newline at end of file diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 81209763d3a8..fd946cdfa48a 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -237,7 +237,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private PhoneCapability mPhoneCapability = null; - private int mPreferredDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + private int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; @TelephonyManager.RadioPowerState private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE; @@ -257,7 +257,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { static final int ENFORCE_PHONE_STATE_PERMISSION_MASK = PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR - | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST; + | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST + | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBID_CHANGE; static final int PRECISE_PHONE_STATE_PERMISSION_MASK = PhoneStateListener.LISTEN_PRECISE_CALL_STATE | @@ -819,9 +820,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } - if ((events & PhoneStateListener.LISTEN_PREFERRED_DATA_SUBID_CHANGE) != 0) { + if ((events & PhoneStateListener.LISTEN_ACTIVE_DATA_SUBID_CHANGE) != 0) { try { - r.callback.onPreferredDataSubIdChanged(mPreferredDataSubId); + r.callback.onActiveDataSubIdChanged(mActiveDataSubId); } catch (RemoteException ex) { remove(r.binder); } @@ -1757,23 +1758,23 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - public void notifyPreferredDataSubIdChanged(int preferredSubId) { - if (!checkNotifyPermission("notifyPreferredDataSubIdChanged()")) { + public void notifyActiveDataSubIdChanged(int activeDataSubId) { + if (!checkNotifyPermission("notifyActiveDataSubIdChanged()")) { return; } if (VDBG) { - log("notifyPreferredDataSubIdChanged: preferredSubId=" + preferredSubId); + log("notifyActiveDataSubIdChanged: activeDataSubId=" + activeDataSubId); } synchronized (mRecords) { - mPreferredDataSubId = preferredSubId; + mActiveDataSubId = activeDataSubId; for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_PREFERRED_DATA_SUBID_CHANGE)) { + PhoneStateListener.LISTEN_ACTIVE_DATA_SUBID_CHANGE)) { try { - r.callback.onPreferredDataSubIdChanged(preferredSubId); + r.callback.onActiveDataSubIdChanged(activeDataSubId); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -1909,7 +1910,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mBackgroundCallState=" + mBackgroundCallState); pw.println("mSrvccState=" + mSrvccState); pw.println("mPhoneCapability=" + mPhoneCapability); - pw.println("mPreferredDataSubId=" + mPreferredDataSubId); + pw.println("mActiveDataSubId=" + mActiveDataSubId); pw.println("mRadioPowerState=" + mRadioPowerState); pw.println("mEmergencyNumberList=" + mEmergencyNumberList); pw.println("mCallQuality=" + mCallQuality); @@ -2181,14 +2182,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); } - if ((events & PhoneStateListener.LISTEN_PREFERRED_DATA_SUBID_CHANGE) != 0) { - // It can have either READ_PHONE_STATE or READ_PRIVILEGED_PHONE_STATE. - TelephonyPermissions.checkReadPhoneState(mContext, - SubscriptionManager.INVALID_SUBSCRIPTION_ID, Binder.getCallingPid(), - Binder.getCallingUid(), callingPackage, "listen to " - + "LISTEN_PREFERRED_DATA_SUBID_CHANGE"); - } - if ((events & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PRECISE_PHONE_STATE, null); diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 026430b5469d..aebe2b78a853 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -319,10 +319,6 @@ public final class ActiveServices { ServiceRecord r = mDelayedStartList.remove(0); if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (exec next): " + r); - if (r.pendingStarts.size() <= 0) { - Slog.w(TAG, "**** NO PENDING STARTS! " + r + " startReq=" + r.startRequested - + " delayedStop=" + r.delayedStop); - } if (DEBUG_DELAYED_SERVICE) { if (mDelayedStartList.size() > 0) { Slog.v(TAG_SERVICE, "Remaining delayed list:"); @@ -332,11 +328,16 @@ public final class ActiveServices { } } r.delayed = false; - try { - startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true, - false); - } catch (TransactionTooLargeException e) { - // Ignore, nobody upstack cares. + if (r.pendingStarts.size() <= 0) { + Slog.wtf(TAG, "**** NO PENDING STARTS! " + r + " startReq=" + r.startRequested + + " delayedStop=" + r.delayedStop); + } else { + try { + startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true, + false); + } catch (TransactionTooLargeException e) { + // Ignore, nobody upstack cares. + } } } if (mStartingBackground.size() > 0) { @@ -2978,6 +2979,7 @@ public final class ActiveServices { // Clear start entries. r.clearDeliveredStartsLocked(); r.pendingStarts.clear(); + smap.mDelayedStartList.remove(r); if (r.app != null) { synchronized (r.stats.getBatteryStats()) { diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java index 8ffb67a1405c..06d015234011 100644 --- a/services/core/java/com/android/server/am/CoreSettingsObserver.java +++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java @@ -79,6 +79,7 @@ final class CoreSettingsObserver extends ContentObserver { sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_BLACKLIST, String.class); sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_WHITELIST, String.class); sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_BLACKLISTS, String.class); + sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, String.class); // add other global settings here... } diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 0d49e4cdc9d0..e1f2651b1ecf 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -1498,6 +1498,13 @@ public final class ProcessList { // Also turn on CheckJNI for debuggable apps. It's quite // awkward to turn on otherwise. runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; + + // Check if the developer does not want ART verification + if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(), + android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) { + runtimeFlags |= Zygote.DISABLE_VERIFIER; + Slog.w(TAG_PROCESSES, app + ": ART verification disabled"); + } } // Run the app in safe mode if its manifest requests so or the // system is booted in safe mode. diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index e12d1dc92714..8051abbdd417 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -27,6 +27,7 @@ import android.content.pm.PackageParser; import android.content.pm.PackageParser.PackageParserException; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.ServiceManager.ServiceNotFoundException; import android.util.Slog; import com.android.internal.util.IndentingPrintWriter; @@ -50,8 +51,12 @@ class ApexManager { private final Map<String, PackageInfo> mActivePackagesCache; ApexManager() { - mApexService = IApexService.Stub.asInterface( - ServiceManager.getService("apexservice")); + try { + mApexService = IApexService.Stub.asInterface( + ServiceManager.getServiceOrThrow("apexservice")); + } catch (ServiceNotFoundException e) { + throw new IllegalStateException("Required service apexservice not available"); + } mActivePackagesCache = populateActivePackagesCache(); } @@ -151,7 +156,7 @@ class ApexManager { } /** - * Mark a staged session previously submitted using {@cde submitStagedSession} as ready to be + * Mark a staged session previously submitted using {@code submitStagedSession} as ready to be * applied at next reboot. * * @param sessionId the identifier of the {@link PackageInstallerSession} being marked as ready. @@ -227,8 +232,6 @@ class ApexManager { ipw.println("State: STAGED"); } else if (si.isActivated) { ipw.println("State: ACTIVATED"); - } else if (si.isActivationPendingRetry) { - ipw.println("State: ACTIVATION PENDING RETRY"); } else if (si.isActivationFailed) { ipw.println("State: ACTIVATION FAILED"); } diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS index 640b155e69d5..8ce2568ac3e2 100644 --- a/services/core/java/com/android/server/pm/OWNERS +++ b/services/core/java/com/android/server/pm/OWNERS @@ -9,6 +9,10 @@ svetoslavganov@google.com toddke@android.com toddke@google.com +# apex support +per-file ApexManager.java = dariofreni@google.com, narayan@google.com, toddke@android.com, toddke@google.com +per-file StagingManager.java = dariofreni@google.com, narayan@google.com, toddke@android.com, toddke@google.com + # dex per-file AbstractStatsBase.java = agampe@google.com per-file AbstractStatsBase.java = calin@google.com diff --git a/services/core/java/com/android/server/rollback/TEST_MAPPING b/services/core/java/com/android/server/rollback/TEST_MAPPING index c1d95ac85c23..6be93a0a199b 100644 --- a/services/core/java/com/android/server/rollback/TEST_MAPPING +++ b/services/core/java/com/android/server/rollback/TEST_MAPPING @@ -2,6 +2,9 @@ "presubmit": [ { "name": "RollbackTest" + }, + { + "name": "StagedRollbackTest" } ] } diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index d40948b305a2..538813e9b21c 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -98,6 +98,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Rect; import android.os.Binder; import android.os.Bundle; @@ -115,6 +116,7 @@ import android.util.Pools.SynchronizedPool; import android.util.Slog; import android.widget.Toast; +import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.IVoiceInteractor; @@ -761,11 +763,11 @@ class ActivityStarter { abort |= (abortBackgroundStart && !mService.isBackgroundActivityStartsEnabled()); // TODO: remove this toast after feature development is done if (abortBackgroundStart) { - final String toastMsg = abort - ? "Background activity start from " + callingPackage - + " blocked. See go/q-bg-block." - : "This background activity start from " + callingPackage - + " will be blocked in future Q builds. See go/q-bg-block."; + final Resources res = mService.mContext.getResources(); + final String toastMsg = res.getString(abort + ? R.string.activity_starter_block_bg_activity_starts_enforcing + : R.string.activity_starter_block_bg_activity_starts_permissive, + callingPackage); mService.mUiHandler.post(() -> { Toast.makeText(mService.mContext, toastMsg, Toast.LENGTH_LONG).show(); }); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 258819fdece9..57dff893ecb1 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -2467,7 +2467,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } final Rect destBounds = new Rect(); stack.getAnimationOrCurrentBounds(destBounds); - if (!destBounds.isEmpty() || !destBounds.equals(compareBounds)) { + if (destBounds.isEmpty() || !destBounds.equals(compareBounds)) { Slog.w(TAG, "The current stack bounds does not matched! It may be obsolete."); return; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 9523202cbb0e..ae48dad7b8f9 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -5181,7 +5181,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = mInjector.userHandleGetCallingUserId(); synchronized (getLockObject()) { - ActiveAdmin ap = getActiveAdminForCallerLocked( + final ActiveAdmin ap = getActiveAdminForCallerLocked( who, DeviceAdminInfo.USES_POLICY_FORCE_LOCK, parent); if (ap.maximumTimeToUnlock != timeMs) { ap.maximumTimeToUnlock = timeMs; @@ -8388,7 +8388,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return true; } - Log.w(LOG_TAG, String.format("Package if %s (uid=%d, pid=%d) cannot access Device IDs", + Log.w(LOG_TAG, String.format("Package %s (uid=%d, pid=%d) cannot access Device IDs", packageName, uid, pid)); return false; } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java index dcca3167c752..42a205a2fb3d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java @@ -100,7 +100,7 @@ public class TaskStackChangedListenerTest { } @Test - @FlakyTest(bugId = 119893767) + @FlakyTest(detail = "Promote to presubmit when shown to be stable.") public void testTaskDescriptionChanged() throws Exception { final Object[] params = new Object[2]; final CountDownLatch latch = new CountDownLatch(1); @@ -122,14 +122,18 @@ public class TaskStackChangedListenerTest { } } }); - final Activity activity = startTestActivity(ActivityTaskDescriptionChange.class); + + int taskId; + synchronized (sLock) { + taskId = startTestActivity(ActivityTaskDescriptionChange.class).getTaskId(); + } waitForCallback(latch); - assertEquals(activity.getTaskId(), params[0]); + assertEquals(taskId, params[0]); assertEquals("Test Label", ((TaskDescription) params[1]).getLabel()); } @Test - @FlakyTest(bugId = 119893767) + @FlakyTest(detail = "Promote to presubmit when shown to be stable.") public void testActivityRequestedOrientationChanged() throws Exception { final int[] params = new int[2]; final CountDownLatch latch = new CountDownLatch(1); @@ -142,9 +146,12 @@ public class TaskStackChangedListenerTest { latch.countDown(); } }); - final Activity activity = startTestActivity(ActivityRequestedOrientationChange.class); + int taskId; + synchronized (sLock) { + taskId = startTestActivity(ActivityRequestedOrientationChange.class).getTaskId(); + } waitForCallback(latch); - assertEquals(activity.getTaskId(), params[0]); + assertEquals(taskId, params[0]); assertEquals(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, params[1]); } @@ -152,7 +159,7 @@ public class TaskStackChangedListenerTest { * Tests for onTaskCreated, onTaskMovedToFront, onTaskRemoved and onTaskRemovalStarted. */ @Test - @FlakyTest(bugId = 119893767) + @FlakyTest(detail = "Promote to presubmit when shown to be stable.") public void testTaskChangeCallBacks() throws Exception { final Object[] params = new Object[2]; final CountDownLatch taskCreatedLaunchLatch = new CountDownLatch(1); @@ -245,7 +252,7 @@ public class TaskStackChangedListenerTest { private void waitForCallback(CountDownLatch latch) { try { - final boolean result = latch.await(2, TimeUnit.SECONDS); + final boolean result = latch.await(4, TimeUnit.SECONDS); if (!result) { throw new RuntimeException("Timed out waiting for task stack change notification"); } @@ -324,7 +331,11 @@ public class TaskStackChangedListenerTest { protected void onPostResume() { super.onPostResume(); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - finish(); + synchronized (sLock) { + // Hold the lock to ensure no one is trying to access fields of this Activity in + // this test. + finish(); + } } } @@ -333,7 +344,11 @@ public class TaskStackChangedListenerTest { protected void onPostResume() { super.onPostResume(); setTaskDescription(new TaskDescription("Test Label")); - finish(); + synchronized (sLock) { + // Hold the lock to ensure no one is trying to access fields of this Activity in + // this test. + finish(); + } } } diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java index 0eb991777d74..16791a4b8680 100644 --- a/telecomm/java/android/telecom/Log.java +++ b/telecomm/java/android/telecom/Log.java @@ -18,7 +18,6 @@ package android.telecom; import android.content.Context; import android.net.Uri; -import android.os.AsyncTask; import android.os.Build; import android.telecom.Logging.EventManager; import android.telecom.Logging.Session; @@ -29,8 +28,6 @@ import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.IllegalFormatException; import java.util.Locale; @@ -373,6 +370,12 @@ public class Log { return FORCE_LOGGING || android.util.Log.isLoggable(TAG, level); } + /** + * Generates an obfuscated string for a calling handle in {@link Uri} format, or a raw phone + * phone number in {@link String} format. + * @param pii The information to obfuscate. + * @return The obfuscated string. + */ public static String piiHandle(Object pii) { if (pii == null || VERBOSE) { return String.valueOf(pii); @@ -389,16 +392,7 @@ public class Log { String textToObfuscate = uri.getSchemeSpecificPart(); if (PhoneAccount.SCHEME_TEL.equals(scheme)) { - int numDigitsToObfuscate = getDialableCount(textToObfuscate) - - NUM_DIALABLE_DIGITS_TO_LOG; - for (int i = 0; i < textToObfuscate.length(); i++) { - char c = textToObfuscate.charAt(i); - boolean isDialable = PhoneNumberUtils.isDialable(c); - if (isDialable) { - numDigitsToObfuscate--; - } - sb.append(isDialable && numDigitsToObfuscate >= 0 ? "*" : c); - } + obfuscatePhoneNumber(sb, textToObfuscate); } else if (PhoneAccount.SCHEME_SIP.equals(scheme)) { for (int i = 0; i < textToObfuscate.length(); i++) { char c = textToObfuscate.charAt(i); @@ -410,12 +404,34 @@ public class Log { } else { sb.append(pii(pii)); } + } else if (pii instanceof String) { + String number = (String) pii; + obfuscatePhoneNumber(sb, number); } return sb.toString(); } /** + * Obfuscates a phone number, allowing NUM_DIALABLE_DIGITS_TO_LOG digits to be exposed for the + * phone number. + * @param sb String buffer to write obfuscated number to. + * @param phoneNumber The number to obfuscate. + */ + private static void obfuscatePhoneNumber(StringBuilder sb, String phoneNumber) { + int numDigitsToObfuscate = getDialableCount(phoneNumber) + - NUM_DIALABLE_DIGITS_TO_LOG; + for (int i = 0; i < phoneNumber.length(); i++) { + char c = phoneNumber.charAt(i); + boolean isDialable = PhoneNumberUtils.isDialable(c); + if (isDialable) { + numDigitsToObfuscate--; + } + sb.append(isDialable && numDigitsToObfuscate >= 0 ? "*" : c); + } + } + + /** * Determines the number of dialable characters in a string. * @param toCount The string to count dialable characters in. * @return The count of dialable characters. diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java index 24db438580c9..d98f37d976df 100644 --- a/telephony/java/android/telephony/LocationAccessPolicy.java +++ b/telephony/java/android/telephony/LocationAccessPolicy.java @@ -42,7 +42,7 @@ import java.util.List; public final class LocationAccessPolicy { private static final String TAG = "LocationAccessPolicy"; private static final boolean DBG = false; - public static final int MAX_SDK_FOR_ANY_ENFORCEMENT = Build.VERSION_CODES.P; + public static final int MAX_SDK_FOR_ANY_ENFORCEMENT = Build.VERSION_CODES.CUR_DEVELOPMENT; public enum LocationPermissionResult { ALLOWED, @@ -198,14 +198,14 @@ public final class LocationAccessPolicy { // If the app fails for some reason, see if it should be allowed to proceed. if (minSdkVersion > MAX_SDK_FOR_ANY_ENFORCEMENT) { String errorMsg = "Allowing " + query.callingPackage + " " + locationTypeForLog - + " because we're not enforcing API " + query.minSdkVersionForFine + " yet." + + " because we're not enforcing API " + minSdkVersion + " yet." + " Please fix this app because it will break in the future. Called from " + query.method; logError(context, errorMsg); return null; } else if (!isAppAtLeastSdkVersion(context, query.callingPackage, minSdkVersion)) { String errorMsg = "Allowing " + query.callingPackage + " " + locationTypeForLog - + " because it doesn't target API " + query.minSdkVersionForFine + " yet." + + " because it doesn't target API " + minSdkVersion + " yet." + " Please fix this app. Called from " + query.method; logError(context, errorMsg); return null; diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 3ce646cb400b..ffebc04c39e6 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -297,14 +297,17 @@ public class PhoneStateListener { public static final int LISTEN_PHONE_CAPABILITY_CHANGE = 0x00200000; /** - * Listen for changes to preferred data subId. - * See {@link SubscriptionManager#setPreferredDataSubId(int)} - * for more details. + * Listen for changes to active data subId. Active data subscription + * is whichever is being used for Internet data. For most of the case, it's + * default data subscription but it could be others. For example, when data is + * switched to opportunistic subscription, that becomes the active data sub. * - * @see #onPreferredDataSubIdChanged + * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE + * READ_PHONE_STATE} + * @see #onActiveDataSubIdChanged * @hide */ - public static final int LISTEN_PREFERRED_DATA_SUBID_CHANGE = 0x00400000; + public static final int LISTEN_ACTIVE_DATA_SUBID_CHANGE = 0x00400000; /** * Listen for changes to the radio power state. @@ -710,14 +713,14 @@ public class PhoneStateListener { } /** - * Callback invoked when preferred data subId changes. Requires - * the READ_PRIVILEGED_PHONE_STATE permission. - * @param subId the new preferred data subId. If it's INVALID_SUBSCRIPTION_ID, - * it means it's unset and defaultDataSub is used to determine which - * modem is preferred. + * Callback invoked when active data subId changes. Requires + * the READ_PHONE_STATE permission. + * @param subId current data subId used for Internet data. It will be default data subscription + * most cases. And it could be other subscriptions for example opportunistic + * subscription if data is switched onto it. * @hide */ - public void onPreferredDataSubIdChanged(int subId) { + public void onActiveDataSubIdChanged(int subId) { // default implementation empty } @@ -1001,12 +1004,12 @@ public class PhoneStateListener { () -> mExecutor.execute(() -> psl.onCallAttributesChanged(callAttributes))); } - public void onPreferredDataSubIdChanged(int subId) { + public void onActiveDataSubIdChanged(int subId) { PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); if (psl == null) return; Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onPreferredDataSubIdChanged(subId))); + () -> mExecutor.execute(() -> psl.onActiveDataSubIdChanged(subId))); } public void onImsCallDisconnectCauseChanged(ImsReasonInfo disconnectCause) { diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index d5c70793d3bc..47c8de52820e 100644 --- a/telephony/java/android/telephony/ims/ImsCallProfile.java +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -548,7 +548,8 @@ public final class ImsCallProfile implements Parcelable { + ", emergencyServiceCategories=" + mEmergencyServiceCategories + ", emergencyUrns=" + mEmergencyUrns + ", emergencyCallRouting=" + mEmergencyCallRouting - + ", emergencyCallTesting=" + mEmergencyCallTesting + " }"; + + ", emergencyCallTesting=" + mEmergencyCallTesting + + ", hasKnownUserIntentEmergency=" + mHasKnownUserIntentEmergency + " }"; } @Override @@ -567,6 +568,7 @@ public final class ImsCallProfile implements Parcelable { out.writeStringList(mEmergencyUrns); out.writeInt(mEmergencyCallRouting); out.writeBoolean(mEmergencyCallTesting); + out.writeBoolean(mHasKnownUserIntentEmergency); } private void readFromParcel(Parcel in) { @@ -578,6 +580,7 @@ public final class ImsCallProfile implements Parcelable { mEmergencyUrns = in.createStringArrayList(); mEmergencyCallRouting = in.readInt(); mEmergencyCallTesting = in.readBoolean(); + mHasKnownUserIntentEmergency = in.readBoolean(); } public static final Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() { diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl index 322ce45797ec..4a263f060ca5 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -54,7 +54,7 @@ oneway interface IPhoneStateListener { void onCarrierNetworkChange(in boolean active); void onUserMobileDataStateChanged(in boolean enabled); void onPhoneCapabilityChanged(in PhoneCapability capability); - void onPreferredDataSubIdChanged(in int subId); + void onActiveDataSubIdChanged(in int subId); void onRadioPowerStateChanged(in int state); void onCallAttributesChanged(in CallAttributes callAttributes); void onEmergencyNumberListChanged(in Map emergencyNumberList); diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index e9eba324acb0..a922ab601442 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -81,7 +81,7 @@ interface ITelephonyRegistry { void notifyCarrierNetworkChange(in boolean active); void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state); void notifyPhoneCapabilityChanged(in PhoneCapability capability); - void notifyPreferredDataSubIdChanged(int preferredSubId); + void notifyActiveDataSubIdChanged(int activeDataSubId); void notifyRadioPowerStateChanged(in int state); void notifyEmergencyNumberList(); void notifyCallQualityChanged(in CallQuality callQuality, int phoneId); diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java index cb6a83d2644b..39608a40b416 100644 --- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java +++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java @@ -56,7 +56,7 @@ public class ColorExtractorTest { @Test public void ColorExtractor_extractWhenInitialized() { ExtractionType type = mock(Tonal.class); - new ColorExtractor(mContext, type); + new ColorExtractor(mContext, type, true); // 1 for lock and 1 for system verify(type, times(2)) .extractInto(any(), any(), any(), any()); @@ -83,7 +83,7 @@ public class ColorExtractorTest { outGradientColorsDark.set(colorsExpectedDark); outGradientColorsExtraDark.set(colorsExpectedExtraDark); }; - ColorExtractor extractor = new ColorExtractor(mContext, type); + ColorExtractor extractor = new ColorExtractor(mContext, type, true); GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM, ColorExtractor.TYPE_NORMAL); @@ -98,7 +98,7 @@ public class ColorExtractorTest { public void addOnColorsChangedListener_invokesListener() { ColorExtractor.OnColorsChangedListener mockedListeners = mock(ColorExtractor.OnColorsChangedListener.class); - ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext)); + ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext), true); extractor.addOnColorsChangedListener(mockedListeners); extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null), diff --git a/tests/RollbackTest/TEST_MAPPING b/tests/RollbackTest/TEST_MAPPING index c1d95ac85c23..6be93a0a199b 100644 --- a/tests/RollbackTest/TEST_MAPPING +++ b/tests/RollbackTest/TEST_MAPPING @@ -2,6 +2,9 @@ "presubmit": [ { "name": "RollbackTest" + }, + { + "name": "StagedRollbackTest" } ] } diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index c1887822ce7d..d0237f80a8f0 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -1637,7 +1637,9 @@ bool ResourceParser::ParsePlural(xml::XmlPullParser* parser, if (!(plural->values[index] = ParseXml( parser, android::ResTable_map::TYPE_STRING, kNoRawString))) { error = true; + continue; } + plural->values[index]->SetSource(item_source); } else if (!ShouldIgnoreElement(element_namespace, element_name)) { diff --git a/tools/aapt2/integration-tests/Android.mk b/tools/aapt2/integration-tests/Android.mk deleted file mode 100644 index 6361f9b8ae7d..000000000000 --- a/tools/aapt2/integration-tests/Android.mk +++ /dev/null @@ -1,2 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tools/aapt2/integration-tests/AutoVersionTest/Android.bp b/tools/aapt2/integration-tests/AutoVersionTest/Android.bp new file mode 100644 index 000000000000..79fb5734cd68 --- /dev/null +++ b/tools/aapt2/integration-tests/AutoVersionTest/Android.bp @@ -0,0 +1,20 @@ +// +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +android_test { + name: "AaptAutoVersionTest", + sdk_version: "current", +} diff --git a/tools/aapt2/integration-tests/BasicTest/Android.bp b/tools/aapt2/integration-tests/BasicTest/Android.bp new file mode 100644 index 000000000000..a94a01f12c9e --- /dev/null +++ b/tools/aapt2/integration-tests/BasicTest/Android.bp @@ -0,0 +1,20 @@ +// +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +android_test { + name: "AaptBasicTest", + sdk_version: "current", +} diff --git a/tools/aapt2/integration-tests/BasicTest/Android.mk b/tools/aapt2/integration-tests/BasicTest/Android.mk deleted file mode 100644 index d1605540371e..000000000000 --- a/tools/aapt2/integration-tests/BasicTest/Android.mk +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (C) 2017 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_USE_AAPT2 := true -LOCAL_PACKAGE_NAME := AaptBasicTest -LOCAL_SDK_VERSION := current -LOCAL_MODULE_TAGS := tests -include $(BUILD_PACKAGE) diff --git a/tools/aapt2/integration-tests/StaticLibTest/Android.mk b/tools/aapt2/integration-tests/StaticLibTest/Android.mk deleted file mode 100644 index 6361f9b8ae7d..000000000000 --- a/tools/aapt2/integration-tests/StaticLibTest/Android.mk +++ /dev/null @@ -1,2 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tools/aapt2/integration-tests/StaticLibTest/App/Android.bp b/tools/aapt2/integration-tests/StaticLibTest/App/Android.bp new file mode 100644 index 000000000000..9aadff3d619e --- /dev/null +++ b/tools/aapt2/integration-tests/StaticLibTest/App/Android.bp @@ -0,0 +1,34 @@ +// +// 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. +// + +android_test { + + name: "AaptTestStaticLib_App", + sdk_version: "current", + srcs: ["src/**/*.java"], + asset_dirs: [ + "assets", + "assets2", + ], + static_libs: [ + "AaptTestStaticLib_LibOne", + "AaptTestStaticLib_LibTwo", + ], + aaptflags: [ + "--no-version-vectors", + "--no-version-transitions", + ], +} diff --git a/tools/aapt2/integration-tests/StaticLibTest/App/Android.mk b/tools/aapt2/integration-tests/StaticLibTest/App/Android.mk deleted file mode 100644 index 3cce35de6a31..000000000000 --- a/tools/aapt2/integration-tests/StaticLibTest/App/Android.mk +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_USE_AAPT2 := true -LOCAL_PACKAGE_NAME := AaptTestStaticLib_App -LOCAL_SDK_VERSION := current -LOCAL_MODULE_TAGS := tests -LOCAL_SRC_FILES := $(call all-java-files-under,src) -LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets $(LOCAL_PATH)/assets2 -LOCAL_STATIC_ANDROID_LIBRARIES := \ - AaptTestStaticLib_LibOne \ - AaptTestStaticLib_LibTwo -LOCAL_AAPT_FLAGS := --no-version-vectors --no-version-transitions -include $(BUILD_PACKAGE) diff --git a/tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.bp b/tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.bp new file mode 100644 index 000000000000..4c8181343a33 --- /dev/null +++ b/tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.bp @@ -0,0 +1,22 @@ +// +// 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. +// + +android_library { + name: "AaptTestStaticLib_LibOne", + sdk_version: "current", + srcs: ["src/**/*.java"], + resource_dirs: ["res"], +} diff --git a/tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.mk b/tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.mk deleted file mode 100644 index da25f6477b08..000000000000 --- a/tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.mk +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_USE_AAPT2 := true -LOCAL_MODULE := AaptTestStaticLib_LibOne -LOCAL_SDK_VERSION := current -LOCAL_MODULE_TAGS := tests -LOCAL_SRC_FILES := $(call all-java-files-under,src) -LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res - -# We need this to compile the Java sources of AaptTestStaticLib_LibTwo using javac. -LOCAL_JAR_EXCLUDE_FILES := none -include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/tools/aapt2/integration-tests/StaticLibTest/LibTwo/Android.bp b/tools/aapt2/integration-tests/StaticLibTest/LibTwo/Android.bp new file mode 100644 index 000000000000..7c4f7ed90e69 --- /dev/null +++ b/tools/aapt2/integration-tests/StaticLibTest/LibTwo/Android.bp @@ -0,0 +1,23 @@ +// +// 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. +// + +android_library { + name: "AaptTestStaticLib_LibTwo", + sdk_version: "current", + srcs: ["src/**/*.java"], + resource_dirs: ["res"], + libs: ["AaptTestStaticLib_LibOne"], +} diff --git a/tools/aapt2/integration-tests/SymlinkTest/Android.bp b/tools/aapt2/integration-tests/SymlinkTest/Android.bp new file mode 100644 index 000000000000..68e6148e480c --- /dev/null +++ b/tools/aapt2/integration-tests/SymlinkTest/Android.bp @@ -0,0 +1,20 @@ +// +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +android_test { + name: "AaptSymlinkTest", + sdk_version: "current", +} diff --git a/tools/aapt2/integration-tests/SymlinkTest/Android.mk b/tools/aapt2/integration-tests/SymlinkTest/Android.mk deleted file mode 100644 index 8da1141df7b3..000000000000 --- a/tools/aapt2/integration-tests/SymlinkTest/Android.mk +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (C) 2017 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_USE_AAPT2 := true -LOCAL_PACKAGE_NAME := AaptSymlinkTest -LOCAL_SDK_VERSION := current -LOCAL_MODULE_TAGS := tests -include $(BUILD_PACKAGE) diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 5e5a59566ce5..7caace6ec854 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -2136,17 +2136,26 @@ public class WifiManager { } /** + * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)} + * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT} and + * {@link android.content.pm.PackageManager#FEATURE_WIFI_AWARE}. + * * @return true if this adapter supports Device-to-device RTT * @hide */ + @Deprecated @SystemApi public boolean isDeviceToDeviceRttSupported() { return isFeatureSupported(WIFI_FEATURE_D2D_RTT); } /** + * @deprecated Please use {@link android.content.pm.PackageManager#hasSystemFeature(String)} + * with {@link android.content.pm.PackageManager#FEATURE_WIFI_RTT}. + * * @return true if this adapter supports Device-to-AP RTT */ + @Deprecated public boolean isDeviceToApRttSupported() { return isFeatureSupported(WIFI_FEATURE_D2AP_RTT); } |