Merge "compare android::Vector and std::vector"
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 7dff1b8..ba6df7a 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -337,9 +337,12 @@
case ADB_AUTH_SIGNATURE: {
// TODO: Switch to string_view.
std::string signature(p->payload.begin(), p->payload.end());
- if (adbd_auth_verify(t->token, sizeof(t->token), signature)) {
+ std::string auth_key;
+ if (adbd_auth_verify(t->token, sizeof(t->token), signature, &auth_key)) {
adbd_auth_verified(t);
t->failed_auth_attempts = 0;
+ t->auth_key = auth_key;
+ adbd_notify_framework_connected_key(t);
} else {
if (t->failed_auth_attempts++ > 256) std::this_thread::sleep_for(1s);
send_auth_request(t);
@@ -348,7 +351,8 @@
}
case ADB_AUTH_RSAPUBLICKEY:
- adbd_auth_confirm_key(p->payload.data(), p->msg.data_length, t);
+ t->auth_key = std::string(p->payload.data());
+ adbd_auth_confirm_key(t);
break;
#endif
default:
diff --git a/adb/adb.h b/adb/adb.h
index 352b2fe..c6cb06a 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -33,6 +33,7 @@
constexpr size_t MAX_PAYLOAD_V1 = 4 * 1024;
constexpr size_t MAX_PAYLOAD = 1024 * 1024;
+constexpr size_t MAX_FRAMEWORK_PAYLOAD = 64 * 1024;
constexpr size_t LINUX_MAX_SOCKET_SIZE = 4194304;
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index 2fc8478..2be9a76 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -50,8 +50,10 @@
void adbd_auth_verified(atransport *t);
void adbd_cloexec_auth_socket();
-bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig);
-void adbd_auth_confirm_key(const char* data, size_t len, atransport* t);
+bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig,
+ std::string* auth_key);
+void adbd_auth_confirm_key(atransport* t);
+void adbd_notify_framework_connected_key(atransport* t);
void send_auth_request(atransport *t);
diff --git a/adb/daemon/auth.cpp b/adb/daemon/auth.cpp
index 2b8f461..7a3a4f5 100644
--- a/adb/daemon/auth.cpp
+++ b/adb/daemon/auth.cpp
@@ -26,7 +26,9 @@
#include <resolv.h>
#include <stdio.h>
#include <string.h>
+#include <iomanip>
+#include <algorithm>
#include <memory>
#include <android-base/file.h>
@@ -38,22 +40,24 @@
static fdevent* listener_fde = nullptr;
static fdevent* framework_fde = nullptr;
-static int framework_fd = -1;
+static auto& framework_mutex = *new std::mutex();
+static int framework_fd GUARDED_BY(framework_mutex) = -1;
+static auto& connected_keys GUARDED_BY(framework_mutex) = *new std::vector<std::string>;
-static void usb_disconnected(void* unused, atransport* t);
-static struct adisconnect usb_disconnect = { usb_disconnected, nullptr};
-static atransport* usb_transport;
+static void adb_disconnected(void* unused, atransport* t);
+static struct adisconnect adb_disconnect = {adb_disconnected, nullptr};
+static atransport* adb_transport;
static bool needs_retry = false;
bool auth_required = true;
-bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig) {
+bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig,
+ std::string* auth_key) {
static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr };
for (const auto& path : key_paths) {
if (access(path, R_OK) == 0) {
LOG(INFO) << "Loading keys from " << path;
-
std::string content;
if (!android::base::ReadFileToString(path, &content)) {
PLOG(ERROR) << "Couldn't read " << path;
@@ -61,6 +65,8 @@
}
for (const auto& line : android::base::Split(content, "\n")) {
+ if (line.empty()) continue;
+ *auth_key = line;
// TODO: do we really have to support both ' ' and '\t'?
char* sep = strpbrk(const_cast<char*>(line.c_str()), " \t");
if (sep) *sep = '\0';
@@ -88,9 +94,31 @@
}
}
}
+ auth_key->clear();
return false;
}
+static bool adbd_send_key_message_locked(std::string_view msg_type, std::string_view key)
+ REQUIRES(framework_mutex) {
+ if (framework_fd < 0) {
+ LOG(ERROR) << "Client not connected to send msg_type " << msg_type;
+ return false;
+ }
+ std::string msg = std::string(msg_type) + std::string(key);
+ int msg_len = msg.length();
+ if (msg_len >= static_cast<int>(MAX_FRAMEWORK_PAYLOAD)) {
+ LOG(ERROR) << "Key too long (" << msg_len << ")";
+ return false;
+ }
+
+ LOG(DEBUG) << "Sending '" << msg << "'";
+ if (!WriteFdExactly(framework_fd, msg.c_str(), msg_len)) {
+ PLOG(ERROR) << "Failed to write " << msg_type;
+ return false;
+ }
+ return true;
+}
+
static bool adbd_auth_generate_token(void* token, size_t token_size) {
FILE* fp = fopen("/dev/urandom", "re");
if (!fp) return false;
@@ -99,17 +127,28 @@
return okay;
}
-static void usb_disconnected(void* unused, atransport* t) {
- LOG(INFO) << "USB disconnect";
- usb_transport = nullptr;
+static void adb_disconnected(void* unused, atransport* t) {
+ LOG(INFO) << "ADB disconnect";
+ adb_transport = nullptr;
needs_retry = false;
+ {
+ std::lock_guard<std::mutex> lock(framework_mutex);
+ if (framework_fd >= 0) {
+ adbd_send_key_message_locked("DC", t->auth_key);
+ }
+ connected_keys.erase(std::remove(connected_keys.begin(), connected_keys.end(), t->auth_key),
+ connected_keys.end());
+ }
}
static void framework_disconnected() {
LOG(INFO) << "Framework disconnect";
if (framework_fde) {
fdevent_destroy(framework_fde);
- framework_fd = -1;
+ {
+ std::lock_guard<std::mutex> lock(framework_mutex);
+ framework_fd = -1;
+ }
}
}
@@ -120,41 +159,28 @@
if (ret <= 0) {
framework_disconnected();
} else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
- if (usb_transport) {
- adbd_auth_verified(usb_transport);
+ if (adb_transport) {
+ adbd_auth_verified(adb_transport);
}
}
}
}
-void adbd_auth_confirm_key(const char* key, size_t len, atransport* t) {
- if (!usb_transport) {
- usb_transport = t;
- t->AddDisconnect(&usb_disconnect);
+void adbd_auth_confirm_key(atransport* t) {
+ if (!adb_transport) {
+ adb_transport = t;
+ t->AddDisconnect(&adb_disconnect);
}
- if (framework_fd < 0) {
- LOG(ERROR) << "Client not connected";
- needs_retry = true;
- return;
- }
+ {
+ std::lock_guard<std::mutex> lock(framework_mutex);
+ if (framework_fd < 0) {
+ LOG(ERROR) << "Client not connected";
+ needs_retry = true;
+ return;
+ }
- if (key[len - 1] != '\0') {
- LOG(ERROR) << "Key must be a null-terminated string";
- return;
- }
-
- char msg[MAX_PAYLOAD_V1];
- int msg_len = snprintf(msg, sizeof(msg), "PK%s", key);
- if (msg_len >= static_cast<int>(sizeof(msg))) {
- LOG(ERROR) << "Key too long (" << msg_len << ")";
- return;
- }
- LOG(DEBUG) << "Sending '" << msg << "'";
-
- if (unix_write(framework_fd, msg, msg_len) == -1) {
- PLOG(ERROR) << "Failed to write PK";
- return;
+ adbd_send_key_message_locked("PK", t->auth_key);
}
}
@@ -165,18 +191,46 @@
return;
}
- if (framework_fd >= 0) {
- LOG(WARNING) << "adb received framework auth socket connection again";
- framework_disconnected();
+ {
+ std::lock_guard<std::mutex> lock(framework_mutex);
+ if (framework_fd >= 0) {
+ LOG(WARNING) << "adb received framework auth socket connection again";
+ framework_disconnected();
+ }
+
+ framework_fd = s;
+ framework_fde = fdevent_create(framework_fd, adbd_auth_event, nullptr);
+ fdevent_add(framework_fde, FDE_READ);
+
+ if (needs_retry) {
+ needs_retry = false;
+ send_auth_request(adb_transport);
+ }
+
+ // if a client connected before the framework was available notify the framework of the
+ // connected key now.
+ if (!connected_keys.empty()) {
+ for (const auto& key : connected_keys) {
+ adbd_send_key_message_locked("CK", key);
+ }
+ }
}
+}
- framework_fd = s;
- framework_fde = fdevent_create(framework_fd, adbd_auth_event, nullptr);
- fdevent_add(framework_fde, FDE_READ);
-
- if (needs_retry) {
- needs_retry = false;
- send_auth_request(usb_transport);
+void adbd_notify_framework_connected_key(atransport* t) {
+ if (!adb_transport) {
+ adb_transport = t;
+ t->AddDisconnect(&adb_disconnect);
+ }
+ {
+ std::lock_guard<std::mutex> lock(framework_mutex);
+ if (std::find(connected_keys.begin(), connected_keys.end(), t->auth_key) ==
+ connected_keys.end()) {
+ connected_keys.push_back(t->auth_key);
+ }
+ if (framework_fd >= 0) {
+ adbd_send_key_message_locked("CK", t->auth_key);
+ }
}
}
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index f4aa9fb..1abae87 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -509,16 +509,14 @@
}
if (id.direction == TransferDirection::READ) {
- if (!HandleRead(id, event.res)) {
- return;
- }
+ HandleRead(id, event.res);
} else {
HandleWrite(id);
}
}
}
- bool HandleRead(TransferId id, int64_t size) {
+ void HandleRead(TransferId id, int64_t size) {
uint64_t read_idx = id.id % kUsbReadQueueDepth;
IoBlock* block = &read_requests_[read_idx];
block->pending = false;
@@ -528,7 +526,7 @@
if (block->id().id != needed_read_id_) {
LOG(VERBOSE) << "read " << block->id().id << " completed while waiting for "
<< needed_read_id_;
- return true;
+ return;
}
for (uint64_t id = needed_read_id_;; ++id) {
@@ -537,22 +535,15 @@
if (current_block->pending) {
break;
}
- if (!ProcessRead(current_block)) {
- return false;
- }
+ ProcessRead(current_block);
++needed_read_id_;
}
-
- return true;
}
- bool ProcessRead(IoBlock* block) {
+ void ProcessRead(IoBlock* block) {
if (!block->payload->empty()) {
if (!incoming_header_.has_value()) {
- if (block->payload->size() != sizeof(amessage)) {
- HandleError("received packet of unexpected length while reading header");
- return false;
- }
+ CHECK_EQ(sizeof(amessage), block->payload->size());
amessage msg;
memcpy(&msg, block->payload->data(), sizeof(amessage));
LOG(DEBUG) << "USB read:" << dump_header(&msg);
@@ -560,10 +551,7 @@
} else {
size_t bytes_left = incoming_header_->data_length - incoming_payload_.size();
Block payload = std::move(*block->payload);
- if (block->payload->size() > bytes_left) {
- HandleError("received too many bytes while waiting for payload");
- return false;
- }
+ CHECK_LE(payload.size(), bytes_left);
incoming_payload_.append(std::make_unique<Block>(std::move(payload)));
}
@@ -582,7 +570,6 @@
PrepareReadBlock(block, block->id().id + kUsbReadQueueDepth);
SubmitRead(block);
- return true;
}
bool SubmitRead(IoBlock* block) {
diff --git a/adb/transport.h b/adb/transport.h
index 245037e..61a3d9a 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -275,6 +275,9 @@
std::string device;
std::string devpath;
+ // Used to provide the key to the framework.
+ std::string auth_key;
+
bool IsTcpDevice() const { return type == kTransportLocal; }
#if ADB_HOST
diff --git a/base/include/android-base/unique_fd.h b/base/include/android-base/unique_fd.h
index 6e11b4e..1605daf 100644
--- a/base/include/android-base/unique_fd.h
+++ b/base/include/android-base/unique_fd.h
@@ -120,7 +120,7 @@
// Catch bogus error checks (i.e.: "!fd" instead of "fd != -1").
bool operator!() const = delete;
- bool ok() const { return get() != -1; }
+ bool ok() const { return get() >= 0; }
int release() __attribute__((warn_unused_result)) {
tag(fd_, this, nullptr);
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index cd9fda3..dd24aac 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -1093,8 +1093,8 @@
void LogBootInfoToStatsd(std::chrono::milliseconds end_time,
std::chrono::milliseconds total_duration, int32_t bootloader_duration_ms,
double time_since_last_boot_sec) {
- const auto reason = android::base::GetProperty(bootloader_reboot_reason_property, "<EMPTY>");
- const auto system_reason = android::base::GetProperty(system_reboot_reason_property, "<EMPTY>");
+ auto reason = android::base::GetProperty(bootloader_reboot_reason_property, "<EMPTY>");
+ auto system_reason = android::base::GetProperty(system_reboot_reason_property, "<EMPTY>");
android::util::stats_write(android::util::BOOT_SEQUENCE_REPORTED, reason.c_str(),
system_reason.c_str(), end_time.count(), total_duration.count(),
(int64_t)bootloader_duration_ms,
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index f8c492d..c5d6a3b 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -579,12 +579,38 @@
return true;
}
-bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size) {
+Interval Interval::Intersect(const Interval& a, const Interval& b) {
+ Interval ret = a;
+ if (a.device_index != b.device_index) {
+ ret.start = ret.end = a.start; // set length to 0 to indicate no intersection.
+ return ret;
+ }
+ ret.start = std::max(a.start, b.start);
+ ret.end = std::max(ret.start, std::min(a.end, b.end));
+ return ret;
+}
+
+std::vector<Interval> Interval::Intersect(const std::vector<Interval>& a,
+ const std::vector<Interval>& b) {
+ std::vector<Interval> ret;
+ for (const Interval& a_interval : a) {
+ for (const Interval& b_interval : b) {
+ auto intersect = Intersect(a_interval, b_interval);
+ if (intersect.length() > 0) ret.emplace_back(std::move(intersect));
+ }
+ }
+ return ret;
+}
+
+bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size,
+ const std::vector<Interval>& free_region_hint) {
uint64_t space_needed = aligned_size - partition->size();
uint64_t sectors_needed = space_needed / LP_SECTOR_SIZE;
DCHECK(sectors_needed * LP_SECTOR_SIZE == space_needed);
std::vector<Interval> free_regions = GetFreeRegions();
+ if (!free_region_hint.empty())
+ free_regions = Interval::Intersect(free_regions, free_region_hint);
const uint64_t sectors_per_block = geometry_.logical_block_size / LP_SECTOR_SIZE;
CHECK_NE(sectors_per_block, 0);
@@ -650,7 +676,7 @@
return true;
}
-std::vector<MetadataBuilder::Interval> MetadataBuilder::PrioritizeSecondHalfOfSuper(
+std::vector<Interval> MetadataBuilder::PrioritizeSecondHalfOfSuper(
const std::vector<Interval>& free_list) {
const auto& super = block_devices_[0];
uint64_t first_sector = super.first_logical_sector;
@@ -926,7 +952,8 @@
return true;
}
-bool MetadataBuilder::ResizePartition(Partition* partition, uint64_t requested_size) {
+bool MetadataBuilder::ResizePartition(Partition* partition, uint64_t requested_size,
+ const std::vector<Interval>& free_region_hint) {
// Align the space needed up to the nearest sector.
uint64_t aligned_size = AlignTo(requested_size, geometry_.logical_block_size);
uint64_t old_size = partition->size();
@@ -936,7 +963,7 @@
}
if (aligned_size > old_size) {
- if (!GrowPartition(partition, aligned_size)) {
+ if (!GrowPartition(partition, aligned_size, free_region_hint)) {
return false;
}
} else if (aligned_size < partition->size()) {
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index c5b4047..bd41f59 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -887,3 +887,38 @@
std::set<std::string> partitions_to_keep{"system_a", "vendor_a", "product_a"};
ASSERT_TRUE(builder->ImportPartitions(*on_disk.get(), partitions_to_keep));
}
+
+// Interval has operator< defined; it is not appropriate to re-define Interval::operator== that
+// compares device index.
+namespace android {
+namespace fs_mgr {
+bool operator==(const Interval& a, const Interval& b) {
+ return a.device_index == b.device_index && a.start == b.start && a.end == b.end;
+}
+} // namespace fs_mgr
+} // namespace android
+
+TEST_F(BuilderTest, Interval) {
+ EXPECT_EQ(0u, Interval::Intersect(Interval(0, 100, 200), Interval(0, 50, 100)).length());
+ EXPECT_EQ(Interval(0, 100, 150),
+ Interval::Intersect(Interval(0, 100, 200), Interval(0, 50, 150)));
+ EXPECT_EQ(Interval(0, 100, 200),
+ Interval::Intersect(Interval(0, 100, 200), Interval(0, 50, 200)));
+ EXPECT_EQ(Interval(0, 100, 200),
+ Interval::Intersect(Interval(0, 100, 200), Interval(0, 50, 250)));
+ EXPECT_EQ(Interval(0, 100, 200),
+ Interval::Intersect(Interval(0, 100, 200), Interval(0, 100, 200)));
+ EXPECT_EQ(Interval(0, 150, 200),
+ Interval::Intersect(Interval(0, 100, 200), Interval(0, 150, 250)));
+ EXPECT_EQ(0u, Interval::Intersect(Interval(0, 100, 200), Interval(0, 200, 250)).length());
+
+ auto v = Interval::Intersect(std::vector<Interval>{Interval(0, 0, 50), Interval(0, 100, 150)},
+ std::vector<Interval>{Interval(0, 25, 125)});
+ ASSERT_EQ(2, v.size());
+ EXPECT_EQ(Interval(0, 25, 50), v[0]);
+ EXPECT_EQ(Interval(0, 100, 125), v[1]);
+
+ EXPECT_EQ(0u, Interval::Intersect(std::vector<Interval>{Interval(0, 0, 50)},
+ std::vector<Interval>{Interval(0, 100, 150)})
+ .size());
+}
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index 5ab42f5..6f2ab75 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -138,6 +138,33 @@
uint64_t size_;
};
+// An interval in the metadata. This is similar to a LinearExtent with one difference.
+// LinearExtent represents a "used" region in the metadata, while Interval can also represent
+// an "unused" region.
+struct Interval {
+ uint32_t device_index;
+ uint64_t start;
+ uint64_t end;
+
+ Interval(uint32_t device_index, uint64_t start, uint64_t end)
+ : device_index(device_index), start(start), end(end) {}
+ uint64_t length() const { return end - start; }
+
+ // Note: the device index is not included in sorting (intervals are
+ // sorted in per-device lists).
+ bool operator<(const Interval& other) const {
+ return (start == other.start) ? end < other.end : start < other.start;
+ }
+
+ // Intersect |a| with |b|.
+ // If no intersection, result has 0 length().
+ static Interval Intersect(const Interval& a, const Interval& b);
+
+ // Intersect two lists of intervals, and store result to |a|.
+ static std::vector<Interval> Intersect(const std::vector<Interval>& a,
+ const std::vector<Interval>& b);
+};
+
class MetadataBuilder {
public:
// Construct an empty logical partition table builder given the specified
@@ -244,7 +271,11 @@
//
// Note, this is an in-memory operation, and it does not alter the
// underlying filesystem or contents of the partition on disk.
- bool ResizePartition(Partition* partition, uint64_t requested_size);
+ //
+ // If |free_region_hint| is not empty, it will only try to allocate extents
+ // in regions within the list.
+ bool ResizePartition(Partition* partition, uint64_t requested_size,
+ const std::vector<Interval>& free_region_hint = {});
// Return the list of partitions belonging to a group.
std::vector<Partition*> ListPartitionsInGroup(const std::string& group_name);
@@ -291,6 +322,9 @@
// Return the name of the block device at |index|.
std::string GetBlockDevicePartitionName(uint64_t index) const;
+ // Return the list of free regions not occupied by extents in the metadata.
+ std::vector<Interval> GetFreeRegions() const;
+
private:
MetadataBuilder();
MetadataBuilder(const MetadataBuilder&) = delete;
@@ -300,7 +334,8 @@
bool Init(const std::vector<BlockDeviceInfo>& block_devices, const std::string& super_partition,
uint32_t metadata_max_size, uint32_t metadata_slot_count);
bool Init(const LpMetadata& metadata);
- bool GrowPartition(Partition* partition, uint64_t aligned_size);
+ bool GrowPartition(Partition* partition, uint64_t aligned_size,
+ const std::vector<Interval>& free_region_hint);
void ShrinkPartition(Partition* partition, uint64_t aligned_size);
uint64_t AlignSector(const LpMetadataBlockDevice& device, uint64_t sector) const;
uint64_t TotalSizeOfGroup(PartitionGroup* group) const;
@@ -323,22 +358,6 @@
bool ValidatePartitionGroups() const;
- struct Interval {
- uint32_t device_index;
- uint64_t start;
- uint64_t end;
-
- Interval(uint32_t device_index, uint64_t start, uint64_t end)
- : device_index(device_index), start(start), end(end) {}
- uint64_t length() const { return end - start; }
-
- // Note: the device index is not included in sorting (intervals are
- // sorted in per-device lists).
- bool operator<(const Interval& other) const {
- return (start == other.start) ? end < other.end : start < other.start;
- }
- };
- std::vector<Interval> GetFreeRegions() const;
bool IsAnyRegionCovered(const std::vector<Interval>& regions,
const LinearExtent& candidate) const;
bool IsAnyRegionAllocated(const LinearExtent& candidate) const;
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index 1f3828e..6f0e804 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -329,6 +329,10 @@
std::string GetSnapshotDeviceName(const std::string& snapshot_name,
const SnapshotStatus& status);
+ // Map the base device, COW devices, and snapshot device.
+ bool MapPartitionWithSnapshot(LockedFile* lock, CreateLogicalPartitionParams params,
+ std::string* path);
+
std::string gsid_dir_;
std::string metadata_dir_;
std::unique_ptr<IDeviceInfo> device_;
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 7f37dc5..7e57421 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sys/unistd.h>
+#include <optional>
#include <thread>
#include <unordered_set>
@@ -152,7 +153,13 @@
auto lock = LockExclusive();
if (!lock) return false;
- if (ReadUpdateState(lock.get()) != UpdateState::Initiated) {
+ auto update_state = ReadUpdateState(lock.get());
+ if (update_state == UpdateState::Unverified) {
+ LOG(INFO) << "FinishedSnapshotWrites already called before. Ignored.";
+ return true;
+ }
+
+ if (update_state != UpdateState::Initiated) {
LOG(ERROR) << "Can only transition to the Unverified state from the Initiated state.";
return false;
}
@@ -211,8 +218,27 @@
}
auto cow_name = GetCowName(name);
- int cow_flags = IImageManager::CREATE_IMAGE_ZERO_FILL;
- return images_->CreateBackingImage(cow_name, cow_size, cow_flags);
+ int cow_flags = IImageManager::CREATE_IMAGE_DEFAULT;
+ if (!images_->CreateBackingImage(cow_name, cow_size, cow_flags)) {
+ return false;
+ }
+
+ // when the kernel creates a persistent dm-snapshot, it requires a CoW file
+ // to store the modifications. The kernel interface does not specify how
+ // the CoW is used, and there is no standard associated.
+ // By looking at the current implementation, the CoW file is treated as:
+ // - a _NEW_ snapshot if its first 32 bits are zero, so the newly created
+ // dm-snapshot device will look like a perfect copy of the origin device;
+ // - an _EXISTING_ snapshot if the first 32 bits are equal to a
+ // kernel-specified magic number and the CoW file metadata is set as valid,
+ // so it can be used to resume the last state of a snapshot device;
+ // - an _INVALID_ snapshot otherwise.
+ // To avoid zero-filling the whole CoW file when a new dm-snapshot is
+ // created, here we zero-fill only the first 32 bits. This is a temporary
+ // workaround that will be discussed again when the kernel API gets
+ // consolidated.
+ ssize_t dm_snap_magic_size = 4; // 32 bit
+ return images_->ZeroFillNewImage(cow_name, dm_snap_magic_size);
}
bool SnapshotManager::MapSnapshot(LockedFile* lock, const std::string& name,
@@ -947,7 +973,7 @@
// flushed remaining I/O. We could in theory replace with dm-zero (or
// re-use the table above), but for now it's better to know why this
// would fail.
- if (!dm.DeleteDeviceIfExists(dm_name)) {
+ if (dm_name != name && !dm.DeleteDeviceIfExists(dm_name)) {
LOG(ERROR) << "Unable to delete snapshot device " << dm_name << ", COW cannot be "
<< "reclaimed until after reboot.";
return false;
@@ -1102,22 +1128,6 @@
auto lock = LockExclusive();
if (!lock) return false;
- std::vector<std::string> snapshot_list;
- if (!ListSnapshots(lock.get(), &snapshot_list)) {
- return false;
- }
-
- std::unordered_set<std::string> live_snapshots;
- for (const auto& snapshot : snapshot_list) {
- SnapshotStatus status;
- if (!ReadSnapshotStatus(lock.get(), snapshot, &status)) {
- return false;
- }
- if (status.state != SnapshotState::MergeCompleted) {
- live_snapshots.emplace(snapshot);
- }
- }
-
const auto& opener = device_->GetPartitionOpener();
uint32_t slot = SlotNumberForSlotSuffix(device_->GetSlotSuffix());
auto metadata = android::fs_mgr::ReadMetadata(opener, super_device, slot);
@@ -1126,59 +1136,102 @@
return false;
}
- // Map logical partitions.
- auto& dm = DeviceMapper::Instance();
for (const auto& partition : metadata->partitions) {
- auto partition_name = GetPartitionName(partition);
- if (!partition.num_extents) {
- LOG(INFO) << "Skipping zero-length logical partition: " << partition_name;
- continue;
- }
-
- if (!(partition.attributes & LP_PARTITION_ATTR_UPDATED)) {
- LOG(INFO) << "Detected re-flashing of partition, will skip snapshot: "
- << partition_name;
- live_snapshots.erase(partition_name);
- }
-
CreateLogicalPartitionParams params = {
.block_device = super_device,
.metadata = metadata.get(),
.partition = &partition,
.partition_opener = &opener,
};
-
- if (auto iter = live_snapshots.find(partition_name); iter != live_snapshots.end()) {
- // If the device has a snapshot, it'll need to be writable, and
- // we'll need to create the logical partition with a marked-up name
- // (since the snapshot will use the partition name).
- params.force_writable = true;
- params.device_name = GetBaseDeviceName(partition_name);
- }
-
std::string ignore_path;
- if (!CreateLogicalPartition(params, &ignore_path)) {
- LOG(ERROR) << "Could not create logical partition " << partition_name << " as device "
- << params.GetDeviceName();
- return false;
- }
- if (!params.force_writable) {
- // No snapshot.
- continue;
- }
-
- // We don't have ueventd in first-stage init, so use device major:minor
- // strings instead.
- std::string base_device;
- if (!dm.GetDeviceString(params.GetDeviceName(), &base_device)) {
- LOG(ERROR) << "Could not determine major/minor for: " << params.GetDeviceName();
- return false;
- }
- if (!MapSnapshot(lock.get(), partition_name, base_device, {}, &ignore_path)) {
- LOG(ERROR) << "Could not map snapshot for partition: " << partition_name;
+ if (!MapPartitionWithSnapshot(lock.get(), std::move(params), &ignore_path)) {
return false;
}
}
+
+ LOG(INFO) << "Created logical partitions with snapshot.";
+ return true;
+}
+
+bool SnapshotManager::MapPartitionWithSnapshot(LockedFile* lock,
+ CreateLogicalPartitionParams params,
+ std::string* path) {
+ CHECK(lock);
+ path->clear();
+
+ // Fill out fields in CreateLogicalPartitionParams so that we have more information (e.g. by
+ // reading super partition metadata).
+ CreateLogicalPartitionParams::OwnedData params_owned_data;
+ if (!params.InitDefaults(¶ms_owned_data)) {
+ return false;
+ }
+
+ if (!params.partition->num_extents) {
+ LOG(INFO) << "Skipping zero-length logical partition: " << params.GetPartitionName();
+ return true; // leave path empty to indicate that nothing is mapped.
+ }
+
+ // Determine if there is a live snapshot for the SnapshotStatus of the partition; i.e. if the
+ // partition still has a snapshot that needs to be mapped. If no live snapshot or merge
+ // completed, live_snapshot_status is set to nullopt.
+ std::optional<SnapshotStatus> live_snapshot_status;
+ do {
+ if (!(params.partition->attributes & LP_PARTITION_ATTR_UPDATED)) {
+ LOG(INFO) << "Detected re-flashing of partition, will skip snapshot: "
+ << params.GetPartitionName();
+ break;
+ }
+ auto file_path = GetSnapshotStatusFilePath(params.GetPartitionName());
+ if (access(file_path.c_str(), F_OK) != 0) {
+ if (errno != ENOENT) {
+ PLOG(INFO) << "Can't map snapshot for " << params.GetPartitionName()
+ << ": Can't access " << file_path;
+ return false;
+ }
+ break;
+ }
+ live_snapshot_status = std::make_optional<SnapshotStatus>();
+ if (!ReadSnapshotStatus(lock, params.GetPartitionName(), &*live_snapshot_status)) {
+ return false;
+ }
+ // No live snapshot if merge is completed.
+ if (live_snapshot_status->state == SnapshotState::MergeCompleted) {
+ live_snapshot_status.reset();
+ }
+ } while (0);
+
+ if (live_snapshot_status.has_value()) {
+ // dm-snapshot requires the base device to be writable.
+ params.force_writable = true;
+ // Map the base device with a different name to avoid collision.
+ params.device_name = GetBaseDeviceName(params.GetPartitionName());
+ }
+
+ auto& dm = DeviceMapper::Instance();
+ std::string ignore_path;
+ if (!CreateLogicalPartition(params, &ignore_path)) {
+ LOG(ERROR) << "Could not create logical partition " << params.GetPartitionName()
+ << " as device " << params.GetDeviceName();
+ return false;
+ }
+ if (!live_snapshot_status.has_value()) {
+ return true;
+ }
+
+ // We don't have ueventd in first-stage init, so use device major:minor
+ // strings instead.
+ std::string base_device;
+ if (!dm.GetDeviceString(params.GetDeviceName(), &base_device)) {
+ LOG(ERROR) << "Could not determine major/minor for: " << params.GetDeviceName();
+ return false;
+ }
+ if (!MapSnapshot(lock, params.GetPartitionName(), base_device, {}, path)) {
+ LOG(ERROR) << "Could not map snapshot for partition: " << params.GetPartitionName();
+ return false;
+ }
+
+ LOG(INFO) << "Mapped " << params.GetPartitionName() << " as snapshot device at " << *path;
+
return true;
}
diff --git a/healthd/Android.mk b/healthd/Android.mk
index b87f3c7..4e34759 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -23,7 +23,6 @@
libcharger_sysprop \
libhidltransport \
libhidlbase \
- libhwbinder_noltopgo \
libhealthstoragedefault \
libminui \
libvndksupport \
@@ -77,7 +76,6 @@
libcharger_sysprop \
libhidltransport \
libhidlbase \
- libhwbinder_noltopgo \
libhealthstoragedefault \
libvndksupport \
libhealthd_charger_nops \
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 7c66de5..d2c73cb 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -80,6 +80,7 @@
using namespace std::literals::string_literals;
using android::base::Basename;
+using android::base::StringPrintf;
using android::base::unique_fd;
using android::fs_mgr::Fstab;
using android::fs_mgr::ReadFstabFromFile;
@@ -1062,34 +1063,59 @@
return android::base::GetProperty("ro.crypto.type", "") == "file";
}
-static Result<void> ExecWithRebootOnFailure(const std::string& reboot_reason,
- const BuiltinArguments& args) {
- auto service = Service::MakeTemporaryOneshotService(args.args);
+static Result<void> ExecWithFunctionOnFailure(const std::vector<std::string>& args,
+ std::function<void(const std::string&)> function) {
+ auto service = Service::MakeTemporaryOneshotService(args);
if (!service) {
- return Error() << "Could not create exec service: " << service.error();
+ function("MakeTemporaryOneshotService failed: " + service.error().message());
}
- (*service)->AddReapCallback([reboot_reason](const siginfo_t& siginfo) {
+ (*service)->AddReapCallback([function](const siginfo_t& siginfo) {
if (siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) {
- // TODO (b/122850122): support this in gsi
- if (fscrypt_is_native() && !android::gsi::IsGsiRunning()) {
- LOG(ERROR) << "Rebooting into recovery, reason: " << reboot_reason;
- if (auto result = reboot_into_recovery(
- {"--prompt_and_wipe_data", "--reason="s + reboot_reason});
- !result) {
- LOG(FATAL) << "Could not reboot into recovery: " << result.error();
- }
- } else {
- LOG(ERROR) << "Failure (reboot suppressed): " << reboot_reason;
- }
+ function(StringPrintf("Exec service failed, status %d", siginfo.si_status));
}
});
if (auto result = (*service)->ExecStart(); !result) {
- return Error() << "Could not start exec service: " << result.error();
+ function("ExecStart failed: " + result.error().message());
}
ServiceList::GetInstance().AddService(std::move(*service));
return {};
}
+static Result<void> do_exec_reboot_on_failure(const BuiltinArguments& args) {
+ auto reboot_reason = args[1];
+ auto reboot = [reboot_reason](const std::string& message) {
+ property_set(LAST_REBOOT_REASON_PROPERTY, reboot_reason);
+ sync();
+ LOG(FATAL) << message << ": rebooting into bootloader, reason: " << reboot_reason;
+ };
+
+ std::vector<std::string> remaining_args(args.begin() + 1, args.end());
+ remaining_args[0] = args[0];
+
+ return ExecWithFunctionOnFailure(remaining_args, reboot);
+}
+
+static Result<void> ExecVdcRebootOnFailure(const std::string& vdc_arg) {
+ auto reboot_reason = vdc_arg + "_failed";
+
+ auto reboot = [reboot_reason](const std::string& message) {
+ // TODO (b/122850122): support this in gsi
+ if (fscrypt_is_native() && !android::gsi::IsGsiRunning()) {
+ LOG(ERROR) << message << ": Rebooting into recovery, reason: " << reboot_reason;
+ if (auto result = reboot_into_recovery(
+ {"--prompt_and_wipe_data", "--reason="s + reboot_reason});
+ !result) {
+ LOG(FATAL) << "Could not reboot into recovery: " << result.error();
+ }
+ } else {
+ LOG(ERROR) << "Failure (reboot suppressed): " << reboot_reason;
+ }
+ };
+
+ std::vector<std::string> args = {"exec", "/system/bin/vdc", "--wait", "cryptfs", vdc_arg};
+ return ExecWithFunctionOnFailure(args, reboot);
+}
+
static Result<void> do_installkey(const BuiltinArguments& args) {
if (!is_file_crypto()) return {};
@@ -1097,15 +1123,11 @@
if (!make_dir(unencrypted_dir, 0700) && errno != EEXIST) {
return ErrnoError() << "Failed to create " << unencrypted_dir;
}
- return ExecWithRebootOnFailure(
- "enablefilecrypto_failed",
- {{"exec", "/system/bin/vdc", "--wait", "cryptfs", "enablefilecrypto"}, args.context});
+ return ExecVdcRebootOnFailure("enablefilecrypto");
}
static Result<void> do_init_user0(const BuiltinArguments& args) {
- return ExecWithRebootOnFailure(
- "init_user0_failed",
- {{"exec", "/system/bin/vdc", "--wait", "cryptfs", "init_user0"}, args.context});
+ return ExecVdcRebootOnFailure("init_user0");
}
static Result<void> do_mark_post_data(const BuiltinArguments& args) {
@@ -1180,6 +1202,7 @@
{"enable", {1, 1, {false, do_enable}}},
{"exec", {1, kMax, {false, do_exec}}},
{"exec_background", {1, kMax, {false, do_exec_background}}},
+ {"exec_reboot_on_failure", {2, kMax, {false, do_exec_reboot_on_failure}}},
{"exec_start", {1, 1, {false, do_exec_start}}},
{"export", {2, 2, {false, do_export}}},
{"hostname", {1, 1, {true, do_hostname}}},
diff --git a/init/check_builtins.cpp b/init/check_builtins.cpp
index 771f1d7..2efaeea 100644
--- a/init/check_builtins.cpp
+++ b/init/check_builtins.cpp
@@ -81,6 +81,15 @@
return check_exec(std::move(args));
}
+Result<void> check_exec_reboot_on_failure(const BuiltinArguments& args) {
+ BuiltinArguments remaining_args(args.context);
+
+ remaining_args.args = std::vector<std::string>(args.begin() + 1, args.end());
+ remaining_args.args[0] = args[0];
+
+ return check_exec(remaining_args);
+}
+
Result<void> check_interface_restart(const BuiltinArguments& args) {
if (auto result = IsKnownInterface(args[1]); !result) {
return result.error();
diff --git a/init/check_builtins.h b/init/check_builtins.h
index 4ff0d0c..fb34556 100644
--- a/init/check_builtins.h
+++ b/init/check_builtins.h
@@ -25,6 +25,7 @@
Result<void> check_chown(const BuiltinArguments& args);
Result<void> check_exec(const BuiltinArguments& args);
Result<void> check_exec_background(const BuiltinArguments& args);
+Result<void> check_exec_reboot_on_failure(const BuiltinArguments& args);
Result<void> check_interface_restart(const BuiltinArguments& args);
Result<void> check_interface_start(const BuiltinArguments& args);
Result<void> check_interface_stop(const BuiltinArguments& args);
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index f1ca446..f71d0c3 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -86,6 +86,7 @@
const bool proxy_read_ready = last_proxy_events_.events & EPOLLIN;
const bool proxy_write_ready = last_proxy_events_.events & EPOLLOUT;
+ last_state_ = state_;
last_device_events_.events = 0;
last_proxy_events_.events = 0;
diff --git a/libcutils/ashmem-host.cpp b/libcutils/ashmem-host.cpp
index 32446d4..6c7655a 100644
--- a/libcutils/ashmem-host.cpp
+++ b/libcutils/ashmem-host.cpp
@@ -34,6 +34,29 @@
#include <utils/Compat.h>
+static bool ashmem_validate_stat(int fd, struct stat* buf) {
+ int result = fstat(fd, buf);
+ if (result == -1) {
+ return false;
+ }
+
+ /*
+ * Check if this is an "ashmem" region.
+ * TODO: This is very hacky, and can easily break.
+ * We need some reliable indicator.
+ */
+ if (!(buf->st_nlink == 0 && S_ISREG(buf->st_mode))) {
+ errno = ENOTTY;
+ return false;
+ }
+ return true;
+}
+
+int ashmem_valid(int fd) {
+ struct stat buf;
+ return ashmem_validate_stat(fd, &buf);
+}
+
int ashmem_create_region(const char* /*ignored*/, size_t size) {
char pattern[PATH_MAX];
snprintf(pattern, sizeof(pattern), "/tmp/android-ashmem-%d-XXXXXXXXX", getpid());
@@ -65,18 +88,7 @@
int ashmem_get_size_region(int fd)
{
struct stat buf;
- int result = fstat(fd, &buf);
- if (result == -1) {
- return -1;
- }
-
- /*
- * Check if this is an "ashmem" region.
- * TODO: This is very hacky, and can easily break.
- * We need some reliable indicator.
- */
- if (!(buf.st_nlink == 0 && S_ISREG(buf.st_mode))) {
- errno = ENOTTY;
+ if (!ashmem_validate_stat(fd, &buf)) {
return -1;
}
diff --git a/libcutils/include/cutils/native_handle.h b/libcutils/include/cutils/native_handle.h
index f6cae36..4f07456 100644
--- a/libcutils/include/cutils/native_handle.h
+++ b/libcutils/include/cutils/native_handle.h
@@ -69,10 +69,11 @@
/*
* native_handle_create
- *
+ *
* creates a native_handle_t and initializes it. must be destroyed with
- * native_handle_delete().
- *
+ * native_handle_delete(). Note that numFds must be <= NATIVE_HANDLE_MAX_FDS,
+ * numInts must be <= NATIVE_HANDLE_MAX_INTS, and both must be >= 0.
+ *
*/
native_handle_t* native_handle_create(int numFds, int numInts);
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 45a9bc9..5a73dc0 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -1747,22 +1747,21 @@
return count;
}
-
-// meant to be handed to ASSERT_TRUE / EXPECT_TRUE only to expand the message
-static testing::AssertionResult IsOk(bool ok, std::string& message) {
- return ok ? testing::AssertionSuccess()
- : (testing::AssertionFailure() << message);
-}
#endif // TEST_PREFIX
TEST(liblog, enoent) {
#ifdef TEST_PREFIX
+ if (getuid() != 0) {
+ GTEST_SKIP() << "Skipping test, must be run as root.";
+ return;
+ }
+
TEST_PREFIX
log_time ts(CLOCK_MONOTONIC);
EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
EXPECT_EQ(SUPPORTS_END_TO_END, count_matching_ts(ts));
- // This call will fail if we are setuid(AID_SYSTEM), beware of any
+ // This call will fail unless we are root, beware of any
// test prior to this one playing with setuid and causing interference.
// We need to run before these tests so that they do not interfere with
// this test.
@@ -1774,20 +1773,7 @@
// liblog.android_logger_get_ is one of those tests that has no recourse
// and that would be adversely affected by emptying the log if it was run
// right after this test.
- if (getuid() != AID_ROOT) {
- fprintf(
- stderr,
- "WARNING: test conditions request being run as root and not AID=%d\n",
- getuid());
- if (!__android_log_is_debuggable()) {
- fprintf(
- stderr,
- "WARNING: can not run test on a \"user\" build, bypassing test\n");
- return;
- }
- }
-
- system((getuid() == AID_ROOT) ? "stop logd" : "su 0 stop logd");
+ system("stop logd");
usleep(1000000);
// A clean stop like we are testing returns -ENOENT, but in the _real_
@@ -1799,19 +1785,15 @@
std::string content = android::base::StringPrintf(
"__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) = %d %s\n",
ret, (ret <= 0) ? strerror(-ret) : "(content sent)");
- EXPECT_TRUE(
- IsOk((ret == -ENOENT) || (ret == -ENOTCONN) || (ret == -ECONNREFUSED),
- content));
+ EXPECT_TRUE(ret == -ENOENT || ret == -ENOTCONN || ret == -ECONNREFUSED) << content;
ret = __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts));
content = android::base::StringPrintf(
"__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) = %d %s\n",
ret, (ret <= 0) ? strerror(-ret) : "(content sent)");
- EXPECT_TRUE(
- IsOk((ret == -ENOENT) || (ret == -ENOTCONN) || (ret == -ECONNREFUSED),
- content));
+ EXPECT_TRUE(ret == -ENOENT || ret == -ENOTCONN || ret == -ECONNREFUSED) << content;
EXPECT_EQ(0, count_matching_ts(ts));
- system((getuid() == AID_ROOT) ? "start logd" : "su 0 start logd");
+ system("start logd");
usleep(1000000);
EXPECT_EQ(0, count_matching_ts(ts));
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index d864d1b..f20df19 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -113,7 +113,7 @@
static_libs: ["libmemunreachable"],
shared_libs: [
"libbinder",
- "libhwbinder",
+ "libhidlbase",
"libutils",
],
test_suites: ["device-tests"],
diff --git a/libstats/statsd_writer.c b/libstats/statsd_writer.c
index b778f92..b1c05ea 100644
--- a/libstats/statsd_writer.c
+++ b/libstats/statsd_writer.c
@@ -109,6 +109,11 @@
if (sock < 0) {
ret = -errno;
} else {
+ int sndbuf = 1 * 1024 * 1024; // set max send buffer size 1MB
+ socklen_t bufLen = sizeof(sndbuf);
+ // SO_RCVBUF does not have an effect on unix domain socket, but SO_SNDBUF does.
+ // Proceed to connect even setsockopt fails.
+ setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, bufLen);
struct sockaddr_un un;
memset(&un, 0, sizeof(struct sockaddr_un));
un.sun_family = AF_UNIX;
diff --git a/libsystem/include/system/graphics-base-v1.2.h b/libsystem/include/system/graphics-base-v1.2.h
new file mode 100644
index 0000000..2194f5e
--- /dev/null
+++ b/libsystem/include/system/graphics-base-v1.2.h
@@ -0,0 +1,31 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+// Source: android.hardware.graphics.common@1.2
+// Location: hardware/interfaces/graphics/common/1.2/
+
+#ifndef HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_
+#define HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ HAL_HDR_HDR10_PLUS = 4,
+} android_hdr_v1_2_t;
+
+typedef enum {
+ HAL_DATASPACE_DISPLAY_BT2020 = 142999552 /* ((STANDARD_BT2020 | TRANSFER_SRGB) | RANGE_FULL) */,
+ HAL_DATASPACE_DYNAMIC_DEPTH = 4098 /* 0x1002 */,
+ HAL_DATASPACE_JPEG_APP_SEGMENTS = 4099 /* 0x1003 */,
+ HAL_DATASPACE_HEIF = 4100 /* 0x1004 */,
+} android_dataspace_v1_2_t;
+
+typedef enum {
+ HAL_PIXEL_FORMAT_HSV_888 = 55 /* 0x37 */,
+} android_pixel_format_v1_2_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_
diff --git a/libsystem/include/system/graphics-base.h b/libsystem/include/system/graphics-base.h
index ea92007..92ee077 100644
--- a/libsystem/include/system/graphics-base.h
+++ b/libsystem/include/system/graphics-base.h
@@ -3,5 +3,6 @@
#include "graphics-base-v1.0.h"
#include "graphics-base-v1.1.h"
+#include "graphics-base-v1.2.h"
#endif // SYSTEM_CORE_GRAPHICS_BASE_H_
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 14246ae..da18af6 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -153,12 +153,12 @@
shared_libs: [
"libunwindstack",
],
+ relative_install_path: "libunwindstack_test",
}
-cc_test {
- name: "libunwindstack_test",
+cc_defaults {
+ name: "libunwindstack_testlib_flags",
defaults: ["libunwindstack_flags"],
- isolated: true,
srcs: [
"tests/ArmExidxDecodeTest.cpp",
@@ -183,7 +183,6 @@
"tests/ElfTestUtils.cpp",
"tests/IsolatedSettings.cpp",
"tests/JitDebugTest.cpp",
- "tests/LocalUnwinderTest.cpp",
"tests/LogFake.cpp",
"tests/MapInfoCreateMemoryTest.cpp",
"tests/MapInfoGetBuildIDTest.cpp",
@@ -253,11 +252,28 @@
"tests/files/offline/straddle_arm/*",
"tests/files/offline/straddle_arm64/*",
],
+}
+
+cc_test {
+ name: "libunwindstack_test",
+ defaults: ["libunwindstack_testlib_flags"],
+ isolated: true,
+
+ srcs: [
+ "tests/LocalUnwinderTest.cpp",
+ ],
required: [
"libunwindstack_local",
],
}
+// Skip LocalUnwinderTest until atest understands required properly.
+cc_test {
+ name: "libunwindstack_unit_test",
+ defaults: ["libunwindstack_testlib_flags"],
+ isolated: true,
+}
+
//-------------------------------------------------------------------------
// Tools
//-------------------------------------------------------------------------
diff --git a/libunwindstack/TEST_MAPPING b/libunwindstack/TEST_MAPPING
new file mode 100644
index 0000000..55771c0
--- /dev/null
+++ b/libunwindstack/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "libunwindstack_unit_test"
+ }
+ ]
+}
diff --git a/libunwindstack/tests/LocalUnwinderTest.cpp b/libunwindstack/tests/LocalUnwinderTest.cpp
index 56a18cd..9936f7a 100644
--- a/libunwindstack/tests/LocalUnwinderTest.cpp
+++ b/libunwindstack/tests/LocalUnwinderTest.cpp
@@ -170,10 +170,10 @@
std::string testlib(testing::internal::GetArgvs()[0]);
auto const value = testlib.find_last_of('/');
- if (value == std::string::npos) {
- testlib = "../";
+ if (value != std::string::npos) {
+ testlib = testlib.substr(0, value + 1);
} else {
- testlib = testlib.substr(0, value + 1) + "../";
+ testlib = "";
}
testlib += "libunwindstack_local.so";
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 42af751..d17da12 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -1433,8 +1433,8 @@
set_process_group_and_prio(pid, SP_FOREGROUND, ANDROID_PRIORITY_HIGHEST);
inc_killcnt(procp->oomadj);
- ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB",
- taskname, pid, uid, procp->oomadj, tasksize * page_k);
+ ALOGE("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB", taskname, pid, uid, procp->oomadj,
+ tasksize * page_k);
TRACE_KILL_END();
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 2fa110b..df1d929 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -233,18 +233,7 @@
LOCAL_POST_INSTALL_CMD += && ln -sf /apex/com.android.i18n/etc/icu $(TARGET_OUT)/usr/icu
# TODO(b/124106384): Clean up compat symlinks for ART binaries.
-ART_BINARIES := \
- dalvikvm \
- dalvikvm32 \
- dalvikvm64 \
- dex2oat \
- dexdiag \
- dexdump \
- dexlist \
- dexoptanalyzer \
- oatdump \
- profman \
-
+ART_BINARIES := dalvikvm dex2oat
LOCAL_POST_INSTALL_CMD += && mkdir -p $(TARGET_OUT)/bin
$(foreach b,$(ART_BINARIES), \
$(eval LOCAL_POST_INSTALL_CMD += \
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index c8c6387..e1da587 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -190,6 +190,7 @@
namespace.media.asan.search.paths = /apex/com.android.media/${LIB}
namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors
+namespace.media.asan.permitted.paths = /apex/com.android.media/${LIB}/extractors
namespace.media.links = default,neuralnetworks
namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES%
@@ -723,6 +724,7 @@
namespace.media.asan.search.paths = /apex/com.android.media/${LIB}
namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors
+namespace.media.asan.permitted.paths = /apex/com.android.media/${LIB}/extractors
namespace.media.links = default,neuralnetworks
namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES%
diff --git a/rootdir/etc/public.libraries.android.txt b/rootdir/etc/public.libraries.android.txt
index d8f6095..27e855f 100644
--- a/rootdir/etc/public.libraries.android.txt
+++ b/rootdir/etc/public.libraries.android.txt
@@ -1,6 +1,7 @@
# See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
libandroid.so
libaaudio.so
+libamidi.so
libbinder_ndk.so
libc.so
libcamera2ndk.so
diff --git a/rootdir/etc/public.libraries.iot.txt b/rootdir/etc/public.libraries.iot.txt
index 20905bf..b565340 100644
--- a/rootdir/etc/public.libraries.iot.txt
+++ b/rootdir/etc/public.libraries.iot.txt
@@ -2,6 +2,7 @@
libandroid.so
libandroidthings.so
libaaudio.so
+libamidi.so
libbinder_ndk.so
libc.so
libcamera2ndk.so
diff --git a/rootdir/etc/public.libraries.wear.txt b/rootdir/etc/public.libraries.wear.txt
index 4ece5b5..7cbda08 100644
--- a/rootdir/etc/public.libraries.wear.txt
+++ b/rootdir/etc/public.libraries.wear.txt
@@ -1,6 +1,7 @@
# See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
libandroid.so
libaaudio.so
+libamidi.so
libbinder_ndk.so
libc.so
libcamera2ndk.so
diff --git a/rootdir/init.rc b/rootdir/init.rc
index bb36139..afa1a86 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -431,10 +431,6 @@
# HALs required before storage encryption can get unlocked (FBE/FDE)
class_start early_hal
- # Check and mark a successful boot, before mounting userdata with mount_all.
- # No-op for non-A/B device.
- exec_start update_verifier_nonencrypted
-
on post-fs-data
mark_post_data
@@ -669,16 +665,22 @@
# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start && property:ro.crypto.state=unencrypted
+ # A/B update verifier that marks a successful boot.
+ exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
on zygote-start && property:ro.crypto.state=unsupported
+ # A/B update verifier that marks a successful boot.
+ exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
+ # A/B update verifier that marks a successful boot.
+ exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
@@ -702,6 +704,12 @@
chown root system /sys/module/lowmemorykiller/parameters/minfree
chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
+ # System server manages zram writeback
+ chown root system /sys/block/zram0/idle
+ chmod 0664 /sys/block/zram0/idle
+ chown root system /sys/block/zram0/writeback
+ chmod 0664 /sys/block/zram0/writeback
+
# Tweak background writeout
write /proc/sys/vm/dirty_expire_centisecs 200
write /proc/sys/vm/dirty_background_ratio 5
@@ -801,6 +809,8 @@
trigger zygote-start
on property:vold.decrypt=trigger_restart_min_framework
+ # A/B update verifier that marks a successful boot.
+ exec_start update_verifier
class_start main
on property:vold.decrypt=trigger_restart_framework
diff --git a/rootdir/init.usb.rc b/rootdir/init.usb.rc
index f0681d2..b6cba90 100644
--- a/rootdir/init.usb.rc
+++ b/rootdir/init.usb.rc
@@ -14,7 +14,7 @@
# adbd is controlled via property triggers in init.<platform>.usb.rc
service adbd /system/bin/adbd --root_seclabel=u:r:su:s0
class core
- socket adbd stream 660 system system
+ socket adbd seqpacket 660 system system
disabled
seclabel u:r:adbd:s0
diff --git a/rootdir/init.zygote32.rc b/rootdir/init.zygote32.rc
index f8e680d..bf3fb42 100644
--- a/rootdir/init.zygote32.rc
+++ b/rootdir/init.zygote32.rc
@@ -4,7 +4,7 @@
user root
group root readproc reserved_disk
socket zygote stream 660 root system
- socket blastula_pool stream 660 root system
+ socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
diff --git a/rootdir/init.zygote32_64.rc b/rootdir/init.zygote32_64.rc
index 0235370..1bab588 100644
--- a/rootdir/init.zygote32_64.rc
+++ b/rootdir/init.zygote32_64.rc
@@ -4,7 +4,7 @@
user root
group root readproc reserved_disk
socket zygote stream 660 root system
- socket blastula_pool stream 660 root system
+ socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
@@ -20,6 +20,6 @@
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
- socket blastula_pool_secondary stream 660 root system
+ socket usap_pool_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
diff --git a/rootdir/init.zygote64.rc b/rootdir/init.zygote64.rc
index 3f3cc15..6fa210a 100644
--- a/rootdir/init.zygote64.rc
+++ b/rootdir/init.zygote64.rc
@@ -4,7 +4,7 @@
user root
group root readproc reserved_disk
socket zygote stream 660 root system
- socket blastula_pool stream 660 root system
+ socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc
index fae38c9..48461ec 100644
--- a/rootdir/init.zygote64_32.rc
+++ b/rootdir/init.zygote64_32.rc
@@ -4,7 +4,7 @@
user root
group root readproc reserved_disk
socket zygote stream 660 root system
- socket blastula_pool stream 660 root system
+ socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
@@ -20,6 +20,6 @@
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
- socket blastula_pool_secondary stream 660 root system
+ socket usap_pool_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks