diff options
-rw-r--r-- | adb/usb_linux_client.cpp | 50 | ||||
-rw-r--r-- | debuggerd/debuggerd.cpp | 2 | ||||
-rw-r--r-- | fastboot/fastboot.cpp | 56 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_verity.c | 70 | ||||
-rw-r--r-- | healthd/BatteryMonitor.cpp | 67 | ||||
-rw-r--r-- | healthd/BatteryMonitor.h | 1 | ||||
-rw-r--r-- | init/bootchart.cpp | 2 | ||||
-rw-r--r-- | init/builtins.cpp | 27 | ||||
-rw-r--r-- | init/init_parser.cpp | 50 | ||||
-rw-r--r-- | init/keywords.h | 6 | ||||
-rw-r--r-- | init/property_service.cpp | 8 | ||||
-rw-r--r-- | init/property_service.h | 2 | ||||
-rw-r--r-- | libbacktrace/BacktraceCurrent.cpp | 18 | ||||
-rw-r--r-- | logd/FlushCommand.cpp | 2 | ||||
-rw-r--r-- | logd/LogBuffer.cpp | 139 | ||||
-rw-r--r-- | logd/LogBuffer.h | 13 | ||||
-rw-r--r-- | logd/LogKlog.cpp | 99 | ||||
-rw-r--r-- | logd/LogKlog.h | 1 | ||||
-rw-r--r-- | logd/LogTimes.h | 8 | ||||
-rw-r--r-- | logd/LogWhiteBlackList.cpp | 28 | ||||
-rw-r--r-- | logd/LogWhiteBlackList.h | 4 | ||||
-rw-r--r-- | rootdir/init.rc | 57 | ||||
-rw-r--r-- | rootdir/init.usb.configfs.rc | 175 | ||||
-rw-r--r-- | rootdir/init.usb.rc | 50 | ||||
-rw-r--r-- | rootdir/init.zygote32.rc | 2 | ||||
-rw-r--r-- | rootdir/init.zygote32_64.rc | 2 | ||||
-rw-r--r-- | rootdir/init.zygote64.rc | 2 | ||||
-rw-r--r-- | rootdir/init.zygote64_32.rc | 2 |
28 files changed, 766 insertions, 177 deletions
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp index 18289e2..f3db346 100644 --- a/adb/usb_linux_client.cpp +++ b/adb/usb_linux_client.cpp @@ -64,6 +64,14 @@ struct func_desc { struct usb_endpoint_descriptor_no_audio sink; } __attribute__((packed)); +struct ss_func_desc { + struct usb_interface_descriptor intf; + struct usb_endpoint_descriptor_no_audio source; + struct usb_ss_ep_comp_descriptor source_comp; + struct usb_endpoint_descriptor_no_audio sink; + struct usb_ss_ep_comp_descriptor sink_comp; +} __attribute__((packed)); + struct desc_v1 { struct usb_functionfs_descs_head_v1 { __le32 magic; @@ -79,7 +87,9 @@ struct desc_v2 { // The rest of the structure depends on the flags in the header. __le32 fs_count; __le32 hs_count; + __le32 ss_count; struct func_desc fs_descs, hs_descs; + struct ss_func_desc ss_descs; } __attribute__((packed)); struct func_desc fs_descriptors = { @@ -136,6 +146,41 @@ struct func_desc hs_descriptors = { }, }; +static struct ss_func_desc ss_descriptors = { + .intf = { + .bLength = sizeof(ss_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(ss_descriptors.source), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 1 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_SS, + }, + .source_comp = { + .bLength = sizeof(ss_descriptors.source_comp), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + }, + .sink = { + .bLength = sizeof(ss_descriptors.sink), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 2 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = MAX_PACKET_SIZE_SS, + }, + .sink_comp = { + .bLength = sizeof(ss_descriptors.sink_comp), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + }, +}; + #define STR_INTERFACE_ "ADB Interface" static const struct { @@ -279,11 +324,14 @@ static void init_functionfs(struct usb_handle *h) 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.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC | + FUNCTIONFS_HAS_SS_DESC; v2_descriptor.fs_count = 3; v2_descriptor.hs_count = 3; + v2_descriptor.ss_count = 5; v2_descriptor.fs_descs = fs_descriptors; v2_descriptor.hs_descs = hs_descriptors; + v2_descriptor.ss_descs = ss_descriptors; if (h->control < 0) { // might have already done this before D("OPENING %s\n", USB_FFS_ADB_EP0); diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp index b84a4e5..9c8a41e 100644 --- a/debuggerd/debuggerd.cpp +++ b/debuggerd/debuggerd.cpp @@ -538,7 +538,7 @@ static int do_server() { return 1; fcntl(s, F_SETFD, FD_CLOEXEC); - ALOGI("debuggerd: " __DATE__ " " __TIME__ "\n"); + ALOGI("debuggerd: starting\n"); for (;;) { sockaddr addr; diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index be80cce..de4c0ea 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -279,17 +279,22 @@ void usage(void) " flashall flash boot, system, vendor and if found,\n" " recovery\n" " flash <partition> [ <filename> ] write a file to a flash partition\n" - " flashing lock locks the device. Prevents flashing" + " flashing lock locks the device. Prevents flashing\n" " partitions\n" - " flashing unlock unlocks the device. Allows user to" - " flash any partition except the ones" + " flashing unlock unlocks the device. Allows user to\n" + " flash any partition except the ones\n" " that are related to bootloader\n" - " flashing lock_critical Prevents flashing bootloader related" + " flashing lock_critical Prevents flashing bootloader related\n" " partitions\n" - " flashing unlock_critical Enables flashing bootloader related" + " flashing unlock_critical Enables flashing bootloader related\n" " partitions\n" - " flashing get_unlock_ability Queries bootloader to see if the" + " flashing get_unlock_ability Queries bootloader to see if the\n" " device is unlocked\n" + " flashing get_unlock_bootloader_nonce Queries the bootloader to get the\n" + " unlock nonce\n" + " flashing unlock_bootloader <request> Issue unlock bootloader using request\n" + " flashing lock_bootloader Locks the bootloader to prevent\n" + " bootloader version rollback\n" " erase <partition> erase a flash partition\n" " format[:[<fs type>][:[<size>]] <partition> format a flash partition.\n" " Can override the fs type and/or\n" @@ -831,6 +836,27 @@ void do_flashall(usb_handle *usb, int erase_first) #define skip(n) do { argc -= (n); argv += (n); } while (0) #define require(n) do { if (argc < (n)) {usage(); exit(1);}} while (0) +int do_bypass_unlock_command(int argc, char **argv) +{ + unsigned sz; + void *data; + + if (argc <= 2) return 0; + skip(2); + + /* + * Process unlock_bootloader, we have to load the message file + * and send that to the remote device. + */ + require(1); + data = load_file(*argv, &sz); + if (data == 0) die("could not load '%s': %s", *argv, strerror(errno)); + fb_queue_download("unlock_message", data, sz); + fb_queue_command("flashing unlock_bootloader", "unlocking bootloader"); + skip(1); + return 0; +} + int do_oem_command(int argc, char **argv) { char command[256]; @@ -1230,12 +1256,18 @@ int main(int argc, char **argv) wants_reboot = 1; } else if(!strcmp(*argv, "oem")) { argc = do_oem_command(argc, argv); - } else if(!strcmp(*argv, "flashing") && argc == 2) { - if(!strcmp(*(argv+1), "unlock") || !strcmp(*(argv+1), "lock") - || !strcmp(*(argv+1), "unlock_critical") - || !strcmp(*(argv+1), "lock_critical") - || !strcmp(*(argv+1), "get_unlock_ability")) { - argc = do_oem_command(argc, argv); + } else if(!strcmp(*argv, "flashing")) { + if (argc == 2 && (!strcmp(*(argv+1), "unlock") || + !strcmp(*(argv+1), "lock") || + !strcmp(*(argv+1), "unlock_critical") || + !strcmp(*(argv+1), "lock_critical") || + !strcmp(*(argv+1), "get_unlock_ability") || + !strcmp(*(argv+1), "get_unlock_bootloader_nonce") || + !strcmp(*(argv+1), "lock_bootloader"))) { + argc = do_oem_command(argc, argv); + } else + if (argc == 3 && !strcmp(*(argv+1), "unlock_bootloader")) { + argc = do_bypass_unlock_command(argc, argv); } else { usage(); return 1; diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c index 2d1abbe..a9e3358 100644 --- a/fs_mgr/fs_mgr_verity.c +++ b/fs_mgr/fs_mgr_verity.c @@ -47,6 +47,8 @@ #define VERITY_METADATA_SIZE 32768 #define VERITY_TABLE_RSA_KEY "/verity_key" +#define VERITY_TABLE_HASH_IDX 8 +#define VERITY_TABLE_SALT_IDX 9 #define METADATA_MAGIC 0x01564c54 #define METADATA_TAG_MAX_LENGTH 63 @@ -141,6 +143,33 @@ out: return retval; } +static int invalidate_table(char *table, int table_length) +{ + int n = 0; + int idx = 0; + int cleared = 0; + + while (n < table_length) { + if (table[n++] == ' ') { + ++idx; + } + + if (idx != VERITY_TABLE_HASH_IDX && idx != VERITY_TABLE_SALT_IDX) { + continue; + } + + while (n < table_length && table[n] != ' ') { + table[n++] = '0'; + } + + if (++cleared == 2) { + return 0; + } + } + + return -1; +} + static int squashfs_get_target_device_size(char *blk_device, uint64_t *device_size) { struct squashfs_info sq_info; @@ -859,6 +888,7 @@ out: int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) { _Alignas(struct dm_ioctl) char buffer[DM_BUF_SIZE]; + bool use_state = true; char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; char *mount_point; char propbuf[PROPERTY_VALUE_MAX]; @@ -875,7 +905,10 @@ int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) property_get("ro.boot.veritymode", propbuf, ""); if (*propbuf != '\0') { - return 0; /* state is kept by the bootloader */ + if (fs_mgr_load_verity_state(&mode) == -1) { + return -1; + } + use_state = false; /* state is kept by the bootloader */ } fd = TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC)); @@ -900,9 +933,11 @@ int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) continue; } - if (get_verity_state_offset(&fstab->recs[i], &offset) < 0 || - read_verity_state(fstab->recs[i].verity_loc, offset, &mode) < 0) { - continue; + if (use_state) { + if (get_verity_state_offset(&fstab->recs[i], &offset) < 0 || + read_verity_state(fstab->recs[i].verity_loc, offset, &mode) < 0) { + continue; + } } mount_point = basename(fstab->recs[i].mount_point); @@ -916,7 +951,7 @@ int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) status = &buffer[io->data_start + sizeof(struct dm_target_spec)]; - if (*status == 'C') { + if (use_state && *status == 'C') { if (write_verity_state(fstab->recs[i].verity_loc, offset, VERITY_MODE_LOGGING) < 0) { continue; @@ -951,6 +986,7 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) { char *verity_blk_name = 0; char *verity_table = 0; char *verity_table_signature = 0; + int verity_table_length = 0; uint64_t device_size = 0; _Alignas(struct dm_ioctl) char buffer[DM_BUF_SIZE]; @@ -977,6 +1013,7 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) { } retval = FS_MGR_SETUP_VERITY_FAIL; + verity_table_length = strlen(verity_table); // get the device mapper fd if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) { @@ -996,13 +1033,6 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) { goto out; } - // verify the signature on the table - if (verify_table(verity_table_signature, - verity_table, - strlen(verity_table)) < 0) { - goto out; - } - if (load_verity_state(fstab, &mode) < 0) { /* if accessing or updating the state failed, switch to the default * safe mode. This makes sure the device won't end up in an endless @@ -1011,6 +1041,22 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) { mode = VERITY_MODE_EIO; } + // verify the signature on the table + if (verify_table(verity_table_signature, + verity_table, + verity_table_length) < 0) { + if (mode == VERITY_MODE_LOGGING) { + // the user has been warned, allow mounting without dm-verity + retval = FS_MGR_SETUP_VERITY_SUCCESS; + goto out; + } + + // invalidate root hash and salt to trigger device-specific recovery + if (invalidate_table(verity_table, verity_table_length) < 0) { + goto out; + } + } + INFO("Enabling dm-verity for %s (mode %d)\n", mount_point, mode); // load the verity mapping table diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp index 7ea8250..396dfef 100644 --- a/healthd/BatteryMonitor.cpp +++ b/healthd/BatteryMonitor.cpp @@ -24,11 +24,13 @@ #include <fcntl.h> #include <stdio.h> #include <stdlib.h> +#include <sys/types.h> #include <unistd.h> + #include <batteryservice/BatteryService.h> #include <cutils/klog.h> #include <cutils/properties.h> -#include <sys/types.h> +#include <log/log_read.h> #include <utils/Errors.h> #include <utils/String8.h> #include <utils/Vector.h> @@ -37,6 +39,7 @@ #define POWER_SUPPLY_SYSFS_PATH "/sys/class/" POWER_SUPPLY_SUBSYSTEM #define FAKE_BATTERY_CAPACITY 42 #define FAKE_BATTERY_TEMPERATURE 424 +#define ALWAYS_PLUGGED_CAPACITY 100 namespace android { @@ -181,6 +184,7 @@ bool BatteryMonitor::update(void) { props.chargerWirelessOnline = false; props.batteryStatus = BATTERY_STATUS_UNKNOWN; props.batteryHealth = BATTERY_HEALTH_UNKNOWN; + props.maxChargingCurrent = 0; if (!mHealthdConfig->batteryPresentPath.isEmpty()) props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath); @@ -196,6 +200,15 @@ bool BatteryMonitor::update(void) { mBatteryFixedTemperature : getIntField(mHealthdConfig->batteryTemperaturePath); + // For devices which do not have battery and are always plugged + // into power souce. + if (mAlwaysPluggedDevice) { + props.chargerAcOnline = true; + props.batteryPresent = true; + props.batteryStatus = BATTERY_STATUS_CHARGING; + props.batteryHealth = BATTERY_HEALTH_GOOD; + } + const int SIZE = 128; char buf[SIZE]; String8 btech; @@ -235,6 +248,15 @@ bool BatteryMonitor::update(void) { KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n", mChargerNames[i].string()); } + path.clear(); + path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH, + mChargerNames[i].string()); + if (access(path.string(), R_OK) == 0) { + int maxChargingCurrent = getIntField(path); + if (props.maxChargingCurrent < maxChargingCurrent) { + props.maxChargingCurrent = maxChargingCurrent; + } + } } } } @@ -265,10 +287,32 @@ bool BatteryMonitor::update(void) { "battery none"); } - KLOG_WARNING(LOG_TAG, "%s chg=%s%s%s\n", dmesgline, - props.chargerAcOnline ? "a" : "", - props.chargerUsbOnline ? "u" : "", - props.chargerWirelessOnline ? "w" : ""); + size_t len = strlen(dmesgline); + snprintf(dmesgline + len, sizeof(dmesgline) - len, " chg=%s%s%s", + props.chargerAcOnline ? "a" : "", + props.chargerUsbOnline ? "u" : "", + props.chargerWirelessOnline ? "w" : ""); + + log_time realtime(CLOCK_REALTIME); + time_t t = realtime.tv_sec; + struct tm *tmp = gmtime(&t); + if (tmp) { + static const char fmt[] = " %Y-%m-%d %H:%M:%S.XXXXXXXXX UTC"; + len = strlen(dmesgline); + if ((len < (sizeof(dmesgline) - sizeof(fmt) - 8)) // margin + && strftime(dmesgline + len, sizeof(dmesgline) - len, + fmt, tmp)) { + char *usec = strchr(dmesgline + len, 'X'); + if (usec) { + len = usec - dmesgline; + snprintf(dmesgline + len, sizeof(dmesgline) - len, + "%09u", realtime.tv_nsec); + usec[9] = ' '; + } + } + } + + KLOG_WARNING(LOG_TAG, "%s\n", dmesgline); } healthd_mode_ops->battery_update(&props); @@ -341,9 +385,9 @@ 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 current_max: %d\n", props.chargerAcOnline, props.chargerUsbOnline, - props.chargerWirelessOnline); + props.chargerWirelessOnline, props.maxChargingCurrent); write(fd, vs, strlen(vs)); snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n", props.batteryStatus, props.batteryHealth, props.batteryPresent); @@ -508,8 +552,15 @@ void BatteryMonitor::init(struct healthd_config *hc) { closedir(dir); } - if (!mChargerNames.size()) + // This indicates that there is no charger driver registered. + // Typically the case for devices which do not have a battery and + // and are always plugged into AC mains. + if (!mChargerNames.size()) { KLOG_ERROR(LOG_TAG, "No charger supplies found\n"); + mBatteryFixedCapacity = ALWAYS_PLUGGED_CAPACITY; + mBatteryFixedTemperature = FAKE_BATTERY_TEMPERATURE; + mAlwaysPluggedDevice = true; + } if (!mBatteryDevicePresent) { KLOG_WARNING(LOG_TAG, "No battery devices found\n"); hc->periodic_chores_interval_fast = -1; diff --git a/healthd/BatteryMonitor.h b/healthd/BatteryMonitor.h index 3425f27..a61171f 100644 --- a/healthd/BatteryMonitor.h +++ b/healthd/BatteryMonitor.h @@ -46,6 +46,7 @@ class BatteryMonitor { struct healthd_config *mHealthdConfig; Vector<String8> mChargerNames; bool mBatteryDevicePresent; + bool mAlwaysPluggedDevice; int mBatteryFixedCapacity; int mBatteryFixedTemperature; struct BatteryProperties props; diff --git a/init/bootchart.cpp b/init/bootchart.cpp index 95687cb..df8359d 100644 --- a/init/bootchart.cpp +++ b/init/bootchart.cpp @@ -89,7 +89,7 @@ static void log_header() { if (out == NULL) { return; } - fprintf(out, "version = Android init 0.8 " __TIME__ "\n"); + fprintf(out, "version = Android init 0.8\n"); fprintf(out, "title = Boot chart for Android (%s)\n", date); fprintf(out, "system.uname = %s %s %s %s\n", uts.sysname, uts.release, uts.version, uts.machine); fprintf(out, "system.release = %s\n", fingerprint); diff --git a/init/builtins.cpp b/init/builtins.cpp index 9e5f9ff..8eb5b5b 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -803,9 +803,9 @@ int do_load_persist_props(int nargs, char **args) { return -1; } -int do_load_all_props(int nargs, char **args) { +int do_load_system_props(int nargs, char **args) { if (nargs == 1) { - load_all_props(); + load_system_props(); return 0; } return -1; @@ -833,18 +833,31 @@ static int do_installkeys_ensure_dir_exists(const char* dir) return 0; } +static bool is_file_crypto() { + char prop_value[PROP_VALUE_MAX] = {0}; + property_get("ro.crypto.type", prop_value); + return strcmp(prop_value, "file") == 0; +} + int do_installkey(int nargs, char **args) { if (nargs != 2) { return -1; } - - char prop_value[PROP_VALUE_MAX] = {0}; - property_get("ro.crypto.type", prop_value); - if (strcmp(prop_value, "file")) { + if (!is_file_crypto()) { return 0; } - return e4crypt_create_device_key(args[1], do_installkeys_ensure_dir_exists); } + +int do_setusercryptopolicies(int nargs, char **args) +{ + if (nargs != 2) { + return -1; + } + if (!is_file_crypto()) { + return 0; + } + return e4crypt_set_user_crypto_policies(args[1]); +} diff --git a/init/init_parser.cpp b/init/init_parser.cpp index 666a86e..9bab67d 100644 --- a/init/init_parser.cpp +++ b/init/init_parser.cpp @@ -159,7 +159,7 @@ static int lookup_keyword(const char *s) case 'l': if (!strcmp(s, "oglevel")) return K_loglevel; if (!strcmp(s, "oad_persist_props")) return K_load_persist_props; - if (!strcmp(s, "oad_all_props")) return K_load_all_props; + if (!strcmp(s, "oad_system_props")) return K_load_system_props; break; case 'm': if (!strcmp(s, "kdir")) return K_mkdir; @@ -187,6 +187,7 @@ static int lookup_keyword(const char *s) if (!strcmp(s, "etenv")) return K_setenv; if (!strcmp(s, "etprop")) return K_setprop; if (!strcmp(s, "etrlimit")) return K_setrlimit; + if (!strcmp(s, "etusercryptopolicies")) return K_setusercryptopolicies; if (!strcmp(s, "ocket")) return K_socket; if (!strcmp(s, "tart")) return K_start; if (!strcmp(s, "top")) return K_stop; @@ -571,7 +572,7 @@ void queue_property_triggers(const char *name, const char *value) list_for_each(node, &action_list) { act = node_to_item(node, struct action, alist); - match = !name; + 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:"))) { @@ -585,29 +586,28 @@ void queue_property_triggers(const char *name, const char *value) 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; + } + 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); diff --git a/init/keywords.h b/init/keywords.h index e637d7d..0910f60 100644 --- a/init/keywords.h +++ b/init/keywords.h @@ -22,6 +22,7 @@ int do_rm(int nargs, char **args); int do_rmdir(int nargs, char **args); int do_setprop(int nargs, char **args); int do_setrlimit(int nargs, char **args); +int do_setusercryptopolicies(int nargs, char **args); int do_start(int nargs, char **args); int do_stop(int nargs, char **args); int do_swapon_all(int nargs, char **args); @@ -34,7 +35,7 @@ int do_chown(int nargs, char **args); int do_chmod(int nargs, char **args); int do_loglevel(int nargs, char **args); int do_load_persist_props(int nargs, char **args); -int do_load_all_props(int nargs, char **args); +int do_load_system_props(int nargs, char **args); int do_verity_load_state(int nargs, char **args); int do_verity_update_state(int nargs, char **args); int do_wait(int nargs, char **args); @@ -66,7 +67,7 @@ enum { KEYWORD(installkey, COMMAND, 1, do_installkey) KEYWORD(ioprio, OPTION, 0, 0) KEYWORD(keycodes, OPTION, 0, 0) - KEYWORD(load_all_props, COMMAND, 0, do_load_all_props) + KEYWORD(load_system_props, COMMAND, 0, do_load_system_props) KEYWORD(load_persist_props, COMMAND, 0, do_load_persist_props) KEYWORD(loglevel, COMMAND, 1, do_loglevel) KEYWORD(mkdir, COMMAND, 1, do_mkdir) @@ -86,6 +87,7 @@ enum { KEYWORD(setenv, OPTION, 2, 0) KEYWORD(setprop, COMMAND, 2, do_setprop) KEYWORD(setrlimit, COMMAND, 3, do_setrlimit) + KEYWORD(setusercryptopolicies, COMMAND, 1, do_setusercryptopolicies) KEYWORD(socket, OPTION, 0, 0) KEYWORD(start, COMMAND, 1, do_start) KEYWORD(stop, COMMAND, 1, do_stop) diff --git a/init/property_service.cpp b/init/property_service.cpp index c2881ae..52f6b98 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -560,16 +560,10 @@ void load_recovery_id_prop() { close(fd); } -void load_all_props() { +void load_system_props() { load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL); load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL); load_properties_from_file(PROP_PATH_FACTORY, "ro.*"); - - load_override_properties(); - - /* Read persistent properties after all default values have been loaded. */ - load_persistent_properties(); - load_recovery_id_prop(); } diff --git a/init/property_service.h b/init/property_service.h index a27053d..303f251 100644 --- a/init/property_service.h +++ b/init/property_service.h @@ -23,7 +23,7 @@ extern void property_init(void); extern void property_load_boot_defaults(void); extern void load_persist_props(void); -extern void load_all_props(void); +extern void load_system_props(void); extern void start_property_service(void); void get_property_workspace(int *fd, int *sz); extern int __property_get(const char *name, char *value); diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp index 2714d93..d339550 100644 --- a/libbacktrace/BacktraceCurrent.cpp +++ b/libbacktrace/BacktraceCurrent.cpp @@ -93,6 +93,10 @@ bool BacktraceCurrent::DiscardFrame(const backtrace_frame_data_t& frame) { static pthread_mutex_t g_sigaction_mutex = PTHREAD_MUTEX_INITIALIZER; +static void SignalLogOnly(int, siginfo_t*, void*) { + BACK_LOGE("pid %d, tid %d: Received a spurious signal %d\n", getpid(), gettid(), THREAD_SIGNAL); +} + static void SignalHandler(int, siginfo_t*, void* sigcontext) { ThreadEntry* entry = ThreadEntry::Get(getpid(), gettid(), false); if (!entry) { @@ -151,9 +155,21 @@ bool BacktraceCurrent::UnwindThread(size_t num_ignore_frames) { // that we are waiting for the first Wake() call made by the thread. bool wait_completed = entry->Wait(1); + if (!wait_completed && oldact.sa_sigaction == nullptr) { + // If the wait failed, it could be that the signal could not be delivered + // within the timeout. Add a signal handler that's simply going to log + // something so that we don't crash if the signal eventually gets + // delivered. Only do this if there isn't already an action set up. + memset(&act, 0, sizeof(act)); + act.sa_sigaction = SignalLogOnly; + act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; + sigemptyset(&act.sa_mask); + sigaction(THREAD_SIGNAL, &act, nullptr); + } else { + sigaction(THREAD_SIGNAL, &oldact, nullptr); + } // After the thread has received the signal, allow other unwinders to // continue. - sigaction(THREAD_SIGNAL, &oldact, nullptr); pthread_mutex_unlock(&g_sigaction_mutex); bool unwind_done = false; diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp index d584925..823a842 100644 --- a/logd/FlushCommand.cpp +++ b/logd/FlushCommand.cpp @@ -72,7 +72,7 @@ void FlushCommand::runSocketCommand(SocketClient *client) { return; } entry = new LogTimeEntry(mReader, client, mNonBlock, mTail, mLogMask, mPid, mStart); - times.push_back(entry); + times.push_front(entry); } client->incRef(); diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index 0f5071b..d72a78c 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -217,29 +217,42 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, return len; } -// If we're using more than 256K of memory for log entries, prune -// at least 10% of the log entries. +// Prune at most 10% of the log entries or 256, whichever is less. // // mLogElementsLock must be held when this function is called. void LogBuffer::maybePrune(log_id_t id) { size_t sizes = stats.sizes(id); - if (sizes > log_buffer_size(id)) { - size_t sizeOver90Percent = sizes - ((log_buffer_size(id) * 9) / 10); + unsigned long maxSize = log_buffer_size(id); + if (sizes > maxSize) { + size_t sizeOver = sizes - ((maxSize * 9) / 10); size_t elements = stats.elements(id); - unsigned long pruneRows = elements * sizeOver90Percent / sizes; - elements /= 10; - if (pruneRows <= elements) { - pruneRows = elements; + size_t minElements = elements / 10; + unsigned long pruneRows = elements * sizeOver / sizes; + if (pruneRows <= minElements) { + pruneRows = minElements; + } + if (pruneRows > 256) { + pruneRows = 256; } prune(id, pruneRows); } } -LogBufferElementCollection::iterator LogBuffer::erase(LogBufferElementCollection::iterator it) { +LogBufferElementCollection::iterator LogBuffer::erase( + LogBufferElementCollection::iterator it, bool engageStats) { LogBufferElement *e = *it; + log_id_t id = e->getLogId(); + LogBufferIteratorMap::iterator f = mLastWorstUid[id].find(e->getUid()); + if ((f != mLastWorstUid[id].end()) && (it == f->second)) { + mLastWorstUid[id].erase(f); + } it = mLogElements.erase(it); - stats.subtract(e); + if (engageStats) { + stats.subtract(e); + } else { + stats.erase(e); + } delete e; return it; @@ -316,7 +329,51 @@ public: // prune "pruneRows" of type "id" from the buffer. // +// This garbage collection task is used to expire log entries. It is called to +// remove all logs (clear), all UID logs (unprivileged clear), or every +// 256 or 10% of the total logs (whichever is less) to prune the logs. +// +// First there is a prep phase where we discover the reader region lock that +// acts as a backstop to any pruning activity to stop there and go no further. +// +// There are three major pruning loops that follow. All expire from the oldest +// entries. Since there are multiple log buffers, the Android logging facility +// will appear to drop entries 'in the middle' when looking at multiple log +// sources and buffers. This effect is slightly more prominent when we prune +// the worst offender by logging source. Thus the logs slowly loose content +// and value as you move back in time. This is preferred since chatty sources +// invariably move the logs value down faster as less chatty sources would be +// expired in the noise. +// +// The first loop performs blacklisting and worst offender pruning. Falling +// through when there are no notable worst offenders and have not hit the +// region lock preventing further worst offender pruning. This loop also looks +// after managing the chatty log entries and merging to help provide +// statistical basis for blame. The chatty entries are not a notification of +// how much logs you may have, but instead represent how much logs you would +// have had in a virtual log buffer that is extended to cover all the in-memory +// logs without loss. They last much longer than the represented pruned logs +// since they get multiplied by the gains in the non-chatty log sources. +// +// The second loop get complicated because an algorithm of watermarks and +// history is maintained to reduce the order and keep processing time +// down to a minimum at scale. These algorithms can be costly in the face +// of larger log buffers, or severly limited processing time granted to a +// background task at lowest priority. +// +// This second loop does straight-up expiration from the end of the logs +// (again, remember for the specified log buffer id) but does some whitelist +// preservation. Thus whitelist is a Hail Mary low priority, blacklists and +// spam filtration all take priority. This second loop also checks if a region +// lock is causing us to buffer too much in the logs to help the reader(s), +// and will tell the slowest reader thread to skip log entries, and if +// persistent and hits a further threshold, kill the reader thread. +// +// The third thread is optional, and only gets hit if there was a whitelist +// and more needs to be pruned against the backstop of the region lock. +// // mLogElementsLock must be held when this function is called. +// void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { LogTimeEntry *oldest = NULL; @@ -378,7 +435,10 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { worst_sizes = sorted[0]->getSizes(); // Calculate threshold as 12.5% of available storage size_t threshold = log_buffer_size(id) / 8; - if (worst_sizes > threshold) { + if ((worst_sizes > threshold) + // Allow time horizon to extend roughly tenfold, assume + // average entry length is 100 characters. + && (worst_sizes > (10 * sorted[0]->getDropped()))) { worst = sorted[0]->getKey(); second_worst_sizes = sorted[1]->getSizes(); if (second_worst_sizes < threshold) { @@ -396,8 +456,28 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { bool kick = false; bool leading = true; + it = mLogElements.begin(); + // Perform at least one mandatory garbage collection cycle in following + // - clear leading chatty tags + // - merge chatty tags + // - check age-out of preserved logs + bool gc = pruneRows <= 1; + if (!gc && (worst != (uid_t) -1)) { + LogBufferIteratorMap::iterator f = mLastWorstUid[id].find(worst); + if ((f != mLastWorstUid[id].end()) + && (f->second != mLogElements.end())) { + leading = false; + it = f->second; + } + } + static const timespec too_old = { + EXPIRE_HOUR_THRESHOLD * 60 * 60, 0 + }; + LogBufferElementCollection::iterator lastt; + lastt = mLogElements.end(); + --lastt; LogBufferElementLast last; - for(it = mLogElements.begin(); it != mLogElements.end();) { + while (it != mLogElements.end()) { LogBufferElement *e = *it; if (oldest && (oldest->mStart <= e->getSequence())) { @@ -419,9 +499,7 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { // merge any drops if (dropped && last.merge(e, dropped)) { - it = mLogElements.erase(it); - stats.erase(e); - delete e; + it = erase(it, false); continue; } @@ -447,25 +525,24 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { continue; } + if ((e->getRealTime() < ((*lastt)->getRealTime() - too_old)) + || (e->getRealTime() > (*lastt)->getRealTime())) { + break; + } + + // unmerged drop message if (dropped) { last.add(e); + if ((!gc && (e->getUid() == worst)) + || (mLastWorstUid[id].find(e->getUid()) + == mLastWorstUid[id].end())) { + mLastWorstUid[id][e->getUid()] = it; + } ++it; continue; } if (e->getUid() != worst) { - if (leading) { - static const timespec too_old = { - EXPIRE_HOUR_THRESHOLD * 60 * 60, 0 - }; - LogBufferElementCollection::iterator last; - last = mLogElements.end(); - --last; - if ((e->getRealTime() < ((*last)->getRealTime() - too_old)) - || (e->getRealTime() > (*last)->getRealTime())) { - break; - } - } leading = false; last.clear(e); ++it; @@ -488,11 +565,13 @@ void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { stats.drop(e); e->setDropped(1); if (last.merge(e, 1)) { - it = mLogElements.erase(it); - stats.erase(e); - delete e; + it = erase(it, false); } else { last.add(e); + if (!gc || (mLastWorstUid[id].find(worst) + == mLastWorstUid[id].end())) { + mLastWorstUid[id][worst] = it; + } ++it; } } diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h index a13fded..4769a6c 100644 --- a/logd/LogBuffer.h +++ b/logd/LogBuffer.h @@ -19,9 +19,10 @@ #include <sys/types.h> +#include <list> + #include <log/log.h> #include <sysutils/SocketClient.h> -#include <utils/List.h> #include <private/android_filesystem_config.h> @@ -30,7 +31,7 @@ #include "LogStatistics.h" #include "LogWhiteBlackList.h" -typedef android::List<LogBufferElement *> LogBufferElementCollection; +typedef std::list<LogBufferElement *> LogBufferElementCollection; class LogBuffer { LogBufferElementCollection mLogElements; @@ -39,6 +40,11 @@ class LogBuffer { LogStatistics stats; PruneList mPrune; + // watermark of any worst/chatty uid processing + typedef std::unordered_map<uid_t, + LogBufferElementCollection::iterator> + LogBufferIteratorMap; + LogBufferIteratorMap mLastWorstUid[LOG_ID_MAX]; unsigned long mMaxSize[LOG_ID_MAX]; @@ -81,7 +87,8 @@ public: private: void maybePrune(log_id_t id); void prune(log_id_t id, unsigned long pruneRows, uid_t uid = AID_ROOT); - LogBufferElementCollection::iterator erase(LogBufferElementCollection::iterator it); + LogBufferElementCollection::iterator erase( + LogBufferElementCollection::iterator it, bool engageStats = true); }; #endif // _LOGD_LOG_BUFFER_H__ diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp index d578c04..0a5df24 100644 --- a/logd/LogKlog.cpp +++ b/logd/LogKlog.cpp @@ -43,10 +43,12 @@ static char *is_prio(char *s) { if (!isdigit(*s++)) { return NULL; } + static const size_t max_prio_len = 4; + size_t len = 0; char c; - while ((c = *s++)) { + while (((c = *s++)) && (++len <= max_prio_len)) { if (!isdigit(c)) { - return (c == '>') ? s : NULL; + return ((c == '>') && (*s == '[')) ? s : NULL; } } return NULL; @@ -73,7 +75,7 @@ static char *is_timestamp(char *s) { } // Like strtok_r with "\r\n" except that we look for log signatures (regex) -// \(\(<[0-9]+>\)\([[] *[0-9]+[.][0-9]+[]] \)\{0,1\}\|[[] *[0-9]+[.][0-9]+[]] \) +// \(\(<[0-9]\{1,4\}>\)\([[] *[0-9]+[.][0-9]+[]] \)\{0,1\}\|[[] *[0-9]+[.][0-9]+[]] \) // and split if we see a second one without a newline. #define SIGNATURE_MASK 0xF0 @@ -165,7 +167,7 @@ char *log_strtok_r(char *s, char **last) { break; } } - /* NOTREACHED */ + // NOTREACHED } log_time LogKlog::correction = log_time(CLOCK_REALTIME) - log_time(CLOCK_MONOTONIC); @@ -254,6 +256,7 @@ void LogKlog::sniffTime(log_time &now, const char **buf, bool reverse) { if ((cp = now.strptime(*buf, "[ %s.%q]"))) { static const char suspend[] = "PM: suspend entry "; static const char resume[] = "PM: suspend exit "; + static const char healthd[] = "healthd: battery "; static const char suspended[] = "Suspended for "; if (isspace(*cp)) { @@ -263,6 +266,15 @@ void LogKlog::sniffTime(log_time &now, const char **buf, bool reverse) { calculateCorrection(now, cp + sizeof(suspend) - 1); } else if (!strncmp(cp, resume, sizeof(resume) - 1)) { calculateCorrection(now, cp + sizeof(resume) - 1); + } else if (!strncmp(cp, healthd, sizeof(healthd) - 1)) { + // look for " 2???-??-?? ??:??:??.????????? ???" + const char *tp; + for (tp = cp + sizeof(healthd) - 1; *tp && (*tp != '\n'); ++tp) { + if ((tp[0] == ' ') && (tp[1] == '2') && (tp[5] == '-')) { + calculateCorrection(now, tp + 1); + break; + } + } } else if (!strncmp(cp, suspended, sizeof(suspended) - 1)) { log_time real; char *endp; @@ -284,6 +296,22 @@ void LogKlog::sniffTime(log_time &now, const char **buf, bool reverse) { } } +pid_t LogKlog::sniffPid(const char *cp) { + while (*cp) { + // Mediatek kernels with modified printk + if (*cp == '[') { + int pid = 0; + char dummy; + if (sscanf(cp, "[%d:%*[a-z_./0-9:A-Z]]%c", &pid, &dummy) == 2) { + return pid; + } + break; // Only the first one + } + ++cp; + } + return 0; +} + // Passed the entire SYSLOG_ACTION_READ_ALL buffer and interpret a // compensated start time. void LogKlog::synchronize(const char *buf) { @@ -407,9 +435,9 @@ int LogKlog::log(const char *buf) { // sniff for start marker const char klogd_message[] = "logd.klogd: "; - if (!strncmp(buf, klogd_message, sizeof(klogd_message) - 1)) { - char *endp; - uint64_t sig = strtoll(buf + sizeof(klogd_message) - 1, &endp, 10); + const char *start = strstr(buf, klogd_message); + if (start) { + uint64_t sig = strtoll(start + sizeof(klogd_message) - 1, NULL, 10); if (sig == signature.nsec()) { if (initialized) { enableLogging = true; @@ -425,10 +453,10 @@ int LogKlog::log(const char *buf) { return 0; } - // Parse pid, tid and uid (not possible) - const pid_t pid = 0; - const pid_t tid = 0; - const uid_t uid = 0; + // Parse pid, tid and uid + const pid_t pid = sniffPid(buf); + const pid_t tid = pid; + const uid_t uid = pid ? logbuf->pidToUid(pid) : 0; // Parse (rules at top) to pull out a tag from the incoming kernel message. // Some may view the following as an ugly heuristic, the desire is to @@ -440,7 +468,7 @@ int LogKlog::log(const char *buf) { if (!*buf) { return 0; } - const char *start = buf; + start = buf; const char *tag = ""; const char *etag = tag; if (!isspace(*buf)) { @@ -451,7 +479,14 @@ int LogKlog::log(const char *buf) { // <PRI>[<TIME>] "[INFO]"<tag> ":" message bt = buf + 6; } - for(et = bt; *et && (*et != ':') && !isspace(*et); ++et); + for(et = bt; *et && (*et != ':') && !isspace(*et); ++et) { + // skip ':' within [ ... ] + if (*et == '[') { + while (*et && *et != ']') { + ++et; + } + } + } for(cp = et; isspace(*cp); ++cp); size_t size; @@ -465,7 +500,7 @@ int LogKlog::log(const char *buf) { if (strncmp(bt, cp, size)) { // <PRI>[<TIME>] <tag>_host '<tag>.<num>' : message if (!strncmp(bt + size - 5, "_host", 5) - && !strncmp(bt, cp, size - 5)) { + && !strncmp(bt, cp, size - 5)) { const char *b = cp; cp += size - 5; if (*cp == '.') { @@ -535,16 +570,30 @@ int LogKlog::log(const char *buf) { } size = etag - tag; if ((size <= 1) - || ((size == 2) && (isdigit(tag[0]) || isdigit(tag[1]))) - || ((size == 3) && !strncmp(tag, "CPU", 3)) - || ((size == 7) && !strncmp(tag, "WARNING", 7)) - || ((size == 5) && !strncmp(tag, "ERROR", 5)) - || ((size == 4) && !strncmp(tag, "INFO", 4))) { + // register names like x9 + || ((size == 2) && (isdigit(tag[0]) || isdigit(tag[1]))) + // register names like x18 but not driver names like en0 + || ((size == 3) && (isdigit(tag[1]) && isdigit(tag[2]))) + // blacklist + || ((size == 3) && !strncmp(tag, "CPU", 3)) + || ((size == 7) && !strncmp(tag, "WARNING", 7)) + || ((size == 5) && !strncmp(tag, "ERROR", 5)) + || ((size == 4) && !strncmp(tag, "INFO", 4))) { buf = start; etag = tag = ""; } } - size_t l = etag - tag; + // Suppress additional stutter in tag: + // eg: [143:healthd]healthd -> [143:healthd] + size_t taglen = etag - tag; + // Mediatek-special printk induced stutter + char *np = strrchr(tag, ']'); + if (np && (++np < etag)) { + size_t s = etag - np; + if (((s + s) < taglen) && !strncmp(np, np - 1 - s, s)) { + taglen = np - tag; + } + } // skip leading space while (isspace(*buf)) { ++buf; @@ -555,11 +604,11 @@ int LogKlog::log(const char *buf) { --b; } // trick ... allow tag with empty content to be logged. log() drops empty - if (!b && l) { + if (!b && taglen) { buf = " "; b = 1; } - size_t n = 1 + l + 1 + b + 1; + size_t n = 1 + taglen + 1 + b + 1; // Allocate a buffer to hold the interpreted log message int rc = n; @@ -568,15 +617,15 @@ int LogKlog::log(const char *buf) { rc = -ENOMEM; return rc; } - char *np = newstr; + np = newstr; // Convert priority into single-byte Android logger priority *np = convertKernelPrioToAndroidPrio(pri); ++np; // Copy parsed tag following priority - strncpy(np, tag, l); - np += l; + strncpy(np, tag, taglen); + np += taglen; *np = '\0'; ++np; diff --git a/logd/LogKlog.h b/logd/LogKlog.h index a898c63..081d344 100644 --- a/logd/LogKlog.h +++ b/logd/LogKlog.h @@ -49,6 +49,7 @@ public: protected: void sniffTime(log_time &now, const char **buf, bool reverse); + pid_t sniffPid(const char *buf); void calculateCorrection(const log_time &monotonic, const char *real_string); virtual bool onDataAvailable(SocketClient *cli); diff --git a/logd/LogTimes.h b/logd/LogTimes.h index 783bce6..39bcdd4 100644 --- a/logd/LogTimes.h +++ b/logd/LogTimes.h @@ -20,8 +20,10 @@ #include <pthread.h> #include <time.h> #include <sys/types.h> + +#include <list> + #include <sysutils/SocketClient.h> -#include <utils/List.h> #include <log/log.h> class LogReader; @@ -107,6 +109,6 @@ public: static int FilterSecondPass(const LogBufferElement *element, void *me); }; -typedef android::List<LogTimeEntry *> LastLogTimes; +typedef std::list<LogTimeEntry *> LastLogTimes; -#endif +#endif // _LOGD_LOG_TIMES_H__ diff --git a/logd/LogWhiteBlackList.cpp b/logd/LogWhiteBlackList.cpp index 277b3ca..16dd6d2 100644 --- a/logd/LogWhiteBlackList.cpp +++ b/logd/LogWhiteBlackList.cpp @@ -50,18 +50,14 @@ void Prune::format(char **strp) { } PruneList::PruneList() : mWorstUidEnabled(true) { - mNaughty.clear(); - mNice.clear(); } PruneList::~PruneList() { PruneCollection::iterator it; for (it = mNice.begin(); it != mNice.end();) { - delete (*it); it = mNice.erase(it); } for (it = mNaughty.begin(); it != mNaughty.end();) { - delete (*it); it = mNaughty.erase(it); } } @@ -70,11 +66,9 @@ int PruneList::init(char *str) { mWorstUidEnabled = true; PruneCollection::iterator it; for (it = mNice.begin(); it != mNice.end();) { - delete (*it); it = mNice.erase(it); } for (it = mNaughty.begin(); it != mNaughty.end();) { - delete (*it); it = mNaughty.erase(it); } @@ -142,28 +136,28 @@ int PruneList::init(char *str) { // insert sequentially into list PruneCollection::iterator it = list->begin(); while (it != list->end()) { - Prune *p = *it; - int m = uid - p->mUid; + Prune &p = *it; + int m = uid - p.mUid; if (m == 0) { - if (p->mPid == p->pid_all) { + if (p.mPid == p.pid_all) { break; } - if ((pid == p->pid_all) && (p->mPid != p->pid_all)) { + if ((pid == p.pid_all) && (p.mPid != p.pid_all)) { it = list->erase(it); continue; } - m = pid - p->mPid; + m = pid - p.mPid; } if (m <= 0) { if (m < 0) { - list->insert(it, new Prune(uid,pid)); + list->insert(it, Prune(uid,pid)); } break; } ++it; } if (it == list->end()) { - list->push_back(new Prune(uid,pid)); + list->push_back(Prune(uid,pid)); } if (!*str) { break; @@ -193,7 +187,7 @@ void PruneList::format(char **strp) { for (it = mNice.begin(); it != mNice.end(); ++it) { char *a = NULL; - (*it)->format(&a); + (*it).format(&a); string.appendFormat(fmt, a); fmt = nice_format; @@ -205,7 +199,7 @@ void PruneList::format(char **strp) { fmt = naughty_format + (*fmt != ' '); for (it = mNaughty.begin(); it != mNaughty.end(); ++it) { char *a = NULL; - (*it)->format(&a); + (*it).format(&a); string.appendFormat(fmt, a); fmt = naughty_format; @@ -223,7 +217,7 @@ void PruneList::format(char **strp) { bool PruneList::naughty(LogBufferElement *element) { PruneCollection::iterator it; for (it = mNaughty.begin(); it != mNaughty.end(); ++it) { - if (!(*it)->cmp(element)) { + if (!(*it).cmp(element)) { return true; } } @@ -233,7 +227,7 @@ bool PruneList::naughty(LogBufferElement *element) { bool PruneList::nice(LogBufferElement *element) { PruneCollection::iterator it; for (it = mNice.begin(); it != mNice.end(); ++it) { - if (!(*it)->cmp(element)) { + if (!(*it).cmp(element)) { return true; } } diff --git a/logd/LogWhiteBlackList.h b/logd/LogWhiteBlackList.h index 5f60801..57cd03b 100644 --- a/logd/LogWhiteBlackList.h +++ b/logd/LogWhiteBlackList.h @@ -19,7 +19,7 @@ #include <sys/types.h> -#include <utils/List.h> +#include <list> #include <LogBufferElement.h> @@ -47,7 +47,7 @@ public: void format(char **strp); }; -typedef android::List<Prune *> PruneCollection; +typedef std::list<Prune> PruneCollection; class PruneList { PruneCollection mNaughty; diff --git a/rootdir/init.rc b/rootdir/init.rc index b71908c..317207c 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -7,6 +7,7 @@ import /init.environ.rc import /init.usb.rc import /init.${ro.hardware}.rc +import /init.usb.configfs.rc import /init.${ro.zygote}.rc import /init.trace.rc @@ -88,10 +89,17 @@ on init write /proc/sys/kernel/panic_on_oops 1 write /proc/sys/kernel/hung_task_timeout_secs 0 write /proc/cpu/alignment 4 + + # scheduler tunables + # Disable auto-scaling of scheduler tunables with hotplug. The tunables + # will vary across devices in unpredictable ways if allowed to scale with + # cpu cores. + write /proc/sys/kernel/sched_tunable_scaling 0 write /proc/sys/kernel/sched_latency_ns 10000000 write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000 write /proc/sys/kernel/sched_compat_yield 1 write /proc/sys/kernel/sched_child_runs_first 0 + write /proc/sys/kernel/randomize_va_space 2 write /proc/sys/kernel/kptr_restrict 2 write /proc/sys/vm/mmap_min_addr 32768 @@ -132,21 +140,37 @@ on init # sets up initial cpusets for ActivityManager mkdir /dev/cpuset mount cpuset none /dev/cpuset - mkdir /dev/cpuset/foreground - mkdir /dev/cpuset/background + # this ensures that the cpusets are present and usable, but the device's # init.rc must actually set the correct cpus + mkdir /dev/cpuset/foreground write /dev/cpuset/foreground/cpus 0 - write /dev/cpuset/background/cpus 0 write /dev/cpuset/foreground/mems 0 + mkdir /dev/cpuset/foreground/boost + write /dev/cpuset/foreground/boost/cpus 0 + write /dev/cpuset/foreground/boost/mems 0 + mkdir /dev/cpuset/background + write /dev/cpuset/background/cpus 0 write /dev/cpuset/background/mems 0 + + # system-background is for system tasks that should only run on + # little cores, not on bigs + # to be used only by init, so don't change system-bg permissions + mkdir /dev/cpuset/system-background + write /dev/cpuset/system-background/cpus 0 + write /dev/cpuset/system-background/mems 0 + + # change permissions for all cpusets we'll touch at runtime chown system system /dev/cpuset chown system system /dev/cpuset/foreground + chown system system /dev/cpuset/foreground/boost chown system system /dev/cpuset/background chown system system /dev/cpuset/tasks chown system system /dev/cpuset/foreground/tasks + chown system system /dev/cpuset/foreground/boost/tasks chown system system /dev/cpuset/background/tasks chmod 0664 /dev/cpuset/foreground/tasks + chmod 0664 /dev/cpuset/foreground/boost/tasks chmod 0664 /dev/cpuset/background/tasks chmod 0664 /dev/cpuset/tasks @@ -182,8 +206,11 @@ on property:sys.boot_from_charger_mode=1 trigger late-init # Load properties from /system/ + /factory after fs mount. -on load_all_props_action - load_all_props +on load_system_props_action + load_system_props + +on load_persist_props_action + load_persist_props start logd start logd-reinit @@ -196,12 +223,16 @@ on late-init trigger early-fs trigger fs trigger post-fs - trigger post-fs-data # Load properties from /system/ + /factory after fs mount. Place # this in another action so that the load will be scheduled after the prior # issued fs triggers have completed. - trigger load_all_props_action + trigger load_system_props_action + + # Now we can mount /data. File encryption requires keymaster to decrypt + # /data, which in turn can only be loaded when system properties are present + trigger post-fs-data + trigger load_persist_props_action # Remove a file to wake up anything waiting for firmware. trigger firmware_mounts_complete @@ -352,6 +383,8 @@ on post-fs-data mkdir /data/system/heapdump 0700 system system mkdir /data/user 0711 system system + setusercryptopolicies /data/user + # Reload policy from /data/security if present. setprop selinux.reload_policy 1 @@ -525,9 +558,11 @@ service logd /system/bin/logd socket logdr seqpacket 0666 logd logd socket logdw dgram 0222 logd logd group root system + writepid /dev/cpuset/system-background/tasks service logd-reinit /system/bin/logd --reinit oneshot + writepid /dev/cpuset/system-background/tasks disabled service healthd /sbin/healthd @@ -562,6 +597,7 @@ service lmkd /system/bin/lmkd class core critical socket lmkd seqpacket 0660 system system + writepid /dev/cpuset/system-background/tasks service servicemanager /system/bin/servicemanager class core @@ -591,9 +627,11 @@ service netd /system/bin/netd service debuggerd /system/bin/debuggerd class main + writepid /dev/cpuset/system-background/tasks service debuggerd64 /system/bin/debuggerd64 class main + writepid /dev/cpuset/system-background/tasks service ril-daemon /system/bin/rild class main @@ -608,6 +646,7 @@ service surfaceflinger /system/bin/surfaceflinger user system group graphics drmrpc onrestart restart zygote + writepid /dev/cpuset/system-background/tasks service drm /system/bin/drmserver class main @@ -628,7 +667,7 @@ service defaultcrypto /system/bin/vdc --wait cryptfs mountdefaultencrypted # encryption) or trigger_restart_min_framework (other encryption) # One shot invocation to encrypt unencrypted volumes -service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default +service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default noui disabled oneshot # vold will set vold.decrypt to trigger_restart_framework (default @@ -702,6 +741,7 @@ service perfprofd /system/xbin/perfprofd class late_start user root oneshot + writepid /dev/cpuset/system-background/tasks on property:persist.logd.logpersistd=logcatd # all exec/services are called with umask(077), so no gain beyond 0700 @@ -716,3 +756,4 @@ service logcatd /system/bin/logcat -b all -v threadtime -v usec -v printable -D # logd for write to /data/misc/logd, log group for read from log daemon user logd group log + writepid /dev/cpuset/system-background/tasks diff --git a/rootdir/init.usb.configfs.rc b/rootdir/init.usb.configfs.rc new file mode 100644 index 0000000..186384b --- /dev/null +++ b/rootdir/init.usb.configfs.rc @@ -0,0 +1,175 @@ +on property:sys.usb.config=none && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/UDC "none" + stop adbd + write /config/usb_gadget/g1/bDeviceClass 0 + write /config/usb_gadget/g1/bDeviceSubClass 0 + write /config/usb_gadget/g1/bDeviceProtocol 0 + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=adb && property:sys.usb.configfs=1 + start adbd + +on property:sys.usb.ffs.ready=1 && property:sys.usb.config=adb && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=mtp && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1 + start adbd + +on property:sys.usb.ffs.ready=1 && property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp_adb" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1 + symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=ptp && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "ptp" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1 + start adbd + +on property:sys.usb.ffs.ready=1 && property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "ptp_adb" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1 + symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=accessory && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "accessory" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=accessory,adb && property:sys.usb.configfs=1 + start adbd + +on property:sys.usb.ffs.ready=1 && property:sys.usb.config=accessory,adb && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "accessory_adb" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1 + symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=audio_source && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "audiosource" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/audio_source.gs2 /config/usb_gadget/g1/configs/b.1/f1 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=audio_source,adb && property:sys.usb.configfs=1 + start adbd + +on property:sys.usb.ffs.ready=1 && property:sys.usb.config=audio_source,adb && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "audiosource_adb" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/audio_source.gs2 /config/usb_gadget/g1/configs/b.1/f1 + symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=accessory,audio_source && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "accessory_audiosource" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1 + symlink /config/usb_gadget/g1/functions/audio_source.gs3 /config/usb_gadget/g1/configs/b.1/f2 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=accessory,audio_source,adb && property:sys.usb.configfs=1 + start adbd + +on property:sys.usb.ffs.ready=1 && property:sys.usb.config=accessory,audio_source,adb && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "accessory_audiosource_adb" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/accessory.gs2 /config/usb_gadget/g1/configs/b.1/f1 + symlink /config/usb_gadget/g1/functions/audio_source.gs3 /config/usb_gadget/g1/configs/b.1/f2 + symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f3 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=midi && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "midi" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/midi.gs5 /config/usb_gadget/g1/configs/b.1/f1 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=midi,adb && property:sys.usb.configfs=1 + start adbd + +on property:sys.usb.ffs.ready=1 && property:sys.usb.config=midi,adb && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "midi_adb" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/midi.gs5 /config/usb_gadget/g1/configs/b.1/f1 + symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=rndis && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "rndis" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/rndis.gs4 /config/usb_gadget/g1/configs/b.1/f1 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + +on property:sys.usb.config=rndis,adb && property:sys.usb.configfs=1 + start adbd + +on property:sys.usb.ffs.ready=1 && property:sys.usb.config=rndis,adb && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "rndis_adb" + rm /config/usb_gadget/g1/configs/b.1/f1 + rm /config/usb_gadget/g1/configs/b.1/f2 + rm /config/usb_gadget/g1/configs/b.1/f3 + symlink /config/usb_gadget/g1/functions/rndis.gs4 /config/usb_gadget/g1/configs/b.1/f1 + symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} diff --git a/rootdir/init.usb.rc b/rootdir/init.usb.rc index e290ca4..a105afe 100644 --- a/rootdir/init.usb.rc +++ b/rootdir/init.usb.rc @@ -9,8 +9,11 @@ on post-fs-data chown system system /sys/class/android_usb/android0/f_rndis/ethaddr chmod 0660 /sys/class/android_usb/android0/f_rndis/ethaddr +on boot + setprop sys.usb.configfs 0 + # Used to disable USB when switching states -on property:sys.usb.config=none +on property:sys.usb.config=none && property:sys.usb.configfs=0 stop adbd write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/bDeviceClass 0 @@ -19,7 +22,7 @@ on property:sys.usb.config=none # adb only USB configuration # This is the fallback configuration if the # USB manager fails to set a standard configuration -on property:sys.usb.config=adb +on property:sys.usb.config=adb && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18d1 write /sys/class/android_usb/android0/idProduct 4EE7 @@ -29,7 +32,7 @@ on property:sys.usb.config=adb setprop sys.usb.state ${sys.usb.config} # USB accessory configuration -on property:sys.usb.config=accessory +on property:sys.usb.config=accessory && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18d1 write /sys/class/android_usb/android0/idProduct 2d00 @@ -38,7 +41,7 @@ on property:sys.usb.config=accessory setprop sys.usb.state ${sys.usb.config} # USB accessory configuration, with adb -on property:sys.usb.config=accessory,adb +on property:sys.usb.config=accessory,adb && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18d1 write /sys/class/android_usb/android0/idProduct 2d01 @@ -48,7 +51,7 @@ on property:sys.usb.config=accessory,adb setprop sys.usb.state ${sys.usb.config} # audio accessory configuration -on property:sys.usb.config=audio_source +on property:sys.usb.config=audio_source && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18d1 write /sys/class/android_usb/android0/idProduct 2d02 @@ -57,7 +60,7 @@ on property:sys.usb.config=audio_source setprop sys.usb.state ${sys.usb.config} # audio accessory configuration, with adb -on property:sys.usb.config=audio_source,adb +on property:sys.usb.config=audio_source,adb && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18d1 write /sys/class/android_usb/android0/idProduct 2d03 @@ -67,7 +70,7 @@ on property:sys.usb.config=audio_source,adb setprop sys.usb.state ${sys.usb.config} # USB and audio accessory configuration -on property:sys.usb.config=accessory,audio_source +on property:sys.usb.config=accessory,audio_source && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18d1 write /sys/class/android_usb/android0/idProduct 2d04 @@ -76,7 +79,7 @@ on property:sys.usb.config=accessory,audio_source setprop sys.usb.state ${sys.usb.config} # USB and audio accessory configuration, with adb -on property:sys.usb.config=accessory,audio_source,adb +on property:sys.usb.config=accessory,audio_source,adb && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18d1 write /sys/class/android_usb/android0/idProduct 2d05 @@ -89,3 +92,34 @@ on property:sys.usb.config=accessory,audio_source,adb # when changing the default configuration on property:persist.sys.usb.config=* setprop sys.usb.config ${persist.sys.usb.config} + +# +# USB type C +# + +# USB mode changes +on property:sys.usb.typec.mode=dfp + write /sys/class/dual_role_usb/otg_default/mode ${sys.usb.typec.mode} + setprop sys.usb.typec.state ${sys.usb.typec.mode} + +on property:sys.usb.typec.mode=ufp + write /sys/class/dual_role_usb/otg_default/mode ${sys.usb.typec.mode} + setprop sys.usb.typec.state ${sys.usb.typec.mode} + +# USB data role changes +on property:sys.usb.typec.data_role=device + write /sys/class/dual_role_usb/otg_default/data_role ${sys.usb.typec.data_role} + setprop sys.usb.typec.state ${sys.usb.typec.data_role} + +on property:sys.usb.typec.data_role=host + write /sys/class/dual_role_usb/otg_default/data_role ${sys.usb.typec.data_role} + setprop sys.usb.typec.state ${sys.usb.typec.data_role} + +# USB power role changes +on property:sys.usb.typec.power_role=source + write /sys/class/dual_role_usb/otg_default/power_role ${sys.usb.typec.power_role} + setprop sys.usb.typec.state ${sys.usb.typec.power_role} + +on property:sys.usb.typec.power_role=sink + write /sys/class/dual_role_usb/otg_default/power_role ${sys.usb.typec.power_role} + setprop sys.usb.typec.state ${sys.usb.typec.power_role} diff --git a/rootdir/init.zygote32.rc b/rootdir/init.zygote32.rc index 75961e6..ff25ac2 100644 --- a/rootdir/init.zygote32.rc +++ b/rootdir/init.zygote32.rc @@ -5,4 +5,4 @@ service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-sys onrestart write /sys/power/state on onrestart restart media onrestart restart netd - + writepid /dev/cpuset/foreground/tasks diff --git a/rootdir/init.zygote32_64.rc b/rootdir/init.zygote32_64.rc index 68c0668..29bb1cf 100644 --- a/rootdir/init.zygote32_64.rc +++ b/rootdir/init.zygote32_64.rc @@ -5,8 +5,10 @@ service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-s onrestart write /sys/power/state on onrestart restart media onrestart restart netd + writepid /dev/cpuset/foreground/tasks service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary class main socket zygote_secondary stream 660 root system onrestart restart zygote + writepid /dev/cpuset/foreground/tasks
\ No newline at end of file diff --git a/rootdir/init.zygote64.rc b/rootdir/init.zygote64.rc index afb6d63..5497524 100644 --- a/rootdir/init.zygote64.rc +++ b/rootdir/init.zygote64.rc @@ -5,4 +5,4 @@ service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-s onrestart write /sys/power/state on onrestart restart media onrestart restart netd - + writepid /dev/cpuset/foreground/tasks diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc index 979ab3b..8ed5e9e 100644 --- a/rootdir/init.zygote64_32.rc +++ b/rootdir/init.zygote64_32.rc @@ -5,8 +5,10 @@ service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-s onrestart write /sys/power/state on onrestart restart media onrestart restart netd + writepid /dev/cpuset/foreground/tasks service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary class main socket zygote_secondary stream 660 root system onrestart restart zygote + writepid /dev/cpuset/foreground/tasks
\ No newline at end of file |