Merge the 2019-10-05 SPL branch from AOSP-Partner
* security-aosp-nyc-mr2-release:
Fix a memory leak in gatekeeper.
Change-Id: If3760009ba30d79649abb51b2310896fda56105a
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index 0ba6b4b..c10b48c 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -400,35 +400,33 @@
v2_descriptor.os_header = os_desc_header;
v2_descriptor.os_desc = os_desc_compat;
- if (h->control < 0) { // might have already done this before
- D("OPENING %s", USB_FFS_ADB_EP0);
- h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
- if (h->control < 0) {
- D("[ %s: cannot open control endpoint: errno=%d]", USB_FFS_ADB_EP0, errno);
+ D("OPENING %s", USB_FFS_ADB_EP0);
+ h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
+ if (h->control < 0) {
+ D("[ %s: cannot open control endpoint: errno=%d]", USB_FFS_ADB_EP0, errno);
+ goto err;
+ }
+
+ ret = adb_write(h->control, &v2_descriptor, sizeof(v2_descriptor));
+ if (ret < 0) {
+ v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
+ v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
+ v1_descriptor.header.fs_count = 3;
+ v1_descriptor.header.hs_count = 3;
+ v1_descriptor.fs_descs = fs_descriptors;
+ v1_descriptor.hs_descs = hs_descriptors;
+ D("[ %s: Switching to V1_descriptor format errno=%d ]", USB_FFS_ADB_EP0, errno);
+ ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor));
+ if (ret < 0) {
+ D("[ %s: write descriptors failed: errno=%d ]", USB_FFS_ADB_EP0, errno);
goto err;
}
+ }
- ret = adb_write(h->control, &v2_descriptor, sizeof(v2_descriptor));
- if (ret < 0) {
- v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
- v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
- v1_descriptor.header.fs_count = 3;
- v1_descriptor.header.hs_count = 3;
- v1_descriptor.fs_descs = fs_descriptors;
- v1_descriptor.hs_descs = hs_descriptors;
- D("[ %s: Switching to V1_descriptor format errno=%d ]", USB_FFS_ADB_EP0, errno);
- ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor));
- if (ret < 0) {
- D("[ %s: write descriptors failed: errno=%d ]", USB_FFS_ADB_EP0, errno);
- goto err;
- }
- }
-
- ret = adb_write(h->control, &strings, sizeof(strings));
- if (ret < 0) {
- D("[ %s: writing strings failed: errno=%d]", USB_FFS_ADB_EP0, errno);
- goto err;
- }
+ ret = adb_write(h->control, &strings, sizeof(strings));
+ if (ret < 0) {
+ D("[ %s: writing strings failed: errno=%d]", USB_FFS_ADB_EP0, errno);
+ goto err;
}
h->bulk_out = adb_open(USB_FFS_ADB_OUT, O_RDWR);
@@ -556,6 +554,7 @@
h->kicked = false;
adb_close(h->bulk_out);
adb_close(h->bulk_in);
+ adb_close(h->control);
// Notify usb_adb_open_thread to open a new connection.
adb_mutex_lock(&h->lock);
h->open_new_connection = true;
diff --git a/debuggerd/backtrace.cpp b/debuggerd/backtrace.cpp
index 8f4a53f..c5126c5 100644
--- a/debuggerd/backtrace.cpp
+++ b/debuggerd/backtrace.cpp
@@ -39,6 +39,9 @@
#include "utility.h"
+#define MAX_FRAMES_FROM_TOP_TO_CHECK 7
+#define LIB_ART_NAME "libart"
+
static void dump_process_header(log_t* log, pid_t pid) {
char path[PATH_MAX];
char procnamebuf[1024];
@@ -113,8 +116,45 @@
dump_process_footer(&log, pid);
}
+void check_coredump_criteria (std::string log, int frame_num) {
+ ALOGI("coredump_criteria: checking backtrace-frame %d in victim thread, signal = %d",
+ frame_num, coredump_signal);
+ size_t len = log.length();
+ for (size_t i = 0; i < len; i++ ) {
+ log[i] = tolower(log[i]);
+ }
+
+ size_t found = log.find(LIB_ART_NAME);
+
+ // Criterion 2: (Check tombstone.cpp for the fisrt one)
+ // Of course, if numero uno frame has libart in it, dump core without much ado
+ if ((found != std::string::npos) && (frame_num == 0)) {
+ ALOGI("coredump_criteria: found %s in first frame, coredump-criteria met", LIB_ART_NAME);
+ force_coredump_generation = true;
+ return;
+ }
+
+ // Criterion 3:
+ // If a frame(less than MAX_FRAMES_FROM_TOP_TO_CHECK) has libart in it,
+ // and the accompanying signal is a SIGABRT, dump the core
+ if ((found != std::string::npos) && (coredump_signal == SIGABRT)) {
+ ALOGI("coredump_criteria: found %s and signal=SIGABRT, coredump-criteria met", LIB_ART_NAME);
+ force_coredump_generation = true;
+ return;
+ }
+ /* Append more lame rules above this line */
+}
+
void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix) {
for (size_t i = 0; i < backtrace->NumFrames(); i++) {
+ // Check for coredump-criteria only in userdebug/eng builds(if enabled), if:
+ // 1) the current thread was the thread that originally got the fatal signal
+ // 2) If no coredump_criteria has been met until now
+ // 3) the current frame number is less than a defined(and customizable) upper-limit
+ if (coredump_enabled && victim_thread &&
+ (!force_coredump_generation) && (i < MAX_FRAMES_FROM_TOP_TO_CHECK)) {
+ check_coredump_criteria(backtrace->FormatFrameData(i), i);
+ }
_LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str());
}
}
diff --git a/debuggerd/backtrace.h b/debuggerd/backtrace.h
index acd5eaa..4213363 100644
--- a/debuggerd/backtrace.h
+++ b/debuggerd/backtrace.h
@@ -35,4 +35,10 @@
/* Dumps the backtrace in the backtrace data structure to the log. */
void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix);
+// Control-parameters for forced coredump-generation
+extern bool force_coredump_generation;
+extern bool coredump_enabled;
+extern int coredump_signal;
+extern bool victim_thread;
+
#endif // _DEBUGGERD_BACKTRACE_H
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 7b57c20..bf3c53c 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -32,7 +32,7 @@
#include <sys/wait.h>
#include <sys/un.h>
#include <time.h>
-
+#include <sys/resource.h>
#include <memory>
#include <set>
#include <string>
@@ -74,6 +74,10 @@
int32_t original_si_code;
};
+bool force_coredump_generation;
+bool coredump_enabled;
+int coredump_signal;
+
static void wait_for_user_action(const debugger_request_t& request) {
// Explain how to attach the debugger.
ALOGI("***********************************************************\n"
@@ -526,6 +530,7 @@
case SIGTRAP:
ALOGV("stopped -- fatal signal\n");
*crash_signal = signal;
+ coredump_signal = signal;
engrave_tombstone(tombstone_fd, backtrace_map, request.pid, request.tid, siblings, signal,
request.original_si_code, request.abort_msg_address, amfd_data);
break;
@@ -652,14 +657,15 @@
}
bool succeeded = false;
+ force_coredump_generation = false;
- // Now that we've done everything that requires privileges, we can drop them.
- if (!drop_privileges()) {
- ALOGE("debuggerd: failed to drop privileges, exiting");
- _exit(1);
- }
+ char value1[PROPERTY_VALUE_MAX], value2[PROPERTY_VALUE_MAX];
+ property_get("ro.debuggable", value1, "0");
+ property_get("persist.coredump.disable", value2, "0");
+ coredump_enabled = ((value1[0] == '1') && (value2[0] == '0'));
int crash_signal = SIGKILL;
+ coredump_signal = SIGKILL;
succeeded = perform_dump(request, fd, tombstone_fd, backtrace_map.get(), siblings,
&crash_signal, amfd_data.get());
if (succeeded) {
@@ -670,6 +676,22 @@
}
}
+ if (coredump_enabled && force_coredump_generation) {
+ struct rlimit r1;
+ r1.rlim_cur = RLIM_INFINITY;
+ r1.rlim_max = RLIM_INFINITY;
+ ALOGE("debuggerd: setting resource-limit for crashing process to dump core");
+ if (prlimit(request.pid, RLIMIT_CORE, &r1, NULL) == -1) {
+ ALOGE("debuggerd: Failed to set RLIMIT_CORE for pid; %d", request.pid);
+ }
+ }
+
+ // Now that we've done everything that requires privileges, we can drop them.
+ if (!drop_privileges()) {
+ ALOGE("debuggerd: failed to drop privileges, exiting");
+ _exit(1);
+ }
+
if (attach_gdb) {
// Tell the signal process to send SIGSTOP to the target.
if (!send_signal(request.pid, 0, SIGSTOP)) {
diff --git a/debuggerd/test/tombstone_test.cpp b/debuggerd/test/tombstone_test.cpp
index 58d640e..866da01 100644
--- a/debuggerd/test/tombstone_test.cpp
+++ b/debuggerd/test/tombstone_test.cpp
@@ -34,6 +34,11 @@
// Including it, also allows us to override the ptrace function.
#define ptrace ptrace_fake
+// Hack for extern variables declared in ../backtrace.h
+// This avoids a compilation error.
+bool force_coredump_generation = false;
+bool coredump_enabled = false;
+
#include "tombstone.cpp"
void dump_registers(log_t*, pid_t) {
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index dfdf29c..c69025a 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -56,6 +56,10 @@
#define TOMBSTONE_DIR "/data/tombstones"
#define TOMBSTONE_TEMPLATE (TOMBSTONE_DIR"/tombstone_%02d")
+// victim_thread will be true only while dumping logs for
+// the thread that actually crashed.
+bool victim_thread = false;
+
static bool signal_has_si_addr(int sig) {
switch (sig) {
case SIGBUS:
@@ -198,6 +202,22 @@
signal, get_signame(signal), si.si_code, get_sigcode(signal, si.si_code), addr_desc);
}
+bool is_heaptaskdaemon(char* threadname) {
+ char c[20] = "heaptaskdaemon";
+ char *target = c;
+
+ if (strlen(threadname) != strlen(target))
+ return false;
+
+ for ( ; *threadname && *target; threadname++, target++) {
+ if (tolower(*threadname) != tolower(*target)) {
+ return false;
+ }
+ }
+ ALOGI("coredump_criteria: victim-threadname is HeapTaskDaemon");
+ return true;
+}
+
static void dump_thread_info(log_t* log, pid_t pid, pid_t tid) {
char path[64];
char threadnamebuf[1024];
@@ -233,6 +253,13 @@
_LOG(log, logtype::HEADER, "pid: %d, tid: %d, name: %s >>> %s <<<\n", pid, tid,
threadname ? threadname : "UNKNOWN", procname ? procname : "UNKNOWN");
+
+ // If the thread that crashed is HeapTaskDaemon,
+ // we are in the process of garbage-collection.
+ // Force core-dump generation.
+ if (coredump_enabled && victim_thread && threadname && is_heaptaskdaemon(threadname)) {
+ force_coredump_generation = true;
+ }
}
static void dump_stack_segment(
@@ -448,6 +475,7 @@
static void dump_thread(log_t* log, pid_t pid, pid_t tid, BacktraceMap* map, int signal,
int si_code, uintptr_t abort_msg_address, bool primary_thread) {
log->current_tid = tid;
+ victim_thread = primary_thread;
if (!primary_thread) {
_LOG(log, logtype::THREAD, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n");
}
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
old mode 100644
new mode 100755
index 387f708..86e0f7a
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -294,6 +294,49 @@
}
/*
+ * Tries to check if filesystem is clean.
+ * partition is appointed by argument data_path.
+ *
+ * property sys.crash.detect indicates filesystem is not clean(if true)
+ */
+static void check_fs_clean(char *data_path, char *fs_type)
+{
+ char super_buf[1024];
+ struct ext4_super_block *sb;
+ int fd;
+
+ if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
+ fd = open(data_path, O_RDONLY);
+ if (fd < 0) {
+ ERROR("open %s failed\n", data_path);
+ return;
+ }
+
+ if (TEMP_FAILURE_RETRY(lseek(fd, 1024, SEEK_SET)) < 0 ||
+ TEMP_FAILURE_RETRY(read(fd, super_buf, 1024)) != 1024) {
+ ERROR("read super block failed\n");
+ } else {
+ sb = (struct ext4_super_block *)super_buf;
+
+ if (sb->s_magic != EXT4_SUPER_MAGIC) {
+ ERROR("from super block, it is not ext{234}\n");
+ close(fd);
+ return;
+ }
+
+ if (sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_RECOVER)) {
+ INFO("Unclean fs\n");
+ property_set("sys.crash.detect", "true");
+ } else {
+ property_set("sys.crash.detect", "false");
+ }
+ }
+ close(fd);
+ }
+}
+
+
+/*
* Tries to mount any of the consecutive fstab entries that match
* the mountpoint of the one given by fstab->recs[start_idx].
*
@@ -333,6 +376,13 @@
continue;
}
+ /* do filesystem clean check */
+ if (!strcmp(fstab->recs[i].mount_point, "/data") &&
+ fstab->recs[i].fs_mgr_flags & MF_CRASHCHECK) {
+ check_fs_clean(fstab->recs[i].blk_device,
+ fstab->recs[i].fs_type);
+ }
+
if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
fstab->recs[i].mount_point);
@@ -484,6 +534,52 @@
}
}
+/*
+ * Reads the kernel cmdline to check if MDTP is activated.
+ * When MDTP is activated, kernel cmdline will have the word 'mdtp'.
+ */
+int fs_mgr_is_mdtp_activated()
+{
+ char cmdline[2048];
+ char *ptr;
+ int fd;
+ static int mdtp_activated = 0;
+ static int mdtp_activated_set = 0;
+
+ if (mdtp_activated_set) {
+ return mdtp_activated;
+ }
+
+ fd = open("/proc/cmdline", O_RDONLY);
+ if (fd >= 0) {
+ int n = read(fd, cmdline, sizeof(cmdline) - 1);
+ if (n < 0) n = 0;
+
+ /* get rid of trailing newline, it happens */
+ if (n > 0 && cmdline[n-1] == '\n') n--;
+
+ cmdline[n] = 0;
+ close(fd);
+ } else {
+ cmdline[0] = 0;
+ }
+
+ ptr = cmdline;
+ while (ptr && *ptr) {
+ char *x = strchr(ptr, ' ');
+ if (x != 0) *x++ = 0;
+ if (!strcmp(ptr,"mdtp")) {
+ mdtp_activated = 1;
+ break;
+ }
+ ptr = x;
+ }
+
+ mdtp_activated_set = 1;
+
+ return mdtp_activated;
+}
+
/* When multiple fstab records share the same mount_point, it will
* try to mount each one in turn, and ignore any duplicates after a
* first successful mount.
@@ -497,12 +593,24 @@
int mret = -1;
int mount_errno = 0;
int attempted_idx = -1;
+ char propbuf[PROPERTY_VALUE_MAX];
+ bool is_ffbm = false;
if (!fstab) {
return -1;
}
+ /**get boot mode*/
+ property_get("ro.bootmode", propbuf, "");
+ if (strncmp(propbuf, "ffbm", 4) == 0)
+ is_ffbm = true;
for (i = 0; i < fstab->num_entries; i++) {
+ /* Skip userdata partition in ffbm mode */
+ if (is_ffbm && !strcmp(fstab->recs[i].mount_point, "/data")){
+ INFO("ffbm mode,skip mount userdata");
+ continue;
+ }
+
/* Don't mount entries that are managed by vold or not for the mount mode*/
if ((fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) ||
((mount_mode == MOUNT_MODE_LATE) && !fs_mgr_is_latemount(&fstab->recs[i])) ||
@@ -549,102 +657,117 @@
continue;
}
}
- int last_idx_inspected;
- int top_idx = i;
- mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
- i = last_idx_inspected;
- mount_errno = errno;
-
- /* Deal with encryptability. */
- if (!mret) {
- int status = handle_encryptable(&fstab->recs[attempted_idx]);
-
- if (status == FS_MGR_MNTALL_FAIL) {
- /* Fatal error - no point continuing */
- return status;
+ if (fs_mgr_is_mdtp_activated() && ((fstab->recs[i].fs_mgr_flags & MF_FORCECRYPT) ||
+ device_is_force_encrypted())) {
+ INFO("%s(): mdtp activated, blkdev %s for mount %s type %s expected to be encrypted)\n",
+ __func__, fstab->recs[i].blk_device, fstab->recs[i].mount_point,
+ fstab->recs[i].fs_type);
+ if (fs_mgr_do_tmpfs_mount(fstab->recs[i].mount_point) < 0) {
+ ++error_count;
+ continue;
}
- if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
- if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
- // Log and continue
- ERROR("Only one encryptable/encrypted partition supported\n");
+ encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
+
+ } else {
+ int last_idx_inspected;
+ int top_idx = i;
+
+ mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
+ i = last_idx_inspected;
+ mount_errno = errno;
+
+ /* Deal with encryptability. */
+ if (!mret) {
+ int status = handle_encryptable(&fstab->recs[attempted_idx]);
+
+ if (status == FS_MGR_MNTALL_FAIL) {
+ /* Fatal error - no point continuing */
+ return status;
}
- encryptable = status;
- }
- /* Success! Go get the next one */
- continue;
- }
-
- /* mount(2) returned an error, handle the encryptable/formattable case */
- bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
- if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
- fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
- /* top_idx and attempted_idx point at the same partition, but sometimes
- * at two different lines in the fstab. Use the top one for formatting
- * as that is the preferred one.
- */
- ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__,
- fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point,
- fstab->recs[top_idx].fs_type);
- if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
- strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
- int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644);
- if (fd >= 0) {
- INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
- wipe_block_device(fd, get_file_size(fd));
- close(fd);
- } else {
- ERROR("%s(): %s wouldn't open (%s)\n", __func__,
- fstab->recs[top_idx].key_loc, strerror(errno));
+ if (status != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
+ if (encryptable != FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
+ // Log and continue
+ ERROR("Only one encryptable/encrypted partition supported\n");
+ }
+ encryptable = status;
}
- }
- if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) {
- /* Let's replay the mount actions. */
- i = top_idx - 1;
- continue;
- } else {
- ERROR("%s(): Format failed. Suggest recovery...\n", __func__);
- encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
+
+ /* Success! Go get the next one */
continue;
}
- }
- if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
- fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
- if (wiped) {
- ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
- fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
- fstab->recs[attempted_idx].fs_type);
- encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
- continue;
- } else {
- /* Need to mount a tmpfs at this mountpoint for now, and set
- * properties that vold will query later for decrypting
+
+ /* mount(2) returned an error, handle the encryptable/formattable case */
+ bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
+ if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
+ fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
+ /* top_idx and attempted_idx point at the same partition, but sometimes
+ * at two different lines in the fstab. Use the top one for formatting
+ * as that is the preferred one.
*/
- ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
- fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
- fstab->recs[attempted_idx].fs_type);
- if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
- ++error_count;
+ ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__,
+ fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point,
+ fstab->recs[top_idx].fs_type);
+ if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
+ strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
+ int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644);
+ if (fd >= 0) {
+ INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
+ wipe_block_device(fd, get_file_size(fd));
+ close(fd);
+ } else {
+ ERROR("%s(): %s wouldn't open (%s)\n", __func__,
+ fstab->recs[top_idx].key_loc, strerror(errno));
+ }
+ }
+ if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) {
+ /* Let's replay the mount actions. */
+ i = top_idx - 1;
+ continue;
+ } else {
+ ERROR("%s(): Format failed. Suggest recovery...\n", __func__);
+ encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
continue;
}
}
- encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
- } else {
- if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
- ERROR("Ignoring failure to mount an un-encryptable or wiped partition on"
- "%s at %s options: %s error: %s\n",
- fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
- fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
+ if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
+ fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
+ if (wiped) {
+ ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
+ fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
+ fstab->recs[attempted_idx].fs_type);
+ encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY;
+ continue;
+ } else {
+ /* Need to mount a tmpfs at this mountpoint for now, and set
+ * properties that vold will query later for decrypting
+ */
+ ERROR("%s(): possibly an encryptable blkdev %s for mount %s type %s )\n", __func__,
+ fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
+ fstab->recs[attempted_idx].fs_type);
+ if (fs_mgr_do_tmpfs_mount(fstab->recs[attempted_idx].mount_point) < 0) {
+ ++error_count;
+ continue;
+ }
+ }
+ encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
} else {
- ERROR("Failed to mount an un-encryptable or wiped partition on"
- "%s at %s options: %s error: %s\n",
- fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
- fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
- ++error_count;
+ if (fs_mgr_is_nofail(&fstab->recs[attempted_idx])) {
+ ERROR("Ignoring failure to mount an un-encryptable or wiped partition on"
+ "%s at %s options: %s error: %s\n",
+ fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
+ fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
+ } else {
+ ERROR("Failed to mount an un-encryptable or wiped partition on"
+ "%s at %s options: %s error: %s\n",
+ fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
+ fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
+ ++error_count;
+ }
+ continue;
}
- continue;
}
}
@@ -693,6 +816,21 @@
wait_for_file(n_blk_device, WAIT_TIMEOUT);
}
+ char encrypt_data_partition[1024];
+
+ /* do filesystem check after crypto device created but before mount it */
+ if (!strcmp(fstab->recs[i].mount_point, "/data") &&
+ fstab->recs[i].fs_mgr_flags & MF_CRASHCHECK) {
+ property_get("ro.crypto.fs_crypto_blkdev", encrypt_data_partition, "");
+ INFO("data_partition=%s\n", encrypt_data_partition);
+
+ if (strcmp(encrypt_data_partition, "")) {
+ check_fs_clean(encrypt_data_partition, fstab->recs[i].fs_type);
+ } else {
+ INFO("crypto device not created!\n");
+ }
+ }
+
if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
check_fs(n_blk_device, fstab->recs[i].fs_type,
fstab->recs[i].mount_point);
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 9225d34..8a59f28 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -80,6 +80,7 @@
{ "slotselect", MF_SLOTSELECT },
{ "nofail", MF_NOFAIL },
{ "latemount", MF_LATEMOUNT },
+ { "crashcheck", MF_CRASHCHECK },
{ "defaults", 0 },
{ 0, 0 },
};
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 120ec5a..f0d0ed7 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -86,6 +86,7 @@
#define MF_LATEMOUNT 0x20000
#define MF_NOFAIL 0x40000
#define MF_VERIFYATBOOT 0x80000
+#define MF_CRASHCHECK 0x100000
#define DM_BUF_SIZE 4096
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 7565965..95bae90 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -119,6 +119,7 @@
int fs_mgr_is_nofail(struct fstab_rec *fstab);
int fs_mgr_is_latemount(struct fstab_rec *fstab);
int fs_mgr_swapon_all(struct fstab *fstab);
+int fs_mgr_is_mdtp_activated(void);
int fs_mgr_do_format(struct fstab_rec *fstab);
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 54d45e6..719d8d2 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -166,7 +166,10 @@
{ "USB_C", ANDROID_POWER_SUPPLY_TYPE_AC },
{ "USB_PD", ANDROID_POWER_SUPPLY_TYPE_AC },
{ "USB_PD_DRP", ANDROID_POWER_SUPPLY_TYPE_USB },
+ { "USB_HVDCP", ANDROID_POWER_SUPPLY_TYPE_AC },
+ { "USB_HVDCP_3", ANDROID_POWER_SUPPLY_TYPE_AC },
{ "Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS },
+ { "Wipower", ANDROID_POWER_SUPPLY_TYPE_WIRELESS },
{ NULL, 0 },
};
@@ -174,10 +177,8 @@
return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
ret = (BatteryMonitor::PowerSupplyType)mapSysfsString(buf, supplyTypeMap);
- if (ret < 0) {
- KLOG_WARNING(LOG_TAG, "Unknown power supply type '%s'\n", buf);
+ if (ret < 0)
ret = ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
- }
return ret;
}
@@ -263,54 +264,87 @@
unsigned int i;
double MaxPower = 0;
- for (i = 0; i < mChargerNames.size(); i++) {
- String8 path;
- path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
- mChargerNames[i].string());
+ // reinitialize the mChargerNames vector everytime there is an update
+ String8 path;
+ DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH);
+ if (dir == NULL) {
+ KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
+ } else {
+ struct dirent* entry;
+ // reconstruct the charger strings
+ mChargerNames.clear();
+ while ((entry = readdir(dir))) {
+ const char* name = entry->d_name;
- if (readFromFile(path, buf, SIZE) > 0) {
- if (buf[0] != '0') {
+ if (!strcmp(name, ".") || !strcmp(name, ".."))
+ continue;
+
+ // Look for "type" file in each subdirectory
+ path.clear();
+ path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
+ switch(readPowerSupplyType(path)) {
+ case ANDROID_POWER_SUPPLY_TYPE_AC:
+ case ANDROID_POWER_SUPPLY_TYPE_USB:
+ case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
+ // Check if any of them is online
path.clear();
- path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
- mChargerNames[i].string());
- switch(readPowerSupplyType(path)) {
- case ANDROID_POWER_SUPPLY_TYPE_AC:
- props.chargerAcOnline = true;
- break;
- case ANDROID_POWER_SUPPLY_TYPE_USB:
- props.chargerUsbOnline = true;
- break;
- case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
- props.chargerWirelessOnline = true;
- break;
- default:
- KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
- mChargerNames[i].string());
+ path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
+ if (access(path.string(), R_OK) == 0) {
+ mChargerNames.add(String8(name));
+ if (readFromFile(path, buf, SIZE) > 0) {
+ if (buf[0] != '0') {
+ path.clear();
+ path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
+ name);
+ switch(readPowerSupplyType(path)) {
+ case ANDROID_POWER_SUPPLY_TYPE_AC:
+ props.chargerAcOnline = true;
+ break;
+ case ANDROID_POWER_SUPPLY_TYPE_USB:
+ props.chargerUsbOnline = true;
+ break;
+ case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
+ props.chargerWirelessOnline = true;
+ break;
+ default:
+ KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
+ name);
+ }
+
+ //If its online, read the voltage and current for power
+ path.clear();
+ path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
+ name);
+ int ChargingCurrent =
+ (access(path.string(), R_OK) == 0) ? getIntField(path) : 0;
+
+ path.clear();
+ path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,
+ name);
+
+ int ChargingVoltage =
+ (access(path.string(), R_OK) == 0) ? getIntField(path) :
+ DEFAULT_VBUS_VOLTAGE;
+
+ double power = ((double)ChargingCurrent / MILLION) *
+ ((double)ChargingVoltage / MILLION);
+ if (MaxPower < power) {
+ props.maxChargingCurrent = ChargingCurrent;
+ props.maxChargingVoltage = ChargingVoltage;
+ MaxPower = power;
+ }
+ }
+ }
}
- path.clear();
- path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
- mChargerNames[i].string());
- int ChargingCurrent =
- (access(path.string(), R_OK) == 0) ? getIntField(path) : 0;
-
- path.clear();
- path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,
- mChargerNames[i].string());
-
- int ChargingVoltage =
- (access(path.string(), R_OK) == 0) ? getIntField(path) :
- DEFAULT_VBUS_VOLTAGE;
-
- double power = ((double)ChargingCurrent / MILLION) *
- ((double)ChargingVoltage / MILLION);
- if (MaxPower < power) {
- props.maxChargingCurrent = ChargingCurrent;
- props.maxChargingVoltage = ChargingVoltage;
- MaxPower = power;
- }
- }
- }
- }
+ break;
+ case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
+ break;
+ default:
+ break;
+ } //switch
+ } //while
+ closedir(dir);
+ }//else
logthis = !healthd_board_battery_update(&props);
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index 1c144b3..2118423 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -37,7 +37,7 @@
#ifndef BOARD_PERIODIC_CHORES_INTERVAL_FAST
// Periodic chores fast interval in seconds
- #define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (60 * 1)
+ #define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (60 * 10)
#else
#define DEFAULT_PERIODIC_CHORES_INTERVAL_FAST (BOARD_PERIODIC_CHORES_INTERVAL_FAST)
#endif
@@ -373,6 +373,9 @@
exit(2);
}
+ periodic_chores();
+ healthd_mode_ops->heartbeat();
+
healthd_mainloop();
KLOG_ERROR("Main loop terminated, exiting\n");
return 3;
diff --git a/healthd/healthd_board_default.cpp b/healthd/healthd_board_default.cpp
index eb55773..960f0d2 100644
--- a/healthd/healthd_board_default.cpp
+++ b/healthd/healthd_board_default.cpp
@@ -27,3 +27,23 @@
// return 0 to log periodic polled battery status to kernel log
return 0;
}
+
+void healthd_board_mode_charger_draw_battery(struct android::BatteryProperties*)
+{
+
+}
+
+void healthd_board_mode_charger_battery_update(struct android::BatteryProperties*)
+{
+
+}
+
+void healthd_board_mode_charger_set_backlight(bool)
+{
+
+}
+
+void healthd_board_mode_charger_init()
+{
+
+}
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index ccf948b..cc41b2e 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -72,7 +72,7 @@
#define BATTERY_UNKNOWN_TIME (2 * MSEC_PER_SEC)
#define POWER_ON_KEY_TIME (2 * MSEC_PER_SEC)
-#define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC)
+#define UNPLUGGED_SHUTDOWN_TIME (1 * MSEC_PER_SEC)
#define LAST_KMSG_PATH "/proc/last_kmsg"
#define LAST_KMSG_PSTORE_PATH "/sys/fs/pstore/console-ramoops"
@@ -93,6 +93,7 @@
struct charger {
bool have_battery_state;
bool charger_connected;
+ bool charger_power_key;
int64_t next_screen_transition;
int64_t next_key_check;
int64_t next_pwr_check;
@@ -404,6 +405,7 @@
anim.cur_frame, frame.min_level,
frame.disp_time);
}
+ healthd_board_mode_charger_draw_battery(batt_prop);
draw_clock(anim);
draw_percent(anim);
}
@@ -477,6 +479,7 @@
init_status_display(batt_anim);
#ifndef CHARGER_DISABLE_INIT_BLANK
+ healthd_board_mode_charger_set_backlight(false);
gr_fb_blank(true);
#endif
minui_inited = true;
@@ -486,6 +489,8 @@
if (batt_anim->num_cycles > 0 && batt_anim->cur_cycle == batt_anim->num_cycles) {
reset_animation(batt_anim);
charger->next_screen_transition = -1;
+ charger->charger_power_key = false;
+ healthd_board_mode_charger_set_backlight(false);
gr_fb_blank(true);
LOGV("[%" PRId64 "] animation done\n", now);
if (charger->charger_connected)
@@ -519,9 +524,12 @@
}
}
- /* unblank the screen on first cycle */
- if (batt_anim->cur_cycle == 0)
+ /* unblank the screen on first cycle */
+ if (batt_anim->cur_cycle == 0) {
gr_fb_blank(false);
+ gr_flip();
+ healthd_board_mode_charger_set_backlight(true);
+ }
/* draw the new frame (@ cur_frame) */
redraw_screen(charger);
@@ -620,11 +628,20 @@
static void process_key(struct charger *charger, int code, int64_t now)
{
+ struct animation *batt_anim = charger->batt_anim;
struct key_state *key = &charger->keys[code];
if (code == KEY_POWER) {
if (key->down) {
int64_t reboot_timeout = key->timestamp + POWER_ON_KEY_TIME;
+
+ /*make sure backlight turn off before fb ready for display
+ *when press the power key */
+ if (charger->charger_power_key == false) {
+ healthd_board_mode_charger_set_backlight(false);
+ gr_fb_blank(true);
+ charger->charger_power_key = true;
+ }
if (now >= reboot_timeout) {
/* We do not currently support booting from charger mode on
all devices. Check the property and continue booting or reboot
@@ -646,17 +663,25 @@
* make sure we wake up at the right-ish time to check
*/
set_next_key_check(charger, key, POWER_ON_KEY_TIME);
-
- /* Turn on the display and kick animation on power-key press
- * rather than on key release
- */
- kick_animation(charger->batt_anim);
- request_suspend(false);
}
} else {
- /* if the power key got released, force screen state cycle */
if (key->pending) {
- kick_animation(charger->batt_anim);
+ /* If key is pressed when the animation is not running, kick
+ * the animation and quite suspend; If key is pressed when
+ * the animation is running, turn off the animation and request
+ * suspend.
+ */
+ if (!batt_anim->run) {
+ kick_animation(batt_anim);
+ request_suspend(false);
+ } else {
+ reset_animation(batt_anim);
+ charger->next_screen_transition = -1;
+ healthd_board_mode_charger_set_backlight(false);
+ gr_fb_blank(true);
+ if (charger->charger_connected)
+ request_suspend(true);
+ }
}
}
}
@@ -677,6 +702,8 @@
if (!charger->have_battery_state)
return;
+ healthd_board_mode_charger_battery_update(batt_prop);
+
if (!charger->charger_connected) {
/* Last cycle would have stopped at the extreme top of battery-icon
@@ -841,6 +868,8 @@
LOGW("--------------- STARTING CHARGER MODE ---------------\n");
+ healthd_board_mode_charger_init();
+
ret = ev_init(input_callback, charger);
if (!ret) {
epollfd = ev_get_epollfd();
diff --git a/healthd/include/healthd/healthd.h b/healthd/include/healthd/healthd.h
index 17efbd6..32f7521 100644
--- a/healthd/include/healthd/healthd.h
+++ b/healthd/include/healthd/healthd.h
@@ -128,4 +128,20 @@
int healthd_board_battery_update(struct android::BatteryProperties *props);
+//This API is called to turn on/off the display backlight incase it can't be
+//handle correcty in the display driver by calling gr_fg_blank();
+void healthd_board_mode_charger_set_backlight(bool en);
+
+//This API is called to update the battery/charging status by using the user
+//noticeable method other then the animation, such as: LEDs
+void healthd_board_mode_charger_battery_update(struct android::BatteryProperties *batt_prop);
+
+//This API is used to handle some board specific charger mode initialization,
+//such as: checking the charging is enabled or not.
+void healthd_board_mode_charger_init(void);
+
+//This API is called in the draw_battery() function to draw more infomation
+//about the battery on the animation, such as the SoC (State of Charge).
+void healthd_board_mode_charger_draw_battery(struct android::BatteryProperties *batt_prop);
+
#endif /* _HEALTHD_H_ */
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 5ccd80e..f03346e 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -103,6 +103,11 @@
/* The range 2900-2999 is reserved for OEM, and must never be
* used here */
#define AID_OEM_RESERVED_START 2900
+
+#define AID_QCOM_DIAG 2950 /* access to QTI diagnostic resources */
+#define AID_RFS 2951 /* Remote Filesystem for peripheral processors */
+#define AID_RFS_SHARED 2952 /* Shared files for Remote Filesystem for peripheral processors */
+
#define AID_OEM_RESERVED_END 2999
/* The 3000 series are intended for use as supplemental group id's only.
@@ -118,9 +123,14 @@
#define AID_READPROC 3009 /* Allow /proc read access */
#define AID_WAKELOCK 3010 /* Allow system wakelock read/write access */
+#define AID_RFS_OLD 3012 /* DEPRECATED OLD ID FOR RFS, DO NOT USE */
+#define AID_RFS_SHARED_OLD 3013 /* DEPRECATED OLD ID FOR RFS-SHARED */
+
/* The range 5000-5999 is also reserved for OEM, and must never be used here. */
#define AID_OEM_RESERVED_2_START 5000
#define AID_OEM_RESERVED_2_END 5999
+#define AID_SENSORS 3011 /* access to /dev/socket/sensor_ctl_socket & QCCI/QCSI */
+
#define AID_EVERYBODY 9997 /* shared between all apps in the same profile */
#define AID_MISC 9998 /* access to misc storage */
@@ -212,6 +222,11 @@
{ "cache", AID_CACHE, },
{ "diag", AID_DIAG, },
+ { "qcom_diag", AID_QCOM_DIAG, },
+
+ { "rfs", AID_RFS, },
+ { "rfs_shared", AID_RFS_SHARED, },
+
{ "net_bt_admin", AID_NET_BT_ADMIN, },
{ "net_bt", AID_NET_BT, },
{ "inet", AID_INET, },
@@ -222,6 +237,10 @@
{ "net_bt_stack", AID_NET_BT_STACK, },
{ "readproc", AID_READPROC, },
{ "wakelock", AID_WAKELOCK, },
+ { "sensors", AID_SENSORS, },
+
+ { "rfs_old", AID_RFS_OLD, },
+ { "rfs_shared_old", AID_RFS_SHARED_OLD, },
{ "everybody", AID_EVERYBODY, },
{ "misc", AID_MISC, },
diff --git a/include/system/camera.h b/include/system/camera.h
index 5d0873a..6de0203 100644
--- a/include/system/camera.h
+++ b/include/system/camera.h
@@ -88,9 +88,20 @@
// Notify on autofocus start and stop. This is useful in continuous
// autofocus - FOCUS_MODE_CONTINUOUS_VIDEO and FOCUS_MODE_CONTINUOUS_PICTURE.
CAMERA_MSG_FOCUS_MOVE = 0x0800, // notifyCallback
+ CAMERA_MSG_VENDOR_START = 0x1000,
+ CAMERA_MSG_STATS_DATA = CAMERA_MSG_VENDOR_START,
+ CAMERA_MSG_META_DATA = 0x2000,
+ CAMERA_MSG_VENDOR_END = 0x8000,
CAMERA_MSG_ALL_MSGS = 0xFFFF
};
+/** meta data type in CameraMetaDataCallback */
+enum {
+ CAMERA_META_DATA_ASD = 0x001, //ASD data
+ CAMERA_META_DATA_FD = 0x002, //FD/FP data
+ CAMERA_META_DATA_HDR = 0x003, //Auto HDR data
+};
+
/** cmdType in sendCommand functions */
enum {
CAMERA_CMD_START_SMOOTH_ZOOM = 1,
@@ -189,7 +200,25 @@
* IMPLEMENTATION_DEFINED, then HALv3 devices will use gralloc usage flags
* of SW_READ_OFTEN.
*/
- CAMERA_CMD_SET_VIDEO_FORMAT = 11
+ CAMERA_CMD_SET_VIDEO_FORMAT = 11,
+
+ CAMERA_CMD_VENDOR_START = 20,
+ /**
+ * Commands to enable/disable preview histogram
+ *
+ * Based on user's input to enable/disable histogram from the camera
+ * UI, send the appropriate command to the HAL to turn on/off the histogram
+ * stats and start sending the data to the application.
+ */
+ CAMERA_CMD_HISTOGRAM_ON = CAMERA_CMD_VENDOR_START,
+ CAMERA_CMD_HISTOGRAM_OFF = CAMERA_CMD_VENDOR_START + 1,
+ CAMERA_CMD_HISTOGRAM_SEND_DATA = CAMERA_CMD_VENDOR_START + 2,
+ CAMERA_CMD_LONGSHOT_ON = CAMERA_CMD_VENDOR_START + 3,
+ CAMERA_CMD_LONGSHOT_OFF = CAMERA_CMD_VENDOR_START + 4,
+ CAMERA_CMD_STOP_LONGSHOT = CAMERA_CMD_VENDOR_START + 5,
+ CAMERA_CMD_METADATA_ON = CAMERA_CMD_VENDOR_START + 6,
+ CAMERA_CMD_METADATA_OFF = CAMERA_CMD_VENDOR_START + 7,
+ CAMERA_CMD_VENDOR_END = 200,
};
/** camera fatal errors */
@@ -275,10 +304,32 @@
* -2000, -2000 if this is not supported.
*/
int32_t mouth[2];
+ int32_t smile_degree;
+ int32_t smile_score;
+ int32_t blink_detected;
+ int32_t face_recognised;
+ int32_t gaze_angle;
+ int32_t updown_dir;
+ int32_t leftright_dir;
+ int32_t roll_dir;
+ int32_t left_right_gaze;
+ int32_t top_bottom_gaze;
+ int32_t leye_blink;
+ int32_t reye_blink;
} camera_face_t;
/**
+ * The information of a data type received in a camera frame.
+ */
+typedef enum {
+ /** Data buffer */
+ CAMERA_FRAME_DATA_BUF = 0x000,
+ /** File descriptor */
+ CAMERA_FRAME_DATA_FD = 0x100
+} camera_frame_data_type_t;
+
+/**
* The metadata of the frame data.
*/
typedef struct camera_frame_metadata {
diff --git a/include/utils/Condition.h b/include/utils/Condition.h
index 5a72519..3e5141c 100644
--- a/include/utils/Condition.h
+++ b/include/utils/Condition.h
@@ -85,19 +85,22 @@
#if !defined(_WIN32)
-inline Condition::Condition() {
- pthread_cond_init(&mCond, NULL);
+inline Condition::Condition() : Condition(PRIVATE) {
}
inline Condition::Condition(int type) {
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+#if defined(__linux__)
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+#endif
+
if (type == SHARED) {
- pthread_condattr_t attr;
- pthread_condattr_init(&attr);
pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
- pthread_cond_init(&mCond, &attr);
- pthread_condattr_destroy(&attr);
- } else {
- pthread_cond_init(&mCond, NULL);
}
+
+ pthread_cond_init(&mCond, &attr);
+ pthread_condattr_destroy(&attr);
+
}
inline Condition::~Condition() {
pthread_cond_destroy(&mCond);
@@ -114,7 +117,7 @@
#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
struct timespec ts;
#if defined(__linux__)
- clock_gettime(CLOCK_REALTIME, &ts);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
#else // __APPLE__
// we don't support the clocks here.
struct timeval t;
diff --git a/init/Android.mk b/init/Android.mk
index 67541b8..944c8b8 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -12,6 +12,14 @@
init_options += -DLOG_UEVENTS=0
+ifneq ($(TARGET_INIT_COLDBOOT_TIMEOUT),)
+init_options += -DCOLDBOOT_TIMEOUT_OVERRIDE=$(TARGET_INIT_COLDBOOT_TIMEOUT)
+endif
+
+ifneq ($(TARGET_INIT_CONSOLE_TIMEOUT),)
+init_options += -DCONSOLE_TIMEOUT_SEC=$(TARGET_INIT_CONSOLE_TIMEOUT)
+endif
+
init_cflags += \
$(init_options) \
-Wall -Wextra \
@@ -71,6 +79,7 @@
ueventd.cpp \
ueventd_parser.cpp \
watchdogd.cpp \
+ vendor_init.cpp
LOCAL_MODULE:= init
LOCAL_C_INCLUDES += \
@@ -110,6 +119,11 @@
LOCAL_SANITIZE := integer
LOCAL_CLANG := true
+
+ifneq ($(strip $(TARGET_INIT_VENDOR_LIB)),)
+LOCAL_WHOLE_STATIC_LIBRARIES += $(TARGET_INIT_VENDOR_LIB)
+endif
+
include $(BUILD_EXECUTABLE)
diff --git a/init/NOTICE b/init/NOTICE
index c5b1efa..383d0f5 100644
--- a/init/NOTICE
+++ b/init/NOTICE
@@ -188,3 +188,29 @@
END OF TERMS AND CONDITIONS
+Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/init/builtins.cpp b/init/builtins.cpp
old mode 100644
new mode 100755
index 44217f0..5294ed0
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -547,6 +547,7 @@
return ret;
}
+
/* Queue event based on fs_mgr return code.
*
* code: return code of fs_mgr_mount_all
@@ -558,6 +559,13 @@
*/
static int queue_fs_event(int code) {
int ret = code;
+
+ std::string bootmode = property_get("ro.bootmode");
+ if (strncmp(bootmode.c_str(), "ffbm", 4) == 0) {
+ NOTICE("ffbm mode, not start class main\n");
+ return 0;
+ }
+
if (code == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
ActionManager::GetInstance().QueueEventTrigger("encrypt");
} else if (code == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
@@ -810,10 +818,92 @@
return fs_mgr_update_verity_state(verity_update_property);
}
+static const char * get_prefix(const std::vector<std::string>& args)
+{
+ uint32_t arglen = args.size();
+ const char *prefix = NULL;
+ for (uint32_t i = 0; i < arglen - 1; i++) {
+ if (args[i].compare("-p") == 0) {
+ prefix = args[++i].c_str();
+ break;
+ }
+ }
+ return prefix;
+
+}
+static int sanitize_path(const char *path, const char *prefix)
+{
+ struct stat st;
+ char buf[PATH_MAX] = {0};
+ if (!path || !prefix) {
+ goto error;
+ }
+ //Confirm the path exists
+ if (lstat(path, &st) < 0) {
+ ERROR("sanitize_path: Failed to locate path %s: %s\n",
+ path,
+ strerror(errno));
+ goto error;
+ }
+ //If this is a symlink check that the prefix matches
+ if (S_ISLNK(st.st_mode)){
+ if (readlink(path, buf, PATH_MAX - 1) < 0) {
+ ERROR("sanitize_path: Failed to resolve link for %s: %s\n",
+ path,
+ strerror(errno));
+ goto error;
+ }
+ if (strncmp(buf, prefix, strlen(prefix))) {
+ ERROR("sanitize_path: Match error: Path:%s Resolved:%s Prefix%s\n",
+ path,
+ buf,
+ prefix);
+ goto error;
+ }
+ }
+ return 0;
+error:
+ return -1;
+}
+
static int do_write(const std::vector<std::string>& args) {
- const char* path = args[1].c_str();
- const char* value = args[2].c_str();
+ const char* path = NULL;
+ const char* value = NULL;
+ const char* prefix = NULL;
+ uint32_t arglen = args.size();
+
+ prefix = get_prefix(args);
+ if (prefix && (arglen != 5)) {
+ ERROR("do_write: Incorrect number of args\n");
+ goto error;
+ }
+ for (uint32_t i = 1; i < arglen - 1; i++) {
+ if (args[i].compare("-p") != 0) {
+ path = args[i++].c_str();
+ value = args[i].c_str();
+ break;
+ } else {
+ //Value at current index is -p. The next index would
+ //be the prefix.Skip it.
+ i++;
+ }
+ }
+ if (!path || !value) {
+ ERROR("do_write: Invalid path/value\n");
+ goto error;
+ }
+ if (prefix) {
+ if (sanitize_path(path, prefix) != 0) {
+ ERROR("do_write: Faield to sanitize path: %s prefix: %s\n",
+ path,
+ prefix);
+ goto error;
+ }
+ return write_file_follow(path, value);
+ }
return write_file(path, value);
+error:
+ return -EINVAL;
}
static int do_copy(const std::vector<std::string>& args) {
@@ -875,18 +965,48 @@
}
static int do_chown(const std::vector<std::string>& args) {
+ const char *prefix = get_prefix(args);
+ uint32_t num_prefix_args = (!prefix) ? 0:2;
/* GID is optional. */
- if (args.size() == 3) {
+ if (args.size() == 3 + num_prefix_args) {
+ if (prefix) {
+ if ((sanitize_path(args[2].c_str(), prefix) != 0)) {
+ ERROR("do_chown: failed for %s..prefix(%s) match error\n",
+ args[2].c_str(),
+ prefix);
+ goto error;
+ }
+ //Following of symlink allowed
+ if (chown(args[2].c_str(), decode_uid(args[1].c_str()), -1) == -1)
+ return -errno;
+ return 0;
+ }
+ //Followng of symlinks not allowed
if (lchown(args[2].c_str(), decode_uid(args[1].c_str()), -1) == -1)
return -errno;
- } else if (args.size() == 4) {
+ } else if (args.size() == 4 + num_prefix_args) {
+ if (prefix) {
+ if ((sanitize_path(args[3].c_str(), prefix) != 0)) {
+ ERROR("do_chown: sanitize_path failed for path: %s prefix:%s\n",
+ args[3].c_str(),
+ prefix);
+ goto error;
+ }
+ //Following of symlink allowed
+ if (chown(args[3].c_str(), decode_uid(args[1].c_str()),
+ decode_uid(args[2].c_str())) == -1)
+ return -errno;
+ return 0;
+ }
if (lchown(args[3].c_str(), decode_uid(args[1].c_str()),
- decode_uid(args[2].c_str())) == -1)
+ decode_uid(args[2].c_str())) == -1)
return -errno;
} else {
return -1;
}
return 0;
+error:
+ return -1;
}
static mode_t get_mode(const char *s) {
@@ -903,8 +1023,19 @@
}
static int do_chmod(const std::vector<std::string>& args) {
+ const char *prefix = get_prefix(args);
+ int flags = AT_SYMLINK_NOFOLLOW;
+ if (prefix) {
+ if (sanitize_path(args[2].c_str(), prefix) != 0) {
+ ERROR("do_chmod: failed for %s..prefix(%s) match err\n",
+ args[2].c_str(),
+ prefix);
+ return -1;
+ }
+ flags = 0;
+ }
mode_t mode = get_mode(args[1].c_str());
- if (fchmodat(AT_FDCWD, args[2].c_str(), mode, AT_SYMLINK_NOFOLLOW) < 0) {
+ if (fchmodat(AT_FDCWD, args[2].c_str(), mode, flags) < 0) {
return -errno;
}
return 0;
@@ -995,8 +1126,8 @@
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
static const Map builtin_functions = {
{"bootchart_init", {0, 0, do_bootchart_init}},
- {"chmod", {2, 2, do_chmod}},
- {"chown", {2, 3, do_chown}},
+ {"chmod", {2, 4, do_chmod}},
+ {"chown", {2, 5, do_chown}},
{"class_reset", {1, 1, do_class_reset}},
{"class_start", {1, 1, do_class_start}},
{"class_stop", {1, 1, do_class_stop}},
@@ -1034,7 +1165,7 @@
{"verity_load_state", {0, 0, do_verity_load_state}},
{"verity_update_state", {0, 0, do_verity_update_state}},
{"wait", {1, 2, do_wait}},
- {"write", {2, 2, do_write}},
+ {"write", {2, 4, do_write}},
};
return builtin_functions;
}
diff --git a/init/devices.cpp b/init/devices.cpp
index cffc561..5edbe2a 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -48,6 +48,7 @@
#include "ueventd_parser.h"
#include "util.h"
#include "log.h"
+#include "property_service.h"
#define SYSFS_PREFIX "/sys"
static const char *firmware_dirs[] = { "/etc/firmware",
@@ -56,6 +57,8 @@
extern struct selabel_handle *sehandle;
+extern std::string boot_device;
+
static int device_fd = -1;
struct uevent {
@@ -526,6 +529,11 @@
else
links[link_num] = NULL;
+ if (pdev && !boot_device.empty() && strstr(device, boot_device.c_str())) {
+ /* Create bootdevice symlink for platform boot stroage device */
+ make_link_init(link_path, "/dev/block/bootdevice");
+ }
+
return links;
}
@@ -731,8 +739,30 @@
base = "/dev/log/";
make_dir(base, 0755);
name += 4;
- } else
- base = "/dev/";
+ } else if (!strncmp(uevent->subsystem, "dvb", 3)) {
+ /* This imitates the file system that would be created
+ * if we were using devfs instead to preserve backward compatibility
+ * for users of dvb devices
+ */
+ int adapter_id=0;
+ char dev_name[20] = {0};
+
+ sscanf(name, "dvb%d.%s", &adapter_id, dev_name);
+
+ /* build dvb directory */
+ base = "/dev/dvb";
+ mkdir(base, 0755);
+
+ /* build adapter directory */
+ snprintf(devpath, sizeof(devpath), "/dev/dvb/adapter%d", adapter_id);
+ mkdir(devpath, 0755);
+
+ /* build actual device directory */
+ snprintf(devpath, sizeof(devpath), "/dev/dvb/adapter%d/%s",
+ adapter_id, dev_name);
+ }
+ else
+ base = "/dev/";
links = get_character_device_symlinks(uevent);
if (!devpath[0])
@@ -766,6 +796,21 @@
return -1;
len_to_copy = st.st_size;
+ if (S_ISBLK(st.st_mode)) {
+ //File points to a block device. Need to calculate it's size
+ //manually
+ len_to_copy = lseek64(fw_fd, 0, SEEK_END);
+ if (len_to_copy < 0) {
+ ERROR("Failed to get size of blk device partition: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ if (lseek64(fw_fd, 0, SEEK_SET) < 0) {
+ ERROR("Failed to set r/w offset for blk device partition: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ }
write(loading_fd, "1", 1); /* start transfer */
while (len_to_copy > 0) {
diff --git a/init/init.cpp b/init/init.cpp
old mode 100644
new mode 100755
index cd2d2e6..164dc0f
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -18,7 +18,6 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
-#include <fstream>
#include <libgen.h>
#include <paths.h>
#include <signal.h>
@@ -161,15 +160,19 @@
static int wait_for_coldboot_done_action(const std::vector<std::string>& args) {
Timer t;
-
+ int timeout = 0;
+#ifdef COLDBOOT_TIMEOUT_OVERRIDE
+ timeout = COLDBOOT_TIMEOUT_OVERRIDE;
+#else
+ timeout = 5;
+#endif
NOTICE("Waiting for %s...\n", COLDBOOT_DONE);
// Any longer than 1s is an unreasonable length of time to delay booting.
// If you're hitting this timeout, check that you didn't make your
// sepolicy regular expressions too expensive (http://b/19899875).
- if (wait_for_file(COLDBOOT_DONE, 1)) {
+ if (wait_for_file(COLDBOOT_DONE, timeout)) {
ERROR("Timed out waiting for %s\n", COLDBOOT_DONE);
}
-
NOTICE("Waiting for %s took %.2fs.\n", COLDBOOT_DONE, t.duration());
return 0;
}
@@ -251,100 +254,6 @@
return result;
}
-static void security_failure() {
- ERROR("Security failure; rebooting into recovery mode...\n");
- android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
- while (true) { pause(); } // never reached
-}
-
-#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits"
-#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits"
-
-/* __attribute__((unused)) due to lack of mips support: see mips block
- * in set_mmap_rnd_bits_action */
-static bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bool compat) {
- std::string path;
- if (compat) {
- path = MMAP_RND_COMPAT_PATH;
- } else {
- path = MMAP_RND_PATH;
- }
- std::ifstream inf(path, std::fstream::in);
- if (!inf) {
- return false;
- }
- while (start >= min) {
- // try to write out new value
- std::string str_val = std::to_string(start);
- std::ofstream of(path, std::fstream::out);
- if (!of) {
- return false;
- }
- of << str_val << std::endl;
- of.close();
-
- // check to make sure it was recorded
- inf.seekg(0);
- std::string str_rec;
- inf >> str_rec;
- if (str_val.compare(str_rec) == 0) {
- break;
- }
- start--;
- }
- inf.close();
- return (start >= min);
-}
-
-/*
- * Set /proc/sys/vm/mmap_rnd_bits and potentially
- * /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values.
- * Returns -1 if unable to set these to an acceptable value. Apply
- * upstream patch-sets https://lkml.org/lkml/2015/12/21/337 and
- * https://lkml.org/lkml/2016/2/4/831 to enable this.
- */
-static int set_mmap_rnd_bits_action(const std::vector<std::string>& args)
-{
- int ret = -1;
-
- /* values are arch-dependent */
-#if defined(__aarch64__)
- /* arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE */
- if (set_mmap_rnd_bits_min(33, 24, false)
- && set_mmap_rnd_bits_min(16, 16, true)) {
- ret = 0;
- }
-#elif defined(__x86_64__)
- /* x86_64 supports 28 - 32 bits */
- if (set_mmap_rnd_bits_min(32, 32, false)
- && set_mmap_rnd_bits_min(16, 16, true)) {
- ret = 0;
- }
-#elif defined(__arm__) || defined(__i386__)
- /* check to see if we're running on 64-bit kernel */
- bool h64 = !access(MMAP_RND_COMPAT_PATH, F_OK);
- /* supported 32-bit architecture must have 16 bits set */
- if (set_mmap_rnd_bits_min(16, 16, h64)) {
- ret = 0;
- }
-#elif defined(__mips__) || defined(__mips64__)
- // TODO: add mips support b/27788820
- ret = 0;
-#else
- ERROR("Unknown architecture\n");
-#endif
-
-#ifdef __BRILLO__
- // TODO: b/27794137
- ret = 0;
-#endif
- if (ret == -1) {
- ERROR("Unable to set adequate mmap entropy value!\n");
- security_failure();
- }
- return ret;
-}
-
static int keychord_init_action(const std::vector<std::string>& args)
{
keychord_init();
@@ -353,15 +262,31 @@
static int console_init_action(const std::vector<std::string>& args)
{
+ int fd = -1;
std::string console = property_get("ro.boot.console");
if (!console.empty()) {
console_name = "/dev/" + console;
}
-
- int fd = open(console_name.c_str(), O_RDWR | O_CLOEXEC);
+ fd = open(console_name.c_str(), O_RDWR | O_CLOEXEC);
+#ifdef CONSOLE_TIMEOUT_SEC
+ int num_console_retries = 0;
+ while ((fd < 0) && num_console_retries++ < CONSOLE_TIMEOUT_SEC) {
+ ERROR("Failed to open console device %s(%s)..Retrying\n",
+ console_name.c_str(), strerror(errno));
+ sleep(1);
+ fd = open(console_name.c_str(), O_RDWR | O_CLOEXEC);
+ }
if (fd >= 0)
+ INFO("Console device located");
+#endif
+ if (fd >= 0) {
have_console = 1;
- close(fd);
+ close(fd);
+ } else {
+ ERROR("console init failed. Open on Console device %s failed(%s)\n",
+ console.c_str(), strerror(errno));
+ return 0;
+ }
fd = open("/dev/tty0", O_WRONLY | O_CLOEXEC);
if (fd >= 0) {
@@ -553,6 +478,12 @@
return 0;
}
+static void security_failure() {
+ ERROR("Security failure; rebooting into recovery mode...\n");
+ android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
+ while (true) { pause(); } // never reached
+}
+
static void selinux_initialize(bool in_kernel_domain) {
Timer t;
@@ -701,7 +632,6 @@
am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
// ... so that we can start queuing up actions that require stuff from /dev.
am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
- am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits");
am.QueueBuiltinAction(keychord_init_action, "keychord_init");
am.QueueBuiltinAction(console_init_action, "console_init");
@@ -716,6 +646,9 @@
std::string bootmode = property_get("ro.bootmode");
if (bootmode == "charger") {
am.QueueEventTrigger("charger");
+ } else if (strncmp(bootmode.c_str(), "ffbm", 4) == 0) {
+ NOTICE("Booting into ffbm mode\n");
+ am.QueueEventTrigger("ffbm");
} else {
am.QueueEventTrigger("late-init");
}
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 5c1ae79..7860748 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -41,6 +41,7 @@
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/mman.h>
+#include <sys/resource.h>
#include <private/android_filesystem_config.h>
#include <selinux/selinux.h>
@@ -54,6 +55,7 @@
#include "init.h"
#include "util.h"
#include "log.h"
+#include "vendor_init.h"
#define PERSISTENT_PROPERTY_DIR "/data/property"
#define FSTAB_PREFIX "/fstab."
@@ -468,6 +470,22 @@
}
}
+static int check_rlim_action() {
+ std::string value ;
+ struct rlimit rl;
+ value = property_get("persist.debug.trace");
+ const char* pval = value.c_str();
+
+ if((strcmp(pval,"1") == 0)) {
+ rl.rlim_cur = RLIM_INFINITY;
+ rl.rlim_max = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+ ERROR("could not enable core file generation");
+ }
+ }
+ return 0;
+}
+
/* When booting an encrypted system, /data is not mounted when the
* property service is started, so any properties stored there are
* not loaded. Vold triggers init to load these properties once it
@@ -477,6 +495,8 @@
load_override_properties();
/* Read persistent properties after all default values have been loaded. */
load_persistent_properties();
+ /*check for coredump*/
+ check_rlim_action();
}
void load_recovery_id_prop() {
@@ -521,6 +541,12 @@
load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL);
load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL);
load_properties_from_file(PROP_PATH_FACTORY, "ro.*");
+
+ /* update with vendor-specific property runtime
+ * overrides
+ */
+ vendor_load_properties();
+
load_recovery_id_prop();
}
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 249739b..131e97f 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -33,6 +33,8 @@
#include "ueventd_parser.h"
#include "property_service.h"
+std::string boot_device;
+
int ueventd_main(int argc, char **argv)
{
/*
@@ -64,6 +66,8 @@
ueventd_parse_config_file("/ueventd.rc");
ueventd_parse_config_file(android::base::StringPrintf("/ueventd.%s.rc", hardware.c_str()).c_str());
+ boot_device = property_get("ro.boot.bootdevice");
+
device_init();
pollfd ufd;
diff --git a/init/util.cpp b/init/util.cpp
old mode 100644
new mode 100755
index 89d3276..babdcbd
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -212,6 +212,21 @@
return result;
}
+int write_file_follow(const char* path, const char* content) {
+ int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY|O_CREAT|O_CLOEXEC, 0600));
+ if (fd == -1) {
+ NOTICE("write_file: Unable to open '%s': %s\n", path, strerror(errno));
+ return -1;
+ }
+ int result = android::base::WriteStringToFd(content, fd) ? 0 : -1;
+ if (result == -1) {
+ NOTICE("write_file: Unable to write to '%s': %s\n", path, strerror(errno));
+ }
+ close(fd);
+ return result;
+}
+
+
#define MAX_MTD_PARTITIONS 16
static struct {
diff --git a/init/util.h b/init/util.h
old mode 100644
new mode 100755
index af4b098..db9025d
--- a/init/util.h
+++ b/init/util.h
@@ -33,6 +33,7 @@
bool read_file(const char* path, std::string* content);
int write_file(const char* path, const char* content);
+int write_file_follow(const char* path, const char* content);
time_t gettime();
uint64_t gettime_ns();
diff --git a/init/vendor_init.cpp b/init/vendor_init.cpp
new file mode 100644
index 0000000..d3fd5ff
--- /dev/null
+++ b/init/vendor_init.cpp
@@ -0,0 +1,37 @@
+/*
+Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "vendor_init.h"
+
+/* init vendor override stubs */
+
+__attribute__ ((weak))
+void vendor_load_properties()
+{
+}
diff --git a/init/vendor_init.h b/init/vendor_init.h
new file mode 100644
index 0000000..9afb449
--- /dev/null
+++ b/init/vendor_init.h
@@ -0,0 +1,33 @@
+/*
+Copyright (c) 2013, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __INIT_VENDOR__H__
+#define __INIT_VENDOR__H__
+extern void vendor_load_properties(void);
+#endif /* __INIT_VENDOR__H__ */
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index 05a2048..0df5bf3 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -66,6 +66,7 @@
static int bg_cpuset_fd = -1;
static int fg_cpuset_fd = -1;
static int ta_cpuset_fd = -1; // special cpuset for top app
+static int system_bg_schedboost_fd = -1;
#endif
// File descriptors open to /dev/stune/../tasks, setup by initialize, or -1 on error
@@ -139,17 +140,21 @@
system_bg_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
filename = "/dev/cpuset/top-app/tasks";
ta_cpuset_fd = open(filename, O_WRONLY | O_CLOEXEC);
+ }
#ifdef USE_SCHEDBOOST
+ if (!access("/dev/stune/tasks", F_OK)) {
filename = "/dev/stune/top-app/tasks";
ta_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
filename = "/dev/stune/foreground/tasks";
fg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
filename = "/dev/stune/background/tasks";
bg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
-#endif
+ filename = "/dev/stune/system-background/tasks";
+ system_bg_schedboost_fd = open(filename, O_WRONLY | O_CLOEXEC);
}
-#endif
+#endif /* USE_SCHEDBOOST */
+#endif /* USE_CPUSETS */
}
/*
@@ -307,6 +312,7 @@
break;
case SP_SYSTEM:
fd = system_bg_cpuset_fd;
+ boost_fd = system_bg_schedboost_fd;
break;
default:
boost_fd = fd = -1;
diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c
index eae32ce..f051558 100644
--- a/libnetutils/ifc_utils.c
+++ b/libnetutils/ifc_utils.c
@@ -173,8 +173,7 @@
static void ifc_init_ifr(const char *name, struct ifreq *ifr)
{
memset(ifr, 0, sizeof(struct ifreq));
- strncpy(ifr->ifr_name, name, IFNAMSIZ);
- ifr->ifr_name[IFNAMSIZ - 1] = 0;
+ strlcpy(ifr->ifr_name, name, IFNAMSIZ);
}
int ifc_get_hwaddr(const char *name, void *ptr)
@@ -625,23 +624,26 @@
int ifc_reset_connections(const char *ifname, const int reset_mask)
{
#if defined(__ANDROID__)
- int result, success;
+ int result = 0, success;
in_addr_t myaddr = 0;
struct ifreq ifr;
struct in6_ifreq ifr6;
+ int ctl_sock = -1;
if (reset_mask & RESET_IPV4_ADDRESSES) {
/* IPv4. Clear connections on the IP address. */
- ifc_init();
- if (!(reset_mask & RESET_IGNORE_INTERFACE_ADDRESS)) {
- ifc_get_info(ifname, &myaddr, NULL, NULL);
+ ctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (ctl_sock >= 0) {
+ if (!(reset_mask & RESET_IGNORE_INTERFACE_ADDRESS)) {
+ ifc_get_info(ifname, &myaddr, NULL, NULL);
+ }
+ ifc_init_ifr(ifname, &ifr);
+ init_sockaddr_in(&ifr.ifr_addr, myaddr);
+ result = ioctl(ctl_sock, SIOCKILLADDR, &ifr);
+ close(ctl_sock);
+ } else {
+ result = -1;
}
- ifc_init_ifr(ifname, &ifr);
- init_sockaddr_in(&ifr.ifr_addr, myaddr);
- result = ioctl(ifc_ctl_sock, SIOCKILLADDR, &ifr);
- ifc_close();
- } else {
- result = 0;
}
if (reset_mask & RESET_IPV6_ADDRESSES) {
@@ -651,14 +653,18 @@
* So we clear all unused IPv6 connections on the device by specifying an
* empty IPv6 address.
*/
- ifc_init6();
+ ctl_sock = socket(AF_INET6, SOCK_DGRAM, 0);
// This implicitly specifies an address of ::, i.e., kill all IPv6 sockets.
memset(&ifr6, 0, sizeof(ifr6));
- success = ioctl(ifc_ctl_sock6, SIOCKILLADDR, &ifr6);
- if (result == 0) {
- result = success;
+ if (ctl_sock >= 0) {
+ success = ioctl(ctl_sock, SIOCKILLADDR, &ifr6);
+ if (result == 0) {
+ result = success;
+ }
+ close(ctl_sock);
+ } else {
+ result = -1;
}
- ifc_close6();
}
return result;
diff --git a/lmkd/Android.mk b/lmkd/Android.mk
index 8c88661..8980d1c 100644
--- a/lmkd/Android.mk
+++ b/lmkd/Android.mk
@@ -2,7 +2,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := lmkd.c
-LOCAL_SHARED_LIBRARIES := liblog libm libc libprocessgroup
+LOCAL_SHARED_LIBRARIES := liblog libm libc libprocessgroup libcutils
LOCAL_CFLAGS := -Werror
LOCAL_MODULE := lmkd
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
old mode 100644
new mode 100755
index afc81ed..51c285b
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -33,6 +33,8 @@
#include <cutils/sockets.h>
#include <log/log.h>
#include <processgroup/processgroup.h>
+#include <dlfcn.h>
+#include <cutils/properties.h>
#ifndef __unused
#define __unused __attribute__((__unused__))
@@ -61,6 +63,14 @@
*/
#define CTRL_PACKET_MAX (sizeof(int) * (MAX_TARGETS * 2 + 1))
+static void* memperf_opt_handle = NULL;
+static int (*memperf_init_fn)(void) = NULL;
+static int (*memperf_am_update_fn)(void*,unsigned int) = NULL;
+static void init_memperf();
+static void de_init_memperf();
+static bool enable_amupdate = false;
+static bool enable_umm = false;
+
/* default to old in-kernel interface if no memory pressure events */
static int use_inkernel_interface = 1;
@@ -356,6 +366,14 @@
if (nargs < 0)
goto wronglen;
+ if (enable_umm && enable_amupdate) {
+ int ret = (*memperf_am_update_fn)(ibuf, sizeof(ibuf));
+ if (ret == -1) {
+ ALOGE("Received Error from mem_ctl. unloading the module %d", ret);
+ de_init_memperf();
+ }
+ }
+
cmd = ntohl(ibuf[0]);
switch(cmd) {
@@ -804,6 +822,48 @@
}
}
+static void de_init_memperf() {
+ memperf_init_fn = NULL;
+ memperf_am_update_fn = NULL;
+
+ if (memperf_opt_handle) dlclose(memperf_opt_handle);
+
+ memperf_opt_handle = NULL;
+}
+
+static void init_memperf() {
+ int mem_ctl_enable = 0;
+ enable_amupdate = property_get_bool("ro.memperf.amupdate", false);
+ mem_ctl_enable = property_get_bool("ro.memperf.enable", 0);
+ enable_umm = property_get_bool("ro.memperf.umm", false);
+ if (mem_ctl_enable) {
+ char prop[PROPERTY_VALUE_MAX];
+ memset(prop, '\0', sizeof(prop));
+ property_get("ro.memperf.lib", prop, "");
+ memperf_opt_handle = dlopen(prop, RTLD_LAZY);
+ if (memperf_opt_handle != NULL) {
+ dlerror();
+ memperf_init_fn = (int(*)(void))dlsym(memperf_opt_handle, "init_mperfd");
+ memperf_am_update_fn = (int(*)(void*,unsigned int))dlsym(memperf_opt_handle, "amUpdate");
+ const char *dlsym_error = dlerror();
+
+ if((memperf_am_update_fn == NULL) || (memperf_init_fn == NULL)) {
+ ALOGD("Error loading symbol. dlerror : %s", dlsym_error);
+ de_init_memperf();
+ }
+
+ if (memperf_init_fn) {
+ if (-1 == (*memperf_init_fn)()) {
+ ALOGE("Error during init. Disabling memperf !!!!");
+ de_init_memperf();
+ }
+ }
+ } else {
+ ALOGE("Failed to load library");
+ }
+ }
+}
+
int main(int argc __unused, char **argv __unused) {
struct sched_param param = {
.sched_priority = 1,
@@ -811,9 +871,15 @@
mlockall(MCL_FUTURE);
sched_setscheduler(0, SCHED_FIFO, ¶m);
+
+ init_memperf();
+
if (!init())
mainloop();
+ if (memperf_opt_handle) {
+ de_init_memperf();
+ }
ALOGI("exiting");
return 0;
}
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 33f22dd..87524b4 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -27,6 +27,7 @@
#include <android-base/file.h>
#include <android-base/strings.h>
+#include <cutils/properties.h>
#include <cutils/sched_policy.h>
#include <cutils/sockets.h>
#include <log/event_tag_map.h>
@@ -70,12 +71,15 @@
/* Global Variables */
static const char * g_outputFileName;
+static const char * g_outputPartitionName = NULL;
// 0 means "no log rotation"
static size_t g_logRotateSizeKBytes;
// 0 means "unbounded"
static size_t g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS;
static int g_outFD = -1;
+static int g_logDumpFD = -1;
static size_t g_outByteCount;
+static size_t g_outByteCountOfLogDump;
static int g_printBinary;
static int g_devCount; // >1 means multiple
static pcrecpp::RE* g_regex;
@@ -83,6 +87,8 @@
static size_t g_maxCount;
static size_t g_printCount;
static bool g_printItAnyways;
+static bool g_logDumpEnabled;
+static size_t g_logDumpEndPosition = 0;
// if showHelp is set, newline required in fmt statement to transition to usage
__noreturn static void logcat_panic(bool showHelp, const char *fmt, ...) __printflike(2,3);
@@ -151,6 +157,42 @@
TEMP_FAILURE_RETRY(write(g_outFD, buf, size));
}
+static void checkAndRotateLogDump(size_t logLength)
+{
+ if (g_outByteCountOfLogDump + logLength >= g_logDumpEndPosition) {
+ lseek(g_logDumpFD, 0, SEEK_SET);
+ g_outByteCountOfLogDump = 0;
+ }
+}
+
+static void writeEntryToLogDump(AndroidLogEntry *entry)
+{
+ int bytesWrittenToLogDump = 0;
+ char defaultBuffer[512];
+ char *outBuffer = NULL;
+ size_t logLength;
+
+ // Get logLength
+ outBuffer = android_log_formatLogLine(g_logformat, defaultBuffer,
+ sizeof(defaultBuffer),
+ entry,
+ &logLength);
+ if (outBuffer != defaultBuffer) {
+ free(outBuffer);
+ }
+
+ // Check if the to-be-inserted log exceeds the available buffer size; And rotate if needed.
+ checkAndRotateLogDump(logLength);
+
+ bytesWrittenToLogDump = android_log_printLogLine(g_logformat, g_logDumpFD, entry);
+
+ if (bytesWrittenToLogDump < 0) {
+ logcat_panic(false, "output error");
+ }
+
+ g_outByteCountOfLogDump += bytesWrittenToLogDump;
+}
+
static bool regexOk(const AndroidLogEntry& entry)
{
if (!g_regex) {
@@ -191,6 +233,10 @@
}
if (android_log_shouldPrintLine(g_logformat, entry.tag, entry.priority)) {
+ if (g_logDumpEnabled) {
+ writeEntryToLogDump(&entry);
+ }
+
bool match = regexOk(entry);
g_printCount += match;
@@ -223,6 +269,14 @@
snprintf(buf, sizeof(buf), "--------- %s %s\n",
dev->printed ? "switch to" : "beginning of",
dev->device);
+ if (g_logDumpEnabled) {
+ checkAndRotateLogDump(strlen(buf));
+ int bytesWrittenToLogDump = write(g_logDumpFD, buf, strlen(buf));
+ if (bytesWrittenToLogDump < 0) {
+ logcat_panic(false, "output error");
+ }
+ g_outByteCountOfLogDump += bytesWrittenToLogDump;
+ }
if (write(g_outFD, buf, strlen(buf)) < 0) {
logcat_panic(false, "output error");
}
@@ -233,6 +287,29 @@
static void setupOutput()
{
+ if (g_logDumpEnabled) {
+ if (g_outputPartitionName == NULL) {
+ property_set("ctl.stop","logdumpd");
+ logcat_panic(false, "partition name is null");
+ }
+
+ struct stat statbuf;
+ if (stat(g_outputPartitionName, &statbuf) == -1) {
+ property_set("ctl.stop","logdumpd");
+ logcat_panic(false, "Couldn't stat output partition\n");
+ }
+
+ g_logDumpFD = openLogFile (g_outputPartitionName);
+ if (g_logDumpFD < 0) {
+ property_set("ctl.stop","logdumpd");
+ logcat_panic(false, "Can't open output partition");
+ }
+
+ //save end of partition to be used later for log rotation
+ g_logDumpEndPosition = lseek(g_logDumpFD, 0, SEEK_END);
+ //set back file offset to the beginning
+ lseek(g_logDumpFD, 0, SEEK_SET);
+ }
if (g_outputFileName == NULL) {
g_outFD = STDOUT_FILENO;
@@ -603,7 +680,7 @@
{ NULL, 0, NULL, 0 }
};
- ret = getopt_long(argc, argv, ":cdDLt:T:gG:sQf:r:n:v:b:BSpP:m:e:",
+ ret = getopt_long(argc, argv, ":cdDLt:T:gG:sQf:r:n:v:b:BSpP:m:e:w:",
long_options, &option_index);
if (ret < 0) {
@@ -927,6 +1004,11 @@
printStatistics = 1;
break;
+ case 'w':
+ g_logDumpEnabled = true;
+ g_outputPartitionName = optarg;
+ break;
+
case ':':
logcat_panic(true, "Option -%c needs an argument\n", optopt);
break;
diff --git a/mkbootimg/mkbootimg b/mkbootimg/mkbootimg
index 5a13da2..d0149e8 100755
--- a/mkbootimg/mkbootimg
+++ b/mkbootimg/mkbootimg
@@ -57,7 +57,7 @@
args.base + args.second_offset, # physical load addr
args.base + args.tags_offset, # physical addr for kernel tags
args.pagesize, # flash page size we assume
- 0, # future expansion: MUST be 0
+ filesize(args.dt), # size in bytes
(args.os_version << 11) | args.os_patch_level)) # os version and patch level
args.output.write(pack('16s', args.board.encode())) # asciiz product name
args.output.write(pack('512s', args.cmdline[:512].encode()))
@@ -66,6 +66,7 @@
update_sha(sha, args.kernel)
update_sha(sha, args.ramdisk)
update_sha(sha, args.second)
+ update_sha(sha, args.dt)
img_id = pack('32s', sha.digest())
args.output.write(img_id)
@@ -150,6 +151,7 @@
choices=[2**i for i in range(11,15)], default=2048)
parser.add_argument('--id', help='print the image ID on standard output',
action='store_true')
+ parser.add_argument('--dt', help='path to the device tree image', type=FileType('rb'))
parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'),
required=True)
return parser.parse_args()
@@ -159,6 +161,7 @@
write_padded_file(args.output, args.kernel, args.pagesize)
write_padded_file(args.output, args.ramdisk, args.pagesize)
write_padded_file(args.output, args.second, args.pagesize)
+ write_padded_file(args.output, args.dt, args.pagesize)
def main():
diff --git a/rootdir/init.rc b/rootdir/init.rc
index df60f65..b9674d3 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -51,18 +51,22 @@
mount cgroup none /dev/stune schedtune
mkdir /dev/stune/foreground
mkdir /dev/stune/background
+ mkdir /dev/stune/system-background
mkdir /dev/stune/top-app
chown system system /dev/stune
chown system system /dev/stune/foreground
chown system system /dev/stune/background
+ chown system system /dev/stune/system-background
chown system system /dev/stune/top-app
chown system system /dev/stune/tasks
chown system system /dev/stune/foreground/tasks
chown system system /dev/stune/background/tasks
+ chown system system /dev/stune/system-background/tasks
chown system system /dev/stune/top-app/tasks
chmod 0664 /dev/stune/tasks
chmod 0664 /dev/stune/foreground/tasks
chmod 0664 /dev/stune/background/tasks
+ chmod 0664 /dev/stune/system-background/tasks
chmod 0664 /dev/stune/top-app/tasks
# Mount staging areas for devices managed by vold
@@ -561,8 +565,11 @@
chown system system /sys/class/leds/button-backlight/brightness
chown system system /sys/class/leds/jogball-backlight/brightness
chown system system /sys/class/leds/red/brightness
+ chown system system /sys/class/leds/red/blink
chown system system /sys/class/leds/green/brightness
+ chown system system /sys/class/leds/green/blink
chown system system /sys/class/leds/blue/brightness
+ chown system system /sys/class/leds/blue/blink
chown system system /sys/class/leds/red/device/grpfreq
chown system system /sys/class/leds/red/device/grppwm
chown system system /sys/class/leds/red/device/blink
diff --git a/rootdir/init.usb.configfs.rc b/rootdir/init.usb.configfs.rc
index 186384b..c46130c 100644
--- a/rootdir/init.usb.configfs.rc
+++ b/rootdir/init.usb.configfs.rc
@@ -1,6 +1,7 @@
on property:sys.usb.config=none && property:sys.usb.configfs=1
write /config/usb_gadget/g1/UDC "none"
stop adbd
+ setprop sys.usb.ffs.ready 0
write /config/usb_gadget/g1/bDeviceClass 0
write /config/usb_gadget/g1/bDeviceSubClass 0
write /config/usb_gadget/g1/bDeviceProtocol 0
@@ -14,6 +15,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x4ee7
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -23,6 +28,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x4ee1
symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -35,6 +44,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x4ee2
symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -45,6 +58,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x4ee5
symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -57,6 +74,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x4ee6
symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -67,6 +88,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x2d00
symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -79,6 +104,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x2d01
symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -89,7 +118,11 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
- symlink /config/usb_gadget/g1/functions/audio_source.gs2 /config/usb_gadget/g1/configs/b.1/f1
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x2d02
+ symlink /config/usb_gadget/g1/functions/audio_source.gs3 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -101,7 +134,11 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
- symlink /config/usb_gadget/g1/functions/audio_source.gs2 /config/usb_gadget/g1/configs/b.1/f1
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x2d03
+ symlink /config/usb_gadget/g1/functions/audio_source.gs3 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -111,6 +148,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x2d04
symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/audio_source.gs3 /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -124,6 +165,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x2d05
symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/audio_source.gs3 /config/usb_gadget/g1/configs/b.1/f2
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f3
@@ -135,6 +180,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x4ee8
symlink /config/usb_gadget/g1/functions/midi.gs5 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -147,6 +196,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x4ee9
symlink /config/usb_gadget/g1/functions/midi.gs5 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -157,6 +210,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x4ee3
symlink /config/usb_gadget/g1/functions/rndis.gs4 /config/usb_gadget/g1/configs/b.1/f1
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
setprop sys.usb.state ${sys.usb.config}
@@ -169,6 +226,10 @@
rm /config/usb_gadget/g1/configs/b.1/f1
rm /config/usb_gadget/g1/configs/b.1/f2
rm /config/usb_gadget/g1/configs/b.1/f3
+ rm /config/usb_gadget/g1/configs/b.1/f4
+ rm /config/usb_gadget/g1/configs/b.1/f5
+ write /config/usb_gadget/g1/idVendor 0x18d1
+ write /config/usb_gadget/g1/idProduct 0x4ee4
symlink /config/usb_gadget/g1/functions/rndis.gs4 /config/usb_gadget/g1/configs/b.1/f1
symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
write /config/usb_gadget/g1/UDC ${sys.usb.controller}
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 6ef491c..d16e02f 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -35,7 +35,7 @@
/dev/dri/* 0666 root graphics
# these should not be world writable
-/dev/diag 0660 radio radio
+/dev/diag 0660 system qcom_diag
/dev/diag_arm9 0660 radio radio
/dev/android_adb 0660 adb adb
/dev/android_adb_enable 0660 adb adb
@@ -45,7 +45,7 @@
/dev/alarm 0664 system radio
/dev/rtc0 0640 system system
/dev/tty0 0660 root system
-/dev/graphics/* 0660 root graphics
+/dev/graphics/* 0660 system graphics
/dev/msm_hw3dm 0660 system graphics
/dev/input/* 0660 root input
/dev/eac 0660 root audio
diff --git a/sdcard/Android.mk b/sdcard/Android.mk
index c5f3d1d..9bfaf6c 100644
--- a/sdcard/Android.mk
+++ b/sdcard/Android.mk
@@ -1,7 +1,10 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+endif
LOCAL_SRC_FILES := sdcard.c
LOCAL_MODULE := sdcard
LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 13ebaf1..4ba7d1b 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -1221,12 +1221,13 @@
}
out.fh = ptr_to_id(h);
out.open_flags = 0;
-
-#ifdef FUSE_SHORTCIRCUIT
- out.lower_fd = h->fd;
-#else
- out.padding = 0;
-#endif
+ #ifdef FUSE_SHORTCIRCUIT
+ out.lower_fd = h->fd;
+ #elif defined FUSE_PASSTHROUGH
+ out.passthrough_fd = h->fd;
+ #else
+ out.padding = 0;
+ #endif
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
return NO_STATUS;
@@ -1391,13 +1392,13 @@
}
out.fh = ptr_to_id(h);
out.open_flags = 0;
-
-#ifdef FUSE_SHORTCIRCUIT
- out.lower_fd = -1;
-#else
- out.padding = 0;
-#endif
-
+ #ifdef FUSE_SHORTCIRCUIT
+ out.lower_fd = -1;
+ #elif defined FUSE_PASSTHROUGH
+ out.passthrough_fd = -1;
+ #else
+ out.padding = 0;
+ #endif
fuse_reply(fuse, hdr->unique, &out, sizeof(out));
return NO_STATUS;
}
@@ -1480,9 +1481,12 @@
out.max_readahead = req->max_readahead;
out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
-#ifdef FUSE_SHORTCIRCUIT
- out.flags |= FUSE_SHORTCIRCUIT;
-#endif
+ #ifdef FUSE_SHORTCIRCUIT
+ out.flags |= FUSE_SHORTCIRCUIT;
+ #endif
+ #ifdef FUSE_PASSTHROUGH
+ out.flags |= FUSE_PASSTHROUGH;
+ #endif
out.max_background = 32;
out.congestion_threshold = 32;