diff options
-rw-r--r-- | fastboot/fastboot.cpp | 56 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_verity.c | 70 | ||||
-rw-r--r-- | healthd/BatteryMonitor.cpp | 14 | ||||
-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 | 17 | ||||
-rw-r--r-- | init/property_service.h | 2 | ||||
-rw-r--r-- | libbacktrace/BacktraceCurrent.cpp | 18 | ||||
-rw-r--r-- | libutils/tests/Vector_test.cpp | 2 | ||||
-rw-r--r-- | logd/FlushCommand.cpp | 2 | ||||
-rw-r--r-- | logd/LogBuffer.cpp | 134 | ||||
-rw-r--r-- | logd/LogBuffer.h | 13 | ||||
-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 | 45 | ||||
-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 |
23 files changed, 587 insertions, 142 deletions
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index 4730d70..4b3758a 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -282,17 +282,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" @@ -834,6 +839,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]; @@ -1233,12 +1259,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 688348e..2e61b73 100644 --- a/healthd/BatteryMonitor.cpp +++ b/healthd/BatteryMonitor.cpp @@ -191,6 +191,7 @@ bool BatteryMonitor::update(void) { props.chargerDockAcOnline = false; props.batteryStatus = BATTERY_STATUS_UNKNOWN; props.batteryHealth = BATTERY_HEALTH_UNKNOWN; + props.maxChargingCurrent = 0; props.dockBatteryStatus = BATTERY_STATUS_UNKNOWN; props.dockBatteryHealth = BATTERY_HEALTH_UNKNOWN; @@ -297,6 +298,15 @@ bool BatteryMonitor::update(void) { KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n", name); } + path.clear(); + path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH, + name); + if (access(path.string(), R_OK) == 0) { + int maxChargingCurrent = getIntField(path); + if (props.maxChargingCurrent < maxChargingCurrent) { + props.maxChargingCurrent = maxChargingCurrent; + } + } } } } @@ -516,9 +526,9 @@ void BatteryMonitor::dumpState(int fd) { int v; char vs[128]; - snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d dock-ac: %d\n", + snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d dock-ac: %d current_max: %d\n", props.chargerAcOnline, props.chargerUsbOnline, - props.chargerWirelessOnline, props.chargerDockAcOnline); + props.chargerWirelessOnline, props.chargerDockAcOnline, props.maxChargingCurrent); write(fd, vs, strlen(vs)); snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n", props.batteryStatus, props.batteryHealth, props.batteryPresent); diff --git a/init/builtins.cpp b/init/builtins.cpp index bab30d7..9901786 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -816,9 +816,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; @@ -846,18 +846,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 c760f53..c36d36e 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; @@ -188,6 +188,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; @@ -573,7 +574,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:"))) { @@ -587,29 +588,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 a5048f4..303685d 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) @@ -87,6 +88,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 001aa1d..11ff06b 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -519,6 +519,11 @@ void load_persist_props(void) { load_override_properties(); /* Read persistent properties after all default values have been loaded. */ load_persistent_properties(); + + /* update with vendor-specific property runtime + * overrides + */ + vendor_load_properties(); } void load_recovery_id_prop() { @@ -561,21 +566,11 @@ 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(); - - /* update with vendor-specific property runtime - * overrides - */ - vendor_load_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/libutils/tests/Vector_test.cpp b/libutils/tests/Vector_test.cpp index 09914bd..96d3168 100644 --- a/libutils/tests/Vector_test.cpp +++ b/libutils/tests/Vector_test.cpp @@ -16,6 +16,8 @@ #define LOG_TAG "Vector_test" +#define __STDC_LIMIT_MACROS +#include <stdint.h> #include <utils/Vector.h> #include <cutils/log.h> #include <gtest/gtest.h> 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..559fa2e 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; @@ -396,8 +453,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 +496,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 +522,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 +562,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/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 d0dd0de..99e3d82 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 316cf4c..4b644bc 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 # Include CM's extra init file @@ -92,10 +93,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 @@ -137,20 +145,32 @@ on init mkdir /dev/cpuset mount cpuset none /dev/cpuset mkdir /dev/cpuset/foreground + mkdir /dev/cpuset/foreground/boost mkdir /dev/cpuset/background + # 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 the permissions + mkdir /dev/cpuset/system-background # this ensures that the cpusets are present and usable, but the device's # init.rc must actually set the correct cpus write /dev/cpuset/foreground/cpus 0 + write /dev/cpuset/foreground/boost/cpus 0 write /dev/cpuset/background/cpus 0 + write /dev/cpuset/system-background/cpus 0 write /dev/cpuset/foreground/mems 0 + write /dev/cpuset/foreground/boost/mems 0 write /dev/cpuset/background/mems 0 + write /dev/cpuset/system-background/mems 0 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 @@ -186,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 @@ -200,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 @@ -356,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 @@ -532,9 +561,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 @@ -569,6 +600,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 @@ -598,9 +630,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 @@ -615,6 +649,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 @@ -714,6 +749,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 @@ -728,3 +764,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 |