Merge "Canonicalize default ringtones." into qt-dev
diff --git a/api/current.txt b/api/current.txt
index feb0bb6..6957161 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5485,7 +5485,8 @@
method @NonNull public android.graphics.drawable.Icon getIcon();
method @NonNull public android.app.PendingIntent getIntent();
method @Deprecated public boolean getSuppressInitialNotification();
- method public boolean getSuppressNotification();
+ method @Deprecated public boolean getSuppressNotification();
+ method public boolean isNotificationSuppressed();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.Notification.BubbleMetadata> CREATOR;
}
@@ -38514,7 +38515,6 @@
field public static final String DISPLAY_NAME = "_display_name";
field public static final String DOCUMENT_ID = "document_id";
field public static final String DURATION = "duration";
- field public static final String GROUP_ID = "group_id";
field public static final String HEIGHT = "height";
field public static final String INSTANCE_ID = "instance_id";
field public static final String IS_PENDING = "is_pending";
diff --git a/api/removed.txt b/api/removed.txt
index 8836326..ab5e7e5 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -539,6 +539,7 @@
}
public static interface MediaStore.MediaColumns extends android.provider.BaseColumns {
+ field @Deprecated public static final String GROUP_ID = "group_id";
field @Deprecated public static final String HASH = "_hash";
field @Deprecated public static final String IS_TRASHED = "is_trashed";
field @Deprecated public static final String PRIMARY_DIRECTORY = "primary_directory";
diff --git a/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl b/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl
index 4a66715..cd474c0 100644
--- a/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl
+++ b/cmds/idmap2/idmap2d/aidl/android/os/IIdmap2.aidl
@@ -25,6 +25,8 @@
const int POLICY_VENDOR_PARTITION = 0x00000004;
const int POLICY_PRODUCT_PARTITION = 0x00000008;
const int POLICY_SIGNATURE = 0x00000010;
+ const int POLICY_ODM_PARTITION = 0x00000020;
+ const int POLICY_OEM_PARTITION = 0x00000040;
@utf8InCpp String getIdmapPath(@utf8InCpp String overlayApkPath, int userId);
boolean removeIdmap(@utf8InCpp String overlayApkPath, int userId);
diff --git a/cmds/idmap2/include/idmap2/Policies.h b/cmds/idmap2/include/idmap2/Policies.h
index 90c698c..87edd35 100644
--- a/cmds/idmap2/include/idmap2/Policies.h
+++ b/cmds/idmap2/include/idmap2/Policies.h
@@ -26,11 +26,13 @@
namespace android::idmap2 {
-constexpr const char* kPolicyPublic = "public";
+constexpr const char* kPolicyOdm = "odm";
+constexpr const char* kPolicyOem = "oem";
constexpr const char* kPolicyProduct = "product";
+constexpr const char* kPolicyPublic = "public";
+constexpr const char* kPolicySignature = "signature";
constexpr const char* kPolicySystem = "system";
constexpr const char* kPolicyVendor = "vendor";
-constexpr const char* kPolicySignature = "signature";
using PolicyFlags = ResTable_overlayable_policy_header::PolicyFlags;
using PolicyBitmask = uint32_t;
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index aec1a6f..4649675 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -282,6 +282,7 @@
const utils::OverlayManifestInfo& overlay_info,
const PolicyBitmask& fulfilled_policies, const ResourceId& resid) {
static constexpr const PolicyBitmask sDefaultPolicies =
+ PolicyFlags::POLICY_ODM_PARTITION | PolicyFlags::POLICY_OEM_PARTITION |
PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION |
PolicyFlags::POLICY_PRODUCT_PARTITION | PolicyFlags::POLICY_SIGNATURE;
diff --git a/cmds/idmap2/libidmap2/Policies.cpp b/cmds/idmap2/libidmap2/Policies.cpp
index 0a0cecf..495fe61 100644
--- a/cmds/idmap2/libidmap2/Policies.cpp
+++ b/cmds/idmap2/libidmap2/Policies.cpp
@@ -17,8 +17,8 @@
#include "idmap2/Policies.h"
#include <iterator>
-#include <map>
#include <string>
+#include <unordered_map>
#include <vector>
#include "androidfw/ResourceTypes.h"
@@ -27,19 +27,17 @@
namespace android::idmap2 {
-namespace {
-
-const std::map<android::StringPiece, PolicyFlags> kStringToFlag = {
- {kPolicyPublic, PolicyFlags::POLICY_PUBLIC},
- {kPolicyProduct, PolicyFlags::POLICY_PRODUCT_PARTITION},
- {kPolicySystem, PolicyFlags::POLICY_SYSTEM_PARTITION},
- {kPolicyVendor, PolicyFlags::POLICY_VENDOR_PARTITION},
- {kPolicySignature, PolicyFlags::POLICY_SIGNATURE},
-};
-
-} // namespace
-
Result<PolicyBitmask> PoliciesToBitmask(const std::vector<std::string>& policies) {
+ static const std::unordered_map<android::StringPiece, PolicyFlags> kStringToFlag = {
+ {kPolicyOdm, PolicyFlags::POLICY_ODM_PARTITION},
+ {kPolicyOem, PolicyFlags::POLICY_OEM_PARTITION},
+ {kPolicyPublic, PolicyFlags::POLICY_PUBLIC},
+ {kPolicyProduct, PolicyFlags::POLICY_PRODUCT_PARTITION},
+ {kPolicySignature, PolicyFlags::POLICY_SIGNATURE},
+ {kPolicySystem, PolicyFlags::POLICY_SYSTEM_PARTITION},
+ {kPolicyVendor, PolicyFlags::POLICY_VENDOR_PARTITION},
+ };
+
PolicyBitmask bitmask = 0;
for (const std::string& policy : policies) {
const auto iter = kStringToFlag.find(policy);
@@ -55,6 +53,15 @@
std::vector<std::string> BitmaskToPolicies(const PolicyBitmask& bitmask) {
std::vector<std::string> policies;
+
+ if ((bitmask & PolicyFlags::POLICY_ODM_PARTITION) != 0) {
+ policies.emplace_back(kPolicyOdm);
+ }
+
+ if ((bitmask & PolicyFlags::POLICY_OEM_PARTITION) != 0) {
+ policies.emplace_back(kPolicyOem);
+ }
+
if ((bitmask & PolicyFlags::POLICY_PUBLIC) != 0) {
policies.emplace_back(kPolicyPublic);
}
@@ -63,6 +70,10 @@
policies.emplace_back(kPolicyProduct);
}
+ if ((bitmask & PolicyFlags::POLICY_SIGNATURE) != 0) {
+ policies.emplace_back(kPolicySignature);
+ }
+
if ((bitmask & PolicyFlags::POLICY_SYSTEM_PARTITION) != 0) {
policies.emplace_back(kPolicySystem);
}
@@ -71,10 +82,6 @@
policies.emplace_back(kPolicyVendor);
}
- if ((bitmask & PolicyFlags::POLICY_SIGNATURE) != 0) {
- policies.emplace_back(kPolicySignature);
- }
-
return policies;
}
diff --git a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
index 9cdc86c..9348ab7 100644
--- a/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
+++ b/cmds/idmap2/tests/BinaryStreamVisitorTests.cpp
@@ -109,49 +109,55 @@
success = LoadedIdmap::Lookup(header, 0x0002, &entry); // string/c
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x0003, &entry); // string/other
+ success = LoadedIdmap::Lookup(header, 0x0003, &entry); // string/policy_odm
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x0004, &entry); // string/not_overlayable
+ success = LoadedIdmap::Lookup(header, 0x0004, &entry); // string/policy_oem
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x0005, &entry); // string/policy_product
+ success = LoadedIdmap::Lookup(header, 0x0005, &entry); // string/other
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x0006, &entry); // string/policy_public
+ success = LoadedIdmap::Lookup(header, 0x0006, &entry); // string/not_overlayable
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x0007, &entry); // string/policy_system
+ success = LoadedIdmap::Lookup(header, 0x0007, &entry); // string/policy_product
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x0008, &entry); // string/policy_system_vendor
+ success = LoadedIdmap::Lookup(header, 0x0008, &entry); // string/policy_public
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x0009, &entry); // string/policy_signature
+ success = LoadedIdmap::Lookup(header, 0x0009, &entry); // string/policy_system
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x000a, &entry); // string/str1
+ success = LoadedIdmap::Lookup(header, 0x000a, &entry); // string/policy_system_vendor
+ ASSERT_FALSE(success);
+
+ success = LoadedIdmap::Lookup(header, 0x000b, &entry); // string/policy_signature
+ ASSERT_FALSE(success);
+
+ success = LoadedIdmap::Lookup(header, 0x000c, &entry); // string/str1
ASSERT_TRUE(success);
ASSERT_EQ(entry, 0x0000);
- success = LoadedIdmap::Lookup(header, 0x000b, &entry); // string/str2
+ success = LoadedIdmap::Lookup(header, 0x000d, &entry); // string/str2
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x000c, &entry); // string/str3
+ success = LoadedIdmap::Lookup(header, 0x000e, &entry); // string/str3
ASSERT_TRUE(success);
ASSERT_EQ(entry, 0x0001);
- success = LoadedIdmap::Lookup(header, 0x000d, &entry); // string/str4
+ success = LoadedIdmap::Lookup(header, 0x000f, &entry); // string/str4
ASSERT_TRUE(success);
ASSERT_EQ(entry, 0x0002);
- success = LoadedIdmap::Lookup(header, 0x000e, &entry); // string/x
+ success = LoadedIdmap::Lookup(header, 0x0010, &entry); // string/x
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x000f, &entry); // string/y
+ success = LoadedIdmap::Lookup(header, 0x0011, &entry); // string/y
ASSERT_FALSE(success);
- success = LoadedIdmap::Lookup(header, 0x0010, &entry); // string/z
+ success = LoadedIdmap::Lookup(header, 0x0012, &entry); // string/z
ASSERT_FALSE(success);
}
diff --git a/cmds/idmap2/tests/Idmap2BinaryTests.cpp b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
index c18744c..8a48f4b 100644
--- a/cmds/idmap2/tests/Idmap2BinaryTests.cpp
+++ b/cmds/idmap2/tests/Idmap2BinaryTests.cpp
@@ -128,9 +128,9 @@
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("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_NE(result->stdout.find("0x7f02000c -> 0x7f020000 string/str1"), std::string::npos);
+ ASSERT_NE(result->stdout.find("0x7f02000e -> 0x7f020001 string/str3"), std::string::npos);
+ ASSERT_NE(result->stdout.find("0x7f02000f -> 0x7f020002 string/str4"), std::string::npos);
ASSERT_EQ(result->stdout.find("00000210: 007f target package id"), std::string::npos);
// clang-format off
@@ -299,7 +299,7 @@
"lookup",
"--idmap-path", GetIdmapPath(),
"--config", "",
- "--resid", "0x7f02000a"}); // string/str1
+ "--resid", "0x7f02000c"}); // 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 90fe9a7..0f47f1e 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -194,7 +194,7 @@
ASSERT_THAT(idmap->GetHeader(), NotNull());
ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
ASSERT_EQ(idmap->GetHeader()->GetVersion(), 0x01U);
- ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0xd513ca1b);
+ ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x76a20829);
ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x8635c2ed);
ASSERT_EQ(idmap->GetHeader()->GetTargetPath().to_string(), target_apk_path);
ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
@@ -220,7 +220,7 @@
ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U);
ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U);
ASSERT_EQ(types[1]->GetEntryCount(), 4U);
- ASSERT_EQ(types[1]->GetEntryOffset(), 10U);
+ ASSERT_EQ(types[1]->GetEntryOffset(), 12U);
ASSERT_EQ(types[1]->GetEntry(0), 0x0000U);
ASSERT_EQ(types[1]->GetEntry(1), kNoEntry);
ASSERT_EQ(types[1]->GetEntry(2), 0x0001U);
@@ -251,7 +251,7 @@
ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
ASSERT_EQ(types[0]->GetEntryCount(), 4U);
- ASSERT_EQ(types[0]->GetEntryOffset(), 6U);
+ ASSERT_EQ(types[0]->GetEntryOffset(), 8U);
ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_public
ASSERT_EQ(types[0]->GetEntry(1), kNoEntry); // string/policy_signature
ASSERT_EQ(types[0]->GetEntry(2), 0x0001U); // string/policy_system
@@ -281,7 +281,7 @@
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]->GetEntryOffset(), 9U);
ASSERT_EQ(types[0]->GetEntry(0), 0x0000U); // string/policy_signature
}
@@ -310,11 +310,11 @@
ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
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]->GetEntryOffset(), 8U);
+ ASSERT_EQ(types[0]->GetEntry(0), 0x0005U); // string/policy_public
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
+ ASSERT_EQ(types[0]->GetEntry(2), 0x0007U); // string/policy_system
+ ASSERT_EQ(types[0]->GetEntry(3), 0x0008U); // string/policy_system_vendor
}
// Overlays should ignore all overlayable restrictions if enforcement of overlayable is disabled.
@@ -341,15 +341,17 @@
ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
- ASSERT_EQ(types[0]->GetEntryCount(), 7U);
+ ASSERT_EQ(types[0]->GetEntryCount(), 9U);
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_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
+ ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/policy_odm
+ ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_oem
+ ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/other
+ ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_product
+ ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_public
+ ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_signature
+ ASSERT_EQ(types[0]->GetEntry(7), 0x0007U); // string/policy_system
+ ASSERT_EQ(types[0]->GetEntry(8), 0x0008U); // string/policy_system_vendor
}
// Overlays that do not specify a target <overlayable> can overlay resources defined as overlayable.
@@ -381,7 +383,7 @@
ASSERT_EQ(types[1]->GetTargetTypeId(), 0x02U);
ASSERT_EQ(types[1]->GetOverlayTypeId(), 0x02U);
ASSERT_EQ(types[1]->GetEntryCount(), 4U);
- ASSERT_EQ(types[1]->GetEntryOffset(), 10U);
+ ASSERT_EQ(types[1]->GetEntryOffset(), 12U);
ASSERT_EQ(types[1]->GetEntry(0), 0x0000U); // string/str1
ASSERT_EQ(types[1]->GetEntry(1), kNoEntry); // string/str2
ASSERT_EQ(types[1]->GetEntry(2), 0x0001U); // string/str3
@@ -412,7 +414,6 @@
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);
@@ -421,15 +422,17 @@
ASSERT_EQ(types[0]->GetTargetTypeId(), 0x02U);
ASSERT_EQ(types[0]->GetOverlayTypeId(), 0x01U);
- ASSERT_EQ(types[0]->GetEntryCount(), 7U);
+ ASSERT_EQ(types[0]->GetEntryCount(), 9U);
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/string/policy_signature
- ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_system
- ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_system_vendor
+ ASSERT_EQ(types[0]->GetEntry(1), 0x0001U); // string/policy_odm
+ ASSERT_EQ(types[0]->GetEntry(2), 0x0002U); // string/policy_oem
+ ASSERT_EQ(types[0]->GetEntry(3), 0x0003U); // string/other
+ ASSERT_EQ(types[0]->GetEntry(4), 0x0004U); // string/policy_product
+ ASSERT_EQ(types[0]->GetEntry(5), 0x0005U); // string/policy_public
+ ASSERT_EQ(types[0]->GetEntry(6), 0x0006U); // string/policy_signature
+ ASSERT_EQ(types[0]->GetEntry(7), 0x0007U); // string/policy_system
+ ASSERT_EQ(types[0]->GetEntry(8), 0x0008U); // string/policy_system_vendor
};
CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_SIGNATURE,
@@ -451,6 +454,16 @@
/* enforce_overlayable */ true, &idmap);
ASSERT_THAT(idmap, NotNull());
CheckEntries();
+
+ CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_ODM_PARTITION,
+ /* enforce_overlayable */ true, &idmap);
+ ASSERT_THAT(idmap, NotNull());
+ CheckEntries();
+
+ CreateIdmap(target_apk_path, overlay_apk_path, PolicyFlags::POLICY_OEM_PARTITION,
+ /* enforce_overlayable */ true, &idmap);
+ ASSERT_THAT(idmap, NotNull());
+ CheckEntries();
}
TEST(IdmapTests, FailToCreateIdmapFromApkAssetsIfPathTooLong) {
diff --git a/cmds/idmap2/tests/PoliciesTests.cpp b/cmds/idmap2/tests/PoliciesTests.cpp
index e30da76..eca7404 100644
--- a/cmds/idmap2/tests/PoliciesTests.cpp
+++ b/cmds/idmap2/tests/PoliciesTests.cpp
@@ -38,9 +38,10 @@
ASSERT_TRUE(bitmask3);
ASSERT_EQ(*bitmask3, PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION);
- const auto bitmask4 = PoliciesToBitmask({"public", "product", "system", "vendor"});
+ const auto bitmask4 = PoliciesToBitmask({"odm", "oem", "public", "product", "system", "vendor"});
ASSERT_TRUE(bitmask4);
- ASSERT_EQ(*bitmask4, PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_PRODUCT_PARTITION |
+ ASSERT_EQ(*bitmask4, PolicyFlags::POLICY_ODM_PARTITION | PolicyFlags::POLICY_OEM_PARTITION |
+ PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_PRODUCT_PARTITION |
PolicyFlags::POLICY_SYSTEM_PARTITION |
PolicyFlags::POLICY_VENDOR_PARTITION);
@@ -64,4 +65,28 @@
ASSERT_FALSE(bitmask10);
}
+TEST(PoliciesTests, BitmaskToPolicies) {
+ const auto policies1 = BitmaskToPolicies(PolicyFlags::POLICY_PUBLIC);
+ ASSERT_EQ(1, policies1.size());
+ ASSERT_EQ(policies1[0], "public");
+
+ const auto policies2 = BitmaskToPolicies(PolicyFlags::POLICY_SYSTEM_PARTITION |
+ PolicyFlags::POLICY_VENDOR_PARTITION);
+ ASSERT_EQ(2, policies2.size());
+ ASSERT_EQ(policies2[0], "system");
+ ASSERT_EQ(policies2[1], "vendor");
+
+ const auto policies3 = BitmaskToPolicies(
+ PolicyFlags::POLICY_ODM_PARTITION | PolicyFlags::POLICY_OEM_PARTITION |
+ PolicyFlags::POLICY_PUBLIC | PolicyFlags::POLICY_PRODUCT_PARTITION |
+ PolicyFlags::POLICY_SYSTEM_PARTITION | PolicyFlags::POLICY_VENDOR_PARTITION);
+ ASSERT_EQ(2, policies2.size());
+ ASSERT_EQ(policies3[0], "odm");
+ ASSERT_EQ(policies3[1], "oem");
+ ASSERT_EQ(policies3[2], "public");
+ ASSERT_EQ(policies3[3], "product");
+ ASSERT_EQ(policies3[4], "system");
+ ASSERT_EQ(policies3[5], "vendor");
+}
+
} // namespace android::idmap2
diff --git a/cmds/idmap2/tests/RawPrintVisitorTests.cpp b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
index 64518fd..2695176 100644
--- a/cmds/idmap2/tests/RawPrintVisitorTests.cpp
+++ b/cmds/idmap2/tests/RawPrintVisitorTests.cpp
@@ -49,7 +49,7 @@
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: d513ca1b target crc\n"), std::string::npos);
+ ASSERT_NE(stream.str().find("00000008: 76a20829 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/system-overlay-invalid/res/values/values.xml b/cmds/idmap2/tests/data/system-overlay-invalid/res/values/values.xml
index 0270400..9ebfae4 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
@@ -23,6 +23,8 @@
<!-- 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>
+ <string name="policy_odm">policy_odm</string>
+ <string name="policy_oem">policy_oem</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
index 9448939..1456e74 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
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/res/values/overlayable.xml b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
index 0bf83fa..8389f56 100644
--- a/cmds/idmap2/tests/data/target/res/values/overlayable.xml
+++ b/cmds/idmap2/tests/data/target/res/values/overlayable.xml
@@ -33,6 +33,14 @@
<item type="string" name="policy_product" />
</policy>
+ <policy type="odm">
+ <item type="string" name="policy_odm" />
+ </policy>
+
+ <policy type="oem">
+ <item type="string" name="policy_oem" />
+ </policy>
+
<!-- Resources publicly overlayable -->
<policy type="public">
<item type="string" name="policy_public" />
diff --git a/cmds/idmap2/tests/data/target/res/values/values.xml b/cmds/idmap2/tests/data/target/res/values/values.xml
index edd53f4..a892c98 100644
--- a/cmds/idmap2/tests/data/target/res/values/values.xml
+++ b/cmds/idmap2/tests/data/target/res/values/values.xml
@@ -29,11 +29,13 @@
<!-- This resources is not marked as overlayable -->
<string name="not_overlayable">not_overlayable</string>
+ <string name="policy_public">policy_public</string>
+ <string name="policy_odm">policy_odm</string>
+ <string name="policy_oem">policy_oem</string>
+ <string name="policy_product">policy_product</string>
+ <string name="policy_signature">policy_signature</string>
<string name="policy_system">policy_system</string>
<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" />
+ <string name="other">other</string>
</resources>
diff --git a/cmds/idmap2/tests/data/target/target-no-overlayable.apk b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
index 908b54a..033305a 100644
--- a/cmds/idmap2/tests/data/target/target-no-overlayable.apk
+++ b/cmds/idmap2/tests/data/target/target-no-overlayable.apk
Binary files differ
diff --git a/cmds/idmap2/tests/data/target/target.apk b/cmds/idmap2/tests/data/target/target.apk
index da3c1ae..9bcd6dc 100644
--- a/cmds/idmap2/tests/data/target/target.apk
+++ b/cmds/idmap2/tests/data/target/target.apk
Binary files differ
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index d28108c..dbf0c3a 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -5467,9 +5467,11 @@
UNKNOWN = 20;
ATTENTION_SUCCESS_ABSENT = 0;
ATTENTION_SUCCESS_PRESENT = 1;
- ATTENTION_FAILURE_PREEMPTED = 2;
- ATTENTION_FAILURE_TIMED_OUT = 3;
- ATTENTION_FAILURE_UNKNOWN = 4;
+ ATTENTION_FAILURE_UNKNOWN = 2;
+ ATTENTION_FAILURE_CANCELLED = 3;
+ ATTENTION_FAILURE_PREEMPTED = 4;
+ ATTENTION_FAILURE_TIMED_OUT = 5;
+ ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6;
}
optional AttentionCheckResult attention_check_result = 1 [default = UNKNOWN];
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index cf4ef20..17368b7 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1863,7 +1863,7 @@
mTopActivityComponent = ComponentName.readFromParcel(source);
mSnapshot = source.readParcelable(null /* classLoader */);
int colorSpaceId = source.readInt();
- mColorSpace = colorSpaceId >= 0
+ mColorSpace = colorSpaceId >= 0 && colorSpaceId < ColorSpace.Named.values().length
? ColorSpace.get(ColorSpace.Named.values()[colorSpaceId])
: ColorSpace.get(ColorSpace.Named.SRGB);
mOrientation = source.readInt();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 5248329..0c6c77f 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -8645,19 +8645,29 @@
* @return whether this bubble should suppress the initial notification when it is posted.
*
* @see BubbleMetadata.Builder#setSuppressInitialNotification(boolean)
- * @deprecated TO BE REMOVED, use {@link #getSuppressNotification()} instead.
+ * @deprecated TO BE REMOVED, use {@link #isNotificationSuppressed()} instead.
*/
@Deprecated
public boolean getSuppressInitialNotification() {
- return (mFlags & FLAG_SUPPRESS_NOTIFICATION) != 0;
+ return isNotificationSuppressed();
}
/**
* @return whether this bubble should suppress the notification when it is posted.
*
- * @see BubbleMetadata.Builder#setSuppressInitialNotification(boolean)
+ * @see BubbleMetadata.Builder#setSuppressNotification(boolean)
+ * @deprecated TO BE REMOVED, use {@link #isNotificationSuppressed()} instead.
*/
public boolean getSuppressNotification() {
+ return isNotificationSuppressed();
+ }
+
+ /**
+ * @return whether this bubble should suppress the notification when it is posted.
+ *
+ * @see BubbleMetadata.Builder#setSuppressNotification(boolean)
+ */
+ public boolean isNotificationSuppressed() {
return (mFlags & FLAG_SUPPRESS_NOTIFICATION) != 0;
}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index bff8328..c50d003 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -1150,8 +1150,11 @@
* {@code IMG1024.BURST001.JPG} and {@code IMG1024.BURST002.JPG}
* will have the same {@link #GROUP_ID} because the first portion of
* their filenames is identical.
+ *
+ * @removed
*/
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ @Deprecated
public static final String GROUP_ID = "group_id";
/**
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index f21fa5e..646aa13 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -764,12 +764,11 @@
KeyCharacteristicsPromise promise = new KeyCharacteristicsPromise();
mBinder.asBinder().linkToDeath(promise, 0);
try {
- KeyCharacteristicsCallbackResult result = null;
int error = mBinder.importWrappedKey(promise, wrappedKeyAlias, wrappedKey,
wrappingKeyAlias, maskingKey, args, rootSid, fingerprintSid);
if (error != NO_ERROR) return error;
- KeyCharacteristicsCallbackResult esult = promise.getFuture().get();
+ KeyCharacteristicsCallbackResult result = promise.getFuture().get();
error = result.getKeystoreResponse().getErrorCode();
if (error != NO_ERROR) return error;
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 875b90b..fc635aa 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1651,6 +1651,14 @@
// The overlay must be signed with the same signature as the actor of the target resource,
// which can be separate or the same as the target package with the resource.
POLICY_SIGNATURE = 0x00000010,
+
+ // The overlay must reside of the odm partition or must have existed on the odm
+ // partition before an upgrade to overlay these resources.
+ POLICY_ODM_PARTITION = 0x00000020,
+
+ // The overlay must reside of the oem partition or must have existed on the oem
+ // partition before an upgrade to overlay these resources.
+ POLICY_OEM_PARTITION = 0x00000040,
};
uint32_t policy_flags;
diff --git a/media/apex/java/android/media/MediaSession2Service.java b/media/apex/java/android/media/MediaSession2Service.java
index 28ead99..3f392d2 100644
--- a/media/apex/java/android/media/MediaSession2Service.java
+++ b/media/apex/java/android/media/MediaSession2Service.java
@@ -370,10 +370,6 @@
}
return;
}
- if (DEBUG) {
- Log.d(TAG, "Handling incoming connection request from the"
- + " controller, controller=" + caller + ", uid=" + uid);
- }
String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME);
// The Binder.getCallingPid() can be 0 for an oneway call from the
@@ -389,13 +385,18 @@
caller,
connectionRequest.getBundle(KEY_CONNECTION_HINTS));
+ if (DEBUG) {
+ Log.d(TAG, "Handling incoming connection request from the"
+ + " controller=" + controllerInfo);
+ }
+
final MediaSession2 session;
session = service.onGetSession(controllerInfo);
if (session == null) {
if (DEBUG) {
Log.d(TAG, "Rejecting incoming connection request from the"
- + " controller, controller=" + caller + ", uid=" + uid);
+ + " controller=" + controllerInfo);
}
// Note: Trusted controllers also can be rejected according to the
// service implementation.
diff --git a/packages/Shell/res/values-ca/strings.xml b/packages/Shell/res/values-ca/strings.xml
index 048c94d..7fac740 100644
--- a/packages/Shell/res/values-ca/strings.xml
+++ b/packages/Shell/res/values-ca/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3701846017049540910">"Protecció"</string>
- <string name="bugreport_notification_channel" msgid="2574150205913861141">"Informes d\'error"</string>
+ <string name="bugreport_notification_channel" msgid="2574150205913861141">"Informes d\'errors"</string>
<string name="bugreport_in_progress_title" msgid="4311705936714972757">"S\'està generant l\'informe d\'errors <xliff:g id="ID">#%d</xliff:g>"</string>
<string name="bugreport_finished_title" msgid="4429132808670114081">"S\'ha capturat l\'informe d\'errors <xliff:g id="ID">#%d</xliff:g>"</string>
<string name="bugreport_updating_title" msgid="4423539949559634214">"S\'estan afegint detalls a l\'informe d\'errors"</string>
@@ -30,7 +30,7 @@
<string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toca per compartir l\'informe d\'errors sense captura de pantalla o espera que es creï la captura"</string>
<string name="bugreport_confirm" msgid="5917407234515812495">"Els informes d\'errors contenen dades dels diferents fitxers de registre del sistema, inclosa informació que pot ser confidencial (com ara l\'ús d\'aplicacions i les dades d\'ubicació). Comparteix-los només amb aplicacions i persones de confiança."</string>
<string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"No ho tornis a mostrar"</string>
- <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes d\'error"</string>
+ <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes d\'errors"</string>
<string name="bugreport_unreadable_text" msgid="586517851044535486">"No s\'ha pogut llegir el fitxer de l\'informe d\'errors"</string>
<string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"No s\'ha pogut afegir la informació detallada de l\'informe d\'errors al fitxer ZIP"</string>
<string name="bugreport_unnamed" msgid="2800582406842092709">"sense nom"</string>
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
index 58d50ea..6c6c927 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
@@ -28,7 +28,7 @@
public interface ClockPlugin extends Plugin {
String ACTION = "com.android.systemui.action.PLUGIN_CLOCK";
- int VERSION = 4;
+ int VERSION = 5;
/**
* Get the name of the clock face.
@@ -72,6 +72,14 @@
}
/**
+ * Returns the preferred Y position of the clock.
+ *
+ * @param totalHeight Height of the parent container.
+ * @return preferred Y position.
+ */
+ int getPreferredY(int totalHeight);
+
+ /**
* Allows the plugin to clean up resources when no longer needed.
*
* Called when the view previously created by {@link ClockPlugin#getView()} has been detached
diff --git a/packages/SystemUI/res-keyguard/layout/analog_clock.xml b/packages/SystemUI/res-keyguard/layout/analog_clock.xml
index cf6d35ee2..ee0df48 100644
--- a/packages/SystemUI/res-keyguard/layout/analog_clock.xml
+++ b/packages/SystemUI/res-keyguard/layout/analog_clock.xml
@@ -19,22 +19,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
>
- <TextClock
- android:id="@+id/digital_clock"
- android:paddingStart="20dp"
- android:layout_marginTop="72dp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="top|left"
- android:textSize="44dp"
- android:letterSpacing="0.05"
- android:textColor="?attr/wallpaperTextColor"
- android:singleLine="true"
- style="@style/widget_big"
- android:format12Hour="@string/keyguard_widget_12_hours_format"
- android:format24Hour="@string/keyguard_widget_24_hours_format"
- android:elegantTextHeight="false"
- />
<com.android.keyguard.clock.ImageClock
android:id="@+id/analog_clock"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res-keyguard/layout/bubble_clock.xml b/packages/SystemUI/res-keyguard/layout/bubble_clock.xml
index f945b10..b44faa9 100644
--- a/packages/SystemUI/res-keyguard/layout/bubble_clock.xml
+++ b/packages/SystemUI/res-keyguard/layout/bubble_clock.xml
@@ -19,22 +19,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
>
- <TextClock
- android:id="@+id/digital_clock"
- android:paddingStart="20dp"
- android:layout_marginTop="72dp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="top|left"
- android:textSize="44dp"
- android:letterSpacing="0.05"
- android:textColor="?attr/wallpaperTextColor"
- android:singleLine="true"
- style="@style/widget_big"
- android:format12Hour="@string/keyguard_widget_12_hours_format"
- android:format24Hour="@string/keyguard_widget_24_hours_format"
- android:elegantTextHeight="false"
- />
<com.android.keyguard.clock.ImageClock
android:id="@+id/analog_clock"
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 70366a8..fbb30d2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -298,6 +298,20 @@
}
/**
+ * Returns the preferred Y position of the clock.
+ *
+ * @param totalHeight Height of the parent container.
+ * @return preferred Y position.
+ */
+ int getPreferredY(int totalHeight) {
+ if (mClockPlugin != null) {
+ return mClockPlugin.getPreferredY(totalHeight);
+ } else {
+ return totalHeight / 2;
+ }
+ }
+
+ /**
* Refresh the time of the clock, due to either time tick broadcast or doze time tick alarm.
*/
public void refresh() {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 0369e4c..b02d514 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -241,6 +241,16 @@
return mClockView.getTextSize();
}
+ /**
+ * Returns the preferred Y position of the clock.
+ *
+ * @param totalHeight The height available to position the clock.
+ * @return Y position of clock.
+ */
+ public int getClockPreferredY(int totalHeight) {
+ return mClockView.getPreferredY(totalHeight);
+ }
+
private void updateLogoutView() {
if (mLogoutView == null) {
return;
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
index 1652121..7d1587c 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
@@ -21,6 +21,7 @@
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Paint.Style;
+import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextClock;
@@ -61,7 +62,6 @@
* Custom clock shown on AOD screen and behind stack scroller on lock.
*/
private ClockLayout mBigClockView;
- private TextClock mDigitalClock;
private ImageClock mAnalogClock;
/**
@@ -71,11 +71,6 @@
private TextClock mLockClock;
/**
- * Controller for transition to dark state.
- */
- private CrossFadeDarkController mDarkController;
-
- /**
* Create a BubbleClockController instance.
*
* @param res Resources contains title and thumbnail.
@@ -92,24 +87,20 @@
private void createViews() {
mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.analog_clock, null);
mAnalogClock = mBigClockView.findViewById(R.id.analog_clock);
- mDigitalClock = mBigClockView.findViewById(R.id.digital_clock);
mView = mLayoutInflater.inflate(R.layout.digital_clock, null);
mLockClock = mView.findViewById(R.id.lock_screen_clock);
- mLockClock.setVisibility(View.GONE);
-
- mDarkController = new CrossFadeDarkController(mDigitalClock, mLockClock);
+ final int textSize = mResources.getDimensionPixelSize(R.dimen.widget_title_font_size);
+ mLockClock.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
}
@Override
public void onDestroyView() {
mBigClockView = null;
- mDigitalClock = null;
mAnalogClock = null;
mView = null;
mLockClock = null;
- mDarkController = null;
}
@Override
@@ -161,12 +152,15 @@
}
@Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 4;
+ }
+
+ @Override
public void setStyle(Style style) {}
@Override
- public void setTextColor(int color) {
- mLockClock.setTextColor(color);
- }
+ public void setTextColor(int color) { }
@Override
public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
@@ -174,7 +168,7 @@
return;
}
final int length = colorPalette.length;
- mDigitalClock.setTextColor(colorPalette[Math.max(0, length - 5)]);
+ mLockClock.setTextColor(colorPalette[Math.max(0, length - 2)]);
mAnalogClock.setClockColors(colorPalette[Math.max(0, length - 5)],
colorPalette[Math.max(0, length - 2)]);
}
@@ -183,14 +177,11 @@
public void onTimeTick() {
mAnalogClock.onTimeChanged();
mBigClockView.onTimeChanged();
- mDigitalClock.refresh();
mLockClock.refresh();
}
@Override
- public void setDarkAmount(float darkAmount) {
- mDarkController.setDarkAmount(darkAmount);
- }
+ public void setDarkAmount(float darkAmount) { }
@Override
public void onTimeZoneChanged(TimeZone timeZone) {
@@ -199,6 +190,6 @@
@Override
public boolean shouldShowStatusArea() {
- return false;
+ return true;
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
index 6069a5e..cadfb79 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
@@ -21,6 +21,7 @@
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Paint.Style;
+import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextClock;
@@ -61,7 +62,6 @@
* Custom clock shown on AOD screen and behind stack scroller on lock.
*/
private ClockLayout mView;
- private TextClock mDigitalClock;
private ImageClock mAnalogClock;
/**
@@ -71,11 +71,6 @@
private TextClock mLockClock;
/**
- * Controller for transition to dark state.
- */
- private CrossFadeDarkController mDarkController;
-
- /**
* Create a BubbleClockController instance.
*
* @param res Resources contains title and thumbnail.
@@ -91,24 +86,20 @@
private void createViews() {
mView = (ClockLayout) mLayoutInflater.inflate(R.layout.bubble_clock, null);
- mDigitalClock = (TextClock) mView.findViewById(R.id.digital_clock);
mAnalogClock = (ImageClock) mView.findViewById(R.id.analog_clock);
mLockClockContainer = mLayoutInflater.inflate(R.layout.digital_clock, null);
mLockClock = (TextClock) mLockClockContainer.findViewById(R.id.lock_screen_clock);
- mLockClock.setVisibility(View.GONE);
-
- mDarkController = new CrossFadeDarkController(mDigitalClock, mLockClock);
+ final int textSize = mResources.getDimensionPixelSize(R.dimen.widget_title_font_size);
+ mLockClock.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
}
@Override
public void onDestroyView() {
mView = null;
- mDigitalClock = null;
mAnalogClock = null;
mLockClockContainer = null;
mLockClock = null;
- mDarkController = null;
}
@Override
@@ -160,12 +151,15 @@
}
@Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 4;
+ }
+
+ @Override
public void setStyle(Style style) {}
@Override
- public void setTextColor(int color) {
- mLockClock.setTextColor(color);
- }
+ public void setTextColor(int color) { }
@Override
public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
@@ -173,21 +167,18 @@
return;
}
final int length = colorPalette.length;
- mDigitalClock.setTextColor(colorPalette[Math.max(0, length - 6)]);
+ mLockClock.setTextColor(colorPalette[Math.max(0, length - 3)]);
mAnalogClock.setClockColors(colorPalette[Math.max(0, length - 6)],
colorPalette[Math.max(0, length - 3)]);
}
@Override
- public void setDarkAmount(float darkAmount) {
- mDarkController.setDarkAmount(darkAmount);
- }
+ public void setDarkAmount(float darkAmount) { }
@Override
public void onTimeTick() {
mAnalogClock.onTimeChanged();
mView.onTimeChanged();
- mDigitalClock.refresh();
mLockClock.refresh();
}
@@ -198,6 +189,6 @@
@Override
public boolean shouldShowStatusArea() {
- return false;
+ return true;
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
index 55088a8..962b8f8 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
@@ -22,7 +22,6 @@
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
-import android.widget.FrameLayout.LayoutParams;
import com.android.keyguard.R;
@@ -36,11 +35,10 @@
/**
* Clock face views.
*/
- private View mDigitalClock;
private View mAnalogClock;
/**
- * Pixel shifting amplitidues used to prevent screen burn-in.
+ * Pixel shifting amplitudes used to prevent screen burn-in.
*/
private int mBurnInPreventionOffsetX;
private int mBurnInPreventionOffsetY;
@@ -60,7 +58,6 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mDigitalClock = findViewById(R.id.digital_clock);
mAnalogClock = findViewById(R.id.analog_clock);
// Get pixel shifting X, Y amplitudes from resources.
@@ -87,13 +84,6 @@
final float offsetY = getBurnInOffset(mBurnInPreventionOffsetY * 2, false)
- mBurnInPreventionOffsetY;
- // Put digital clock in two left corner of the screen.
- if (mDigitalClock != null) {
- LayoutParams params = (LayoutParams) mDigitalClock.getLayoutParams();
- mDigitalClock.setX(offsetX + params.leftMargin);
- mDigitalClock.setY(offsetY + params.topMargin);
- }
-
// Put the analog clock in the middle of the screen.
if (mAnalogClock != null) {
mAnalogClock.setX(Math.max(0f, 0.5f * (getWidth() - mAnalogClock.getWidth()))
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
index 488cb27..ce1f09c 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
@@ -145,6 +145,11 @@
}
@Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
public void setStyle(Style style) {}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 6d0141b..d53c6e9 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -595,7 +595,7 @@
private void updateShowInShadeForSuppressNotification(NotificationEntry entry) {
boolean suppressNotification = entry.getBubbleMetadata() != null
- && entry.getBubbleMetadata().getSuppressNotification()
+ && entry.getBubbleMetadata().isNotificationSuppressed()
&& isForegroundApp(mContext, entry.notification.getPackageName());
entry.setShowInShadeWhenBubble(!suppressNotification);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
index 1cc6dc3..0fe5f8a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
@@ -33,6 +33,14 @@
*/
boolean isLockscreenPublicMode(int userId);
+ /**
+ * Does a user require a separate work challenge? If so, the unlock mechanism is decoupled from
+ * the current user and has to be solved separately.
+ */
+ default boolean needsSeparateWorkChallenge(int userId) {
+ return false;
+ }
+
void setUpWithPresenter(NotificationPresenter presenter);
int getCurrentUserId();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 9cb6f11..ed59f79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -77,6 +77,7 @@
private final DevicePolicyManager mDevicePolicyManager;
private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray();
+ private final SparseBooleanArray mUsersWithSeperateWorkChallenge = new SparseBooleanArray();
private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray();
private final UserManager mUserManager;
@@ -394,6 +395,11 @@
return mLockscreenPublicMode.get(userId, false);
}
+ @Override
+ public boolean needsSeparateWorkChallenge(int userId) {
+ return mUsersWithSeperateWorkChallenge.get(userId, false);
+ }
+
/**
* Has the given user chosen to allow notifications to be shown even when the lockscreen is in
* "public" (secure & locked) mode?
@@ -493,20 +499,23 @@
// - device keyguard is shown in secure mode;
// - profile is locked with a work challenge.
SparseArray<UserInfo> currentProfiles = getCurrentProfiles();
+ mUsersWithSeperateWorkChallenge.clear();
for (int i = currentProfiles.size() - 1; i >= 0; i--) {
final int userId = currentProfiles.valueAt(i).id;
boolean isProfilePublic = devicePublic;
+ boolean needsSeparateChallenge = mLockPatternUtils.isSeparateProfileChallengeEnabled(
+ userId);
if (!devicePublic && userId != getCurrentUserId()) {
// We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge
// due to a race condition where this code could be called before
// TrustManagerService updates its internal records, resulting in an incorrect
// state being cached in mLockscreenPublicMode. (b/35951989)
- if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
- && isSecure(userId)) {
+ if (needsSeparateChallenge && isSecure(userId)) {
isProfilePublic = mKeyguardManager.isDeviceLocked(userId);
}
}
setLockscreenPublicMode(isProfilePublic, userId);
+ mUsersWithSeperateWorkChallenge.put(userId, needsSeparateChallenge);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 97f2dd0..b3da62e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.os.Trace;
+import android.os.UserHandle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -26,6 +27,7 @@
import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleData;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -33,6 +35,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.UnlockMethodCache;
import java.util.ArrayList;
import java.util.HashMap;
@@ -52,7 +55,7 @@
* notifications that might affect their display.
*/
@Singleton
-public class NotificationViewHierarchyManager {
+public class NotificationViewHierarchyManager implements DynamicPrivacyController.Listener {
private static final String TAG = "NotificationViewHierarchyManager";
//TODO: change this top <Entry, List<Entry>>?
@@ -76,6 +79,7 @@
*/
private final boolean mAlwaysExpandNonGroupedNotification;
private final BubbleData mBubbleData;
+ private final DynamicPrivacyController mDynamicPrivacyController;
private NotificationPresenter mPresenter;
private NotificationListContainer mListContainer;
@@ -88,7 +92,8 @@
StatusBarStateController statusBarStateController,
NotificationEntryManager notificationEntryManager,
Lazy<ShadeController> shadeController,
- BubbleData bubbleData) {
+ BubbleData bubbleData,
+ DynamicPrivacyController privacyController) {
mLockscreenUserManager = notificationLockscreenUserManager;
mGroupManager = groupManager;
mVisualStabilityManager = visualStabilityManager;
@@ -99,6 +104,8 @@
mAlwaysExpandNonGroupedNotification =
res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications);
mBubbleData = bubbleData;
+ mDynamicPrivacyController = privacyController;
+ privacyController.addListener(this);
}
public void setUpWithPresenter(NotificationPresenter presenter,
@@ -130,15 +137,20 @@
// Display public version of the notification if we need to redact.
// TODO: This area uses a lot of calls into NotificationLockscreenUserManager.
// We can probably move some of this code there.
- boolean devicePublic = mLockscreenUserManager.isLockscreenPublicMode(
- mLockscreenUserManager.getCurrentUserId());
+ int currentUserId = mLockscreenUserManager.getCurrentUserId();
+ boolean devicePublic = mLockscreenUserManager.isLockscreenPublicMode(currentUserId);
boolean userPublic = devicePublic
|| mLockscreenUserManager.isLockscreenPublicMode(userId);
+ if (userPublic && mDynamicPrivacyController.isDynamicallyUnlocked()
+ && (userId == currentUserId || userId == UserHandle.USER_ALL
+ || !mLockscreenUserManager.needsSeparateWorkChallenge(userId))) {
+ userPublic = false;
+ }
boolean needsRedaction = mLockscreenUserManager.needsRedaction(ent);
boolean sensitive = userPublic && needsRedaction;
boolean deviceSensitive = devicePublic
&& !mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(
- mLockscreenUserManager.getCurrentUserId());
+ currentUserId);
ent.getRow().setSensitive(sensitive, deviceSensitive);
ent.getRow().setNeedsRedaction(needsRedaction);
if (mGroupManager.isChildInGroupWithSummary(ent.notification)) {
@@ -153,7 +165,6 @@
} else {
toShow.add(ent.getRow());
}
-
}
ArrayList<ExpandableNotificationRow> viewsToRemove = new ArrayList<>();
@@ -406,4 +417,9 @@
Trace.endSection();
Trace.endSection();
}
+
+ @Override
+ public void onDynamicPrivacyChanged() {
+ updateNotificationViews();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
new file mode 100644
index 0000000..16bd884
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification;
+
+import android.content.Context;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.phone.UnlockMethodCache;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * A controller which dynamically controls the visibility of Notification content
+ */
+@Singleton
+public class DynamicPrivacyController implements UnlockMethodCache.OnUnlockMethodChangedListener {
+
+ private final UnlockMethodCache mUnlockMethodCache;
+ private final NotificationLockscreenUserManager mLockscreenUserManager;
+ private ArraySet<Listener> mListeners = new ArraySet<>();
+
+ private boolean mLastDynamicUnlocked;
+ private boolean mCacheInvalid;
+
+ @Inject
+ DynamicPrivacyController(Context context,
+ NotificationLockscreenUserManager notificationLockscreenUserManager) {
+ this(notificationLockscreenUserManager, UnlockMethodCache.getInstance(context));
+ }
+
+ @VisibleForTesting
+ DynamicPrivacyController(NotificationLockscreenUserManager notificationLockscreenUserManager,
+ UnlockMethodCache unlockMethodCache) {
+ mLockscreenUserManager = notificationLockscreenUserManager;
+ mUnlockMethodCache = unlockMethodCache;
+ mUnlockMethodCache.addListener(this);
+ mLastDynamicUnlocked = isDynamicallyUnlocked();
+ }
+
+ @Override
+ public void onUnlockMethodStateChanged() {
+ if (isDynamicPrivacyEnabled()) {
+ // We only want to notify our listeners if dynamic privacy is actually active
+ boolean dynamicallyUnlocked = isDynamicallyUnlocked();
+ if (dynamicallyUnlocked != mLastDynamicUnlocked || mCacheInvalid) {
+ mLastDynamicUnlocked = dynamicallyUnlocked;
+ for (Listener listener : mListeners) {
+ listener.onDynamicPrivacyChanged();
+ }
+ }
+ mCacheInvalid = false;
+ } else {
+ mCacheInvalid = true;
+ }
+ }
+
+ private boolean isDynamicPrivacyEnabled() {
+ return !mLockscreenUserManager.shouldHideNotifications(
+ mLockscreenUserManager.getCurrentUserId());
+ }
+
+ public boolean isDynamicallyUnlocked() {
+ return mUnlockMethodCache.canSkipBouncer() && isDynamicPrivacyEnabled();
+ }
+
+ public void addListener(Listener listener) {
+ mListeners.add(listener);
+ }
+
+ public interface Listener {
+ void onDynamicPrivacyChanged();
+ }
+}
\ No newline at end of file
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 09f513d..18dcf4c 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
@@ -120,8 +120,6 @@
@InflationFlag
private int mInflationFlags = REQUIRED_INFLATION_FLAGS;
- static final InflationExecutor EXECUTOR = new InflationExecutor();
-
private final ExpandableNotificationRow mRow;
private boolean mIsLowPriority;
private boolean mUsesIncreasedHeight;
@@ -638,14 +636,14 @@
cancellationSignal = newContentView.applyAsync(
result.packageContext,
parentLayout,
- EXECUTOR,
+ null,
listener,
remoteViewClickHandler);
} else {
cancellationSignal = newContentView.reapplyAsync(
result.packageContext,
existingView,
- EXECUTOR,
+ null,
listener,
remoteViewClickHandler);
}
@@ -996,40 +994,4 @@
public abstract void setResultView(View v);
public abstract RemoteViews getRemoteView();
}
-
- /**
- * A custom executor that allows more tasks to be queued. Default values are copied from
- * AsyncTask
- */
- private static class InflationExecutor implements Executor {
- private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
- // We want at least 2 threads and at most 4 threads in the core pool,
- // preferring to have 1 less than the CPU count to avoid saturating
- // the CPU with background work
- private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
- private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
- private static final int KEEP_ALIVE_SECONDS = 30;
-
- private static final ThreadFactory sThreadFactory = new ThreadFactory() {
- private final AtomicInteger mCount = new AtomicInteger(1);
-
- public Thread newThread(Runnable r) {
- return new Thread(r, "InflaterThread #" + mCount.getAndIncrement());
- }
- };
-
- private final ThreadPoolExecutor mExecutor;
-
- private InflationExecutor() {
- mExecutor = new ThreadPoolExecutor(
- CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
- new LinkedBlockingQueue<>(), sThreadFactory);
- mExecutor.allowCoreThreadTimeOut(true);
- }
-
- @Override
- public void execute(Runnable runnable) {
- mExecutor.execute(runnable);
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java
index 6eb376b..4b0e2ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java
@@ -52,7 +52,7 @@
@Override
public void preload(Uri uri) {
PreloadImageTask newTask = new PreloadImageTask(mResolver);
- newTask.executeOnExecutor(NotificationContentInflater.EXECUTOR, uri);
+ newTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, uri);
mCache.put(uri, newTask);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 562e535..058cb2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -101,6 +101,7 @@
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.FakeShadowView;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -153,7 +154,8 @@
* A layout which handles a dynamic amount of notifications and presents them in a scrollable stack.
*/
public class NotificationStackScrollLayout extends ViewGroup implements ScrollAdapter,
- NotificationListContainer, ConfigurationListener, Dumpable {
+ NotificationListContainer, ConfigurationListener, Dumpable,
+ DynamicPrivacyController.Listener {
public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
private static final String TAG = "StackScroller";
@@ -498,6 +500,7 @@
* If the {@link NotificationShelf} should be visible when dark.
*/
private boolean mShowDarkShelf;
+ private boolean mAnimateBottomOnLayout;
@Inject
public NotificationStackScrollLayout(
@@ -505,7 +508,8 @@
AttributeSet attrs,
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
NotificationRoundnessManager notificationRoundnessManager,
- AmbientPulseManager ambientPulseManager) {
+ AmbientPulseManager ambientPulseManager,
+ DynamicPrivacyController dynamicPrivacyController) {
super(context, attrs, 0, 0);
Resources res = getResources();
@@ -576,6 +580,7 @@
}
}
});
+ dynamicPrivacyController.addListener(this);
}
private void updateDismissRtlSetting(boolean dismissRtl) {
@@ -2479,9 +2484,8 @@
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void updateBackgroundBounds() {
- getLocationInWindow(mTempInt2);
- int left = mTempInt2[0] + mSidePaddings;
- int right = mTempInt2[0] + getWidth() - mSidePaddings;
+ int left = mSidePaddings;
+ int right = getWidth() - mSidePaddings;
for (NotificationSection section : mSections) {
section.getBounds().left = left;
section.getBounds().right = right;
@@ -3165,7 +3169,7 @@
if (mAnimationsEnabled && mIsExpanded) {
mAnimateNextBackgroundTop = firstChild != previousFirstChild;
- mAnimateNextBackgroundBottom = lastChild != previousLastChild;
+ mAnimateNextBackgroundBottom = lastChild != previousLastChild || mAnimateBottomOnLayout;
mAnimateNextSectionBoundsChange = sectionViewsChanged;
} else {
mAnimateNextBackgroundTop = false;
@@ -3174,6 +3178,7 @@
}
mAmbientState.setLastVisibleBackgroundChild(lastChild);
mRoundnessManager.updateRoundedChildren(mSections);
+ mAnimateBottomOnLayout = false;
invalidate();
}
@@ -4842,8 +4847,8 @@
* If the shelf should be visible when the device is in ambient mode (dozing.)
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setShowDarkShelf(boolean showDarkShelf) {
- mShowDarkShelf = showDarkShelf;
+ public void showDarkShelf() {
+ mShowDarkShelf = true;
}
private void updateDarkShelfVisibility() {
@@ -5714,6 +5719,14 @@
}
}
+ @Override
+ public void onDynamicPrivacyChanged() {
+ if (mIsExpanded) {
+ // The bottom might change because we're using the final actual height of the view
+ mAnimateBottomOnLayout = true;
+ }
+ }
+
/**
* A listener that is notified when the empty space below the notifications is clicked on
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 195d02d..5d144a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -220,7 +220,6 @@
if (mStatusBarStateController.isDozing()
&& mStatusBarComponent.getPanel().hasCustomClock()) {
state |= DISABLE_CLOCK | DISABLE_SYSTEM_INFO;
- state &= ~DISABLE_NOTIFICATION_ICONS;
}
return state;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index c68fdd4..d59f248 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -22,7 +22,6 @@
import android.content.res.Resources;
import android.util.MathUtils;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -55,6 +54,11 @@
private int mKeyguardStatusHeight;
/**
+ * Preferred Y position of clock.
+ */
+ private int mClockPreferredY;
+
+ /**
* Height of notification stack: Sum of height of each notification.
*/
private int mNotificationStackHeight;
@@ -117,14 +121,15 @@
}
public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight,
- float panelExpansion, int parentHeight, int keyguardStatusHeight, float dark,
- boolean secure, float emptyDragAmount) {
+ float panelExpansion, int parentHeight, int keyguardStatusHeight, int clockPreferredY,
+ float dark, boolean secure, float emptyDragAmount) {
mMinTopMargin = minTopMargin + mContainerTopPadding;
mMaxShadeBottom = maxShadeBottom;
mNotificationStackHeight = notificationStackHeight;
mPanelExpansion = panelExpansion;
mHeight = parentHeight;
mKeyguardStatusHeight = keyguardStatusHeight;
+ mClockPreferredY = clockPreferredY;
mDarkAmount = dark;
mCurrentlySecure = secure;
mEmptyDragAmount = emptyDragAmount;
@@ -146,6 +151,10 @@
return mHeight / 2 - mKeyguardStatusHeight - mClockNotificationsMargin;
}
+ private int getPreferredClockY() {
+ return mClockPreferredY - mKeyguardStatusHeight - mClockNotificationsMargin;
+ }
+
/**
* Vertically align the clock and the shade in the available space considering only
* a percentage of the clock height defined by {@code CLOCK_HEIGHT_WEIGHT}.
@@ -172,7 +181,7 @@
private int getClockY() {
// Dark: Align the bottom edge of the clock at about half of the screen:
- float clockYDark = getMaxClockY() + burnInPreventionOffsetY();
+ float clockYDark = getPreferredClockY() + burnInPreventionOffsetY();
clockYDark = MathUtils.max(0, clockYDark);
float clockYRegular = getExpandedClockPosition();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index dd957b4..ab13149 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -78,6 +78,7 @@
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.AnimatableProperty;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -109,7 +110,7 @@
KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener,
OnHeadsUpChangedListener, QS.HeightListener, ZenModeController.Callback,
ConfigurationController.ConfigurationListener, StateListener,
- PulseExpansionHandler.ExpansionCallback {
+ PulseExpansionHandler.ExpansionCallback, DynamicPrivacyController.Listener {
private static final boolean DEBUG = false;
@@ -208,9 +209,9 @@
private int mUnlockMoveDistance;
private float mEmptyDragAmount;
- private KeyguardClockPositionAlgorithm mClockPositionAlgorithm =
+ private final KeyguardClockPositionAlgorithm mClockPositionAlgorithm =
new KeyguardClockPositionAlgorithm();
- private KeyguardClockPositionAlgorithm.Result mClockPositionResult =
+ private final KeyguardClockPositionAlgorithm.Result mClockPositionResult =
new KeyguardClockPositionAlgorithm.Result();
private boolean mIsExpanding;
@@ -343,7 +344,8 @@
public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
InjectionInflationController injectionInflationController,
NotificationWakeUpCoordinator coordinator,
- PulseExpansionHandler pulseExpansionHandler) {
+ PulseExpansionHandler pulseExpansionHandler,
+ DynamicPrivacyController dynamicPrivacyController) {
super(context, attrs);
setWillNotDraw(!DEBUG);
mInjectionInflationController = injectionInflationController;
@@ -358,6 +360,7 @@
mDisplayId = context.getDisplayId();
mPulseExpansionHandler = pulseExpansionHandler;
mThemeResId = context.getThemeResId();
+ dynamicPrivacyController.addListener(this);
}
/**
@@ -627,6 +630,7 @@
} else {
int totalHeight = getHeight();
int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
+ int clockPreferredY = mKeyguardStatusView.getClockPreferredY(totalHeight);
mClockPositionAlgorithm.setup(
mStatusBarMinHeight,
totalHeight - bottomPadding,
@@ -634,6 +638,7 @@
getExpandedFraction(),
totalHeight,
mKeyguardStatusView.getHeight(),
+ clockPreferredY,
mInterpolatedDarkAmount,
mStatusBar.isKeyguardCurrentlySecure(),
mEmptyDragAmount);
@@ -2830,7 +2835,7 @@
mDozing = dozing;
mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation);
if (mDozing) {
- mNotificationStackScroller.setShowDarkShelf(!hasCustomClock());
+ mNotificationStackScroller.showDarkShelf();
}
mKeyguardBottomArea.setDozing(mDozing, animate);
@@ -3113,4 +3118,9 @@
}
return y;
}
+
+ @Override
+ public void onDynamicPrivacyChanged() {
+ mAnimateNextPositionUpdate = true;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index 44c82c8..39bf728 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -16,10 +16,18 @@
package com.android.systemui.statusbar.phone;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.hardware.biometrics.BiometricSourceType;
+import android.media.AudioManager;
+import android.os.Build;
import android.os.Trace;
+import android.telephony.TelephonyManager;
+import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -34,6 +42,8 @@
public class UnlockMethodCache {
private static UnlockMethodCache sInstance;
+ private static final boolean DEBUG_AUTH_WITH_ADB = false;
+ private static final String AUTH_BROADCAST_KEY = "debug_trigger_auth";
private final LockPatternUtils mLockPatternUtils;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -44,12 +54,27 @@
private boolean mCanSkipBouncer;
private boolean mTrustManaged;
private boolean mTrusted;
+ private boolean mDebugUnlocked = false;
private UnlockMethodCache(Context ctx) {
mLockPatternUtils = new LockPatternUtils(ctx);
mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(ctx);
KeyguardUpdateMonitor.getInstance(ctx).registerCallback(mCallback);
update(true /* updateAlways */);
+ if (Build.IS_DEBUGGABLE && DEBUG_AUTH_WITH_ADB) {
+ // Watch for interesting updates
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(AUTH_BROADCAST_KEY);
+ ctx.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG_AUTH_WITH_ADB && AUTH_BROADCAST_KEY.equals(intent.getAction())) {
+ mDebugUnlocked = !mDebugUnlocked;
+ update(true /* updateAlways */);
+ }
+ }
+ }, filter, null, null);
+ }
}
public static UnlockMethodCache getInstance(Context context) {
@@ -89,7 +114,8 @@
Trace.beginSection("UnlockMethodCache#update");
int user = KeyguardUpdateMonitor.getCurrentUser();
boolean secure = mLockPatternUtils.isSecure(user);
- boolean canSkipBouncer = !secure || mKeyguardUpdateMonitor.getUserCanSkipBouncer(user);
+ boolean canSkipBouncer = !secure || mKeyguardUpdateMonitor.getUserCanSkipBouncer(user)
+ || (Build.IS_DEBUGGABLE && DEBUG_AUTH_WITH_ADB && mDebugUnlocked);
boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer ||
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java
index 4bb2395..3f48ea7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java
@@ -54,20 +54,20 @@
}
@Test
- public void setDarkAmount_fadeIn() {
+ public void setDarkAmount_AOD() {
ViewGroup smallClockFrame = (ViewGroup) mClockController.getView();
View smallClock = smallClockFrame.getChildAt(0);
// WHEN dark amount is set to AOD
mClockController.setDarkAmount(1f);
- // THEN small clock should not be shown.
- assertThat(smallClock.getVisibility()).isEqualTo(View.GONE);
+ // THEN small clock should be shown.
+ assertThat(smallClock.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
- public void setTextColor_setDigitalClock() {
+ public void setColorPalette_setDigitalClock() {
ViewGroup smallClock = (ViewGroup) mClockController.getView();
- // WHEN text color is set
- mClockController.setTextColor(42);
+ // WHEN color palette is set
+ mClockController.setColorPalette(true, new int[]{42});
// THEN child of small clock should have text color set.
TextView digitalClock = (TextView) smallClock.getChildAt(0);
assertThat(digitalClock.getCurrentTextColor()).isEqualTo(42);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
index f03c234..90083b4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
@@ -53,20 +53,20 @@
}
@Test
- public void setDarkAmount_fadeIn() {
+ public void setDarkAmount_AOD() {
ViewGroup smallClockFrame = (ViewGroup) mClockController.getView();
View smallClock = smallClockFrame.getChildAt(0);
// WHEN dark amount is set to AOD
mClockController.setDarkAmount(1f);
// THEN small clock should not be shown.
- assertThat(smallClock.getVisibility()).isEqualTo(View.GONE);
+ assertThat(smallClock.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
- public void setTextColor_setDigitalClock() {
+ public void setColorPalette_setDigitalClock() {
ViewGroup smallClock = (ViewGroup) mClockController.getView();
// WHEN text color is set
- mClockController.setTextColor(42);
+ mClockController.setColorPalette(true, new int[]{42});
// THEN child of small clock should have text color set.
TextView digitalClock = (TextView) smallClock.getChildAt(0);
assertThat(digitalClock.getCurrentTextColor()).isEqualTo(42);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 3662c38..c476d80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -39,6 +39,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.bubbles.BubbleData;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationData;
@@ -98,7 +99,7 @@
mViewHierarchyManager = new NotificationViewHierarchyManager(mContext,
mLockscreenUserManager, mGroupManager, mVisualStabilityManager,
mock(StatusBarStateControllerImpl.class), mEntryManager,
- () -> mShadeController, new BubbleData(mContext));
+ () -> mShadeController, new BubbleData(mContext), mock(DynamicPrivacyController.class));
Dependency.get(InitController.class).executePostInitTasks();
mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
new file mode 100644
index 0000000..6ca5d2c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/DynamicPrivacyControllerTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.notification;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.phone.UnlockMethodCache;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import dagger.Lazy;
+
+
+@SmallTest
+@org.junit.runner.RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class DynamicPrivacyControllerTest extends SysuiTestCase {
+
+ private DynamicPrivacyController mDynamicPrivacyController;
+ private UnlockMethodCache mCache = mock(UnlockMethodCache.class);
+ private NotificationLockscreenUserManager mLockScreenUserManager
+ = mock(NotificationLockscreenUserManager.class);
+ private DynamicPrivacyController.Listener mListener
+ = mock(DynamicPrivacyController.Listener.class);
+
+ @Before
+ public void setUp() throws Exception {
+ when(mCache.canSkipBouncer()).thenReturn(false);
+ mDynamicPrivacyController = new DynamicPrivacyController(
+ mLockScreenUserManager, mCache);
+ mDynamicPrivacyController.addListener(mListener);
+ }
+
+ @Test
+ public void testDynamicFalseWhenCannotSkipBouncer() {
+ enableDynamicPrivacy();
+ when(mCache.canSkipBouncer()).thenReturn(false);
+ Assert.assertFalse("can't skip bouncer but is dynamically unlocked",
+ mDynamicPrivacyController.isDynamicallyUnlocked());
+ }
+
+ @Test
+ public void testDynamicTrueWhenCanSkipBouncer() {
+ enableDynamicPrivacy();
+ when(mCache.canSkipBouncer()).thenReturn(true);
+ Assert.assertTrue("Isn't dynamically unlocked even though we can skip bouncer",
+ mDynamicPrivacyController.isDynamicallyUnlocked());
+ }
+
+ @Test
+ public void testNotifiedWhenEnabled() {
+ when(mCache.canSkipBouncer()).thenReturn(true);
+ enableDynamicPrivacy();
+ mDynamicPrivacyController.onUnlockMethodStateChanged();
+ verify(mListener).onDynamicPrivacyChanged();
+ }
+
+ private void enableDynamicPrivacy() {
+ when(mLockScreenUserManager.shouldHideNotifications(any())).thenReturn(
+ false);
+ }
+
+ @Test
+ public void testNotNotifiedWithoutNotifications() {
+ when(mCache.canSkipBouncer()).thenReturn(true);
+ when(mLockScreenUserManager.shouldHideNotifications(anyInt())).thenReturn(
+ true);
+ mDynamicPrivacyController.onUnlockMethodStateChanged();
+ verifyNoMoreInteractions(mListener);
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 1f57593..04f911a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -60,6 +60,7 @@
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -144,7 +145,8 @@
// member variables, not the spy's member variables.
mStackScrollerInternal = new NotificationStackScrollLayout(getContext(), null,
true /* allowLongPress */, mNotificationRoundnessManager,
- new AmbientPulseManager(mContext));
+ new AmbientPulseManager(mContext),
+ mock(DynamicPrivacyController.class));
mStackScroller = spy(mStackScrollerInternal);
mStackScroller.setShelf(notificationShelf);
mStackScroller.setStatusBar(mBar);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index fcf4c71..3f4d96c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -35,6 +35,7 @@
public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase {
private static final int SCREEN_HEIGHT = 2000;
+ private static final int PREFERRED_CLOCK_Y = SCREEN_HEIGHT / 2;
private static final int EMPTY_MARGIN = 0;
private static final int EMPTY_HEIGHT = 0;
private static final boolean SECURE_LOCKED = false;
@@ -305,8 +306,8 @@
private void positionClock() {
mClockPositionAlgorithm.setup(EMPTY_MARGIN, SCREEN_HEIGHT, mNotificationStackHeight,
- mPanelExpansion, SCREEN_HEIGHT, mKeyguardStatusHeight, mDark, SECURE_LOCKED,
- ZERO_DRAG);
+ mPanelExpansion, SCREEN_HEIGHT, mKeyguardStatusHeight, PREFERRED_CLOCK_Y, mDark,
+ SECURE_LOCKED, ZERO_DRAG);
mClockPositionAlgorithm.run(mClockPosition);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 6d6af47..08471d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -20,6 +20,7 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -40,6 +41,7 @@
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -117,7 +119,7 @@
mNotificationPanelView.setDozing(true /* dozing */, true /* animate */, null /* touch */);
InOrder inOrder = inOrder(mNotificationStackScrollLayout, mStatusBarStateController);
inOrder.verify(mNotificationStackScrollLayout).setDark(eq(true), eq(true), eq(null));
- inOrder.verify(mNotificationStackScrollLayout).setShowDarkShelf(eq(true));
+ inOrder.verify(mNotificationStackScrollLayout).showDarkShelf();
inOrder.verify(mStatusBarStateController).setDozeAmount(eq(1f), eq(true));
}
@@ -125,14 +127,14 @@
public void testSetDozing_showsDarkShelfWithDefaultClock() {
when(mKeyguardStatusView.hasCustomClock()).thenReturn(false);
mNotificationPanelView.setDozing(true /* dozing */, true /* animate */, null /* touch */);
- verify(mNotificationStackScrollLayout).setShowDarkShelf(eq(true));
+ verify(mNotificationStackScrollLayout).showDarkShelf();
}
@Test
- public void testSetDozing_hidesDarkShelfWhenCustomClock() {
+ public void testSetDozing_showsDarkShelfWhenCustomClock() {
when(mKeyguardStatusView.hasCustomClock()).thenReturn(true);
mNotificationPanelView.setDozing(true /* dozing */, true /* animate */, null /* touch */);
- verify(mNotificationStackScrollLayout).setShowDarkShelf(eq(false));
+ verify(mNotificationStackScrollLayout).showDarkShelf();
}
@Test
@@ -172,7 +174,7 @@
super(NotificationPanelViewTest.this.mContext, null,
new InjectionInflationController(
SystemUIFactory.getInstance().getRootComponent()),
- coordinator, expansionHandler);
+ coordinator, expansionHandler, mock(DynamicPrivacyController.class));
mNotificationStackScroller = mNotificationStackScrollLayout;
mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index fd68a8b..4b435de 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -220,9 +220,19 @@
return fulfilledPolicies | IIdmap2.POLICY_PRODUCT_PARTITION;
}
+ // Odm partition (/odm)
+ if (ai.isOdm()) {
+ return fulfilledPolicies | IIdmap2.POLICY_ODM_PARTITION;
+ }
+
+ // Oem partition (/oem)
+ if (ai.isOem()) {
+ return fulfilledPolicies | IIdmap2.POLICY_OEM_PARTITION;
+ }
+
// Check partitions for which there exists no policy so overlays on these partitions will
// not fulfill the system policy.
- if (ai.isOem() || ai.isProductServices()) {
+ if (ai.isProductServices()) {
return fulfilledPolicies;
}
diff --git a/services/core/java/com/android/server/os/SchedulingPolicyService.java b/services/core/java/com/android/server/os/SchedulingPolicyService.java
index 5cbe1a1..2371b04 100644
--- a/services/core/java/com/android/server/os/SchedulingPolicyService.java
+++ b/services/core/java/com/android/server/os/SchedulingPolicyService.java
@@ -40,7 +40,7 @@
private static final int PRIORITY_MAX = 3;
private static final String[] MEDIA_PROCESS_NAMES = new String[] {
- "media.codec", // vendor/bin/hw/android.hardware.media.omx@1.0-service
+ "media.swcodec", // /apex/com.android.media.swcodec/bin/mediaswcodec
};
private final IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
@Override
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 5e8d870..fe401e2 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -1143,34 +1143,38 @@
} else if (Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
// Parse the polices separated by vertical bar characters to allow for specifying multiple
// policies. Items within the policy tag will have the specified policy.
- for (StringPiece part : util::Tokenize(maybe_type.value(), '|')) {
+ static const auto kPolicyMap =
+ ImmutableMap<StringPiece, OverlayableItem::Policy>::CreatePreSorted({
+ {"odm", OverlayableItem::Policy::kOdm},
+ {"oem", OverlayableItem::Policy::kOem},
+ {"product", OverlayableItem::Policy::kProduct},
+ {"public", OverlayableItem::Policy::kPublic},
+ {"signature", OverlayableItem::Policy::kSignature},
+ {"system", OverlayableItem::Policy::kSystem},
+ {"vendor", OverlayableItem::Policy::kVendor},
+ });
+
+ for (const StringPiece& part : util::Tokenize(maybe_type.value(), '|')) {
StringPiece trimmed_part = util::TrimWhitespace(part);
- if (trimmed_part == "public") {
- current_policies |= OverlayableItem::Policy::kPublic;
- } else if (trimmed_part == "product") {
- current_policies |= OverlayableItem::Policy::kProduct;
- } else if (trimmed_part == "system") {
- current_policies |= OverlayableItem::Policy::kSystem;
- } else if (trimmed_part == "vendor") {
- current_policies |= OverlayableItem::Policy::kVendor;
- } else if (trimmed_part == "signature") {
- current_policies |= OverlayableItem::Policy::kSignature;
- } else {
+ const auto policy = kPolicyMap.find(trimmed_part);
+ if (policy == kPolicyMap.end()) {
diag_->Error(DiagMessage(element_source)
<< "<policy> has unsupported type '" << trimmed_part << "'");
error = true;
continue;
}
+
+ current_policies |= policy->second;
}
} else {
diag_->Error(DiagMessage(element_source)
- << "<policy> must have a 'type' attribute");
+ << "<policy> must have a 'type' attribute");
error = true;
continue;
}
} else if (!ShouldIgnoreElement(element_namespace, element_name)) {
diag_->Error(DiagMessage(element_source) << "invalid element <" << element_name << "> "
- << " in <overlayable>");
+ << " in <overlayable>");
error = true;
break;
}
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 8577921..7c8b6d0 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -971,6 +971,12 @@
<policy type="signature">
<item type="string" name="foz" />
</policy>
+ <policy type="odm">
+ <item type="string" name="biz" />
+ </policy>
+ <policy type="oem">
+ <item type="string" name="buz" />
+ </policy>
</overlayable>)";
ASSERT_TRUE(TestParse(input));
@@ -1013,6 +1019,22 @@
result_overlayable_item = search_result.value().entry->overlayable_item.value();
EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name"));
EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature));
+
+ search_result = table_.FindResource(test::ParseNameOrDie("string/biz"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ ASSERT_TRUE(search_result.value().entry->overlayable_item);
+ result_overlayable_item = search_result.value().entry->overlayable_item.value();
+ EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name"));
+ EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kOdm));
+
+ search_result = table_.FindResource(test::ParseNameOrDie("string/buz"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ ASSERT_TRUE(search_result.value().entry->overlayable_item);
+ result_overlayable_item = search_result.value().entry->overlayable_item.value();
+ EXPECT_THAT(result_overlayable_item.overlayable->name, Eq("Name"));
+ EXPECT_THAT(result_overlayable_item.policies, Eq(OverlayableItem::Policy::kOem));
}
TEST_F(ResourceParserTest, ParseOverlayableNoPolicyError) {
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 7ed7897..30ba1ae 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -79,22 +79,28 @@
// Represents the types overlays that are allowed to overlay the resource.
typedef uint32_t PolicyFlags;
enum Policy : uint32_t {
- kNone = 0x00,
+ kNone = 0x00000000,
// The resource can be overlaid by any overlay.
- kPublic = 0x01,
+ kPublic = 0x00000001,
// The resource can be overlaid by any overlay on the system partition.
- kSystem = 0x02,
+ kSystem = 0x00000002,
// The resource can be overlaid by any overlay on the vendor partition.
- kVendor = 0x04,
+ kVendor = 0x00000004,
// The resource can be overlaid by any overlay on the product partition.
- kProduct = 0x08,
+ kProduct = 0x00000008,
// The resource can be overlaid by any overlay signed with the same signature as its actor.
- kSignature = 0x010,
+ kSignature = 0x00000010,
+
+ // The resource can be overlaid by any overlay on the odm partition.
+ kOdm = 0x00000020,
+
+ // The resource can be overlaid by any overlay on the oem partition.
+ kOem = 0x00000040,
};
std::shared_ptr<Overlayable> overlayable;
diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto
index a2fd7c6..12cf65b 100644
--- a/tools/aapt2/Resources.proto
+++ b/tools/aapt2/Resources.proto
@@ -157,6 +157,8 @@
VENDOR = 3;
PRODUCT = 4;
SIGNATURE = 5;
+ ODM = 6;
+ OEM = 7;
}
// The location of the <item> declaration in source.
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp
index 59eb9ec2..fd8e36e 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.cpp
+++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp
@@ -475,6 +475,14 @@
& ResTable_overlayable_policy_header::POLICY_SIGNATURE) {
policies |= OverlayableItem::Policy::kSignature;
}
+ if (policy_header->policy_flags
+ & ResTable_overlayable_policy_header::POLICY_ODM_PARTITION) {
+ policies |= OverlayableItem::Policy::kOdm;
+ }
+ if (policy_header->policy_flags
+ & ResTable_overlayable_policy_header::POLICY_OEM_PARTITION) {
+ policies |= OverlayableItem::Policy::kOem;
+ }
const ResTable_ref* const ref_begin = reinterpret_cast<const ResTable_ref*>(
((uint8_t *)policy_header) + util::DeviceToHost32(policy_header->header.headerSize));
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index aa578a2..f2e72da 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -496,6 +496,12 @@
if (item.policies & OverlayableItem::Policy::kSignature) {
policy_flags |= ResTable_overlayable_policy_header::POLICY_SIGNATURE;
}
+ if (item.policies & OverlayableItem::Policy::kOdm) {
+ policy_flags |= ResTable_overlayable_policy_header::POLICY_ODM_PARTITION;
+ }
+ if (item.policies & OverlayableItem::Policy::kOem) {
+ policy_flags |= ResTable_overlayable_policy_header::POLICY_OEM_PARTITION;
+ }
auto policy = overlayable_chunk->policy_ids.find(policy_flags);
if (policy != overlayable_chunk->policy_ids.end()) {
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index 4c5dbec..a940923 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -724,8 +724,8 @@
std::string name_two = "com.app.test:integer/overlayable_two";
OverlayableItem overlayable_item_two(group);
- overlayable_item_two.policies |= OverlayableItem::Policy::kProduct;
- overlayable_item_two.policies |= OverlayableItem::Policy::kSystem;
+ overlayable_item_two.policies |= OverlayableItem::Policy::kOdm;
+ overlayable_item_two.policies |= OverlayableItem::Policy::kOem;
overlayable_item_two.policies |= OverlayableItem::Policy::kVendor;
std::string name_three = "com.app.test:integer/overlayable_three";
@@ -744,6 +744,7 @@
.AddSimple(name_three, ResourceId(0x7f020003))
.SetOverlayable(name_three, overlayable_item_three)
.Build();
+
ResourceTable output_table;
ASSERT_TRUE(Flatten(context_.get(), {}, table.get(), &output_table));
auto search_result = output_table.FindResource(test::ParseNameOrDie(name_zero));
@@ -755,6 +756,7 @@
EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://theme");
EXPECT_EQ(result_overlayable.policies, OverlayableItem::Policy::kSystem
| OverlayableItem::Policy::kProduct);
+
search_result = output_table.FindResource(test::ParseNameOrDie(name_one));
ASSERT_TRUE(search_result);
ASSERT_THAT(search_result.value().entry, NotNull());
@@ -763,6 +765,7 @@
EXPECT_EQ(result_overlayable.overlayable->name, "OtherName");
EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://customization");
EXPECT_EQ(result_overlayable.policies, OverlayableItem::Policy::kPublic);
+
search_result = output_table.FindResource(test::ParseNameOrDie(name_two));
ASSERT_TRUE(search_result);
ASSERT_THAT(search_result.value().entry, NotNull());
@@ -770,9 +773,10 @@
result_overlayable = search_result.value().entry->overlayable_item.value();
EXPECT_EQ(result_overlayable.overlayable->name, "TestName");
EXPECT_EQ(result_overlayable.overlayable->actor, "overlay://theme");
- EXPECT_EQ(result_overlayable.policies, OverlayableItem::Policy::kSystem
- | OverlayableItem::Policy::kProduct
+ EXPECT_EQ(result_overlayable.policies, OverlayableItem::Policy::kOdm
+ | OverlayableItem::Policy::kOem
| OverlayableItem::Policy::kVendor);
+
search_result = output_table.FindResource(test::ParseNameOrDie(name_three));
ASSERT_TRUE(search_result);
ASSERT_THAT(search_result.value().entry, NotNull());
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index 06f1bf7..bb21c1c 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -393,6 +393,12 @@
case pb::OverlayableItem::SIGNATURE:
out_overlayable->policies |= OverlayableItem::Policy::kSignature;
break;
+ case pb::OverlayableItem::ODM:
+ out_overlayable->policies |= OverlayableItem::Policy::kOdm;
+ break;
+ case pb::OverlayableItem::OEM:
+ out_overlayable->policies |= OverlayableItem::Policy::kOem;
+ break;
default:
*out_error = "unknown overlayable policy";
return false;
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index eb2b1a2..58e1e6e 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -312,6 +312,12 @@
if (overlayable_item.policies & OverlayableItem::Policy::kSignature) {
pb_overlayable_item->add_policy(pb::OverlayableItem::SIGNATURE);
}
+ if (overlayable_item.policies & OverlayableItem::Policy::kOdm) {
+ pb_overlayable_item->add_policy(pb::OverlayableItem::ODM);
+ }
+ if (overlayable_item.policies & OverlayableItem::Policy::kOem) {
+ pb_overlayable_item->add_policy(pb::OverlayableItem::OEM);
+ }
SerializeSourceToPb(overlayable_item.source, source_pool,
pb_overlayable_item->mutable_source());
diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
index d369ac4..f252f33 100644
--- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
@@ -529,6 +529,8 @@
OverlayableItem overlayable_item_boz(std::make_shared<Overlayable>(
"IconPack", "overlay://theme"));
overlayable_item_boz.policies |= OverlayableItem::Policy::kSignature;
+ overlayable_item_boz.policies |= OverlayableItem::Policy::kOdm;
+ overlayable_item_boz.policies |= OverlayableItem::Policy::kOem;
OverlayableItem overlayable_item_biz(std::make_shared<Overlayable>(
"Other", "overlay://customization"));
@@ -587,7 +589,9 @@
overlayable_item = search_result.value().entry->overlayable_item.value();
EXPECT_THAT(overlayable_item.overlayable->name, Eq("IconPack"));
EXPECT_THAT(overlayable_item.overlayable->actor, Eq("overlay://theme"));
- EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature));
+ EXPECT_THAT(overlayable_item.policies, Eq(OverlayableItem::Policy::kSignature
+ | OverlayableItem::Policy::kOdm
+ | OverlayableItem::Policy::kOem));
search_result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/biz"));
ASSERT_TRUE(search_result);