diff options
-rw-r--r-- | adb/Android.mk | 2 | ||||
-rw-r--r-- | adb/adb.h | 7 | ||||
-rw-r--r-- | adb/adb_client.c | 2 | ||||
-rw-r--r-- | adb/adb_trace.h | 24 | ||||
-rw-r--r-- | adb/commandline.c | 4 | ||||
-rw-r--r-- | adb/fdevent.c | 2 | ||||
-rw-r--r-- | adb/jdwp_service.c | 1 | ||||
-rw-r--r-- | adb/remount_service.c | 67 | ||||
-rw-r--r-- | adb/services.c | 8 | ||||
-rw-r--r-- | adb/set_verity_enable_state_service.c (renamed from adb/disable_verity_service.c) | 52 | ||||
-rw-r--r-- | adb/sysdeps.h | 11 | ||||
-rw-r--r-- | adb/transport.c | 3 | ||||
-rw-r--r-- | adb/usb_linux_client.c | 167 | ||||
-rw-r--r-- | fastboot/fastboot.c | 45 | ||||
-rw-r--r-- | fastbootd/usb_linux_client.c | 167 | ||||
-rw-r--r-- | healthd/healthd.cpp | 1 | ||||
-rw-r--r-- | healthd/healthd.h | 1 | ||||
-rw-r--r-- | healthd/healthd_mode_charger.cpp | 23 | ||||
-rw-r--r-- | init/init.c | 22 | ||||
-rw-r--r-- | init/init.h | 10 | ||||
-rw-r--r-- | init/init_parser.c | 134 | ||||
-rw-r--r-- | init/parser.c | 9 | ||||
-rw-r--r-- | init/readme.txt | 9 | ||||
-rw-r--r-- | libion/ion.c | 14 | ||||
-rw-r--r-- | rootdir/init.rc | 7 |
25 files changed, 519 insertions, 273 deletions
diff --git a/adb/Android.mk b/adb/Android.mk index 24cbce0..22bca2c 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -112,7 +112,7 @@ LOCAL_SRC_FILES := \ jdwp_service.c \ framebuffer_service.c \ remount_service.c \ - disable_verity_service.c \ + set_verity_enable_state_service.c \ usb_linux_client.c LOCAL_CFLAGS := \ @@ -328,8 +328,10 @@ int handle_forward_request(const char* service, transport_type ttype, char* seri #if !ADB_HOST void framebuffer_service(int fd, void *cookie); +// Allow enable-verity to write to system and vendor block devices +int make_system_and_vendor_block_devices_writable(); void remount_service(int fd, void *cookie); -void disable_verity_service(int fd, void* cookie); +void set_verity_enabled_state_service(int fd, void* cookie); #endif /* packet allocator */ @@ -339,6 +341,9 @@ void put_apacket(apacket *p); int check_header(apacket *p); int check_data(apacket *p); +// Define it if you want to dump packets. +#define DEBUG_PACKETS 0 + #if !DEBUG_PACKETS #define print_packet(tag,p) do {} while (0) #endif diff --git a/adb/adb_client.c b/adb/adb_client.c index eb1720d..ac5e15a 100644 --- a/adb/adb_client.c +++ b/adb/adb_client.c @@ -279,7 +279,7 @@ int adb_connect(const char *service) fd = _adb_connect(service); if(fd == -1) { - D("_adb_connect error: %s\n", __adb_error); + D("_adb_connect error: %s", __adb_error); } else if(fd == -2) { fprintf(stderr,"** daemon still not running\n"); } diff --git a/adb/adb_trace.h b/adb/adb_trace.h index 8a5d9f8..b8a2f4c 100644 --- a/adb/adb_trace.h +++ b/adb/adb_trace.h @@ -73,8 +73,9 @@ void adb_trace_init(void); if (ADB_TRACING) { \ int save_errno = errno; \ adb_mutex_lock(&D_lock); \ - fprintf(stderr, "%s::%s():", \ - __FILE__, __FUNCTION__); \ + fprintf(stderr, "%16s: %5d:%5lu | ", \ + __FUNCTION__, \ + getpid(), adb_thread_id()); \ errno = save_errno; \ fprintf(stderr, __VA_ARGS__ ); \ fflush(stderr); \ @@ -96,15 +97,16 @@ void adb_trace_init(void); } while (0) # define DD(...) \ do { \ - int save_errno = errno; \ - adb_mutex_lock(&D_lock); \ - fprintf(stderr, "%s::%s():", \ - __FILE__, __FUNCTION__); \ - errno = save_errno; \ - fprintf(stderr, __VA_ARGS__ ); \ - fflush(stderr); \ - adb_mutex_unlock(&D_lock); \ - errno = save_errno; \ + int save_errno = errno; \ + adb_mutex_lock(&D_lock); \ + fprintf(stderr, "%16s: %5d:%5lu | ", \ + __FUNCTION__, \ + getpid(), adb_thread_id()); \ + errno = save_errno; \ + fprintf(stderr, __VA_ARGS__ ); \ + fflush(stderr); \ + adb_mutex_unlock(&D_lock); \ + errno = save_errno; \ } while (0) #else # define D(...) \ diff --git a/adb/commandline.c b/adb/commandline.c index 903b818..49f1b95 100644 --- a/adb/commandline.c +++ b/adb/commandline.c @@ -191,6 +191,7 @@ void help() " adb restore <file> - restore device contents from the <file> backup archive\n" "\n" " adb disable-verity - disable dm-verity checking on USERDEBUG builds\n" + " adb enable-verity - re-enable dm-verity checking on USERDEBUG builds\n" " adb keygen <file> - generate adb public/private key. The private key is stored in <file>,\n" " and the public key is stored in <file>.pub. Any existing files\n" " are overwritten.\n" @@ -1446,7 +1447,8 @@ top: if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot") || !strcmp(argv[0], "reboot-bootloader") || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb") - || !strcmp(argv[0], "root") || !strcmp(argv[0], "disable-verity")) { + || !strcmp(argv[0], "root") || !strcmp(argv[0], "disable-verity") + || !strcmp(argv[0], "enable-verity")) { char command[100]; if (!strcmp(argv[0], "reboot-bootloader")) snprintf(command, sizeof(command), "reboot:bootloader"); diff --git a/adb/fdevent.c b/adb/fdevent.c index 43e600c..f5ecd14 100644 --- a/adb/fdevent.c +++ b/adb/fdevent.c @@ -661,6 +661,8 @@ void fdevent_subproc_setup() if(adb_socketpair(s)) { FATAL("cannot create shell-exit socket-pair\n"); } + D("socketpair: (%d,%d)", s[0], s[1]); + SHELL_EXIT_NOTIFY_FD = s[0]; fdevent *fde; fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL); diff --git a/adb/jdwp_service.c b/adb/jdwp_service.c index cd62b55..3074e42 100644 --- a/adb/jdwp_service.c +++ b/adb/jdwp_service.c @@ -415,6 +415,7 @@ FoundIt: __FUNCTION__, strerror(errno)); return -1; } + D("socketpair: (%d,%d)", fds[0], fds[1]); proc->out_fds[ proc->out_count ] = fds[1]; if (++proc->out_count == 1) diff --git a/adb/remount_service.c b/adb/remount_service.c index 36367a7..05d3169 100644 --- a/adb/remount_service.c +++ b/adb/remount_service.c @@ -79,29 +79,57 @@ static int hasVendorPartition() return false; } +static int make_block_device_writable(const char* dir) +{ + char *dev = 0; + int fd = -1; + int OFF = 0; + int rc = -1; + + dev = find_mount(dir); + if (!dev) + goto errout; + + fd = unix_open(dev, O_RDONLY | O_CLOEXEC); + if (fd < 0) + goto errout; + + if (ioctl(fd, BLKROSET, &OFF)) { + goto errout; + } + + rc = 0; + +errout: + if (fd >= 0) { + adb_close(fd); + } + + if (dev) { + free(dev); + } + return rc; +} + /* Init mounts /system as read only, remount to enable writes. */ static int remount(const char* dir, int* dir_ro) { char *dev; - int fd; int OFF = 0; if (dir_ro == 0) { return 0; } + if (make_block_device_writable(dir)) { + return -1; + } + dev = find_mount(dir); if (!dev) return -1; - fd = unix_open(dev, O_RDONLY | O_CLOEXEC); - if (fd < 0) - return -1; - - ioctl(fd, BLKROSET, &OFF); - adb_close(fd); - *dir_ro = mount(dev, dir, "none", MS_REMOUNT, NULL); free(dev); @@ -114,6 +142,28 @@ static void write_string(int fd, const char* str) writex(fd, str, strlen(str)); } +int make_system_and_vendor_block_devices_writable(int fd) +{ + char buffer[200]; + if (make_block_device_writable("/system")) { + snprintf(buffer, sizeof(buffer), + "Failed to make system block device writable %s\n", + strerror(errno)); + write_string(fd, buffer); + return -1; + } + + if (hasVendorPartition() && make_block_device_writable("/vendor")) { + snprintf(buffer, sizeof(buffer), + "Failed to make vendor block device writable: %s\n", + strerror(errno)); + write_string(fd, buffer); + return -1; + } + + return 0; +} + void remount_service(int fd, void *cookie) { char buffer[200]; @@ -167,4 +217,3 @@ void remount_service(int fd, void *cookie) adb_close(fd); } - diff --git a/adb/services.c b/adb/services.c index 703aec8..d5a4642 100644 --- a/adb/services.c +++ b/adb/services.c @@ -164,6 +164,7 @@ static int create_service_thread(void (*func)(int, void *), void *cookie) printf("cannot create service socket pair\n"); return -1; } + D("socketpair: (%d,%d)", s[0], s[1]); sti = malloc(sizeof(stinfo)); if(sti == 0) fatal("cannot allocate stinfo"); @@ -264,10 +265,11 @@ static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg // 0 is parent socket, 1 is child socket int sv[2]; - if (unix_socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) { + if (adb_socketpair(sv) < 0) { printf("[ cannot create socket pair - %s ]\n", strerror(errno)); return -1; } + D("socketpair: (%d,%d)", sv[0], sv[1]); *pid = fork(); if (*pid < 0) { @@ -470,7 +472,9 @@ int service_to_fd(const char *name) } } } else if(!strncmp(name, "disable-verity:", 15)) { - ret = create_service_thread(disable_verity_service, NULL); + ret = create_service_thread(set_verity_enabled_state_service, (void*)0); + } else if(!strncmp(name, "enable-verity:", 15)) { + ret = create_service_thread(set_verity_enabled_state_service, (void*)1); #endif } if (ret >= 0) { diff --git a/adb/disable_verity_service.c b/adb/set_verity_enable_state_service.c index ed3da52..1e22149 100644 --- a/adb/disable_verity_service.c +++ b/adb/set_verity_enable_state_service.c @@ -78,11 +78,13 @@ static int get_target_device_size(int fd, const char *blk_device, return 0; } -static int disable_verity(int fd, const char *block_device, - const char* mount_point) +/* Turn verity on/off */ +static int set_verity_enabled_state(int fd, const char *block_device, + const char* mount_point, bool enable) { uint32_t magic_number; - const uint32_t voff = VERITY_METADATA_MAGIC_DISABLE; + const uint32_t new_magic = enable ? VERITY_METADATA_MAGIC_NUMBER + : VERITY_METADATA_MAGIC_DISABLE; uint64_t device_length; int device; int retval = -1; @@ -114,12 +116,18 @@ static int disable_verity(int fd, const char *block_device, goto errout; } - if (magic_number == VERITY_METADATA_MAGIC_DISABLE) { + if (!enable && magic_number == VERITY_METADATA_MAGIC_DISABLE) { write_console(fd, "Verity already disabled on %s\n", mount_point); goto errout; } - if (magic_number != VERITY_METADATA_MAGIC_NUMBER) { + if (enable && magic_number == VERITY_METADATA_MAGIC_NUMBER) { + write_console(fd, "Verity already enabled on %s\n", mount_point); + goto errout; + } + + if (magic_number != VERITY_METADATA_MAGIC_NUMBER + && magic_number != VERITY_METADATA_MAGIC_DISABLE) { write_console(fd, "Couldn't find verity metadata at offset %"PRIu64"!\n", device_length); @@ -132,13 +140,17 @@ static int disable_verity(int fd, const char *block_device, goto errout; } - if (adb_write(device, &voff, sizeof(voff)) != sizeof(voff)) { - write_console(fd, "Could not set verity disabled flag on device %s\n", - block_device); + if (adb_write(device, &new_magic, sizeof(new_magic)) != sizeof(new_magic)) { + write_console(fd, "Could not set verity %s flag on device %s with error %s\n", + enable ? "enabled" : "disabled", + block_device, + strerror(errno)); goto errout; } - write_console(fd, "Verity disabled on %s\n", mount_point); + write_console(fd, "Verity %s on %s\n", + enable ? "enabled" : "disabled", + mount_point); retval = 0; errout: if (device != -1) @@ -146,13 +158,14 @@ errout: return retval; } -void disable_verity_service(int fd, void* cookie) +void set_verity_enabled_state_service(int fd, void* cookie) { + bool enable = (cookie != NULL); #ifdef ALLOW_ADBD_DISABLE_VERITY char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; char propbuf[PROPERTY_VALUE_MAX]; int i; - bool any_disabled = false; + bool any_changed = false; property_get("ro.secure", propbuf, "0"); if (strcmp(propbuf, "1")) { @@ -162,7 +175,7 @@ void disable_verity_service(int fd, void* cookie) property_get("ro.debuggable", propbuf, "0"); if (strcmp(propbuf, "1")) { - write_console(fd, "verity cannot be disabled - USER build\n"); + write_console(fd, "verity cannot be disabled/enabled - USER build\n"); goto errout; } @@ -176,22 +189,27 @@ void disable_verity_service(int fd, void* cookie) goto errout; } + if (enable && make_system_and_vendor_block_devices_writable(fd)) { + goto errout; + } + /* Loop through entries looking for ones that vold manages */ for (i = 0; i < fstab->num_entries; i++) { if(fs_mgr_is_verified(&fstab->recs[i])) { - if (!disable_verity(fd, fstab->recs[i].blk_device, - fstab->recs[i].mount_point)) { - any_disabled = true; + if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device, + fstab->recs[i].mount_point, enable)) { + any_changed = true; } } } - if (any_disabled) { + if (any_changed) { write_console(fd, "Now reboot your device for settings to take effect\n"); } #else - write_console(fd, "disable-verity only works for userdebug builds\n"); + write_console(fd, "%s-verity only works for userdebug builds\n", + enable ? "enable" : "disable"); #endif errout: diff --git a/adb/sysdeps.h b/adb/sysdeps.h index cc1f839..8d63d14 100644 --- a/adb/sysdeps.h +++ b/adb/sysdeps.h @@ -77,6 +77,11 @@ static __inline__ int adb_thread_create( adb_thread_t *thread, adb_thread_func return 0; } +static __inline__ unsigned long adb_thread_id() +{ + return GetCurrentThreadId(); +} + static __inline__ void close_on_exec(int fd) { /* nothing really */ @@ -516,6 +521,12 @@ static __inline__ char* adb_strtok_r(char *str, const char *delim, char **savep { return strtok_r(str, delim, saveptr); } + +static __inline__ unsigned long adb_thread_id() +{ + return (unsigned long)pthread_self(); +} + #undef strtok_r #define strtok_r ___xxx_strtok_r diff --git a/adb/transport.c b/adb/transport.c index f35880c..7db6a47 100644 --- a/adb/transport.c +++ b/adb/transport.c @@ -629,7 +629,7 @@ static void transport_registration_func(int _fd, unsigned ev, void *data) fatal_errno("cannot open transport socketpair"); } - D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]); + D("transport: %s socketpair: (%d,%d) starting", t->serial, s[0], s[1]); t->transport_socket = s[0]; t->fd = s[1]; @@ -673,6 +673,7 @@ void init_transport_registration(void) if(adb_socketpair(s)){ fatal_errno("cannot open transport registration socketpair"); } + D("socketpair: (%d,%d)", s[0], s[1]); transport_registration_send = s[0]; transport_registration_recv = s[1]; diff --git a/adb/usb_linux_client.c b/adb/usb_linux_client.c index 8426e0e..ecfae5d 100644 --- a/adb/usb_linux_client.c +++ b/adb/usb_linux_client.c @@ -55,71 +55,85 @@ struct usb_handle int bulk_in; /* "in" from the host's perspective => sink for adbd */ }; -static const struct { - struct usb_functionfs_descs_head header; - struct { - struct usb_interface_descriptor intf; - struct usb_endpoint_descriptor_no_audio source; - struct usb_endpoint_descriptor_no_audio sink; - } __attribute__((packed)) fs_descs, hs_descs; -} __attribute__((packed)) descriptors = { - .header = { - .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC), - .length = cpu_to_le32(sizeof(descriptors)), - .fs_count = 3, - .hs_count = 3, +struct func_desc { + struct usb_interface_descriptor intf; + struct usb_endpoint_descriptor_no_audio source; + struct usb_endpoint_descriptor_no_audio sink; +} __attribute__((packed)); + +struct desc_v1 { + struct usb_functionfs_descs_head_v1 { + __le32 magic; + __le32 length; + __le32 fs_count; + __le32 hs_count; + } __attribute__((packed)) header; + struct func_desc fs_descs, hs_descs; +} __attribute__((packed)); + +struct desc_v2 { + struct usb_functionfs_descs_head_v2 { + __le32 magic; + __le32 length; + __le32 flags; + __le32 fs_count; + __le32 hs_count; + __le32 ss_count; + } __attribute__((packed)) header; + struct func_desc fs_descs, hs_descs; +} __attribute__((packed)); + +struct func_desc fs_descriptors = { + .intf = { + .bLength = sizeof(fs_descriptors.intf), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 2, + .bInterfaceClass = ADB_CLASS, + .bInterfaceSubClass = ADB_SUBCLASS, + .bInterfaceProtocol = ADB_PROTOCOL, + .iInterface = 1, /* first string from the provided table */ + }, + .source = { + .bLength = sizeof(fs_descriptors.source), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 1 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_FS, + }, + .sink = { + .bLength = sizeof(fs_descriptors.sink), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 2 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_FS, }, - .fs_descs = { - .intf = { - .bLength = sizeof(descriptors.fs_descs.intf), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = ADB_CLASS, - .bInterfaceSubClass = ADB_SUBCLASS, - .bInterfaceProtocol = ADB_PROTOCOL, - .iInterface = 1, /* first string from the provided table */ - }, - .source = { - .bLength = sizeof(descriptors.fs_descs.source), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 1 | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = MAX_PACKET_SIZE_FS, - }, - .sink = { - .bLength = sizeof(descriptors.fs_descs.sink), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 2 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = MAX_PACKET_SIZE_FS, - }, +}; + +struct func_desc hs_descriptors = { + .intf = { + .bLength = sizeof(hs_descriptors.intf), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 2, + .bInterfaceClass = ADB_CLASS, + .bInterfaceSubClass = ADB_SUBCLASS, + .bInterfaceProtocol = ADB_PROTOCOL, + .iInterface = 1, /* first string from the provided table */ + }, + .source = { + .bLength = sizeof(hs_descriptors.source), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 1 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_HS, }, - .hs_descs = { - .intf = { - .bLength = sizeof(descriptors.hs_descs.intf), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = ADB_CLASS, - .bInterfaceSubClass = ADB_SUBCLASS, - .bInterfaceProtocol = ADB_PROTOCOL, - .iInterface = 1, /* first string from the provided table */ - }, - .source = { - .bLength = sizeof(descriptors.hs_descs.source), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 1 | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = MAX_PACKET_SIZE_HS, - }, - .sink = { - .bLength = sizeof(descriptors.hs_descs.sink), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 2 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = MAX_PACKET_SIZE_HS, - }, + .sink = { + .bLength = sizeof(hs_descriptors.sink), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 2 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_HS, }, }; @@ -263,6 +277,17 @@ static void usb_adb_init() static void init_functionfs(struct usb_handle *h) { ssize_t ret; + struct desc_v1 v1_descriptor; + struct desc_v2 v2_descriptor; + + v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2); + v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor)); + v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC; + v2_descriptor.header.fs_count = 3; + v2_descriptor.header.hs_count = 3; + v2_descriptor.header.ss_count = 0; + v2_descriptor.fs_descs = fs_descriptors; + v2_descriptor.hs_descs = hs_descriptors; if (h->control < 0) { // might have already done this before D("OPENING %s\n", USB_FFS_ADB_EP0); @@ -272,10 +297,20 @@ static void init_functionfs(struct usb_handle *h) goto err; } - ret = adb_write(h->control, &descriptors, sizeof(descriptors)); + ret = adb_write(h->control, &v2_descriptor, sizeof(v2_descriptor)); if (ret < 0) { - D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno); - goto err; + v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC); + v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor)); + v1_descriptor.header.fs_count = 3; + v1_descriptor.header.hs_count = 3; + v1_descriptor.fs_descs = fs_descriptors; + v1_descriptor.hs_descs = hs_descriptors; + D("[ %s: Switching to V1_descriptor format errno=%d ]\n", USB_FFS_ADB_EP0, errno); + ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor)); + if (ret < 0) { + D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno); + goto err; + } } ret = adb_write(h->control, &strings, sizeof(strings)); 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/fastbootd/usb_linux_client.c b/fastbootd/usb_linux_client.c index 64420e9..2c678b9 100644 --- a/fastbootd/usb_linux_client.c +++ b/fastbootd/usb_linux_client.c @@ -69,71 +69,85 @@ struct usb_handle { struct transport_handle handle; }; -static const struct { - struct usb_functionfs_descs_head header; - struct { - struct usb_interface_descriptor intf; - struct usb_endpoint_descriptor_no_audio source; - struct usb_endpoint_descriptor_no_audio sink; - } __attribute__((packed)) fs_descs, hs_descs; -} __attribute__((packed)) descriptors = { - .header = { - .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC), - .length = cpu_to_le32(sizeof(descriptors)), - .fs_count = 3, - .hs_count = 3, +struct func_desc { + struct usb_interface_descriptor intf; + struct usb_endpoint_descriptor_no_audio source; + struct usb_endpoint_descriptor_no_audio sink; +} __attribute__((packed)); + +struct desc_v1 { + struct usb_functionfs_descs_head_v1 { + __le32 magic; + __le32 length; + __le32 fs_count; + __le32 hs_count; + } __attribute__((packed)) header; + struct func_desc fs_descs, hs_descs; +} __attribute__((packed)); + +struct desc_v2 { + struct usb_functionfs_descs_head_v2 { + __le32 magic; + __le32 length; + __le32 flags; + __le32 fs_count; + __le32 hs_count; + __le32 ss_count; + } __attribute__((packed)) header; + struct func_desc fs_descs, hs_descs; +} __attribute__((packed)); + +struct func_desc fs_descriptors = { + .intf = { + .bLength = sizeof(fs_descriptors.intf), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 2, + .bInterfaceClass = FASTBOOT_CLASS, + .bInterfaceSubClass = FASTBOOT_SUBCLASS, + .bInterfaceProtocol = FASTBOOT_PROTOCOL, + .iInterface = 1, /* first string from the provided table */ }, - .fs_descs = { - .intf = { - .bLength = sizeof(descriptors.fs_descs.intf), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = FASTBOOT_CLASS, - .bInterfaceSubClass = FASTBOOT_SUBCLASS, - .bInterfaceProtocol = FASTBOOT_PROTOCOL, - .iInterface = 1, /* first string from the provided table */ - }, - .source = { - .bLength = sizeof(descriptors.fs_descs.source), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 1 | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = MAX_PACKET_SIZE_FS, - }, - .sink = { - .bLength = sizeof(descriptors.fs_descs.sink), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 2 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = MAX_PACKET_SIZE_FS, - }, + .source = { + .bLength = sizeof(fs_descriptors.source), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 1 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_FS, }, - .hs_descs = { - .intf = { - .bLength = sizeof(descriptors.hs_descs.intf), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = FASTBOOT_CLASS, - .bInterfaceSubClass = FASTBOOT_SUBCLASS, - .bInterfaceProtocol = FASTBOOT_PROTOCOL, - .iInterface = 1, /* first string from the provided table */ - }, - .source = { - .bLength = sizeof(descriptors.hs_descs.source), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 1 | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = MAX_PACKET_SIZE_HS, - }, - .sink = { - .bLength = sizeof(descriptors.hs_descs.sink), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 2 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = MAX_PACKET_SIZE_HS, - }, + .sink = { + .bLength = sizeof(fs_descriptors.sink), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 2 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_FS, + }, +}; + +struct func_desc hs_descriptors = { + .intf = { + .bLength = sizeof(hs_descriptors.intf), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bNumEndpoints = 2, + .bInterfaceClass = FASTBOOT_CLASS, + .bInterfaceSubClass = FASTBOOT_SUBCLASS, + .bInterfaceProtocol = FASTBOOT_PROTOCOL, + .iInterface = 1, /* first string from the provided table */ + }, + .source = { + .bLength = sizeof(hs_descriptors.source), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 1 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_HS, + }, + .sink = { + .bLength = sizeof(hs_descriptors.sink), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 2 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_HS, }, }; @@ -161,6 +175,17 @@ static const struct { static int init_functionfs(struct usb_transport *usb_transport) { ssize_t ret; + struct desc_v1 v1_descriptor; + struct desc_v2 v2_descriptor; + + v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2); + v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor)); + v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC; + v2_descriptor.header.fs_count = 3; + v2_descriptor.header.hs_count = 3; + v2_descriptor.header.ss_count = 0; + v2_descriptor.fs_descs = fs_descriptors; + v2_descriptor.hs_descs = hs_descriptors; D(VERBOSE, "OPENING %s", USB_FFS_FASTBOOT_EP0); usb_transport->control = open(USB_FFS_FASTBOOT_EP0, O_RDWR); @@ -169,10 +194,20 @@ static int init_functionfs(struct usb_transport *usb_transport) goto err; } - ret = write(usb_transport->control, &descriptors, sizeof(descriptors)); + ret = write(usb_transport->control, &v2_descriptor, sizeof(v2_descriptor)); if (ret < 0) { - D(ERR, "[ %s: write descriptors failed: errno=%d ]", USB_FFS_FASTBOOT_EP0, errno); - goto err; + v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC); + v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor)); + v1_descriptor.header.fs_count = 3; + v1_descriptor.header.hs_count = 3; + v1_descriptor.fs_descs = fs_descriptors; + v1_descriptor.hs_descs = hs_descriptors; + D(ERR, "[ %s: Switching to V1_descriptor format errno=%d ]\n", USB_FFS_FASTBOOT_EP0, errno); + ret = write(usb_transport->control, &v1_descriptor, sizeof(v1_descriptor)); + if (ret < 0) { + D(ERR, "[ %s: write descriptors failed: errno=%d ]", USB_FFS_FASTBOOT_EP0, errno); + goto err; + } } ret = write(usb_transport->control, &strings, sizeof(strings)); 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 2b82937..269c11b 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 cbcb842..9f444c1 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -520,6 +520,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 @@ -553,6 +554,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 |