diff options
34 files changed, 990 insertions, 61 deletions
diff --git a/adb/adb.cpp b/adb/adb.cpp index f64b19f..c2ac674 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -54,6 +54,8 @@ int HOST = 0; #if !ADB_HOST const char *adb_device_banner = "device"; + +int recovery_mode = 0; #endif void fatal(const char *fmt, ...) @@ -194,6 +196,8 @@ void adb_trace_init() { #if !ADB_HOST start_device_log(); + + recovery_mode = (strcmp(adb_device_banner, "recovery") == 0); #endif } @@ -339,6 +339,8 @@ int adb_commandline(int argc, const char **argv); int connection_state(atransport *t); +extern int recovery_mode; + #define CS_ANY -1 #define CS_OFFLINE 0 #define CS_BOOTLOADER 1 @@ -350,6 +352,9 @@ int connection_state(atransport *t); #define CS_UNAUTHORIZED 7 extern const char *adb_device_banner; + +#define CS_ONLINE 10 /* recovery or device */ + extern int HOST; extern int SHELL_EXIT_NOTIFY_FD; diff --git a/adb/adb_main.cpp b/adb/adb_main.cpp index 45a2158..1ff305b 100644 --- a/adb/adb_main.cpp +++ b/adb/adb_main.cpp @@ -239,7 +239,9 @@ int adb_main(int is_daemon, int server_port) // descriptor will always be open. adbd_cloexec_auth_socket(); - if (ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) { + // Override auth in factory test mode + if ((ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) || + (property_get_bool("ro.boot.ftm", 0) == 1)) { auth_required = false; } diff --git a/adb/services.cpp b/adb/services.cpp index 1847447..ef2fa56 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -76,6 +76,18 @@ void restart_root_service(int fd, void *cookie) { return; } + char build_type[PROPERTY_VALUE_MAX]; + char cm_version[PROPERTY_VALUE_MAX]; + property_get("persist.sys.root_access", value, "0"); + property_get("ro.build.type", build_type, ""); + property_get("ro.cm.version", cm_version, ""); + + if (strlen(cm_version) > 0 && strcmp(build_type, "eng") != 0 && (atoi(value) & 2) != 2) { + WriteFdExactly(fd, "root access is disabled by system setting - enable in settings -> development options\n"); + adb_close(fd); + return; + } + property_set("service.adb.root", "1"); WriteFdExactly(fd, "restarting adbd as root\n"); adb_close(fd); @@ -342,8 +354,10 @@ static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg #if ADB_HOST #define SHELL_COMMAND "/bin/sh" +#define ALTERNATE_SHELL_COMMAND "" #else #define SHELL_COMMAND "/system/bin/sh" +#define ALTERNATE_SHELL_COMMAND "/sbin/sh" #endif #if !ADB_HOST @@ -384,6 +398,9 @@ static int create_subproc_thread(const char *name, const subproc_mode mode) int ret_fd; pid_t pid = -1; + const char* shell_command; + struct stat st; + const char *arg0, *arg1; if (name == 0 || *name == 0) { arg0 = "-"; arg1 = 0; @@ -391,12 +408,24 @@ static int create_subproc_thread(const char *name, const subproc_mode mode) arg0 = "-c"; arg1 = name; } + char value[PROPERTY_VALUE_MAX]; + property_get("persist.sys.adb.shell", value, ""); + if (value[0] != '\0' && stat(value, &st) == 0) { + shell_command = value; + } + else if (stat(ALTERNATE_SHELL_COMMAND, &st) == 0) { + shell_command = ALTERNATE_SHELL_COMMAND; + } + else { + shell_command = SHELL_COMMAND; + } + switch (mode) { case SUBPROC_PTY: - ret_fd = create_subproc_pty(SHELL_COMMAND, arg0, arg1, &pid); + ret_fd = create_subproc_pty(shell_command, arg0, arg1, &pid); break; case SUBPROC_RAW: - ret_fd = create_subproc_raw(SHELL_COMMAND, arg0, arg1, &pid); + ret_fd = create_subproc_raw(shell_command, arg0, arg1, &pid); break; default: fprintf(stderr, "invalid subproc_mode %d\n", mode); @@ -422,6 +451,13 @@ static int create_subproc_thread(const char *name, const subproc_mode mode) } #endif +#if !ADB_HOST +static const char* bu_path() +{ + return (recovery_mode ? "/sbin/bu" : "/system/bin/bu"); +} +#endif + int service_to_fd(const char *name) { int ret = -1; @@ -478,10 +514,14 @@ int service_to_fd(const char *name) } else if(!strncmp(name, "unroot:", 7)) { ret = create_service_thread(restart_unroot_service, NULL); } else if(!strncmp(name, "backup:", 7)) { - ret = create_subproc_thread(android::base::StringPrintf("/system/bin/bu backup %s", + ret = create_subproc_thread(android::base::StringPrintf("%s backup %s", bu_path(), (name + 7)).c_str(), SUBPROC_RAW); } else if(!strncmp(name, "restore:", 8)) { - ret = create_subproc_thread("/system/bin/bu restore", SUBPROC_RAW); + char* cmd; + if (asprintf(&cmd, "%s restore", bu_path()) != -1) { + ret = create_subproc_thread(cmd, SUBPROC_RAW); + free(cmd); + } } else if(!strncmp(name, "tcpip:", 6)) { int port; if (sscanf(name + 6, "%d", &port) != 1) { @@ -672,6 +712,15 @@ asocket* host_service_to_socket(const char* name, const char *serial) } else if (!strncmp(name, "any", strlen("any"))) { sinfo->transport = kTransportAny; sinfo->state = CS_DEVICE; + } else if (!strncmp(name, "sideload", strlen("sideload"))) { + sinfo->transport = kTransportAny; + sinfo->state = CS_SIDELOAD; + } else if (!strncmp(name, "recovery", strlen("recovery"))) { + sinfo->transport = kTransportAny; + sinfo->state = CS_RECOVERY; + } else if (!strncmp(name, "online", strlen("online"))) { + sinfo->transport = kTransportAny; + sinfo->state = CS_ONLINE; } else { free(sinfo); return NULL; diff --git a/adb/transport.cpp b/adb/transport.cpp index 2cd6ac2..5ae49d3 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -821,8 +821,10 @@ retry: result = NULL; } - /* check for required connection state */ - if (result && state != CS_ANY && result->connection_state != state) { + /* check for required connection state */ + if (result && state != CS_ANY && ((state != CS_ONLINE && result->connection_state != state) + || (state == CS_ONLINE && !(result->connection_state == CS_DEVICE + || result->connection_state == CS_RECOVERY)))) { if (error_out) *error_out = "invalid device state"; result = NULL; } diff --git a/fastboot/Android.mk b/fastboot/Android.mk index 66a470a..b5212ba 100644 --- a/fastboot/Android.mk +++ b/fastboot/Android.mk @@ -68,14 +68,14 @@ ifneq ($(HOST_OS),windows) LOCAL_STATIC_LIBRARIES += libselinux endif # HOST_OS != windows -ifeq ($(HOST_OS),linux) +ifneq (,$(filter linux darwin,$(HOST_OS))) # libf2fs_dlutils_host will dlopen("libf2fs_fmt_host_dyn") LOCAL_CFLAGS += -DUSE_F2FS LOCAL_LDFLAGS += -ldl -rdynamic -Wl,-rpath,. LOCAL_REQUIRED_MODULES := libf2fs_fmt_host_dyn # The following libf2fs_* are from system/extras/f2fs_utils, # and do not use code in external/f2fs-tools. -LOCAL_STATIC_LIBRARIES += libf2fs_utils_host libf2fs_ioutils_host libf2fs_dlutils_host +LOCAL_STATIC_LIBRARIES += libf2fs_utils_host libf2fs_dlutils_host endif # libc++ not available on windows yet @@ -91,7 +91,7 @@ LOCAL_SHARED_LIBRARIES := include $(BUILD_HOST_EXECUTABLE) my_dist_files := $(LOCAL_BUILT_MODULE) -ifeq ($(HOST_OS),linux) +ifneq (,$(filter linux darwin,$(HOST_OS))) my_dist_files += $(HOST_LIBRARY_PATH)/libf2fs_fmt_host_dyn$(HOST_SHLIB_SUFFIX) endif $(call dist-for-goals,dist_files sdk,$(my_dist_files)) diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk index 8ed5cc9..d105b0b 100644 --- a/fs_mgr/Android.mk +++ b/fs_mgr/Android.mk @@ -12,8 +12,8 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \ external/openssl/include LOCAL_MODULE:= libfs_mgr -LOCAL_STATIC_LIBRARIES := liblogwrap libmincrypt libext4_utils_static libsquashfs_utils -LOCAL_C_INCLUDES += system/extras/ext4_utils system/extras/squashfs_utils +LOCAL_STATIC_LIBRARIES := liblogwrap libmincrypt libext4_utils_static libsquashfs_utils libext2_blkid libext2_uuid_static +LOCAL_C_INCLUDES += system/extras/ext4_utils system/extras/squashfs_utils external/e2fsprogs/lib LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include LOCAL_CFLAGS := -Werror @@ -38,7 +38,7 @@ LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) -LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libmincrypt libext4_utils_static libsquashfs_utils +LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libmincrypt libext4_utils_static libsquashfs_utils libext2_blkid libext2_uuid_static LOCAL_STATIC_LIBRARIES += libsparse_static libz libselinux LOCAL_CXX_STL := libc++_static diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c index 1b26b43..6e20560 100644 --- a/fs_mgr/fs_mgr.c +++ b/fs_mgr/fs_mgr.c @@ -39,6 +39,7 @@ #include <cutils/partition_utils.h> #include <cutils/properties.h> #include <logwrap/logwrap.h> +#include <blkid/blkid.h> #include "mincrypt/rsa.h" #include "mincrypt/sha.h" @@ -60,6 +61,7 @@ #define FSCK_LOG_FILE "/dev/fscklogs/log" #define ZRAM_CONF_DEV "/sys/block/zram0/disksize" +#define ZRAM_STREAMS "/sys/block/zram0/max_comp_streams" #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) @@ -304,6 +306,8 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_ int i; int mount_errno = 0; int mounted = 0; + int cmp_len; + char *detected_fs_type; if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) { errno = EINVAL; @@ -329,8 +333,16 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_ } 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); + /* Skip file system check unless we are sure we are the right type */ + detected_fs_type = blkid_get_tag_value(NULL, "TYPE", fstab->recs[i].blk_device); + if (detected_fs_type) { + cmp_len = (!strncmp(detected_fs_type, "ext", 3) && + strlen(detected_fs_type) == 4) ? 3 : strlen(detected_fs_type); + if (!strncmp(fstab->recs[i].fs_type, detected_fs_type, cmp_len)) { + 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; @@ -860,6 +872,14 @@ int fs_mgr_swapon_all(struct fstab *fstab) */ FILE *zram_fp; + /* The stream count parameter is only available on new kernels. + * It must be set before the disk size. */ + zram_fp = fopen(ZRAM_STREAMS, "r+"); + if (zram_fp) { + fprintf(zram_fp, "%d\n", fstab->recs[i].zram_streams); + fclose(zram_fp); + } + zram_fp = fopen(ZRAM_CONF_DEV, "r+"); if (zram_fp == NULL) { ERROR("Unable to open zram conf device %s\n", ZRAM_CONF_DEV); diff --git a/fs_mgr/fs_mgr_format.c b/fs_mgr/fs_mgr_format.c index c73045d..7b6a40f 100644 --- a/fs_mgr/fs_mgr_format.c +++ b/fs_mgr/fs_mgr_format.c @@ -31,7 +31,7 @@ extern struct fs_info info; /* magic global from ext4_utils */ extern void reset_ext4fs_info(); -static int format_ext4(char *fs_blkdev, char *fs_mnt_point) +static int format_ext4(char *fs_blkdev, char *fs_mnt_point, long long fs_length) { unsigned int nr_sec; int fd, rc = 0; @@ -51,6 +51,12 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point) reset_ext4fs_info(); info.len = ((off64_t)nr_sec * 512); + if (fs_length > 0) { + info.len = fs_length; + } else if (fs_length < 0) { + info.len += fs_length; + } + /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */ rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL); if (rc) { @@ -61,15 +67,27 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point) return rc; } -static int format_f2fs(char *fs_blkdev) +static int format_f2fs(char *fs_blkdev, long long fs_length) { - char * args[3]; + char * args[5]; int pid; int rc = 0; + char buff[65]; args[0] = (char *)"/sbin/mkfs.f2fs"; - args[1] = fs_blkdev; - args[2] = (char *)0; + + if (fs_length >= 0) { + snprintf(buff, sizeof(buff), "%lld", fs_length / 512); + args[1] = fs_blkdev; + args[2] = buff; + args[3] = (char *)0; + } else if (fs_length < 0) { + snprintf(buff, sizeof(buff), "%lld", -fs_length); + args[1] = "-r"; + args[2] = buff; + args[3] = fs_blkdev; + args[4] = (char *)0; + } pid = fork(); if (pid < 0) { @@ -108,9 +126,9 @@ int fs_mgr_do_format(struct fstab_rec *fstab) ERROR("%s: Format %s as '%s'.\n", __func__, fstab->blk_device, fstab->fs_type); if (!strncmp(fstab->fs_type, "f2fs", 4)) { - rc = format_f2fs(fstab->blk_device); + rc = format_f2fs(fstab->blk_device, fstab->length); } else if (!strncmp(fstab->fs_type, "ext4", 4)) { - rc = format_ext4(fstab->blk_device, fstab->mount_point); + rc = format_ext4(fstab->blk_device, fstab->mount_point, fstab->length); } else { ERROR("File system type '%s' is not supported\n", fstab->fs_type); } diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c index f24af1f..b1b0325 100644 --- a/fs_mgr/fs_mgr_fstab.c +++ b/fs_mgr/fs_mgr_fstab.c @@ -32,6 +32,7 @@ struct fs_mgr_flag_values { int partnum; int swap_prio; unsigned int zram_size; + unsigned int zram_streams; }; struct flag_list { @@ -74,6 +75,7 @@ static struct flag_list fs_mgr_flags[] = { { "noemulatedsd", MF_NOEMULATEDSD }, { "notrim", MF_NOTRIM }, { "formattable", MF_FORMATTABLE }, + { "zramstreams=",MF_ZRAMSTREAMS }, { "defaults", 0 }, { 0, 0 }, }; @@ -106,6 +108,7 @@ static int parse_flags(char *flags, struct flag_list *fl, memset(flag_vals, 0, sizeof(*flag_vals)); flag_vals->partnum = -1; flag_vals->swap_prio = -1; /* negative means it wasn't specified. */ + flag_vals->zram_streams = 1; } /* initialize fs_options to the null string */ @@ -178,6 +181,8 @@ static int parse_flags(char *flags, struct flag_list *fl, flag_vals->zram_size = calculate_zram_size(val); else flag_vals->zram_size = val; + } else if ((fl[i].flag == MF_ZRAMSTREAMS) && flag_vals) { + flag_vals->zram_streams = strtoll(strchr(p, '=') + 1, NULL, 0); } break; } @@ -329,6 +334,7 @@ struct fstab *fs_mgr_read_fstab(const char *fstab_path) fstab->recs[cnt].partnum = flag_vals.partnum; fstab->recs[cnt].swap_prio = flag_vals.swap_prio; fstab->recs[cnt].zram_size = flag_vals.zram_size; + fstab->recs[cnt].zram_streams = flag_vals.zram_streams; cnt++; } fclose(fstab_file); diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index 682fd11..b72e200 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -79,6 +79,7 @@ #define MF_NOTRIM 0x1000 #define MF_FILEENCRYPTION 0x2000 #define MF_FORMATTABLE 0x4000 +#define MF_ZRAMSTREAMS 0x8000 #define DM_BUF_SIZE 4096 diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index adcb07b..5e05d9a 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h @@ -65,6 +65,7 @@ struct fstab_rec { int partnum; int swap_prio; unsigned int zram_size; + unsigned int zram_streams; }; // Callback function for verity status @@ -97,6 +98,7 @@ int fs_mgr_add_entry(struct fstab *fstab, const char *mount_point, const char *fs_type, const char *blk_device); struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path); +struct fstab_rec *fs_mgr_get_entry_for_mount_point_after(struct fstab_rec *start_rec, struct fstab *fstab, const char *path); int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab); int fs_mgr_is_nonremovable(const struct fstab_rec *fstab); int fs_mgr_is_verified(const struct fstab_rec *fstab); diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp index b0e9a4d..0665a46 100644 --- a/healthd/BatteryMonitor.cpp +++ b/healthd/BatteryMonitor.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -138,6 +139,8 @@ BatteryMonitor::PowerSupplyType BatteryMonitor::readPowerSupplyType(const String { "USB_HVDCP_3", ANDROID_POWER_SUPPLY_TYPE_AC }, { "Wireless", ANDROID_POWER_SUPPLY_TYPE_WIRELESS }, { "Wipower", ANDROID_POWER_SUPPLY_TYPE_WIRELESS }, + { "DockBattery", ANDROID_POWER_SUPPLY_TYPE_DOCK_BATTERY }, + { "DockAC", ANDROID_POWER_SUPPLY_TYPE_DOCK_AC }, { NULL, 0 }, }; @@ -182,8 +185,11 @@ bool BatteryMonitor::update(void) { props.chargerAcOnline = false; props.chargerUsbOnline = false; props.chargerWirelessOnline = false; + props.chargerDockAcOnline = false; props.batteryStatus = BATTERY_STATUS_UNKNOWN; props.batteryHealth = BATTERY_HEALTH_UNKNOWN; + props.dockBatteryStatus = BATTERY_STATUS_UNKNOWN; + props.dockBatteryHealth = BATTERY_HEALTH_UNKNOWN; if (!mHealthdConfig->batteryPresentPath.isEmpty()) props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath); @@ -212,6 +218,32 @@ bool BatteryMonitor::update(void) { if (readFromFile(mHealthdConfig->batteryTechnologyPath, buf, SIZE) > 0) props.batteryTechnology = String8(buf); + props.dockBatterySupported = mHealthdConfig->dockBatterySupported; + if (props.dockBatterySupported) { + if (!mHealthdConfig->dockBatteryPresentPath.isEmpty()) + props.dockBatteryPresent = getBooleanField(mHealthdConfig->dockBatteryPresentPath); + else + props.dockBatteryPresent = mDockBatteryDevicePresent; + + props.dockBatteryLevel = mBatteryFixedCapacity ? + mBatteryFixedCapacity : + getIntField(mHealthdConfig->dockBatteryCapacityPath); + props.dockBatteryVoltage = getIntField(mHealthdConfig->dockBatteryVoltagePath) / 1000; + + props.dockBatteryTemperature = mBatteryFixedTemperature ? + mBatteryFixedTemperature : + getIntField(mHealthdConfig->dockBatteryTemperaturePath); + + if (readFromFile(mHealthdConfig->dockBatteryStatusPath, buf, SIZE) > 0) + props.dockBatteryStatus = getBatteryStatus(buf); + + if (readFromFile(mHealthdConfig->dockBatteryHealthPath, buf, SIZE) > 0) + props.dockBatteryHealth = getBatteryHealth(buf); + + if (readFromFile(mHealthdConfig->dockBatteryTechnologyPath, buf, SIZE) > 0) + props.dockBatteryTechnology = String8(buf); + } + // reinitialize the mChargerNames vector everytime there is an update String8 path; DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH); @@ -231,9 +263,10 @@ bool BatteryMonitor::update(void) { 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: + case ANDROID_POWER_SUPPLY_TYPE_BATTERY: + case ANDROID_POWER_SUPPLY_TYPE_DOCK_BATTERY: + break; + default: path.clear(); path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name); if (access(path.string(), R_OK) == 0) { @@ -253,6 +286,10 @@ bool BatteryMonitor::update(void) { case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: props.chargerWirelessOnline = true; break; + case ANDROID_POWER_SUPPLY_TYPE_DOCK_AC: + if (mHealthdConfig->dockBatterySupported) { + props.chargerDockAcOnline = true; + } default: KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n", name); @@ -261,10 +298,6 @@ bool BatteryMonitor::update(void) { } } break; - case ANDROID_POWER_SUPPLY_TYPE_BATTERY: - break; - default: - break; } //switch } //while closedir(dir); @@ -274,10 +307,11 @@ bool BatteryMonitor::update(void) { if (logthis) { char dmesgline[256]; + char dmesglinedock[256]; if (props.batteryPresent) { snprintf(dmesgline, sizeof(dmesgline), - "battery l=%d v=%d t=%s%d.%d h=%d st=%d", + "battery [l=%d v=%d t=%s%d.%d h=%d st=%d]", props.batteryLevel, props.batteryVoltage, props.batteryTemperature < 0 ? "-" : "", abs(props.batteryTemperature / 10), @@ -296,15 +330,37 @@ bool BatteryMonitor::update(void) { "battery none"); } - KLOG_WARNING(LOG_TAG, "%s chg=%s%s%s\n", dmesgline, + if (props.dockBatteryPresent) { + snprintf(dmesglinedock, sizeof(dmesglinedock), + "dock-battery [l=%d v=%d t=%s%d.%d h=%d st=%d]", + props.dockBatteryLevel, props.dockBatteryVoltage, + props.dockBatteryTemperature < 0 ? "-" : "", + abs(props.dockBatteryTemperature / 10), + abs(props.dockBatteryTemperature % 10), props.dockBatteryHealth, + props.dockBatteryStatus); + + if (!mHealthdConfig->dockBatteryCurrentNowPath.isEmpty()) { + int c = getIntField(mHealthdConfig->dockBatteryCurrentNowPath); + char b[20]; + + snprintf(b, sizeof(b), " c=%d", c / 1000); + strlcat(dmesglinedock, b, sizeof(dmesglinedock)); + } + } else { + snprintf(dmesglinedock, sizeof(dmesglinedock), + "dock-battery none"); + } + + KLOG_WARNING(LOG_TAG, "%s %s chg=%s%s%s%s\n", dmesgline, dmesglinedock, props.chargerAcOnline ? "a" : "", props.chargerUsbOnline ? "u" : "", - props.chargerWirelessOnline ? "w" : ""); + props.chargerWirelessOnline ? "w" : "", + props.chargerDockAcOnline ? "d" : ""); } healthd_mode_ops->battery_update(&props); return props.chargerAcOnline | props.chargerUsbOnline | - props.chargerWirelessOnline; + props.chargerWirelessOnline | props.chargerDockAcOnline; } status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) { @@ -368,13 +424,77 @@ status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) { return ret; } +status_t BatteryMonitor::getDockProperty(int id, struct BatteryProperty *val) { + status_t ret = BAD_VALUE; + if (!mHealthdConfig->dockBatterySupported) { + return ret; + } + + val->valueInt64 = LONG_MIN; + + switch(id) { + case BATTERY_PROP_CHARGE_COUNTER: + if (!mHealthdConfig->dockBatteryChargeCounterPath.isEmpty()) { + val->valueInt64 = + getIntField(mHealthdConfig->dockBatteryChargeCounterPath); + ret = NO_ERROR; + } else { + ret = NAME_NOT_FOUND; + } + break; + + case BATTERY_PROP_CURRENT_NOW: + if (!mHealthdConfig->dockBatteryCurrentNowPath.isEmpty()) { + val->valueInt64 = + getIntField(mHealthdConfig->dockBatteryCurrentNowPath); + ret = NO_ERROR; + } else { + ret = NAME_NOT_FOUND; + } + break; + + case BATTERY_PROP_CURRENT_AVG: + if (!mHealthdConfig->dockBatteryCurrentAvgPath.isEmpty()) { + val->valueInt64 = + getIntField(mHealthdConfig->dockBatteryCurrentAvgPath); + ret = NO_ERROR; + } else { + ret = NAME_NOT_FOUND; + } + break; + + case BATTERY_PROP_CAPACITY: + if (!mHealthdConfig->dockBatteryCapacityPath.isEmpty()) { + val->valueInt64 = + getIntField(mHealthdConfig->dockBatteryCapacityPath); + ret = NO_ERROR; + } else { + ret = NAME_NOT_FOUND; + } + break; + + case BATTERY_PROP_ENERGY_COUNTER: + if (mHealthdConfig->dockEnergyCounter) { + ret = mHealthdConfig->dockEnergyCounter(&val->valueInt64); + } else { + ret = NAME_NOT_FOUND; + } + break; + + default: + break; + } + + return ret; +} + void BatteryMonitor::dumpState(int fd) { int v; char vs[128]; - snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d\n", + snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d dock-ac: %d\n", props.chargerAcOnline, props.chargerUsbOnline, - props.chargerWirelessOnline); + props.chargerWirelessOnline, props.chargerDockAcOnline); write(fd, vs, strlen(vs)); snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n", props.batteryStatus, props.batteryHealth, props.batteryPresent); @@ -401,6 +521,34 @@ void BatteryMonitor::dumpState(int fd) { snprintf(vs, sizeof(vs), "charge counter: %d\n", v); write(fd, vs, strlen(vs)); } + + if (mHealthdConfig->dockBatterySupported) { + snprintf(vs, sizeof(vs), "dock-status: %d dock-health: %d dock-present: %d\n", + props.dockBatteryStatus, props.dockBatteryHealth, props.dockBatteryPresent); + write(fd, vs, strlen(vs)); + snprintf(vs, sizeof(vs), "dock-level: %d dock-voltage: %d dock-temp: %d\n", + props.dockBatteryLevel, props.dockBatteryVoltage, + props.dockBatteryTemperature); + write(fd, vs, strlen(vs)); + + if (!mHealthdConfig->dockBatteryCurrentNowPath.isEmpty()) { + v = getIntField(mHealthdConfig->dockBatteryCurrentNowPath); + snprintf(vs, sizeof(vs), "dock-current now: %d\n", v); + write(fd, vs, strlen(vs)); + } + + if (!mHealthdConfig->dockBatteryCurrentAvgPath.isEmpty()) { + v = getIntField(mHealthdConfig->dockBatteryCurrentAvgPath); + snprintf(vs, sizeof(vs), "dock-current avg: %d\n", v); + write(fd, vs, strlen(vs)); + } + + if (!mHealthdConfig->dockBatteryChargeCounterPath.isEmpty()) { + v = getIntField(mHealthdConfig->dockBatteryChargeCounterPath); + snprintf(vs, sizeof(vs), "dock-charge counter: %d\n", v); + write(fd, vs, strlen(vs)); + } + } } void BatteryMonitor::init(struct healthd_config *hc) { @@ -427,6 +575,7 @@ void BatteryMonitor::init(struct healthd_config *hc) { case ANDROID_POWER_SUPPLY_TYPE_AC: case ANDROID_POWER_SUPPLY_TYPE_USB: case ANDROID_POWER_SUPPLY_TYPE_WIRELESS: + case ANDROID_POWER_SUPPLY_TYPE_DOCK_AC: path.clear(); path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name); if (access(path.string(), R_OK) == 0) @@ -532,6 +681,107 @@ void BatteryMonitor::init(struct healthd_config *hc) { break; + case ANDROID_POWER_SUPPLY_TYPE_DOCK_BATTERY: + if (mHealthdConfig->dockBatterySupported) { + mDockBatteryDevicePresent = true; + + if (mHealthdConfig->dockBatteryStatusPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryStatusPath = path; + } + + if (mHealthdConfig->dockBatteryHealthPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryHealthPath = path; + } + + if (mHealthdConfig->dockBatteryPresentPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryPresentPath = path; + } + + if (mHealthdConfig->dockBatteryCapacityPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/capacity", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryCapacityPath = path; + } + + if (mHealthdConfig->dockBatteryVoltagePath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/voltage_now", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) { + mHealthdConfig->dockBatteryVoltagePath = path; + } else { + path.clear(); + path.appendFormat("%s/%s/batt_vol", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryVoltagePath = path; + } + } + + if (mHealthdConfig->dockBatteryCurrentNowPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/current_now", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryCurrentNowPath = path; + } + + if (mHealthdConfig->dockBatteryCurrentAvgPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/current_avg", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryCurrentAvgPath = path; + } + + if (mHealthdConfig->dockBatteryChargeCounterPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/charge_counter", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryChargeCounterPath = path; + } + + if (mHealthdConfig->dockBatteryTemperaturePath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/temp", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path, R_OK) == 0) { + mHealthdConfig->dockBatteryTemperaturePath = path; + } else { + path.clear(); + path.appendFormat("%s/%s/batt_temp", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryTemperaturePath = path; + } + } + + if (mHealthdConfig->dockBatteryTechnologyPath.isEmpty()) { + path.clear(); + path.appendFormat("%s/%s/technology", + POWER_SUPPLY_SYSFS_PATH, name); + if (access(path, R_OK) == 0) + mHealthdConfig->dockBatteryTechnologyPath = path; + } + } + + break; + case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN: break; } @@ -541,7 +791,7 @@ void BatteryMonitor::init(struct healthd_config *hc) { if (!mChargerNames.size()) KLOG_ERROR(LOG_TAG, "No charger supplies found\n"); - if (!mBatteryDevicePresent) { + if (!mBatteryDevicePresent && !mDockBatteryDevicePresent) { KLOG_WARNING(LOG_TAG, "No battery devices found\n"); hc->periodic_chores_interval_fast = -1; hc->periodic_chores_interval_slow = -1; @@ -560,6 +810,23 @@ void BatteryMonitor::init(struct healthd_config *hc) { KLOG_WARNING(LOG_TAG, "BatteryTemperaturePath not found\n"); if (mHealthdConfig->batteryTechnologyPath.isEmpty()) KLOG_WARNING(LOG_TAG, "BatteryTechnologyPath not found\n"); + + if (mHealthdConfig->dockBatterySupported) { + if (mHealthdConfig->dockBatteryStatusPath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryStatusPath not found\n"); + if (mHealthdConfig->dockBatteryHealthPath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryHealthPath not found\n"); + if (mHealthdConfig->dockBatteryPresentPath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryPresentPath not found\n"); + if (mHealthdConfig->dockBatteryCapacityPath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryCapacityPath not found\n"); + if (mHealthdConfig->dockBatteryVoltagePath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryVoltagePath not found\n"); + if (mHealthdConfig->dockBatteryTemperaturePath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryTemperaturePath not found\n"); + if (mHealthdConfig->dockBatteryTechnologyPath.isEmpty()) + KLOG_WARNING(LOG_TAG, "DockBatteryTechnologyPath not found\n"); + } } if (property_get("ro.boot.fake_battery", pval, NULL) > 0 diff --git a/healthd/BatteryMonitor.h b/healthd/BatteryMonitor.h index 3425f27..6e3ec98 100644 --- a/healthd/BatteryMonitor.h +++ b/healthd/BatteryMonitor.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,18 +35,22 @@ class BatteryMonitor { ANDROID_POWER_SUPPLY_TYPE_AC, ANDROID_POWER_SUPPLY_TYPE_USB, ANDROID_POWER_SUPPLY_TYPE_WIRELESS, - ANDROID_POWER_SUPPLY_TYPE_BATTERY + ANDROID_POWER_SUPPLY_TYPE_BATTERY, + ANDROID_POWER_SUPPLY_TYPE_DOCK_AC, + ANDROID_POWER_SUPPLY_TYPE_DOCK_BATTERY }; void init(struct healthd_config *hc); bool update(void); status_t getProperty(int id, struct BatteryProperty *val); + status_t getDockProperty(int id, struct BatteryProperty *val); void dumpState(int fd); private: struct healthd_config *mHealthdConfig; Vector<String8> mChargerNames; bool mBatteryDevicePresent; + bool mDockBatteryDevicePresent; int mBatteryFixedCapacity; int mBatteryFixedTemperature; struct BatteryProperties props; diff --git a/healthd/BatteryPropertiesRegistrar.cpp b/healthd/BatteryPropertiesRegistrar.cpp index 09667a1..7a28ead 100644 --- a/healthd/BatteryPropertiesRegistrar.cpp +++ b/healthd/BatteryPropertiesRegistrar.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,6 +77,10 @@ status_t BatteryPropertiesRegistrar::getProperty(int id, struct BatteryProperty return healthd_get_property(id, val); } +status_t BatteryPropertiesRegistrar::getDockProperty(int id, struct BatteryProperty *val) { + return healthd_get_dock_property(id, val); +} + status_t BatteryPropertiesRegistrar::dump(int fd, const Vector<String16>& /*args*/) { IPCThreadState* self = IPCThreadState::self(); const int pid = self->getCallingPid(); diff --git a/healthd/BatteryPropertiesRegistrar.h b/healthd/BatteryPropertiesRegistrar.h index 8853874..5ca4fc1 100644 --- a/healthd/BatteryPropertiesRegistrar.h +++ b/healthd/BatteryPropertiesRegistrar.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,6 +41,7 @@ private: void registerListener(const sp<IBatteryPropertiesListener>& listener); void unregisterListener(const sp<IBatteryPropertiesListener>& listener); status_t getProperty(int id, struct BatteryProperty *val); + status_t getDockProperty(int id, struct BatteryProperty *val); status_t dump(int fd, const Vector<String16>& args); void binderDied(const wp<IBinder>& who); }; diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp index 452cc25..c3de13c 100644 --- a/healthd/healthd.cpp +++ b/healthd/healthd.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,6 +56,18 @@ static struct healthd_config healthd_config = { .energyCounter = NULL, .boot_min_cap = 0, .screen_on = NULL, + .dockBatterySupported = false, + .dockBatteryStatusPath = String8(String8::kEmptyString), + .dockBatteryHealthPath = String8(String8::kEmptyString), + .dockBatteryPresentPath = String8(String8::kEmptyString), + .dockBatteryCapacityPath = String8(String8::kEmptyString), + .dockBatteryVoltagePath = String8(String8::kEmptyString), + .dockBatteryTemperaturePath = String8(String8::kEmptyString), + .dockBatteryTechnologyPath = String8(String8::kEmptyString), + .dockBatteryCurrentNowPath = String8(String8::kEmptyString), + .dockBatteryCurrentAvgPath = String8(String8::kEmptyString), + .dockBatteryChargeCounterPath = String8(String8::kEmptyString), + .dockEnergyCounter = NULL, }; static int eventct; @@ -173,6 +186,10 @@ status_t healthd_get_property(int id, struct BatteryProperty *val) { return gBatteryMonitor->getProperty(id, val); } +status_t healthd_get_dock_property(int id, struct BatteryProperty *val) { + return gBatteryMonitor->getDockProperty(id, val); +} + void healthd_battery_update(void) { // Fast wake interval when on charger (watch for overheat); // slow wake interval when on battery (watch for drained battery). diff --git a/healthd/healthd.h b/healthd/healthd.h index b9ffb35..0b2a16e 100644 --- a/healthd/healthd.h +++ b/healthd/healthd.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2015 The CyanogenMod Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,8 +49,25 @@ // batteryTemperaturePath: battery temperature (POWER_SUPPLY_PROP_TEMP) // batteryTechnologyPath: battery technology (POWER_SUPPLY_PROP_TECHNOLOGY) // batteryCurrentNowPath: battery current (POWER_SUPPLY_PROP_CURRENT_NOW) +// batteryCurrentAvgPath: battery average (POWER_SUPPLY_PROP_CURRENT_AVG) // batteryChargeCounterPath: battery accumulated charge // (POWER_SUPPLY_PROP_CHARGE_COUNTER) +// +// dockBatteryStatusPath: dock charging status (POWER_SUPPLY_PROP_STATUS) +// dockBatteryHealthPath: dock battery health (POWER_SUPPLY_PROP_HEALTH) +// dockBatteryPresentPath: dock battery present (POWER_SUPPLY_PROP_PRESENT) +// dockBatteryCapacityPath: remaining dock capacity (POWER_SUPPLY_PROP_CAPACITY) +// dockBatteryVoltagePath: dock battery voltage (POWER_SUPPLY_PROP_VOLTAGE_NOW) +// dockBatteryTemperaturePath: dock battery temperature (POWER_SUPPLY_PROP_TEMP) +// dockBatteryTechnologyPath: dock battery technology (POWER_SUPPLY_PROP_TECHNOLOGY) +// dockBatteryCurrentNowPath: dock battery current (POWER_SUPPLY_PROP_CURRENT_NOW) +// dockBatteryCurrentAvgPath: dock battery average (POWER_SUPPLY_PROP_CURRENT_AVG) +// dockBatteryChargeCounterPath: dock battery accumulated charge +// (POWER_SUPPLY_PROP_CHARGE_COUNTER) +// +// The dockBatterySupported property indicates whether a dock battery is supported +// by the device, and whether this module should fetch dock battery values. +// Defaults is to false. struct healthd_config { int periodic_chores_interval_fast; @@ -69,6 +87,20 @@ struct healthd_config { int (*energyCounter)(int64_t *); int boot_min_cap; bool (*screen_on)(android::BatteryProperties *props); + + bool dockBatterySupported; + android::String8 dockBatteryStatusPath; + android::String8 dockBatteryHealthPath; + android::String8 dockBatteryPresentPath; + android::String8 dockBatteryCapacityPath; + android::String8 dockBatteryVoltagePath; + android::String8 dockBatteryTemperaturePath; + android::String8 dockBatteryTechnologyPath; + android::String8 dockBatteryCurrentNowPath; + android::String8 dockBatteryCurrentAvgPath; + android::String8 dockBatteryChargeCounterPath; + + int (*dockEnergyCounter)(int64_t *); }; // Global helper functions @@ -77,6 +109,8 @@ int healthd_register_event(int fd, void (*handler)(uint32_t)); void healthd_battery_update(); android::status_t healthd_get_property(int id, struct android::BatteryProperty *val); +android::status_t healthd_get_dock_property(int id, + struct android::BatteryProperty *val); void healthd_dump_battery_state(int fd); struct healthd_mode_ops { diff --git a/include/cutils/iosched_policy.h b/include/cutils/iosched_policy.h index 07c5d1f..25b87ba 100644 --- a/include/cutils/iosched_policy.h +++ b/include/cutils/iosched_policy.h @@ -31,6 +31,8 @@ typedef enum { extern int android_set_ioprio(int pid, IoSchedClass clazz, int ioprio); extern int android_get_ioprio(int pid, IoSchedClass *clazz, int *ioprio); +extern int android_set_rt_ioprio(int pid, int rt); + #ifdef __cplusplus } #endif diff --git a/init/Android.mk b/init/Android.mk index de065dc..b060f04 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -48,6 +48,7 @@ LOCAL_SRC_FILES:= \ ueventd.cpp \ ueventd_parser.cpp \ watchdogd.cpp \ + vendor_init.cpp LOCAL_MODULE:= init LOCAL_C_INCLUDES += \ @@ -71,6 +72,9 @@ LOCAL_STATIC_LIBRARIES := \ libc \ libselinux \ libmincrypt \ + libext4_utils_static \ + libext2_blkid \ + libext2_uuid_static \ libc++_static \ libdl \ libsparse_static \ @@ -82,6 +86,11 @@ LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \ ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd LOCAL_CLANG := $(init_clang) + +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/init_parser.cpp b/init/init_parser.cpp index 666a86e..c760f53 100644 --- a/init/init_parser.cpp +++ b/init/init_parser.cpp @@ -44,7 +44,7 @@ struct import { const char *filename; }; -static void *parse_service(struct parse_state *state, int nargs, char **args); +static void *parse_service(struct parse_state *state, int nargs, char **args, bool redefine); static void parse_line_service(struct parse_state *state, int nargs, char **args); static void *parse_action(struct parse_state *state, int nargs, char **args); @@ -184,6 +184,7 @@ static int lookup_keyword(const char *s) case 's': if (!strcmp(s, "eclabel")) return K_seclabel; if (!strcmp(s, "ervice")) return K_service; + if (!strcmp(s, "ervice_redefine")) return K_service_redefine; if (!strcmp(s, "etenv")) return K_setenv; if (!strcmp(s, "etprop")) return K_setprop; if (!strcmp(s, "etrlimit")) return K_setrlimit; @@ -361,7 +362,8 @@ static void parse_new_section(struct parse_state *state, int kw, nargs > 1 ? args[1] : ""); switch(kw) { case K_service: - state->context = parse_service(state, nargs, args); + case K_service_redefine: + state->context = parse_service(state, nargs, args, (kw == K_service_redefine)); if (state->context) { state->parse_line = parse_line_service; return; @@ -725,7 +727,7 @@ service* make_exec_oneshot_service(int nargs, char** args) { return svc; } -static void *parse_service(struct parse_state *state, int nargs, char **args) +static void *parse_service(struct parse_state *state, int nargs, char **args, bool redefine) { if (nargs < 3) { parse_error(state, "services must have a name and a program\n"); @@ -737,13 +739,18 @@ static void *parse_service(struct parse_state *state, int nargs, char **args) } service* svc = (service*) service_find_by_name(args[1]); - if (svc) { + if (svc && !redefine) { parse_error(state, "ignored duplicate definition of service '%s'\n", args[1]); return 0; } nargs -= 2; - svc = (service*) calloc(1, sizeof(*svc) + sizeof(char*) * nargs); + + if (!svc) { + svc = (service*) calloc(1, sizeof(*svc) + sizeof(char*) * nargs); + redefine = false; + } + if (!svc) { parse_error(state, "out of memory\n"); return 0; @@ -758,7 +765,8 @@ static void *parse_service(struct parse_state *state, int nargs, char **args) cur_trigger->name = "onrestart"; list_add_tail(&svc->onrestart.triggers, &cur_trigger->nlist); list_init(&svc->onrestart.commands); - list_add_tail(&service_list, &svc->slist); + if (!redefine) + list_add_tail(&service_list, &svc->slist); return svc; } diff --git a/init/keywords.h b/init/keywords.h index e637d7d..a5048f4 100644 --- a/init/keywords.h +++ b/init/keywords.h @@ -83,6 +83,7 @@ enum { KEYWORD(rmdir, COMMAND, 1, do_rmdir) KEYWORD(seclabel, OPTION, 0, 0) KEYWORD(service, SECTION, 0, 0) + KEYWORD(service_redefine, SECTION, 0, 0) KEYWORD(setenv, OPTION, 2, 0) KEYWORD(setprop, COMMAND, 2, do_setprop) KEYWORD(setrlimit, COMMAND, 3, do_setrlimit) diff --git a/init/property_service.cpp b/init/property_service.cpp index c2881ae..001aa1d 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -54,6 +54,7 @@ #include "init.h" #include "util.h" #include "log.h" +#include "vendor_init.h" #define PERSISTENT_PROPERTY_DIR "/data/property" #define FSTAB_PREFIX "/fstab." @@ -570,6 +571,11 @@ void load_all_props() { /* Read persistent properties after all default values have been loaded. */ load_persistent_properties(); + /* update with vendor-specific property runtime + * overrides + */ + vendor_load_properties(); + load_recovery_id_prop(); } diff --git a/init/util.cpp b/init/util.cpp index a5392c6..b006e0b 100644 --- a/init/util.cpp +++ b/init/util.cpp @@ -458,9 +458,13 @@ int restorecon(const char* pathname) return selinux_android_restorecon(pathname, 0); } +#define RESTORECON_RECURSIVE_FLAGS \ + (SELINUX_ANDROID_RESTORECON_FORCE | \ + SELINUX_ANDROID_RESTORECON_RECURSE) + int restorecon_recursive(const char* pathname) { - return selinux_android_restorecon(pathname, SELINUX_ANDROID_RESTORECON_RECURSE); + return selinux_android_restorecon(pathname, RESTORECON_RECURSIVE_FLAGS); } /* 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/iosched_policy.c b/libcutils/iosched_policy.c index 8946d3c..745e2b6 100644 --- a/libcutils/iosched_policy.c +++ b/libcutils/iosched_policy.c @@ -1,9 +1,10 @@ /* -** Copyright 2007, The Android Open Source Project +** Copyright 2007-2014, The Android Open Source Project +** Copyright 2015, The CyanogenMod Project ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** @@ -20,28 +21,30 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <pthread.h> #include <cutils/iosched_policy.h> +#define LOG_TAG "iosched_policy" +#include <cutils/log.h> + +#define __android_unused __attribute__((__unused__)) #ifdef HAVE_ANDROID_OS #include <linux/ioprio.h> #include <sys/syscall.h> -#define __android_unused -#else -#define __android_unused __attribute__((__unused__)) -#endif +#include <sys/stat.h> + +static int __rtio_cgroup_supported = -1; +static pthread_once_t __rtio_init_once = PTHREAD_ONCE_INIT; int android_set_ioprio(int pid __android_unused, IoSchedClass clazz __android_unused, int ioprio __android_unused) { -#ifdef HAVE_ANDROID_OS if (syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, pid, ioprio | (clazz << IOPRIO_CLASS_SHIFT))) { return -1; } -#endif return 0; } int android_get_ioprio(int pid __android_unused, IoSchedClass *clazz, int *ioprio) { -#ifdef HAVE_ANDROID_OS int rc; if ((rc = syscall(SYS_ioprio_get, IOPRIO_WHO_PROCESS, pid)) < 0) { @@ -50,9 +53,83 @@ int android_get_ioprio(int pid __android_unused, IoSchedClass *clazz, int *iopri *clazz = (rc >> IOPRIO_CLASS_SHIFT); *ioprio = (rc & 0xff); + return 0; +} + +static void __initialize_rtio(void) { + if (!access("/sys/fs/cgroup/bfqio/tasks", W_OK) || + !access("/sys/fs/cgroup/bfqio/rt-display/tasks", W_OK)) { + __rtio_cgroup_supported = 1; + } else { + __rtio_cgroup_supported = 0; + } +} + +int android_set_rt_ioprio(int tid, int rt) { + int fd = -1, rc = -1; + + pthread_once(&__rtio_init_once, __initialize_rtio); + if (__rtio_cgroup_supported != 1) { + return -1; + } + + if (rt) { + fd = open("/sys/fs/cgroup/bfqio/rt-display/tasks", O_WRONLY | O_CLOEXEC); + } else { + fd = open("/sys/fs/cgroup/bfqio/tasks", O_WRONLY | O_CLOEXEC); + } + + if (fd < 0) { + return -1; + } + +#ifdef HAVE_GETTID + if (tid == 0) { + tid = gettid(); + } +#endif + + // specialized itoa -- works for tid > 0 + char text[22]; + char *end = text + sizeof(text) - 1; + char *ptr = end; + *ptr = '\0'; + while (tid > 0) { + *--ptr = '0' + (tid % 10); + tid = tid / 10; + } + + rc = write(fd, ptr, end - ptr); + if (rc < 0) { + /* + * If the thread is in the process of exiting, + * don't flag an error + */ + if (errno == ESRCH) { + rc = 0; + } else { + SLOGV("android_set_rt_ioprio failed to write '%s' (%s); fd=%d\n", + ptr, strerror(errno), fd); + } + } + + close(fd); + return rc; +} + #else +int android_set_ioprio(int pid __android_unused, IoSchedClass clazz __android_unused, int ioprio __android_unused) { + return 0; +} + +int android_get_ioprio(int pid __android_unused, IoSchedClass *clazz, int *ioprio) { *clazz = IoSchedClass_NONE; *ioprio = 0; -#endif return 0; } + +int android_set_rt_ioprio(int tid __android_unused, int rt __android_unused) +{ + return 0; +} +#endif diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp index e598bb8..07d0a5c 100644 --- a/logcat/logcat.cpp +++ b/logcat/logcat.cpp @@ -284,6 +284,7 @@ static void show_help(const char *cmd) " other pruning activity is oldest first. Special case ~!\n" " represents an automatic quicker pruning for the noisiest\n" " UID as determined by the current statistics.\n" + " -C colored output\n" " -P '<list> ...' set prune white and ~black list, using same format as\n" " printed above. Must be quoted.\n"); @@ -492,7 +493,7 @@ int main(int argc, char **argv) for (;;) { int ret; - ret = getopt(argc, argv, ":cdDLt:T:gG:sQf:r:n:v:b:BSpP:"); + ret = getopt(argc, argv, ":cdDLt:T:gG:sQf:r:n:v:b:BSpCP:"); if (ret < 0) { break; @@ -597,6 +598,10 @@ int main(int argc, char **argv) setPruneList = optarg; break; + case 'C': + setLogFormat ("color"); + break; + case 'b': { if (strcmp(optarg, "all") == 0) { while (devices) { diff --git a/mkbootimg/Android.mk b/mkbootimg/Android.mk index 0c9b0c6..c020323 100644 --- a/mkbootimg/Android.mk +++ b/mkbootimg/Android.mk @@ -10,4 +10,33 @@ LOCAL_MODULE := mkbootimg include $(BUILD_HOST_EXECUTABLE) +include $(CLEAR_VARS) +LOCAL_SRC_FILES := unpackbootimg.c +LOCAL_MODULE := unpackbootimg +include $(BUILD_HOST_EXECUTABLE) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES := mkbootimg.c +LOCAL_STATIC_LIBRARIES := libmincrypt libcutils libc +LOCAL_MODULE := utility_mkbootimg +LOCAL_MODULE_TAGS := eng +LOCAL_MODULE_STEM := mkbootimg +LOCAL_MODULE_CLASS := EXECUTABLES +LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities +LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities +LOCAL_FORCE_STATIC_EXECUTABLE := true +include $(BUILD_EXECUTABLE) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES := unpackbootimg.c +LOCAL_STATIC_LIBRARIES := libcutils libc +LOCAL_MODULE := utility_unpackbootimg +LOCAL_MODULE_TAGS := eng +LOCAL_MODULE_STEM := unpackbootimg +LOCAL_MODULE_CLASS := EXECUTABLES +LOCAL_UNSTRIPPED_PATH := $(PRODUCT_OUT)/symbols/utilities +LOCAL_MODULE_PATH := $(PRODUCT_OUT)/utilities +LOCAL_FORCE_STATIC_EXECUTABLE := true +include $(BUILD_EXECUTABLE) + $(call dist-for-goals,dist_files,$(LOCAL_BUILT_MODULE)) diff --git a/mkbootimg/bootimg.h b/mkbootimg/bootimg.h index 5ab6195..e66e269 100644 --- a/mkbootimg/bootimg.h +++ b/mkbootimg/bootimg.h @@ -43,7 +43,8 @@ struct boot_img_hdr uint32_t tags_addr; /* physical addr for kernel tags */ uint32_t page_size; /* flash page size we assume */ - uint32_t unused[2]; /* future expansion: should be 0 */ + uint32_t dt_size; /* device tree in bytes */ + uint32_t unused; /* future expansion: should be 0 */ uint8_t name[BOOT_NAME_SIZE]; /* asciiz product name */ @@ -66,10 +67,13 @@ struct boot_img_hdr ** +-----------------+ ** | second stage | o pages ** +-----------------+ +** | device tree | p pages +** +-----------------+ ** ** n = (kernel_size + page_size - 1) / page_size ** m = (ramdisk_size + page_size - 1) / page_size ** o = (second_size + page_size - 1) / page_size +** p = (dt_size + page_size - 1) / page_size ** ** 0. all entities are page_size aligned in flash ** 1. kernel and ramdisk are required (size != 0) diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c index b6a2801..fa8697d 100644 --- a/mkbootimg/mkbootimg.c +++ b/mkbootimg/mkbootimg.c @@ -66,6 +66,9 @@ int usage(void) " [ --board <boardname> ]\n" " [ --base <address> ]\n" " [ --pagesize <pagesize> ]\n" + " [ --dt <filename> ]\n" + " [ --ramdisk_offset <address> ]\n" + " [ --tags_offset <address> ]\n" " [ --id ]\n" " -o|--output <filename>\n" ); @@ -74,11 +77,12 @@ int usage(void) -static unsigned char padding[16384] = { 0, }; +static unsigned char padding[131072] = { 0, }; static void print_id(const uint8_t *id, size_t id_len) { printf("0x"); - for (unsigned i = 0; i < id_len; i++) { + unsigned i = 0; + for (i = 0; i < id_len; i++) { printf("%02x", id[i]); } printf("\n"); @@ -115,6 +119,8 @@ int main(int argc, char **argv) char *cmdline = ""; char *bootimg = NULL; char *board = ""; + char *dt_fn = 0; + void *dt_data = 0; uint32_t pagesize = 2048; int fd; SHA_CTX ctx; @@ -167,10 +173,14 @@ int main(int argc, char **argv) } else if(!strcmp(arg,"--pagesize")) { pagesize = strtoul(val, 0, 10); if ((pagesize != 2048) && (pagesize != 4096) - && (pagesize != 8192) && (pagesize != 16384)) { + && (pagesize != 8192) && (pagesize != 16384) + && (pagesize != 32768) && (pagesize != 65536) + && (pagesize != 131072)) { fprintf(stderr,"error: unsupported page size %d\n", pagesize); return -1; } + } else if(!strcmp(arg, "--dt")) { + dt_fn = val; } else { return usage(); } @@ -243,6 +253,14 @@ int main(int argc, char **argv) } } + if(dt_fn) { + dt_data = load_file(dt_fn, &hdr.dt_size); + if (dt_data == 0) { + fprintf(stderr,"error: could not load device tree image '%s'\n", dt_fn); + return 1; + } + } + /* put a hash of the contents in the header so boot images can be * differentiated based on their first 2k. */ @@ -253,6 +271,10 @@ int main(int argc, char **argv) SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size)); SHA_update(&ctx, second_data, hdr.second_size); SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size)); + if(dt_data) { + SHA_update(&ctx, dt_data, hdr.dt_size); + SHA_update(&ctx, &hdr.dt_size, sizeof(hdr.dt_size)); + } sha = SHA_final(&ctx); memcpy(hdr.id, sha, SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE); @@ -281,6 +303,10 @@ int main(int argc, char **argv) print_id((uint8_t *) hdr.id, sizeof(hdr.id)); } + if(dt_data) { + if(write(fd, dt_data, hdr.dt_size) != (ssize_t) hdr.dt_size) goto fail; + if(write_padding(fd, pagesize, hdr.dt_size)) goto fail; + } return 0; fail: diff --git a/mkbootimg/unpackbootimg.c b/mkbootimg/unpackbootimg.c new file mode 100644 index 0000000..3d2fda7 --- /dev/null +++ b/mkbootimg/unpackbootimg.c @@ -0,0 +1,211 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <limits.h> +#include <libgen.h> + +#include "mincrypt/sha.h" +#include "bootimg.h" + +typedef unsigned char byte; + +int read_padding(FILE* f, unsigned itemsize, int pagesize) +{ + byte* buf = (byte*)malloc(sizeof(byte) * pagesize); + unsigned pagemask = pagesize - 1; + unsigned count; + + if((itemsize & pagemask) == 0) { + free(buf); + return 0; + } + + count = pagesize - (itemsize & pagemask); + + fread(buf, count, 1, f); + free(buf); + return count; +} + +void write_string_to_file(char* file, char* string) +{ + FILE* f = fopen(file, "w"); + fwrite(string, strlen(string), 1, f); + fwrite("\n", 1, 1, f); + fclose(f); +} + +int usage() { + printf("usage: unpackbootimg\n"); + printf("\t-i|--input boot.img\n"); + printf("\t[ -o|--output output_directory]\n"); + printf("\t[ -p|--pagesize <size-in-hexadecimal> ]\n"); + return 0; +} + +int main(int argc, char** argv) +{ + char tmp[PATH_MAX]; + char* directory = "./"; + char* filename = NULL; + int pagesize = 0; + + argc--; + argv++; + while(argc > 0){ + char *arg = argv[0]; + char *val = argv[1]; + argc -= 2; + argv += 2; + if(!strcmp(arg, "--input") || !strcmp(arg, "-i")) { + filename = val; + } else if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { + directory = val; + } else if(!strcmp(arg, "--pagesize") || !strcmp(arg, "-p")) { + pagesize = strtoul(val, 0, 16); + } else { + return usage(); + } + } + + if (filename == NULL) { + return usage(); + } + + int total_read = 0; + FILE* f = fopen(filename, "rb"); + boot_img_hdr header; + + //printf("Reading header...\n"); + int i; + for (i = 0; i <= 512; i++) { + fseek(f, i, SEEK_SET); + fread(tmp, BOOT_MAGIC_SIZE, 1, f); + if (memcmp(tmp, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) + break; + } + total_read = i; + if (i > 512) { + printf("Android boot magic not found.\n"); + return 1; + } + fseek(f, i, SEEK_SET); + printf("Android magic found at: %d\n", i); + + fread(&header, sizeof(header), 1, f); + printf("BOARD_KERNEL_CMDLINE %s\n", header.cmdline); + printf("BOARD_KERNEL_BASE %08x\n", header.kernel_addr - 0x00008000); + printf("BOARD_RAMDISK_OFFSET %08x\n", header.ramdisk_addr - header.kernel_addr + 0x00008000); + printf("BOARD_SECOND_OFFSET %08x\n", header.second_addr - header.kernel_addr + 0x00008000); + printf("BOARD_TAGS_OFFSET %08x\n",header.tags_addr - header.kernel_addr + 0x00008000); + printf("BOARD_PAGE_SIZE %d\n", header.page_size); + printf("BOARD_SECOND_SIZE %d\n", header.second_size); + printf("BOARD_DT_SIZE %d\n", header.dt_size); + + if (pagesize == 0) { + pagesize = header.page_size; + } + + //printf("cmdline...\n"); + sprintf(tmp, "%s/%s", directory, basename(filename)); + strcat(tmp, "-cmdline"); + write_string_to_file(tmp, header.cmdline); + + //printf("base...\n"); + sprintf(tmp, "%s/%s", directory, basename(filename)); + strcat(tmp, "-base"); + char basetmp[200]; + sprintf(basetmp, "%08x", header.kernel_addr - 0x00008000); + write_string_to_file(tmp, basetmp); + + //printf("ramdisk_offset...\n"); + sprintf(tmp, "%s/%s", directory, basename(filename)); + strcat(tmp, "-ramdisk_offset"); + char ramdisktmp[200]; + sprintf(ramdisktmp, "%08x", header.ramdisk_addr - header.kernel_addr + 0x00008000); + write_string_to_file(tmp, ramdisktmp); + + //printf("second_offset...\n"); + sprintf(tmp, "%s/%s", directory, basename(filename)); + strcat(tmp, "-second_offset"); + char secondtmp[200]; + sprintf(secondtmp, "%08x", header.second_addr - header.kernel_addr + 0x00008000); + write_string_to_file(tmp, secondtmp); + + //printf("tags_offset...\n"); + sprintf(tmp, "%s/%s", directory, basename(filename)); + strcat(tmp, "-tags_offset"); + char tagstmp[200]; + sprintf(tagstmp, "%08x", header.tags_addr - header.kernel_addr + 0x00008000); + write_string_to_file(tmp, tagstmp); + + //printf("pagesize...\n"); + sprintf(tmp, "%s/%s", directory, basename(filename)); + strcat(tmp, "-pagesize"); + char pagesizetmp[200]; + sprintf(pagesizetmp, "%d", header.page_size); + write_string_to_file(tmp, pagesizetmp); + + total_read += sizeof(header); + //printf("total read: %d\n", total_read); + total_read += read_padding(f, sizeof(header), pagesize); + + sprintf(tmp, "%s/%s", directory, basename(filename)); + strcat(tmp, "-zImage"); + FILE *k = fopen(tmp, "wb"); + byte* kernel = (byte*)malloc(header.kernel_size); + //printf("Reading kernel...\n"); + fread(kernel, header.kernel_size, 1, f); + total_read += header.kernel_size; + fwrite(kernel, header.kernel_size, 1, k); + fclose(k); + + //printf("total read: %d\n", header.kernel_size); + total_read += read_padding(f, header.kernel_size, pagesize); + + + byte* ramdisk = (byte*)malloc(header.ramdisk_size); + //printf("Reading ramdisk...\n"); + fread(ramdisk, header.ramdisk_size, 1, f); + total_read += header.ramdisk_size; + sprintf(tmp, "%s/%s", directory, basename(filename)); + if(ramdisk[0] == 0x02 && ramdisk[1]== 0x21) + strcat(tmp, "-ramdisk.lz4"); + else + strcat(tmp, "-ramdisk.gz"); + FILE *r = fopen(tmp, "wb"); + fwrite(ramdisk, header.ramdisk_size, 1, r); + fclose(r); + + total_read += read_padding(f, header.ramdisk_size, pagesize); + + sprintf(tmp, "%s/%s", directory, basename(filename)); + strcat(tmp, "-second"); + FILE *s = fopen(tmp, "wb"); + byte* second = (byte*)malloc(header.second_size); + //printf("Reading second...\n"); + fread(second, header.second_size, 1, f); + total_read += header.second_size; + fwrite(second, header.second_size, 1, r); + fclose(s); + + total_read += read_padding(f, header.second_size, pagesize); + + sprintf(tmp, "%s/%s", directory, basename(filename)); + strcat(tmp, "-dt"); + FILE *d = fopen(tmp, "wb"); + byte* dt = (byte*)malloc(header.dt_size); + //printf("Reading dt...\n"); + fread(dt, header.dt_size, 1, f); + total_read += header.dt_size; + fwrite(dt, header.dt_size, 1, r); + fclose(d); + + fclose(f); + + //printf("Total Read: %d\n", total_read); + return 0; +} diff --git a/rootdir/init.rc b/rootdir/init.rc index d5d12a5..316cf4c 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -9,6 +9,9 @@ import /init.usb.rc import /init.${ro.hardware}.rc import /init.${ro.zygote}.rc import /init.trace.rc +# Include CM's extra init file +import /init.cm.rc + on early-init # Set init and its forked children's oom_adj. @@ -46,6 +49,7 @@ on init write /sys/fs/cgroup/memory/sw/memory.move_charge_at_immigrate 1 chown root system /sys/fs/cgroup/memory/sw/tasks chmod 0660 /sys/fs/cgroup/memory/sw/tasks + chmod 0220 /sys/fs/cgroup/memory/cgroup.event_control mkdir /system mkdir /data 0771 system system @@ -357,6 +361,9 @@ on post-fs-data # Set SELinux security contexts on upgrade or policy update. restorecon_recursive /data + restorecon /data/data + restorecon /data/user + restorecon /data/user/0 # Check any timezone data in /data is newer than the copy in /system, delete if not. exec - system system -- /system/bin/tzdatacheck /system/usr/share/zoneinfo /data/misc/zoneinfo @@ -652,6 +659,11 @@ service installd /system/bin/installd service flash_recovery /system/bin/install-recovery.sh class main oneshot + disabled + +# update recovery if enabled +on property:persist.sys.recovery_update=true + start flash_recovery service racoon /system/bin/racoon class main |