Merge "liblp: Add a ResizePartition helper to MetadataBuilder."
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 19300f6..38c6f62 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -920,13 +920,45 @@
}
#endif /* ADB_HOST */
+bool handle_forward_request(const char* service, atransport* transport, int reply_fd) {
+ return handle_forward_request(service, [transport](std::string*) { return transport; },
+ reply_fd);
+}
+
// Try to handle a network forwarding request.
-// This returns 1 on success, 0 on failure, and -1 to indicate this is not
-// a forwarding-related request.
-int handle_forward_request(const char* service, atransport* transport, int reply_fd) {
+bool handle_forward_request(const char* service,
+ std::function<atransport*(std::string* error)> transport_acquirer,
+ int reply_fd) {
+ if (!strcmp(service, "list-forward")) {
+ // Create the list of forward redirections.
+ std::string listeners = format_listeners();
+#if ADB_HOST
+ SendOkay(reply_fd);
+#endif
+ SendProtocolString(reply_fd, listeners);
+ return true;
+ }
+
+ if (!strcmp(service, "killforward-all")) {
+ remove_all_listeners();
+#if ADB_HOST
+ /* On the host: 1st OKAY is connect, 2nd OKAY is status */
+ SendOkay(reply_fd);
+#endif
+ SendOkay(reply_fd);
+ return true;
+ }
+
if (!strncmp(service, "forward:", 8) || !strncmp(service, "killforward:", 12)) {
// killforward:local
// forward:(norebind:)?local;remote
+ std::string error;
+ atransport* transport = transport_acquirer(&error);
+ if (!transport) {
+ SendFail(reply_fd, error);
+ return true;
+ }
+
bool kill_forward = false;
bool no_rebind = false;
if (android::base::StartsWith(service, "killforward:")) {
@@ -946,17 +978,16 @@
// Check killforward: parameter format: '<local>'
if (pieces.size() != 1 || pieces[0].empty()) {
SendFail(reply_fd, android::base::StringPrintf("bad killforward: %s", service));
- return 1;
+ return true;
}
} else {
// Check forward: parameter format: '<local>;<remote>'
if (pieces.size() != 2 || pieces[0].empty() || pieces[1].empty() || pieces[1][0] == '*') {
SendFail(reply_fd, android::base::StringPrintf("bad forward: %s", service));
- return 1;
+ return true;
}
}
- std::string error;
InstallStatus r;
int resolved_tcp_port = 0;
if (kill_forward) {
@@ -977,7 +1008,7 @@
SendProtocolString(reply_fd, android::base::StringPrintf("%d", resolved_tcp_port));
}
- return 1;
+ return true;
}
std::string message;
@@ -996,9 +1027,10 @@
break;
}
SendFail(reply_fd, message);
- return 1;
+ return true;
}
- return 0;
+
+ return false;
}
#if ADB_HOST
@@ -1186,35 +1218,15 @@
return SendOkay(reply_fd, response);
}
- if (!strcmp(service, "list-forward")) {
- // Create the list of forward redirections.
- std::string listeners = format_listeners();
-#if ADB_HOST
- SendOkay(reply_fd);
-#endif
- return SendProtocolString(reply_fd, listeners);
+ if (handle_forward_request(service,
+ [=](std::string* error) {
+ return acquire_one_transport(type, serial, transport_id, nullptr,
+ error);
+ },
+ reply_fd)) {
+ return 0;
}
- if (!strcmp(service, "killforward-all")) {
- remove_all_listeners();
-#if ADB_HOST
- /* On the host: 1st OKAY is connect, 2nd OKAY is status */
- SendOkay(reply_fd);
-#endif
- SendOkay(reply_fd);
- return 1;
- }
-
- std::string error;
- atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error);
- if (!t) {
- SendFail(reply_fd, error);
- return 1;
- }
-
- int ret = handle_forward_request(service, t, reply_fd);
- if (ret >= 0)
- return ret - 1;
return -1;
}
diff --git a/adb/adb.h b/adb/adb.h
index 13ca4d7..e6af780 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -158,7 +158,10 @@
unique_fd create_jdwp_connection_fd(int jdwp_pid);
#endif
-int handle_forward_request(const char* service, atransport* transport, int reply_fd);
+bool handle_forward_request(const char* service, atransport* transport, int reply_fd);
+bool handle_forward_request(const char* service,
+ std::function<atransport*(std::string* error)> transport_acquirer,
+ int reply_fd);
/* packet allocator */
apacket* get_apacket(void);
diff --git a/adb/client/bugreport.cpp b/adb/client/bugreport.cpp
index 346bb4b..fe98737 100644
--- a/adb/client/bugreport.cpp
+++ b/adb/client/bugreport.cpp
@@ -16,6 +16,8 @@
#define TRACE_TAG ADB
+#include "sysdeps.h"
+
#include "bugreport.h"
#include <string>
@@ -24,8 +26,6 @@
#include <android-base/file.h>
#include <android-base/strings.h>
-#include "sysdeps.h"
-
#include "adb_utils.h"
#include "client/file_sync_client.h"
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index a7a94e7..3fb14f3 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -1614,9 +1614,9 @@
return bugreport.DoIt(argc, argv);
} else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
bool reverse = !strcmp(argv[0], "reverse");
- ++argv;
--argc;
if (argc < 1) return syntax_error("%s requires an argument", argv[0]);
+ ++argv;
// Determine the <host-prefix> for this command.
std::string host_prefix;
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp
index 6588587..0e79d82 100644
--- a/adb/daemon/remount_service.cpp
+++ b/adb/daemon/remount_service.cpp
@@ -92,12 +92,13 @@
return result;
}
-static bool fs_has_shared_blocks(const char* dev) {
+static bool fs_has_shared_blocks(const std::string& mount_point, const std::string& device) {
+ std::string path = mount_point + "/lost+found";
struct statfs fs;
- if (statfs(dev, &fs) == -1 || fs.f_type == EXT4_SUPER_MAGIC) {
+ if (statfs(path.c_str(), &fs) == -1 || fs.f_type != EXT4_SUPER_MAGIC) {
return false;
}
- unique_fd fd(unix_open(dev, O_RDONLY));
+ unique_fd fd(unix_open(device.c_str(), O_RDONLY));
if (fd < 0) {
return false;
}
@@ -237,7 +238,7 @@
std::set<std::string> dedup;
for (const auto& partition : partitions) {
std::string dev = find_mount(partition.c_str(), partition == "/");
- if (dev.empty() || !fs_has_shared_blocks(dev.c_str())) {
+ if (dev.empty() || !fs_has_shared_blocks(partition, dev)) {
continue;
}
if (can_unshare_blocks(fd.get(), dev.c_str())) {
diff --git a/adb/daemon/services.cpp b/adb/daemon/services.cpp
index 25024b0..1f59d64 100644
--- a/adb/daemon/services.cpp
+++ b/adb/daemon/services.cpp
@@ -157,7 +157,7 @@
return unique_fd{};
}
VLOG(SERVICES) << "service socketpair: " << s[0] << ", " << s[1];
- if (handle_forward_request(command, transport, s[1]) < 0) {
+ if (!handle_forward_request(command, transport, s[1])) {
SendFail(s[1], "not a reverse forwarding command");
}
adb_close(s[1]);
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 793c283..9222008 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -50,6 +50,7 @@
#include "adb_trace.h"
#include "adb_utils.h"
#include "fdevent.h"
+#include "sysdeps/chrono.h"
static void register_transport(atransport* transport);
static void remove_transport(atransport* transport);
@@ -80,6 +81,7 @@
~ScopedAssumeLocked() RELEASE() {}
};
+#if ADB_HOST
// Tracks and handles atransport*s that are attempting reconnection.
class ReconnectHandler {
public:
@@ -102,12 +104,18 @@
// Tracks a reconnection attempt.
struct ReconnectAttempt {
atransport* transport;
- std::chrono::system_clock::time_point deadline;
+ std::chrono::steady_clock::time_point reconnect_time;
size_t attempts_left;
+
+ bool operator<(const ReconnectAttempt& rhs) const {
+ // std::priority_queue returns the largest element first, so we want attempts that have
+ // less time remaining (i.e. smaller time_points) to compare greater.
+ return reconnect_time > rhs.reconnect_time;
+ }
};
// Only retry for up to one minute.
- static constexpr const std::chrono::seconds kDefaultTimeout = std::chrono::seconds(10);
+ static constexpr const std::chrono::seconds kDefaultTimeout = 10s;
static constexpr const size_t kMaxAttempts = 6;
// Protects all members.
@@ -115,7 +123,7 @@
bool running_ GUARDED_BY(reconnect_mutex_) = true;
std::thread handler_thread_;
std::condition_variable reconnect_cv_;
- std::queue<ReconnectAttempt> reconnect_queue_ GUARDED_BY(reconnect_mutex_);
+ std::priority_queue<ReconnectAttempt> reconnect_queue_ GUARDED_BY(reconnect_mutex_);
DISALLOW_COPY_AND_ASSIGN(ReconnectHandler);
};
@@ -137,7 +145,7 @@
// Drain the queue to free all resources.
std::lock_guard<std::mutex> lock(reconnect_mutex_);
while (!reconnect_queue_.empty()) {
- ReconnectAttempt attempt = reconnect_queue_.front();
+ ReconnectAttempt attempt = reconnect_queue_.top();
reconnect_queue_.pop();
remove_transport(attempt.transport);
}
@@ -148,9 +156,10 @@
{
std::lock_guard<std::mutex> lock(reconnect_mutex_);
if (!running_) return;
- reconnect_queue_.emplace(ReconnectAttempt{
- transport, std::chrono::system_clock::now() + ReconnectHandler::kDefaultTimeout,
- ReconnectHandler::kMaxAttempts});
+ // Arbitrary sleep to give adbd time to get ready, if we disconnected because it exited.
+ auto reconnect_time = std::chrono::steady_clock::now() + 250ms;
+ reconnect_queue_.emplace(
+ ReconnectAttempt{transport, reconnect_time, ReconnectHandler::kMaxAttempts});
}
reconnect_cv_.notify_one();
}
@@ -162,15 +171,27 @@
std::unique_lock<std::mutex> lock(reconnect_mutex_);
ScopedAssumeLocked assume_lock(reconnect_mutex_);
- auto deadline = std::chrono::time_point<std::chrono::system_clock>::max();
- if (!reconnect_queue_.empty()) deadline = reconnect_queue_.front().deadline;
- reconnect_cv_.wait_until(lock, deadline, [&]() REQUIRES(reconnect_mutex_) {
- return !running_ ||
- (!reconnect_queue_.empty() && reconnect_queue_.front().deadline < deadline);
- });
+ if (!reconnect_queue_.empty()) {
+ // FIXME: libstdc++ (used on Windows) implements condition_variable with
+ // system_clock as its clock, so we're probably hosed if the clock changes,
+ // even if we use steady_clock throughout. This problem goes away once we
+ // switch to libc++.
+ reconnect_cv_.wait_until(lock, reconnect_queue_.top().reconnect_time);
+ } else {
+ reconnect_cv_.wait(lock);
+ }
if (!running_) return;
- attempt = reconnect_queue_.front();
+ if (reconnect_queue_.empty()) continue;
+
+ // Go back to sleep in case |reconnect_cv_| woke up spuriously and we still
+ // have more time to wait for the current attempt.
+ auto now = std::chrono::steady_clock::now();
+ if (reconnect_queue_.top().reconnect_time > now) {
+ continue;
+ }
+
+ attempt = reconnect_queue_.top();
reconnect_queue_.pop();
if (attempt.transport->kicked()) {
D("transport %s was kicked. giving up on it.", attempt.transport->serial.c_str());
@@ -191,9 +212,9 @@
std::lock_guard<std::mutex> lock(reconnect_mutex_);
reconnect_queue_.emplace(ReconnectAttempt{
- attempt.transport,
- std::chrono::system_clock::now() + ReconnectHandler::kDefaultTimeout,
- attempt.attempts_left - 1});
+ attempt.transport,
+ std::chrono::steady_clock::now() + ReconnectHandler::kDefaultTimeout,
+ attempt.attempts_left - 1});
continue;
}
@@ -204,6 +225,8 @@
static auto& reconnect_handler = *new ReconnectHandler();
+#endif
+
} // namespace
TransportId NextTransportId() {
@@ -677,9 +700,11 @@
update_transports();
}
+#if ADB_HOST
void init_reconnect_handler(void) {
reconnect_handler.Start();
}
+#endif
void init_transport_registration(void) {
int s[2];
@@ -698,7 +723,9 @@
}
void kick_all_transports() {
+#if ADB_HOST
reconnect_handler.Stop();
+#endif
// To avoid only writing part of a packet to a transport after exit, kick all transports.
std::lock_guard<std::recursive_mutex> lock(transport_lock);
for (auto t : transport_list) {
@@ -736,13 +763,19 @@
t->ref_count--;
if (t->ref_count == 0) {
t->connection()->Stop();
+#if ADB_HOST
if (t->IsTcpDevice() && !t->kicked()) {
- D("transport: %s unref (attempting reconnection) %d", t->serial.c_str(), t->kicked());
+ D("transport: %s unref (attempting reconnection)", t->serial.c_str());
reconnect_handler.TrackTransport(t);
} else {
D("transport: %s unref (kicking and closing)", t->serial.c_str());
remove_transport(t);
}
+#else
+ D("transport: %s unref (kicking and closing)", t->serial.c_str());
+ remove_transport(t);
+#endif
+
} else {
D("transport: %s unref (count=%zu)", t->serial.c_str(), t->ref_count);
}
diff --git a/base/include/android-base/logging.h b/base/include/android-base/logging.h
index aea6ce6..f94cc25 100644
--- a/base/include/android-base/logging.h
+++ b/base/include/android-base/logging.h
@@ -447,11 +447,6 @@
private:
const std::unique_ptr<LogMessageData> data_;
- // TODO(b/35361699): remove these symbols once all prebuilds stop using it.
- LogMessage(const char* file, unsigned int line, LogId id, LogSeverity severity, int error);
- static void LogLine(const char* file, unsigned int line, LogId id, LogSeverity severity,
- const char* msg);
-
DISALLOW_COPY_AND_ASSIGN(LogMessage);
};
diff --git a/base/logging.cpp b/base/logging.cpp
index 35054ac..d60d91d 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -410,10 +410,6 @@
const char* tag, int error)
: data_(new LogMessageData(file, line, id, severity, tag, error)) {}
-LogMessage::LogMessage(const char* file, unsigned int line, LogId id, LogSeverity severity,
- int error)
- : LogMessage(file, line, id, severity, nullptr, error) {}
-
LogMessage::~LogMessage() {
// Check severity again. This is duplicate work wrt/ LOG macros, but not LOG_STREAM.
if (!WOULD_LOG(data_->GetSeverity())) {
@@ -470,11 +466,6 @@
}
}
-void LogMessage::LogLine(const char* file, unsigned int line, LogId id, LogSeverity severity,
- const char* message) {
- LogLine(file, line, id, severity, nullptr, message);
-}
-
LogSeverity GetMinimumLogSeverity() {
return gMinimumLogSeverity;
}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 263ea17..321e6ba 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -114,20 +114,26 @@
bool is_optional;
bool is_secondary;
} images[] = {
- // clang-format off
+ // clang-format off
{ "boot", "boot.img", "boot.sig", "boot", false, false },
{ nullptr, "boot_other.img", "boot.sig", "boot", true, true },
{ "dtbo", "dtbo.img", "dtbo.sig", "dtbo", true, false },
{ "dts", "dt.img", "dt.sig", "dts", true, false },
{ "odm", "odm.img", "odm.sig", "odm", true, false },
{ "product", "product.img", "product.sig", "product", true, false },
+ { "product-services",
+ "product-services.img",
+ "product-services.sig",
+ "product-services",
+ true, false },
{ "recovery", "recovery.img", "recovery.sig", "recovery", true, false },
+ { "super", "super.img", "super.sig", "super", true, false },
{ "system", "system.img", "system.sig", "system", false, false },
{ nullptr, "system_other.img", "system.sig", "system", true, true },
{ "vbmeta", "vbmeta.img", "vbmeta.sig", "vbmeta", true, false },
{ "vendor", "vendor.img", "vendor.sig", "vendor", true, false },
{ nullptr, "vendor_other.img", "vendor.sig", "vendor", true, true },
- // clang-format on
+ // clang-format on
};
static std::string find_item_given_name(const char* img_name) {
diff --git a/fastboot/fastboot_driver.cpp b/fastboot/fastboot_driver.cpp
index c308420..aabc620 100644
--- a/fastboot/fastboot_driver.cpp
+++ b/fastboot/fastboot_driver.cpp
@@ -462,6 +462,10 @@
}
RetCode FastBootDriver::SendBuffer(const void* buf, size_t size) {
+ if (!size) {
+ return SUCCESS;
+ }
+
// Write the buffer
ssize_t tmp = transport->Write(buf, size);
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index b3df811..5f57182 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1052,6 +1052,9 @@
return FS_MGR_DOMNT_FAILED;
}
+ // Run fsck if needed
+ prepare_fs_for_mount(rec->blk_device, rec);
+
int ret = __mount(rec->blk_device, rec->mount_point, rec);
if (ret) {
ret = (errno == EBUSY) ? FS_MGR_DOMNT_BUSY : FS_MGR_DOMNT_FAILED;
@@ -1177,8 +1180,8 @@
{
int ret;
- ret = mount("tmpfs", n_name, "tmpfs",
- MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
+ ret = mount("tmpfs", n_name, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV | MS_NOEXEC,
+ CRYPTO_TMPFS_OPTIONS);
if (ret < 0) {
LERROR << "Cannot mount tmpfs filesystem at " << n_name;
return -1;
diff --git a/healthd/healthd_draw.cpp b/healthd/healthd_draw.cpp
index ea3d991..30f2cf3 100644
--- a/healthd/healthd_draw.cpp
+++ b/healthd/healthd_draw.cpp
@@ -21,77 +21,96 @@
#include "healthd_draw.h"
#define LOGE(x...) KLOG_ERROR("charger", x);
+#define LOGW(x...) KLOG_WARNING("charger", x);
#define LOGV(x...) KLOG_DEBUG("charger", x);
HealthdDraw::HealthdDraw(animation* anim)
: kSplitScreen(HEALTHD_DRAW_SPLIT_SCREEN),
kSplitOffset(HEALTHD_DRAW_SPLIT_OFFSET) {
- gr_init();
- gr_font_size(gr_sys_font(), &char_width_, &char_height_);
+ int ret = gr_init();
- screen_width_ = gr_fb_width() / (kSplitScreen ? 2 : 1);
- screen_height_ = gr_fb_height();
+ if (ret < 0) {
+ LOGE("gr_init failed\n");
+ graphics_available = false;
+ return;
+ }
- int res;
- if (!anim->text_clock.font_file.empty() &&
- (res = gr_init_font(anim->text_clock.font_file.c_str(),
- &anim->text_clock.font)) < 0) {
- LOGE("Could not load time font (%d)\n", res);
- }
- if (!anim->text_percent.font_file.empty() &&
- (res = gr_init_font(anim->text_percent.font_file.c_str(),
- &anim->text_percent.font)) < 0) {
- LOGE("Could not load percent font (%d)\n", res);
- }
+ graphics_available = true;
+ sys_font = gr_sys_font();
+ if (sys_font == nullptr) {
+ LOGW("No system font, screen fallback text not available\n");
+ } else {
+ gr_font_size(sys_font, &char_width_, &char_height_);
+ }
+
+ screen_width_ = gr_fb_width() / (kSplitScreen ? 2 : 1);
+ screen_height_ = gr_fb_height();
+
+ int res;
+ if (!anim->text_clock.font_file.empty() &&
+ (res = gr_init_font(anim->text_clock.font_file.c_str(), &anim->text_clock.font)) < 0) {
+ LOGE("Could not load time font (%d)\n", res);
+ }
+ if (!anim->text_percent.font_file.empty() &&
+ (res = gr_init_font(anim->text_percent.font_file.c_str(), &anim->text_percent.font)) < 0) {
+ LOGE("Could not load percent font (%d)\n", res);
+ }
}
HealthdDraw::~HealthdDraw() {}
void HealthdDraw::redraw_screen(const animation* batt_anim, GRSurface* surf_unknown) {
- clear_screen();
+ if (!graphics_available) return;
+ clear_screen();
- /* try to display *something* */
- if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0)
- draw_unknown(surf_unknown);
- else
- draw_battery(batt_anim);
- gr_flip();
+ /* try to display *something* */
+ if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0)
+ draw_unknown(surf_unknown);
+ else
+ draw_battery(batt_anim);
+ gr_flip();
}
-void HealthdDraw::blank_screen(bool blank) { gr_fb_blank(blank); }
+void HealthdDraw::blank_screen(bool blank) {
+ if (!graphics_available) return;
+ gr_fb_blank(blank);
+}
void HealthdDraw::clear_screen(void) {
- gr_color(0, 0, 0, 255);
- gr_clear();
+ if (!graphics_available) return;
+ gr_color(0, 0, 0, 255);
+ gr_clear();
}
int HealthdDraw::draw_surface_centered(GRSurface* surface) {
- int w = gr_get_width(surface);
- int h = gr_get_height(surface);
- int x = (screen_width_ - w) / 2 + kSplitOffset;
- int y = (screen_height_ - h) / 2;
+ if (!graphics_available) return 0;
- LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y);
- gr_blit(surface, 0, 0, w, h, x, y);
- if (kSplitScreen) {
- x += screen_width_ - 2 * kSplitOffset;
+ int w = gr_get_width(surface);
+ int h = gr_get_height(surface);
+ int x = (screen_width_ - w) / 2 + kSplitOffset;
+ int y = (screen_height_ - h) / 2;
+
LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y);
gr_blit(surface, 0, 0, w, h, x, y);
- }
+ if (kSplitScreen) {
+ x += screen_width_ - 2 * kSplitOffset;
+ LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y);
+ gr_blit(surface, 0, 0, w, h, x, y);
+ }
- return y + h;
+ return y + h;
}
int HealthdDraw::draw_text(const GRFont* font, int x, int y, const char* str) {
- int str_len_px = gr_measure(font, str);
+ if (!graphics_available) return 0;
+ int str_len_px = gr_measure(font, str);
- if (x < 0) x = (screen_width_ - str_len_px) / 2;
- if (y < 0) y = (screen_height_ - char_height_) / 2;
- gr_text(font, x + kSplitOffset, y, str, false /* bold */);
- if (kSplitScreen)
- gr_text(font, x - kSplitOffset + screen_width_, y, str, false /* bold */);
+ if (x < 0) x = (screen_width_ - str_len_px) / 2;
+ if (y < 0) y = (screen_height_ - char_height_) / 2;
+ gr_text(font, x + kSplitOffset, y, str, false /* bold */);
+ if (kSplitScreen) gr_text(font, x - kSplitOffset + screen_width_, y, str, false /* bold */);
- return y + char_height_;
+ return y + char_height_;
}
void HealthdDraw::determine_xy(const animation::text_field& field,
@@ -119,77 +138,80 @@
}
void HealthdDraw::draw_clock(const animation* anim) {
- static constexpr char CLOCK_FORMAT[] = "%H:%M";
- static constexpr int CLOCK_LENGTH = 6;
+ static constexpr char CLOCK_FORMAT[] = "%H:%M";
+ static constexpr int CLOCK_LENGTH = 6;
- const animation::text_field& field = anim->text_clock;
+ const animation::text_field& field = anim->text_clock;
- if (field.font == nullptr || field.font->char_width == 0 ||
- field.font->char_height == 0)
- return;
+ if (!graphics_available || field.font == nullptr || field.font->char_width == 0 ||
+ field.font->char_height == 0)
+ return;
- time_t rawtime;
- time(&rawtime);
- tm* time_info = localtime(&rawtime);
+ time_t rawtime;
+ time(&rawtime);
+ tm* time_info = localtime(&rawtime);
- char clock_str[CLOCK_LENGTH];
- size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info);
- if (length != CLOCK_LENGTH - 1) {
- LOGE("Could not format time\n");
- return;
- }
+ char clock_str[CLOCK_LENGTH];
+ size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info);
+ if (length != CLOCK_LENGTH - 1) {
+ LOGE("Could not format time\n");
+ return;
+ }
- int x, y;
- determine_xy(field, length, &x, &y);
+ int x, y;
+ determine_xy(field, length, &x, &y);
- LOGV("drawing clock %s %d %d\n", clock_str, x, y);
- gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
- draw_text(field.font, x, y, clock_str);
+ LOGV("drawing clock %s %d %d\n", clock_str, x, y);
+ gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
+ draw_text(field.font, x, y, clock_str);
}
void HealthdDraw::draw_percent(const animation* anim) {
- int cur_level = anim->cur_level;
- if (anim->cur_status == BATTERY_STATUS_FULL) {
- cur_level = 100;
- }
+ if (!graphics_available) return;
+ int cur_level = anim->cur_level;
+ if (anim->cur_status == BATTERY_STATUS_FULL) {
+ cur_level = 100;
+ }
- if (cur_level <= 0) return;
+ if (cur_level <= 0) return;
- const animation::text_field& field = anim->text_percent;
- if (field.font == nullptr || field.font->char_width == 0 ||
- field.font->char_height == 0) {
- return;
- }
+ const animation::text_field& field = anim->text_percent;
+ if (field.font == nullptr || field.font->char_width == 0 || field.font->char_height == 0) {
+ return;
+ }
- std::string str = base::StringPrintf("%d%%", cur_level);
+ std::string str = base::StringPrintf("%d%%", cur_level);
- int x, y;
- determine_xy(field, str.size(), &x, &y);
+ int x, y;
+ determine_xy(field, str.size(), &x, &y);
- LOGV("drawing percent %s %d %d\n", str.c_str(), x, y);
- gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
- draw_text(field.font, x, y, str.c_str());
+ LOGV("drawing percent %s %d %d\n", str.c_str(), x, y);
+ gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
+ draw_text(field.font, x, y, str.c_str());
}
void HealthdDraw::draw_battery(const animation* anim) {
- const animation::frame& frame = anim->frames[anim->cur_frame];
+ if (!graphics_available) return;
+ const animation::frame& frame = anim->frames[anim->cur_frame];
- if (anim->num_frames != 0) {
- draw_surface_centered(frame.surface);
- LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame,
- frame.min_level, frame.disp_time);
- }
- draw_clock(anim);
- draw_percent(anim);
+ if (anim->num_frames != 0) {
+ draw_surface_centered(frame.surface);
+ LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame, frame.min_level,
+ frame.disp_time);
+ }
+ draw_clock(anim);
+ draw_percent(anim);
}
void HealthdDraw::draw_unknown(GRSurface* surf_unknown) {
int y;
if (surf_unknown) {
- draw_surface_centered(surf_unknown);
+ draw_surface_centered(surf_unknown);
+ } else if (sys_font) {
+ gr_color(0xa4, 0xc6, 0x39, 255);
+ y = draw_text(sys_font, -1, -1, "Charging!");
+ draw_text(sys_font, -1, y + 25, "?\?/100");
} else {
- gr_color(0xa4, 0xc6, 0x39, 255);
- y = draw_text(gr_sys_font(), -1, -1, "Charging!");
- draw_text(gr_sys_font(), -1, y + 25, "?\?/100");
+ LOGW("Charging, level unknown\n");
}
}
diff --git a/healthd/healthd_draw.h b/healthd/healthd_draw.h
index 6a6ba76..7c847bd 100644
--- a/healthd/healthd_draw.h
+++ b/healthd/healthd_draw.h
@@ -70,6 +70,12 @@
const bool kSplitScreen;
// Pixels to offset graphics towards center split.
const int kSplitOffset;
+
+ // system text font, may be nullptr
+ const GRFont* sys_font;
+
+ // true if minui init'ed OK, false if minui init failed
+ bool graphics_available;
};
#endif // HEALTHD_DRAW_H
diff --git a/init/init.cpp b/init/init.cpp
index 73194bd..7ad9ec3 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -670,6 +670,10 @@
CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)));
CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)));
+ // This is needed for log wrapper, which gets called before ueventd runs.
+ CHECKCALL(mknod("/dev/ptmx", S_IFCHR | 0666, makedev(5, 2)));
+ CHECKCALL(mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3)));
+
// Mount staging areas for devices managed by vold
// See storage config details at http://source.android.com/devices/storage/
CHECKCALL(mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 94f206e..b788be9 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -414,6 +414,8 @@
if constexpr (WORLD_WRITABLE_KMSG) {
selinux_android_restorecon("/dev/kmsg_debug", 0);
}
+ selinux_android_restorecon("/dev/null", 0);
+ selinux_android_restorecon("/dev/ptmx", 0);
selinux_android_restorecon("/dev/socket", 0);
selinux_android_restorecon("/dev/random", 0);
selinux_android_restorecon("/dev/urandom", 0);
diff --git a/liblog/include/log/log_event_list.h b/liblog/include/log/log_event_list.h
index bb1ce34..1b7c377 100644
--- a/liblog/include/log/log_event_list.h
+++ b/liblog/include/log/log_event_list.h
@@ -108,6 +108,13 @@
android_log_list_element android_log_read_next(android_log_context ctx);
android_log_list_element android_log_peek_next(android_log_context ctx);
+/* Reset writer context */
+int android_log_reset(android_log_context ctx);
+
+/* Reset reader context */
+int android_log_parser_reset(android_log_context ctx,
+ const char* msg, size_t len);
+
/* Finished with reader or writer context */
int android_log_destroy(android_log_context* ctx);
diff --git a/liblog/include_vndk/log/log_event_list.h b/liblog/include_vndk/log/log_event_list.h
index cbd3091..9f74534 100644
--- a/liblog/include_vndk/log/log_event_list.h
+++ b/liblog/include_vndk/log/log_event_list.h
@@ -63,6 +63,13 @@
/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */
int android_log_write_list(android_log_context ctx, log_id_t id);
+/* Reset writer context */
+int android_log_reset(android_log_context ctx);
+
+/* Reset reader context */
+int android_log_parser_reset(android_log_context ctx,
+ const char* msg, size_t len);
+
/* Finished with reader or writer context */
int android_log_destroy(android_log_context* ctx);
diff --git a/liblog/liblog.map.txt b/liblog/liblog.map.txt
index 66670fe..015c9cb 100644
--- a/liblog/liblog.map.txt
+++ b/liblog/liblog.map.txt
@@ -53,3 +53,9 @@
__android_log_is_loggable_len;
__android_log_is_debuggable; # vndk
};
+
+LIBLOG_Q {
+ global:
+ android_log_reset; #vndk
+ android_log_parser_reset; #vndk
+};
diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c
index a59cb87..14002ce 100644
--- a/liblog/log_event_list.c
+++ b/liblog/log_event_list.c
@@ -45,14 +45,9 @@
uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
} android_log_context_internal;
-LIBLOG_ABI_PUBLIC android_log_context create_android_logger(uint32_t tag) {
- size_t needed, i;
- android_log_context_internal* context;
+static void init_context(android_log_context_internal* context, uint32_t tag) {
+ size_t needed;
- context = calloc(1, sizeof(android_log_context_internal));
- if (!context) {
- return NULL;
- }
context->tag = tag;
context->read_write_flag = kAndroidLoggerWrite;
needed = sizeof(uint8_t) + sizeof(uint8_t);
@@ -63,6 +58,24 @@
context->storage[context->pos + 0] = EVENT_TYPE_LIST;
context->list[0] = context->pos + 1;
context->pos += needed;
+}
+
+static void init_parser_context(android_log_context_internal* context,
+ const char* msg, size_t len) {
+ len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
+ context->len = len;
+ memcpy(context->storage, msg, len);
+ context->read_write_flag = kAndroidLoggerRead;
+}
+
+LIBLOG_ABI_PUBLIC android_log_context create_android_logger(uint32_t tag) {
+ android_log_context_internal* context;
+
+ context = calloc(1, sizeof(android_log_context_internal));
+ if (!context) {
+ return NULL;
+ }
+ init_context(context, tag);
return (android_log_context)context;
}
@@ -76,10 +89,7 @@
if (!context) {
return NULL;
}
- len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
- context->len = len;
- memcpy(context->storage, msg, len);
- context->read_write_flag = kAndroidLoggerRead;
+ init_parser_context(context, msg, len);
return (android_log_context)context;
}
@@ -97,6 +107,38 @@
return 0;
}
+LIBLOG_ABI_PUBLIC int android_log_reset(android_log_context ctx) {
+ android_log_context_internal* context;
+ uint32_t tag;
+
+ context = (android_log_context_internal*)ctx;
+ if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
+ return -EBADF;
+ }
+
+ tag = context->tag;
+ memset(context, 0, sizeof(*context));
+ init_context(context, tag);
+
+ return 0;
+}
+
+LIBLOG_ABI_PUBLIC int android_log_parser_reset(android_log_context ctx,
+ const char* msg, size_t len) {
+ android_log_context_internal* context;
+
+ context = (android_log_context_internal*)ctx;
+ if (!context || (kAndroidLoggerRead != context->read_write_flag)) {
+ return -EBADF;
+ }
+
+ memset(context, 0, sizeof(*context));
+ init_parser_context(context, msg, len);
+
+ return 0;
+}
+
+
LIBLOG_ABI_PUBLIC int android_log_write_list_begin(android_log_context ctx) {
size_t needed;
android_log_context_internal* context;
diff --git a/rootdir/init.rc b/rootdir/init.rc
index d3f038e..486d096 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -26,6 +26,7 @@
# Mount cgroup mount point for cpu accounting
mount cgroup none /acct nodev noexec nosuid cpuacct
+ chmod 0555 /acct
mkdir /acct/uid
# root memory control cgroup, used by lmkd
diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp
index 0586381..3d7521c 100644
--- a/shell_and_utilities/Android.bp
+++ b/shell_and_utilities/Android.bp
@@ -27,6 +27,7 @@
phony {
name: "shell_and_utilities_recovery",
required: [
+ "grep.recovery",
"sh.recovery",
"toolbox.recovery",
"toybox.recovery",
diff --git a/toolbox/Android.bp b/toolbox/Android.bp
index e75e4af..f08cf93 100644
--- a/toolbox/Android.bp
+++ b/toolbox/Android.bp
@@ -62,8 +62,8 @@
}
// We build BSD grep separately (but see http://b/111849261).
-cc_binary {
- name: "grep",
+cc_defaults {
+ name: "grep_common",
defaults: ["toolbox_defaults"],
srcs: [
"upstream-netbsd/usr.bin/grep/fastgrep.c",
@@ -72,8 +72,27 @@
"upstream-netbsd/usr.bin/grep/queue.c",
"upstream-netbsd/usr.bin/grep/util.c",
],
-
+ symlinks: [
+ "egrep",
+ "fgrep",
+ ],
sanitize: {
integer_overflow: false,
},
}
+
+cc_binary {
+ name: "grep",
+ defaults: ["grep_common"],
+ recovery_available: true,
+}
+
+// Build vendor grep.
+// TODO: Add vendor_available to "grep" module and remove "grep_vendor" module
+// when vendor_available is fully supported.
+cc_binary {
+ name: "grep_vendor",
+ stem: "grep",
+ vendor: true,
+ defaults: ["grep_common"],
+}