DO NOT MERGE - Merge Android 10 into master
Bug: 139893257 Change-Id: Id5c7c0c40d29884640b649db217be1eb86ee9147
This commit is contained in:
commit
d4ef92d866
35 changed files with 450 additions and 210 deletions
|
|
@ -337,9 +337,12 @@ void handle_packet(apacket *p, atransport *t)
|
|||
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 @@ void handle_packet(apacket *p, atransport *t)
|
|||
}
|
||||
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -50,8 +50,10 @@ void adbd_auth_init(void);
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ bool adbd_auth_verify(const char* token, size_t token_size, const std::string& s
|
|||
}
|
||||
|
||||
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 @@ bool adbd_auth_verify(const char* token, size_t token_size, const std::string& s
|
|||
}
|
||||
}
|
||||
}
|
||||
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 @@ static bool adbd_auth_generate_token(void* token, size_t token_size) {
|
|||
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 @@ static void adbd_auth_event(int fd, unsigned events, void*) {
|
|||
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 @@ static void adbd_auth_listener(int fd, unsigned events, void* data) {
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -509,16 +509,14 @@ struct UsbFfsConnection : public Connection {
|
|||
}
|
||||
|
||||
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 @@ struct UsbFfsConnection : public Connection {
|
|||
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 @@ struct UsbFfsConnection : public Connection {
|
|||
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 @@ struct UsbFfsConnection : public Connection {
|
|||
} 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 @@ struct UsbFfsConnection : public Connection {
|
|||
|
||||
PrepareReadBlock(block, block->id().id + kUsbReadQueueDepth);
|
||||
SubmitRead(block);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SubmitRead(IoBlock* block) {
|
||||
|
|
|
|||
|
|
@ -275,6 +275,9 @@ class atransport {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ class unique_fd_impl final {
|
|||
// 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);
|
||||
|
|
|
|||
|
|
@ -1093,8 +1093,8 @@ void RecordAbsoluteBootTime(BootEventRecordStore* boot_event_store,
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -579,12 +579,38 @@ bool MetadataBuilder::ValidatePartitionSizeChange(Partition* partition, uint64_t
|
|||
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 @@ bool MetadataBuilder::GrowPartition(Partition* partition, uint64_t aligned_size)
|
|||
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 @@ bool MetadataBuilder::UpdateBlockDeviceInfo(size_t index, const BlockDeviceInfo&
|
|||
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 @@ bool MetadataBuilder::ResizePartition(Partition* partition, uint64_t requested_s
|
|||
}
|
||||
|
||||
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()) {
|
||||
|
|
|
|||
|
|
@ -887,3 +887,38 @@ TEST_F(BuilderTest, UpdateSuper) {
|
|||
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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,6 +138,33 @@ class Partition final {
|
|||
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 @@ class MetadataBuilder {
|
|||
//
|
||||
// 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 @@ class MetadataBuilder {
|
|||
// 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 @@ class MetadataBuilder {
|
|||
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 @@ class MetadataBuilder {
|
|||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -329,6 +329,10 @@ class SnapshotManager final {
|
|||
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_;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
|
||||
|
|
@ -217,8 +218,27 @@ bool SnapshotManager::CreateSnapshot(LockedFile* lock, const std::string& name,
|
|||
}
|
||||
|
||||
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,
|
||||
|
|
@ -1108,22 +1128,6 @@ bool SnapshotManager::CreateLogicalAndSnapshotPartitions(const std::string& supe
|
|||
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);
|
||||
|
|
@ -1132,59 +1136,102 @@ bool SnapshotManager::CreateLogicalAndSnapshotPartitions(const std::string& supe
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ CHARGER_STATIC_LIBRARIES := \
|
|||
libcharger_sysprop \
|
||||
libhidltransport \
|
||||
libhidlbase \
|
||||
libhwbinder_noltopgo \
|
||||
libhealthstoragedefault \
|
||||
libminui \
|
||||
libvndksupport \
|
||||
|
|
@ -77,7 +76,6 @@ LOCAL_STATIC_LIBRARIES := \
|
|||
libcharger_sysprop \
|
||||
libhidltransport \
|
||||
libhidlbase \
|
||||
libhwbinder_noltopgo \
|
||||
libhealthstoragedefault \
|
||||
libvndksupport \
|
||||
libhealthd_charger_nops \
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ class FuseBridgeEntry {
|
|||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,10 +69,11 @@ native_handle_t* native_handle_init(char* storage, int numFds, int numInts);
|
|||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -1747,22 +1747,21 @@ static int count_matching_ts(log_time ts) {
|
|||
|
||||
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 @@ TEST(liblog, enoent) {
|
|||
// 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 @@ TEST(liblog, enoent) {
|
|||
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));
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ cc_test {
|
|||
static_libs: ["libmemunreachable"],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libhwbinder",
|
||||
"libhidlbase",
|
||||
"libutils",
|
||||
],
|
||||
test_suites: ["device-tests"],
|
||||
|
|
|
|||
|
|
@ -109,6 +109,11 @@ static int statsdOpen() {
|
|||
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;
|
||||
|
|
|
|||
31
libsystem/include/system/graphics-base-v1.2.h
Normal file
31
libsystem/include/system/graphics-base-v1.2.h
Normal file
|
|
@ -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_
|
||||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -153,12 +153,12 @@ cc_test_library {
|
|||
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 @@ cc_test {
|
|||
"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 @@ cc_test {
|
|||
"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
|
||||
//-------------------------------------------------------------------------
|
||||
|
|
|
|||
7
libunwindstack/TEST_MAPPING
Normal file
7
libunwindstack/TEST_MAPPING
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "libunwindstack_unit_test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -170,10 +170,10 @@ TEST_F(LocalUnwinderTest, unwind_after_dlopen) {
|
|||
|
||||
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";
|
||||
|
||||
|
|
|
|||
|
|
@ -1433,8 +1433,8 @@ static int kill_one_process(struct proc* procp, int min_oom_score) {
|
|||
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();
|
||||
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ namespace.media.search.paths = /apex/com.android.media/${LIB}
|
|||
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.search.paths = /apex/com.android.media/${LIB}
|
|||
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%
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
libandroid.so
|
||||
libandroidthings.so
|
||||
libaaudio.so
|
||||
libamidi.so
|
||||
libbinder_ndk.so
|
||||
libc.so
|
||||
libcamera2ndk.so
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -431,10 +431,6 @@ on late-fs
|
|||
# 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 @@ on zygote-start && property:persist.sys.fuse=""
|
|||
# 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 @@ on boot
|
|||
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 @@ on property:vold.decrypt=trigger_post_fs_data
|
|||
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
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ on post-fs-data
|
|||
# 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
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-sys
|
|||
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
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-s
|
|||
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 @@ service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote
|
|||
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
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-s
|
|||
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
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-s
|
|||
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 @@ service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote
|
|||
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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue