summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fastboot/fastboot.c45
-rw-r--r--healthd/healthd.cpp1
-rw-r--r--healthd/healthd.h1
-rw-r--r--healthd/healthd_mode_charger.cpp23
-rw-r--r--init/init.c22
-rw-r--r--init/init.h10
-rw-r--r--init/init_parser.c134
-rw-r--r--init/parser.c9
-rw-r--r--init/readme.txt9
-rw-r--r--libion/ion.c14
-rw-r--r--rootdir/init.rc11
11 files changed, 182 insertions, 97 deletions
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c
index 959d3ad..2dc8ced 100644
--- a/fastboot/fastboot.c
+++ b/fastboot/fastboot.c
@@ -295,9 +295,8 @@ void usage(void)
" Can override the fs type and/or\n"
" size the bootloader reports.\n"
" getvar <variable> display a bootloader variable\n"
- " boot <kernel> [ <ramdisk> [ <second> ] ] download and boot kernel\n"
- " flash:raw boot <kernel> [ <ramdisk> [ <second> ] ] create bootimage and \n"
- " flash it\n"
+ " boot <kernel> [ <ramdisk> ] download and boot kernel\n"
+ " flash:raw boot <kernel> [ <ramdisk> ] create bootimage and flash it\n"
" devices list all connected devices\n"
" continue continue with autoboot\n"
" reboot reboot device normally\n"
@@ -325,11 +324,10 @@ void usage(void)
}
void *load_bootable_image(const char *kernel, const char *ramdisk,
- const char *secondstage, unsigned *sz,
- const char *cmdline)
+ unsigned *sz, const char *cmdline)
{
- void *kdata = 0, *rdata = 0, *sdata = 0;
- unsigned ksize = 0, rsize = 0, ssize = 0;
+ void *kdata = 0, *rdata = 0;
+ unsigned ksize = 0, rsize = 0;
void *bdata;
unsigned bsize;
@@ -365,18 +363,10 @@ void *load_bootable_image(const char *kernel, const char *ramdisk,
}
}
- if (secondstage) {
- sdata = load_file(secondstage, &ssize);
- if(sdata == 0) {
- fprintf(stderr,"cannot load '%s': %s\n", secondstage, strerror(errno));
- return 0;
- }
- }
-
fprintf(stderr,"creating boot image...\n");
bdata = mkbootimg(kdata, ksize, kernel_offset,
rdata, rsize, ramdisk_offset,
- sdata, ssize, second_offset,
+ 0, 0, second_offset,
page_size, base_addr, tags_offset, &bsize);
if(bdata == 0) {
fprintf(stderr,"failed to create boot.img\n");
@@ -1162,7 +1152,6 @@ int main(int argc, char **argv)
} else if(!strcmp(*argv, "boot")) {
char *kname = 0;
char *rname = 0;
- char *sname = 0;
skip(1);
if (argc > 0) {
kname = argv[0];
@@ -1172,11 +1161,7 @@ int main(int argc, char **argv)
rname = argv[0];
skip(1);
}
- if (argc > 0) {
- sname = argv[0];
- skip(1);
- }
- data = load_bootable_image(kname, rname, sname, &sz, cmdline);
+ data = load_bootable_image(kname, rname, &sz, cmdline);
if (data == 0) return 1;
fb_queue_download("boot.img", data, sz);
fb_queue_command("boot", "booting");
@@ -1200,18 +1185,14 @@ int main(int argc, char **argv)
char *pname = argv[1];
char *kname = argv[2];
char *rname = 0;
- char *sname = 0;
require(3);
- skip(3);
- if (argc > 0) {
- rname = argv[0];
- skip(1);
- }
- if (argc > 0) {
- sname = argv[0];
- skip(1);
+ if(argc > 3) {
+ rname = argv[3];
+ skip(4);
+ } else {
+ skip(3);
}
- data = load_bootable_image(kname, rname, sname, &sz, cmdline);
+ data = load_bootable_image(kname, rname, &sz, cmdline);
if (data == 0) die("cannot load bootable image");
fb_queue_flash(pname, data, sz);
} else if(!strcmp(*argv, "flashall")) {
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index 1fee855..b0002cc 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -53,6 +53,7 @@ static struct healthd_config healthd_config = {
.batteryCurrentAvgPath = String8(String8::kEmptyString),
.batteryChargeCounterPath = String8(String8::kEmptyString),
.energyCounter = NULL,
+ .boot_min_cap = 0,
.screen_on = NULL,
};
diff --git a/healthd/healthd.h b/healthd/healthd.h
index 4704f0b..84b6d76 100644
--- a/healthd/healthd.h
+++ b/healthd/healthd.h
@@ -67,6 +67,7 @@ struct healthd_config {
android::String8 batteryChargeCounterPath;
int (*energyCounter)(int64_t *);
+ int boot_min_cap;
bool (*screen_on)(android::BatteryProperties *props);
};
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 9ed5944..8931983 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -116,6 +116,7 @@ struct charger {
struct animation *batt_anim;
gr_surface surf_unknown;
+ int boot_min_cap;
};
static struct frame batt_anim_frames[] = {
@@ -520,19 +521,29 @@ static void process_key(struct charger *charger, int code, int64_t now)
LOGW("[%" PRId64 "] booting from charger mode\n", now);
property_set("sys.boot_from_charger_mode", "1");
} else {
- LOGW("[%" PRId64 "] rebooting\n", now);
- android_reboot(ANDROID_RB_RESTART, 0, 0);
+ if (charger->batt_anim->capacity >= charger->boot_min_cap) {
+ LOGW("[%" PRId64 "] rebooting\n", now);
+ android_reboot(ANDROID_RB_RESTART, 0, 0);
+ } else {
+ LOGV("[%lld] ignore power-button press, battery level "
+ "less than minimum\n", now);
+ }
}
} else {
/* if the key is pressed but timeout hasn't expired,
* make sure we wake up at the right-ish time to check
*/
set_next_key_check(charger, key, POWER_ON_KEY_TIME);
+
+ /* Turn on the display and kick animation on power-key press
+ * rather than on key release
+ */
+ kick_animation(charger->batt_anim);
+ request_suspend(false);
}
} else {
/* if the power key got released, force screen state cycle */
if (key->pending) {
- request_suspend(false);
kick_animation(charger->batt_anim);
}
}
@@ -555,6 +566,11 @@ static void handle_power_supply_state(struct charger *charger, int64_t now)
return;
if (!charger->charger_connected) {
+
+ /* Last cycle would have stopped at the extreme top of battery-icon
+ * Need to show the correct level corresponding to capacity.
+ */
+ kick_animation(charger->batt_anim);
request_suspend(false);
if (charger->next_pwr_check == -1) {
charger->next_pwr_check = now + UNPLUGGED_SHUTDOWN_TIME;
@@ -705,4 +721,5 @@ void healthd_mode_charger_init(struct healthd_config* config)
charger->next_key_check = -1;
charger->next_pwr_check = -1;
healthd_config = config;
+ charger->boot_min_cap = config->boot_min_cap;
}
diff --git a/init/init.c b/init/init.c
index 7ddab80..d1845dd 100644
--- a/init/init.c
+++ b/init/init.c
@@ -540,17 +540,35 @@ static int is_last_command(struct action *act, struct command *cmd)
return (list_tail(&act->commands) == &cmd->clist);
}
+
+void build_triggers_string(char *name_str, int length, struct action *cur_action) {
+ struct listnode *node;
+ struct trigger *cur_trigger;
+
+ list_for_each(node, &cur_action->triggers) {
+ cur_trigger = node_to_item(node, struct trigger, nlist);
+ if (node != cur_action->triggers.next) {
+ strlcat(name_str, " " , length);
+ }
+ strlcat(name_str, cur_trigger->name , length);
+ }
+}
+
void execute_one_command(void)
{
int ret, i;
char cmd_str[256] = "";
+ char name_str[256] = "";
if (!cur_action || !cur_command || is_last_command(cur_action, cur_command)) {
cur_action = action_remove_queue_head();
cur_command = NULL;
if (!cur_action)
return;
- INFO("processing action %p (%s)\n", cur_action, cur_action->name);
+
+ build_triggers_string(name_str, sizeof(name_str), cur_action);
+
+ INFO("processing action %p (%s)\n", cur_action, name_str);
cur_command = get_first_command(cur_action);
} else {
cur_command = get_next_command(cur_action, cur_command);
@@ -568,7 +586,7 @@ void execute_one_command(void)
}
}
INFO("command '%s' action=%s status=%d (%s:%d)\n",
- cmd_str, cur_action ? cur_action->name : "", ret, cur_command->filename,
+ cmd_str, cur_action ? name_str : "", ret, cur_command->filename,
cur_command->line);
}
}
diff --git a/init/init.h b/init/init.h
index a7615a3..e03bd53 100644
--- a/init/init.h
+++ b/init/init.h
@@ -37,6 +37,11 @@ struct command
char *args[1];
};
+struct trigger {
+ struct listnode nlist;
+ const char *name;
+};
+
struct action {
/* node in list of all actions */
struct listnode alist;
@@ -46,12 +51,15 @@ struct action {
struct listnode tlist;
unsigned hash;
- const char *name;
+ /* list of actions which triggers the commands*/
+ struct listnode triggers;
struct listnode commands;
struct command *current;
};
+void build_triggers_string(char *name_str, int length, struct action *cur_action);
+
struct socketinfo {
struct socketinfo *next;
const char *name;
diff --git a/init/init_parser.c b/init/init_parser.c
index 2b4db8e..a124fa2 100644
--- a/init/init_parser.c
+++ b/init/init_parser.c
@@ -499,77 +499,92 @@ void service_for_each_flags(unsigned matchflags,
void action_for_each_trigger(const char *trigger,
void (*func)(struct action *act))
{
- struct listnode *node;
+ struct listnode *node, *node2;
struct action *act;
+ struct trigger *cur_trigger;
+
list_for_each(node, &action_list) {
act = node_to_item(node, struct action, alist);
- if (!strcmp(act->name, trigger)) {
- func(act);
+ list_for_each(node2, &act->triggers) {
+ cur_trigger = node_to_item(node2, struct trigger, nlist);
+ if (!strcmp(cur_trigger->name, trigger)) {
+ func(act);
+ }
}
}
}
+
void queue_property_triggers(const char *name, const char *value)
{
- struct listnode *node;
+ struct listnode *node, *node2;
struct action *act;
+ struct trigger *cur_trigger;
+ bool match;
+ int name_length;
+
list_for_each(node, &action_list) {
act = node_to_item(node, struct action, alist);
- if (!strncmp(act->name, "property:", strlen("property:"))) {
- const char *test = act->name + strlen("property:");
- int name_length = strlen(name);
-
- if (!strncmp(name, test, name_length) &&
- test[name_length] == '=' &&
- (!strcmp(test + name_length + 1, value) ||
- !strcmp(test + name_length + 1, "*"))) {
- action_add_queue_tail(act);
- }
+ match = !name;
+ list_for_each(node2, &act->triggers) {
+ cur_trigger = node_to_item(node2, struct trigger, nlist);
+ if (!strncmp(cur_trigger->name, "property:", strlen("property:"))) {
+ const char *test = cur_trigger->name + strlen("property:");
+ if (!match) {
+ name_length = strlen(name);
+ if (!strncmp(name, test, name_length) &&
+ test[name_length] == '=' &&
+ (!strcmp(test + name_length + 1, value) ||
+ !strcmp(test + name_length + 1, "*"))) {
+ match = true;
+ continue;
+ }
+ } else {
+ const char* equals = strchr(test, '=');
+ if (equals) {
+ char prop_name[PROP_NAME_MAX + 1];
+ char value[PROP_VALUE_MAX];
+ int length = equals - test;
+ if (length <= PROP_NAME_MAX) {
+ int ret;
+ memcpy(prop_name, test, length);
+ prop_name[length] = 0;
+
+ /* does the property exist, and match the trigger value? */
+ ret = property_get(prop_name, value);
+ if (ret > 0 && (!strcmp(equals + 1, value) ||
+ !strcmp(equals + 1, "*"))) {
+ continue;
+ }
+ }
+ }
+ }
+ }
+ match = false;
+ break;
+ }
+ if (match) {
+ action_add_queue_tail(act);
}
}
}
void queue_all_property_triggers()
{
- struct listnode *node;
- struct action *act;
- list_for_each(node, &action_list) {
- act = node_to_item(node, struct action, alist);
- if (!strncmp(act->name, "property:", strlen("property:"))) {
- /* parse property name and value
- syntax is property:<name>=<value> */
- const char* name = act->name + strlen("property:");
- const char* equals = strchr(name, '=');
- if (equals) {
- char prop_name[PROP_NAME_MAX + 1];
- char value[PROP_VALUE_MAX];
- int length = equals - name;
- if (length > PROP_NAME_MAX) {
- ERROR("property name too long in trigger %s", act->name);
- } else {
- int ret;
- memcpy(prop_name, name, length);
- prop_name[length] = 0;
-
- /* does the property exist, and match the trigger value? */
- ret = property_get(prop_name, value);
- if (ret > 0 && (!strcmp(equals + 1, value) ||
- !strcmp(equals + 1, "*"))) {
- action_add_queue_tail(act);
- }
- }
- }
- }
- }
+ queue_property_triggers(NULL, NULL);
}
void queue_builtin_action(int (*func)(int nargs, char **args), char *name)
{
struct action *act;
struct command *cmd;
+ struct trigger *cur_trigger;
act = calloc(1, sizeof(*act));
- act->name = name;
+ cur_trigger = calloc(1, sizeof(*cur_trigger));
+ cur_trigger->name = name;
+ list_init(&act->triggers);
+ list_add_tail(&act->triggers, &cur_trigger->nlist);
list_init(&act->commands);
list_init(&act->qlist);
@@ -611,6 +626,7 @@ int action_queue_empty()
static void *parse_service(struct parse_state *state, int nargs, char **args)
{
struct service *svc;
+ struct trigger *cur_trigger;
if (nargs < 3) {
parse_error(state, "services must have a name and a program\n");
return 0;
@@ -635,9 +651,12 @@ static void *parse_service(struct parse_state *state, int nargs, char **args)
svc->name = args[1];
svc->classname = "default";
memcpy(svc->args, args + 2, sizeof(char*) * nargs);
+ cur_trigger = calloc(1, sizeof(*cur_trigger));
svc->args[nargs] = 0;
svc->nargs = nargs;
- svc->onrestart.name = "onrestart";
+ list_init(&svc->onrestart.triggers);
+ 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);
return svc;
@@ -821,16 +840,29 @@ 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)
{
struct action *act;
+ struct trigger *cur_trigger;
+ int i;
if (nargs < 2) {
parse_error(state, "actions must have a trigger\n");
return 0;
}
- if (nargs > 2) {
- parse_error(state, "actions may not have extra parameters\n");
- return 0;
- }
+
act = calloc(1, sizeof(*act));
- act->name = args[1];
+ list_init(&act->triggers);
+
+ for (i = 1; i < nargs; i++) {
+ if (!(i % 2)) {
+ if (strcmp(args[i], "&&")) {
+ parse_error(state, "& is the only symbol allowed to concatenate actions\n");
+ return 0;
+ } else
+ continue;
+ }
+ cur_trigger = calloc(1, sizeof(*cur_trigger));
+ cur_trigger->name = args[i];
+ list_add_tail(&act->triggers, &cur_trigger->nlist);
+ }
+
list_init(&act->commands);
list_init(&act->qlist);
list_add_tail(&action_list, &act->alist);
diff --git a/init/parser.c b/init/parser.c
index 48e7aec..80bfb09 100644
--- a/init/parser.c
+++ b/init/parser.c
@@ -15,9 +15,10 @@ void DUMP(void)
struct command *cmd;
struct listnode *node;
struct listnode *node2;
+ char name_str[256] = "";
struct socketinfo *si;
int n;
-
+
list_for_each(node, &service_list) {
svc = node_to_item(node, struct service, slist);
RAW("service %s\n", svc->name);
@@ -34,7 +35,11 @@ void DUMP(void)
list_for_each(node, &action_list) {
act = node_to_item(node, struct action, alist);
- RAW("on %s\n", act->name);
+ RAW("on ");
+ build_triggers_string(name_str, sizeof(name_str), act);
+ RAW("%s", name_str);
+ RAW("\n");
+
list_for_each(node2, &act->commands) {
cmd = node_to_item(node2, struct command, clist);
RAW(" %p", cmd->func);
diff --git a/init/readme.txt b/init/readme.txt
index 750d953..0b43fd5 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -123,6 +123,15 @@ boot
Triggers of this form occur when the property <name> is set
to the specific value <value>.
+ One can also test Mutliple properties to execute a group
+ of commands. For example:
+
+ on property:test.a=1 && property:test.b=1
+ setprop test.c 1
+
+ The above stub sets test.c to 1 only when
+ both test.a=1 and test.b=1
+
Commands
--------
diff --git a/libion/ion.c b/libion/ion.c
index a79525d..27ec47a 100644
--- a/libion/ion.c
+++ b/libion/ion.c
@@ -90,6 +90,7 @@ int ion_map(int fd, ion_user_handle_t handle, size_t length, int prot,
int flags, off_t offset, unsigned char **ptr, int *map_fd)
{
int ret;
+ unsigned char *tmp_ptr;
struct ion_fd_data data = {
.handle = handle,
};
@@ -102,16 +103,17 @@ int ion_map(int fd, ion_user_handle_t handle, size_t length, int prot,
ret = ion_ioctl(fd, ION_IOC_MAP, &data);
if (ret < 0)
return ret;
- *map_fd = data.fd;
- if (*map_fd < 0) {
+ if (data.fd < 0) {
ALOGE("map ioctl returned negative fd\n");
return -EINVAL;
}
- *ptr = mmap(NULL, length, prot, flags, *map_fd, offset);
- if (*ptr == MAP_FAILED) {
+ tmp_ptr = mmap(NULL, length, prot, flags, data.fd, offset);
+ if (tmp_ptr == MAP_FAILED) {
ALOGE("mmap failed: %s\n", strerror(errno));
return -errno;
}
+ *map_fd = data.fd;
+ *ptr = tmp_ptr;
return ret;
}
@@ -128,11 +130,11 @@ int ion_share(int fd, ion_user_handle_t handle, int *share_fd)
ret = ion_ioctl(fd, ION_IOC_SHARE, &data);
if (ret < 0)
return ret;
- *share_fd = data.fd;
- if (*share_fd < 0) {
+ if (data.fd < 0) {
ALOGE("share ioctl returned negative fd\n");
return -EINVAL;
}
+ *share_fd = data.fd;
return ret;
}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index b4bed91..2f33952 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -114,6 +114,10 @@ on init
# set fwmark on accepted sockets
write /proc/sys/net/ipv4/tcp_fwmark_accept 1
+ # disable icmp redirects
+ write /proc/sys/net/ipv4/conf/all/accept_redirects 0
+ write /proc/sys/net/ipv6/conf/all/accept_redirects 0
+
# Create cgroup mount points for process groups
mkdir /dev/cpuctl
mount cgroup none /dev/cpuctl cpu
@@ -522,6 +526,7 @@ service servicemanager /system/bin/servicemanager
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
+ onrestart restart inputflinger
onrestart restart drm
service vold /system/bin/vold
@@ -555,6 +560,12 @@ service surfaceflinger /system/bin/surfaceflinger
group graphics drmrpc
onrestart restart zygote
+service inputflinger /system/bin/inputflinger
+ class main
+ user system
+ group input
+ onrestart restart zygote
+
service drm /system/bin/drmserver
class main
user drm