summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--adb/adb.cpp4
-rw-r--r--adb/adb.h5
-rw-r--r--adb/adb_main.cpp4
-rw-r--r--adb/services.cpp57
-rw-r--r--adb/transport.cpp6
-rw-r--r--fastboot/Android.mk6
-rw-r--r--fs_mgr/Android.mk6
-rw-r--r--fs_mgr/fs_mgr.c24
-rw-r--r--fs_mgr/fs_mgr_format.c32
-rw-r--r--fs_mgr/fs_mgr_fstab.c6
-rw-r--r--fs_mgr/fs_mgr_priv.h1
-rw-r--r--fs_mgr/include/fs_mgr.h2
-rw-r--r--healthd/BatteryMonitor.cpp295
-rw-r--r--healthd/BatteryMonitor.h7
-rw-r--r--healthd/BatteryPropertiesRegistrar.cpp5
-rw-r--r--healthd/BatteryPropertiesRegistrar.h2
-rw-r--r--healthd/healthd.cpp17
-rw-r--r--healthd/healthd.h34
-rw-r--r--include/cutils/iosched_policy.h2
-rw-r--r--init/Android.mk9
-rw-r--r--init/NOTICE26
-rw-r--r--init/init_parser.cpp20
-rw-r--r--init/keywords.h1
-rw-r--r--init/property_service.cpp6
-rw-r--r--init/util.cpp6
-rw-r--r--init/vendor_init.cpp37
-rw-r--r--init/vendor_init.h33
-rw-r--r--libcutils/iosched_policy.c101
-rw-r--r--logcat/logcat.cpp7
-rw-r--r--mkbootimg/Android.mk29
-rw-r--r--mkbootimg/bootimg.h6
-rw-r--r--mkbootimg/mkbootimg.c32
-rw-r--r--mkbootimg/unpackbootimg.c211
-rw-r--r--rootdir/init.rc12
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
}
diff --git a/adb/adb.h b/adb/adb.h
index fd9d0e6..1155cd3 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -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