Merge "add sideload-host mode to adb"
diff --git a/adb/commandline.c b/adb/commandline.c
index 27e436d..bcfdba0 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -41,7 +41,7 @@
void get_my_path(char *s, size_t maxLen);
int find_sync_dirs(const char *srcarg,
- char **android_srcdir_out, char **data_srcdir_out);
+ char **android_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out);
int install_app(transport_type transport, char* serial, int argc, char** argv);
int uninstall_app(transport_type transport, char* serial, int argc, char** argv);
@@ -196,7 +196,7 @@
" adb get-serialno - prints: <serial-number>\n"
" adb get-devpath - prints: <device-path>\n"
" adb status-window - continuously print device status for a specified device\n"
- " adb remount - remounts the /system partition on the device read-write\n"
+ " adb remount - remounts the /system and /vendor (if present) partitions on the device read-write\n"
" adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
" adb reboot-bootloader - reboots the device into the bootloader\n"
" adb root - restarts the adbd daemon with root permissions\n"
@@ -212,9 +212,9 @@
"adb sync notes: adb sync [ <directory> ]\n"
" <localdir> can be interpreted in several ways:\n"
"\n"
- " - If <directory> is not specified, both /system and /data partitions will be updated.\n"
+ " - If <directory> is not specified, /system, /vendor (if present), and /data partitions will be updated.\n"
"\n"
- " - If it is \"system\" or \"data\", only the corresponding partition\n"
+ " - If it is \"system\", \"vendor\" or \"data\", only the corresponding partition\n"
" is updated.\n"
"\n"
"environmental variables:\n"
@@ -1607,7 +1607,7 @@
}
if(!strcmp(argv[0], "sync")) {
- char *srcarg, *android_srcpath, *data_srcpath;
+ char *srcarg, *android_srcpath, *data_srcpath, *vendor_srcpath;
int listonly = 0;
int ret;
@@ -1627,15 +1627,18 @@
} else {
return usage();
}
- ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath);
+ ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath, &vendor_srcpath);
if(ret != 0) return usage();
if(android_srcpath != NULL)
ret = do_sync_sync(android_srcpath, "/system", listonly);
+ if(ret == 0 && vendor_srcpath != NULL)
+ ret = do_sync_sync(vendor_srcpath, "/vendor", listonly);
if(ret == 0 && data_srcpath != NULL)
ret = do_sync_sync(data_srcpath, "/data", listonly);
free(android_srcpath);
+ free(vendor_srcpath);
free(data_srcpath);
return ret;
}
@@ -1746,25 +1749,30 @@
}
int find_sync_dirs(const char *srcarg,
- char **android_srcdir_out, char **data_srcdir_out)
+ char **android_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out)
{
- char *android_srcdir, *data_srcdir;
+ char *android_srcdir = NULL, *data_srcdir = NULL, *vendor_srcdir = NULL;
+ struct stat st;
if(srcarg == NULL) {
android_srcdir = product_file("system");
data_srcdir = product_file("data");
+ vendor_srcdir = product_file("vendor");
+ /* Check if vendor partition exists */
+ if (lstat(vendor_srcdir, &st) || !S_ISDIR(st.st_mode))
+ vendor_srcdir = NULL;
} else {
/* srcarg may be "data", "system" or NULL.
* if srcarg is NULL, then both data and system are synced
*/
if(strcmp(srcarg, "system") == 0) {
android_srcdir = product_file("system");
- data_srcdir = NULL;
} else if(strcmp(srcarg, "data") == 0) {
- android_srcdir = NULL;
data_srcdir = product_file("data");
+ } else if(strcmp(srcarg, "vendor") == 0) {
+ vendor_srcdir = product_file("vendor");
} else {
- /* It's not "system" or "data".
+ /* It's not "system", "vendor", or "data".
*/
return 1;
}
@@ -1775,11 +1783,15 @@
else
free(android_srcdir);
- if(data_srcdir_out != NULL)
- *data_srcdir_out = data_srcdir;
+ if(vendor_srcdir_out != NULL)
+ *vendor_srcdir_out = vendor_srcdir;
else
- free(data_srcdir);
+ free(vendor_srcdir);
+ if(data_srcdir_out != NULL)
+ *data_srcdir_out = data_srcdir;
+ else
+ free(data_srcdir);
return 0;
}
diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c
index d3cb113..c1ab808 100644
--- a/adb/file_sync_client.c
+++ b/adb/file_sync_client.c
@@ -697,30 +697,33 @@
continue;
strcpy(stat_path, lpath);
strcat(stat_path, de->d_name);
- stat(stat_path, &st);
- if (S_ISDIR(st.st_mode)) {
- ci = mkcopyinfo(lpath, rpath, name, 1);
- ci->next = dirlist;
- dirlist = ci;
- } else {
- ci = mkcopyinfo(lpath, rpath, name, 0);
- if(lstat(ci->src, &st)) {
- fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno));
- free(ci);
- closedir(d);
- return -1;
- }
- if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
- fprintf(stderr, "skipping special file '%s'\n", ci->src);
- free(ci);
+ if(!lstat(stat_path, &st)) {
+ if (S_ISDIR(st.st_mode)) {
+ ci = mkcopyinfo(lpath, rpath, name, 1);
+ ci->next = dirlist;
+ dirlist = ci;
} else {
- ci->time = st.st_mtime;
- ci->mode = st.st_mode;
- ci->size = st.st_size;
- ci->next = *filelist;
- *filelist = ci;
+ ci = mkcopyinfo(lpath, rpath, name, 0);
+ if(lstat(ci->src, &st)) {
+ fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno));
+ free(ci);
+ closedir(d);
+ return -1;
+ }
+ if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
+ fprintf(stderr, "skipping special file '%s'\n", ci->src);
+ free(ci);
+ } else {
+ ci->time = st.st_mtime;
+ ci->mode = st.st_mode;
+ ci->size = st.st_size;
+ ci->next = *filelist;
+ *filelist = ci;
+ }
}
+ } else {
+ fprintf(stderr, "cannot lstat '%s': %s\n",stat_path , strerror(errno));
}
}
diff --git a/adb/file_sync_service.c b/adb/file_sync_service.c
index 1d80d26..e6f64bb 100644
--- a/adb/file_sync_service.c
+++ b/adb/file_sync_service.c
@@ -39,6 +39,11 @@
return (strncmp(SYSTEM, name, strlen(SYSTEM)) == 0);
}
+static bool is_on_vendor(const char *name) {
+ const char *VENDOR = "/vendor/";
+ return (strncmp(VENDOR, name, strlen(VENDOR)) == 0);
+}
+
static int mkdirs(char *name)
{
int ret;
@@ -54,7 +59,7 @@
x = adb_dirstart(x);
if(x == 0) return 0;
*x = 0;
- if (is_on_system(name)) {
+ if (is_on_system(name) || is_on_vendor(name)) {
fs_config(name, 1, &uid, &gid, &mode, &cap);
}
ret = adb_mkdir(name, mode);
@@ -369,7 +374,7 @@
if(*tmp == '/') {
tmp++;
}
- if (is_on_system(path)) {
+ if (is_on_system(path) || is_on_vendor(path)) {
fs_config(tmp, 0, &uid, &gid, &mode, &cap);
}
ret = handle_send_file(s, path, uid, gid, mode, buffer, do_unlink);
diff --git a/adb/remount_service.c b/adb/remount_service.c
index d3a649b..fd81e28 100644
--- a/adb/remount_service.c
+++ b/adb/remount_service.c
@@ -29,6 +29,7 @@
static int system_ro = 1;
+static int vendor_ro = 1;
/* Returns the device used to mount a directory in /proc/mounts */
static char *find_mount(const char *dir)
@@ -67,18 +68,27 @@
return NULL;
}
+static int hasVendorPartition()
+{
+ struct stat info;
+ if (!lstat("/vendor", &info))
+ if ((info.st_mode & S_IFMT) == S_IFDIR)
+ return true;
+ return false;
+}
+
/* Init mounts /system as read only, remount to enable writes. */
-static int remount_system()
+static int remount(const char* dir, int* dir_ro)
{
char *dev;
int fd;
int OFF = 0;
- if (system_ro == 0) {
+ if (dir_ro == 0) {
return 0;
}
- dev = find_mount("/system");
+ dev = find_mount(dir);
if (!dev)
return -1;
@@ -90,11 +100,11 @@
ioctl(fd, BLKROSET, &OFF);
adb_close(fd);
- system_ro = mount(dev, "/system", "none", MS_REMOUNT, NULL);
+ *dir_ro = mount(dev, dir, "none", MS_REMOUNT, NULL);
free(dev);
- return system_ro;
+ return *dir_ro;
}
static void write_string(int fd, const char* str)
@@ -104,16 +114,25 @@
void remount_service(int fd, void *cookie)
{
- int ret = remount_system();
-
- if (!ret)
- write_string(fd, "remount succeeded\n");
- else {
- char buffer[200];
- snprintf(buffer, sizeof(buffer), "remount failed: %s\n", strerror(errno));
+ char buffer[200];
+ if (remount("/system", &system_ro)) {
+ snprintf(buffer, sizeof(buffer), "remount of system failed: %s\n",strerror(errno));
write_string(fd, buffer);
}
+ if (hasVendorPartition()) {
+ if (remount("/vendor", &vendor_ro)) {
+ snprintf(buffer, sizeof(buffer), "remount of vendor failed: %s\n",strerror(errno));
+ write_string(fd, buffer);
+ }
+ }
+
+ if (!system_ro && (!vendor_ro || !hasVendorPartition()))
+ write_string(fd, "remount succeeded\n");
+ else {
+ write_string(fd, "remount failed\n");
+ }
+
adb_close(fd);
}
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index e9b4125..3f94af5 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -245,31 +245,89 @@
return strcmp(value, "1") ? 0 : 1;
}
-void wipe_data_via_recovery()
+/*
+ * Tries to mount any of the consecutive fstab entries that match
+ * the mountpoint of the one given by fstab->recs[start_idx].
+ *
+ * end_idx: On return, will be the last rec that was looked at.
+ * attempted_idx: On return, will indicate which fstab rec
+ * succeeded. In case of failure, it will be the start_idx.
+ * Returns
+ * -1 on failure with errno set to match the 1st mount failure.
+ * 0 on success.
+ */
+static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_idx, int *attempted_idx)
{
- mkdir("/cache/recovery", 0700);
- int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC, 0600);
- if (fd >= 0) {
- write(fd, "--wipe_data", strlen("--wipe_data") + 1);
- close(fd);
- } else {
- ERROR("could not open /cache/recovery/command\n");
+ int i;
+ int mount_errno = 0;
+ int mounted = 0;
+
+ if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) {
+ errno = EINVAL;
+ if (end_idx) *end_idx = start_idx;
+ if (attempted_idx) *end_idx = start_idx;
+ return -1;
}
- property_set(ANDROID_RB_PROPERTY, "reboot,recovery");
+
+ /* Hunt down an fstab entry for the same mount point that might succeed */
+ for (i = start_idx;
+ /* We required that fstab entries for the same mountpoint be consecutive */
+ i < fstab->num_entries && !strcmp(fstab->recs[start_idx].mount_point, fstab->recs[i].mount_point);
+ i++) {
+ /*
+ * Don't try to mount/encrypt the same mount point again.
+ * Deal with alternate entries for the same point which are required to be all following
+ * each other.
+ */
+ if (mounted) {
+ ERROR("%s(): skipping fstab dup mountpoint=%s rec[%d].fs_type=%s already mounted as %s.\n", __func__,
+ fstab->recs[i].mount_point, i, fstab->recs[i].fs_type, fstab->recs[*attempted_idx].fs_type);
+ continue;
+ }
+
+ 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);
+ }
+ if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) {
+ *attempted_idx = i;
+ mounted = 1;
+ if (i != start_idx) {
+ ERROR("%s(): Mounted %s on %s with fs_type=%s instead of %s\n", __func__,
+ fstab->recs[i].blk_device, fstab->recs[i].mount_point, fstab->recs[i].fs_type,
+ fstab->recs[start_idx].fs_type);
+ }
+ } else {
+ /* back up errno for crypto decisions */
+ mount_errno = errno;
+ }
+ }
+
+ /* Adjust i for the case where it was still withing the recs[] */
+ if (i < fstab->num_entries) --i;
+
+ *end_idx = i;
+ if (!mounted) {
+ *attempted_idx = start_idx;
+ errno = mount_errno;
+ return -1;
+ }
+ return 0;
}
/* 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.
+ * Returns -1 on error, and FS_MGR_MNTALL_* otherwise.
*/
int fs_mgr_mount_all(struct fstab *fstab)
{
- int i = 0, j = 0;
- int encryptable = 0;
+ int i = 0;
+ int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTED;
int error_count = 0;
int mret = -1;
int mount_errno = 0;
- const char *last_ok_mount_point = NULL;
+ int attempted_idx = -1;
if (!fstab) {
return -1;
@@ -299,55 +357,27 @@
continue;
}
}
-
- /*
- * Don't try to mount/encrypt the same mount point again.
- * Deal with alternate entries for the same point which are required to be all following
- * each other.
- */
- if (last_ok_mount_point && !strcmp(last_ok_mount_point, fstab->recs[i].mount_point)) {
- INFO("%s(): skipping fstab dup mountpoint=%s rec[%d].fs_type=%s already mounted.\n", __func__,
- last_ok_mount_point, i, fstab->recs[i].fs_type);
- continue;
- }
- /* Hunt down an fstab entry for the same mount point that might succeed */
- for (j = i;
- /* We required that fstab entries for the same mountpoint be consecutive */
- j < fstab->num_entries && !strcmp(fstab->recs[i].mount_point, fstab->recs[j].mount_point);
- j++) {
- if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
- check_fs(fstab->recs[j].blk_device, fstab->recs[j].fs_type,
- fstab->recs[j].mount_point);
- }
- mret = __mount(fstab->recs[j].blk_device, fstab->recs[j].mount_point, &fstab->recs[j]);
- if (!mret) {
- last_ok_mount_point = fstab->recs[j].mount_point;
- if (i != j) {
- INFO("%s(): some alternate mount worked for mount_point=%s fs_type=%s instead of fs_type=%s\n", __func__,
- last_ok_mount_point, fstab->recs[j].fs_type, fstab->recs[i].fs_type);
- i = j; /* We advance the recs index to the working entry */
- }
- break;
- } else {
- /* back up errno for crypto decisions */
- mount_errno = errno;
- }
- }
+ int last_idx_inspected;
+ mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
+ i = last_idx_inspected;
+ mount_errno = errno;
/* Deal with encryptability. */
if (!mret) {
/* If this is encryptable, need to trigger encryption */
- if ((fstab->recs[i].fs_mgr_flags & MF_FORCECRYPT)) {
- if (umount(fstab->recs[i].mount_point) == 0) {
- if (!encryptable) {
- encryptable = 2;
+ if ((fstab->recs[attempted_idx].fs_mgr_flags & MF_FORCECRYPT)) {
+ if (umount(fstab->recs[attempted_idx].mount_point) == 0) {
+ if (encryptable == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
+ ERROR("Will try to encrypt %s %s\n", fstab->recs[attempted_idx].mount_point,
+ fstab->recs[attempted_idx].fs_type);
+ encryptable = FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION;
} else {
ERROR("Only one encryptable/encrypted partition supported\n");
- encryptable = 1;
+ encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
}
} else {
INFO("Could not umount %s - allow continue unencrypted\n",
- fstab->recs[i].mount_point);
+ fstab->recs[attempted_idx].mount_point);
continue;
}
}
@@ -357,28 +387,31 @@
/* mount(2) returned an error, check if it's encryptable and deal with it */
if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
- fs_mgr_is_encryptable(&fstab->recs[i])) {
- if(partition_wiped(fstab->recs[i].blk_device) && fstab->recs[i].fs_mgr_flags & MF_FORCECRYPT) {
- ERROR("Found an encryptable wiped partition with force encrypt. Formating via recovery.\n");
- wipe_data_via_recovery(); /* This is queue up a reboot */
- ++error_count;
+ fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
+ if(partition_wiped(fstab->recs[attempted_idx].blk_device)) {
+ 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
*/
- if (fs_mgr_do_tmpfs_mount(fstab->recs[i].mount_point) < 0) {
+ 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;
}
- last_ok_mount_point = fstab->recs[i].mount_point;
}
- encryptable = 1;
+ 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[i].blk_device, fstab->recs[i].mount_point,
- fstab->recs[i].fs_options, strerror(mount_errno));
+ fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
+ fstab->recs[attempted_idx].fs_options, strerror(mount_errno));
++error_count;
continue;
}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 7ac8db2..34938fa 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -73,12 +73,8 @@
#define MF_ZRAMSIZE 0x100
#define MF_VERIFY 0x200
#define MF_FORCECRYPT 0x400
-/*
- * There is no emulated sdcard daemon running on /data/media on this device,
- * so treat the physical SD card as the only external storage device,
- * a la the Nexus One.
- */
-#define MF_NOEMULATEDSD 0x400
+#define MF_NOEMULATEDSD 0x800 /* no emulated sdcard daemon, sd card is the only
+ external storage */
#define DM_BUF_SIZE 4096
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index b8bb5aa..d9c58d4 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -53,6 +53,11 @@
struct fstab *fs_mgr_read_fstab(const char *fstab_path);
void fs_mgr_free_fstab(struct fstab *fstab);
+
+#define FS_MGR_MNTALL_DEV_NEEDS_RECOVERY 3
+#define FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION 2
+#define FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED 1
+#define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 0
int fs_mgr_mount_all(struct fstab *fstab);
int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
char *tmp_mount_point);
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index d11f609..67d4944 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -68,6 +68,7 @@
#define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC)
#define BATTERY_FULL_THRESH 95
+#define SCREEN_ON_BATTERY_THRESH 1
#define LAST_KMSG_PATH "/proc/last_kmsg"
#define LAST_KMSG_PSTORE_PATH "/sys/fs/pstore/console-ramoops"
@@ -172,6 +173,7 @@
static int char_width;
static int char_height;
+static bool minui_inited;
/* current time in milliseconds */
static int64_t curr_time_ms(void)
@@ -354,6 +356,27 @@
if (!batt_anim->run || now < charger->next_screen_transition)
return;
+ if (!minui_inited) {
+ int batt_cap = get_battery_capacity();
+
+ if (batt_cap < SCREEN_ON_BATTERY_THRESH) {
+ LOGV("[%" PRId64 "] level %d, leave screen off\n", now, batt_cap);
+ batt_anim->run = false;
+ charger->next_screen_transition = -1;
+ if (charger->charger_connected)
+ request_suspend(true);
+ return;
+ }
+
+ gr_init();
+ gr_font_size(&char_width, &char_height);
+
+#ifndef CHARGER_DISABLE_INIT_BLANK
+ gr_fb_blank(true);
+#endif
+ minui_inited = true;
+ }
+
/* animation is over, blank screen and leave */
if (batt_anim->cur_cycle == batt_anim->num_cycles) {
reset_animation(batt_anim);
@@ -657,9 +680,6 @@
LOGI("--------------- STARTING CHARGER MODE ---------------\n");
- gr_init();
- gr_font_size(&char_width, &char_height);
-
ret = ev_init(input_callback, charger);
if (!ret) {
epollfd = ev_get_epollfd();
@@ -694,10 +714,6 @@
ev_sync_key_state(set_key_callback, charger);
-#ifndef CHARGER_DISABLE_INIT_BLANK
- gr_fb_blank(true);
-#endif
-
charger->next_screen_transition = -1;
charger->next_key_check = -1;
charger->next_pwr_check = -1;
diff --git a/include/log/log.h b/include/log/log.h
index 5b76c1a..ace12d6 100644
--- a/include/log/log.h
+++ b/include/log/log.h
@@ -491,7 +491,7 @@
#endif
#ifndef LOG_EVENT_STRING
#define LOG_EVENT_STRING(_tag, _value) \
- ((void) 0) /* not implemented -- must combine len with string */
+ (void) __android_log_bswrite(_tag, _value);
#endif
/* TODO: something for LIST */
diff --git a/include/log/logd.h b/include/log/logd.h
index 379c373..2e6f220 100644
--- a/include/log/logd.h
+++ b/include/log/logd.h
@@ -41,6 +41,7 @@
int __android_log_bwrite(int32_t tag, const void *payload, size_t len);
int __android_log_btwrite(int32_t tag, char type, const void *payload,
size_t len);
+int __android_log_bswrite(int32_t tag, const char *payload);
#ifdef __cplusplus
}
diff --git a/include/system/audio_policy.h b/include/system/audio_policy.h
index a6554de..3085830 100644
--- a/include/system/audio_policy.h
+++ b/include/system/audio_policy.h
@@ -44,6 +44,9 @@
AUDIO_POLICY_FORCE_DIGITAL_DOCK,
AUDIO_POLICY_FORCE_NO_BT_A2DP, /* A2DP sink is not preferred to speaker or wired HS */
AUDIO_POLICY_FORCE_SYSTEM_ENFORCED,
+ AUDIO_POLICY_FORCE_SYSTEM_AUDIO_HDMI_ARC,
+ AUDIO_POLICY_FORCE_SYSTEM_AUDIO_SPDIF,
+ AUDIO_POLICY_FORCE_SYSTEM_AUDIO_LINE,
AUDIO_POLICY_FORCE_CFG_CNT,
AUDIO_POLICY_FORCE_CFG_MAX = AUDIO_POLICY_FORCE_CFG_CNT - 1,
diff --git a/include/system/sound_trigger.h b/include/system/sound_trigger.h
index 0270baa..57225e9 100644
--- a/include/system/sound_trigger.h
+++ b/include/system/sound_trigger.h
@@ -92,6 +92,7 @@
*/
struct sound_trigger_sound_model {
sound_trigger_sound_model_type_t type; /* model type. e.g. SOUND_MODEL_TYPE_KEYPHRASE */
+ sound_trigger_uuid_t uuid; /* unique sound model ID. */
unsigned int data_size; /* size of opaque model data */
unsigned int data_offset; /* offset of opaque data start from head of struct
(e.g sizeof struct sound_trigger_sound_model) */
@@ -99,6 +100,7 @@
/* key phrase descriptor */
struct sound_trigger_phrase {
+ unsigned int id; /* keyphrase ID */
unsigned int recognition_mode; /* recognition modes supported by this key phrase */
unsigned int num_users; /* number of users in the key phrase */
char locale[SOUND_TRIGGER_MAX_LOCALE_LEN]; /* locale - JAVA Locale style (e.g. en_US) */
diff --git a/init/builtins.c b/init/builtins.c
index 452119e..f7bd8a9 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -474,6 +474,26 @@
}
+static int wipe_data_via_recovery()
+{
+ mkdir("/cache/recovery", 0700);
+ int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC, 0600);
+ if (fd >= 0) {
+ write(fd, "--wipe_data", strlen("--wipe_data") + 1);
+ close(fd);
+ } else {
+ ERROR("could not open /cache/recovery/command\n");
+ return -1;
+ }
+ android_reboot(ANDROID_RB_RESTART2, 0, "recovery");
+ while (1) { pause(); } // never reached
+}
+
+
+/*
+ * This function might request a reboot, in which case it will
+ * not return.
+ */
int do_mount_all(int nargs, char **args)
{
pid_t pid;
@@ -511,27 +531,33 @@
if (child_ret == -1) {
ERROR("fs_mgr_mount_all returned an error\n");
}
- exit(child_ret);
+ _exit(child_ret);
} else {
/* fork failed, return an error */
return -1;
}
- /* ret is 2 if device needs encrypted, 1 if the device appears encrypted,
- * 0 if not, and -1 on error */
- if (ret == 2) {
+ if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
property_set("ro.crypto.state", "unencrypted");
property_set("vold.decrypt", "trigger_encryption");
- } else if (ret == 1) {
+ } else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
property_set("ro.crypto.state", "encrypted");
property_set("vold.decrypt", "trigger_default_encryption");
- } else if (ret == 0) {
+ } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
property_set("ro.crypto.state", "unencrypted");
/* If fs_mgr determined this is an unencrypted device, then trigger
* that action.
*/
action_for_each_trigger("nonencrypted", action_add_queue_tail);
+ } else if (ret == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
+ /* Setup a wipe via recovery, and reboot into recovery */
+ ERROR("fs_mgr_mount_all suggested recovery, so wiping data via recovery.\n");
+ ret = wipe_data_via_recovery();
+ /* If reboot worked, there is no return. */
+ } else if (ret > 0) {
+ ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret);
}
+ /* else ... < 0: error */
return ret;
}
diff --git a/init/devices.c b/init/devices.c
index b896410..304888e 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -170,7 +170,24 @@
}
}
-static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
+static bool perm_path_matches(const char *path, struct perms_ *dp)
+{
+ if (dp->prefix) {
+ if (strncmp(path, dp->name, strlen(dp->name)) == 0)
+ return true;
+ } else if (dp->wildcard) {
+ if (fnmatch(dp->name, path, FNM_PATHNAME) == 0)
+ return true;
+ } else {
+ if (strcmp(path, dp->name) == 0)
+ return true;
+ }
+
+ return false;
+}
+
+static mode_t get_device_perm(const char *path, const char **links,
+ unsigned *uid, unsigned *gid)
{
mode_t perm;
struct listnode *node;
@@ -181,22 +198,30 @@
* override ueventd.rc
*/
list_for_each_reverse(node, &dev_perms) {
+ bool match = false;
+
perm_node = node_to_item(node, struct perm_node, plist);
dp = &perm_node->dp;
- if (dp->prefix) {
- if (strncmp(path, dp->name, strlen(dp->name)))
- continue;
- } else if (dp->wildcard) {
- if (fnmatch(dp->name, path, FNM_PATHNAME) != 0)
- continue;
+ if (perm_path_matches(path, dp)) {
+ match = true;
} else {
- if (strcmp(path, dp->name))
- continue;
+ if (links) {
+ int i;
+ for (i = 0; links[i]; i++) {
+ if (perm_path_matches(links[i], dp)) {
+ match = true;
+ break;
+ }
+ }
+ }
}
- *uid = dp->uid;
- *gid = dp->gid;
- return dp->perm;
+
+ if (match) {
+ *uid = dp->uid;
+ *gid = dp->gid;
+ return dp->perm;
+ }
}
/* Default if nothing found. */
*uid = 0;
@@ -215,7 +240,7 @@
dev_t dev;
char *secontext = NULL;
- mode = get_device_perm(path, &uid, &gid) | (block ? S_IFBLK : S_IFCHR);
+ mode = get_device_perm(path, links, &uid, &gid) | (block ? S_IFBLK : S_IFCHR);
if (sehandle) {
selabel_lookup_best_match(sehandle, &secontext, path, links, mode);
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index f10eb8e..3171c78 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -107,7 +107,7 @@
close(i);
}
- i = socket(PF_UNIX, SOCK_DGRAM, 0);
+ i = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (i < 0) {
ret = -errno;
write_to_log = __write_to_log_null;
@@ -473,3 +473,25 @@
return write_to_log(LOG_ID_EVENTS, vec, 3);
}
+
+/*
+ * Like __android_log_bwrite, but used for writing strings to the
+ * event log.
+ */
+int __android_log_bswrite(int32_t tag, const char *payload)
+{
+ struct iovec vec[4];
+ char type = EVENT_TYPE_STRING;
+ uint32_t len = strlen(payload);
+
+ vec[0].iov_base = &tag;
+ vec[0].iov_len = sizeof(tag);
+ vec[1].iov_base = &type;
+ vec[1].iov_len = sizeof(type);
+ vec[2].iov_base = &len;
+ vec[2].iov_len = sizeof(len);
+ vec[3].iov_base = (void*)payload;
+ vec[3].iov_len = len;
+
+ return write_to_log(LOG_ID_EVENTS, vec, 4);
+}
diff --git a/liblog/logd_write_kern.c b/liblog/logd_write_kern.c
index 1d10748..1ed5ecf 100644
--- a/liblog/logd_write_kern.c
+++ b/liblog/logd_write_kern.c
@@ -317,3 +317,25 @@
return write_to_log(LOG_ID_EVENTS, vec, 3);
}
+
+/*
+ * Like __android_log_bwrite, but used for writing strings to the
+ * event log.
+ */
+int __android_log_bswrite(int32_t tag, const char *payload)
+{
+ struct iovec vec[4];
+ char type = EVENT_TYPE_STRING;
+ uint32_t len = strlen(payload);
+
+ vec[0].iov_base = &tag;
+ vec[0].iov_len = sizeof(tag);
+ vec[1].iov_base = &type;
+ vec[1].iov_len = sizeof(type);
+ vec[2].iov_base = &len;
+ vec[2].iov_len = sizeof(len);
+ vec[3].iov_base = (void*)payload;
+ vec[3].iov_len = len;
+
+ return write_to_log(LOG_ID_EVENTS, vec, 4);
+}
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 16fe7ee..7c6af42 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -336,7 +336,7 @@
for (;;) {
int ret;
- ret = getopt(argc, argv, "cdt:T:gG:sQf:r::n:v:b:BSpP:");
+ ret = getopt(argc, argv, "cdt:T:gG:sQf:r:n:v:b:BSpP:");
if (ret < 0) {
break;