static bool property_get_bool_svelte(const char *key) { bool not_user; { char property[PROPERTY_VALUE_MAX]; property_get("ro.build.type", property, ""); not_user = !!strcmp(property, "user"); } return property_get_bool(key, not_user && !property_get_bool("ro.config.low_ram", false)); }
bool property_get_bool(const char *key, int flag) { char def[PROPERTY_VALUE_MAX]; char property[PROPERTY_VALUE_MAX]; def[0] = '\0'; if (flag & BOOL_DEFAULT_FLAG_PERSIST) { char newkey[PROPERTY_KEY_MAX]; snprintf(newkey, sizeof(newkey), "ro.%s", key); property_get(newkey, property, ""); // persist properties set by /data require innoculation with // logd-reinit. They may be set in init.rc early and function, but // otherwise are defunct unless reset. Do not rely on persist // properties for startup-only keys unless you are willing to restart // logd daemon (not advised). snprintf(newkey, sizeof(newkey), "persist.%s", key); property_get(newkey, def, property); } property_get(key, property, def); if (check_flag(property, "true")) { return true; } if (check_flag(property, "false")) { return false; } if (check_flag(property, "eng")) { flag |= BOOL_DEFAULT_FLAG_ENG; } // this is really a "not" flag if (check_flag(property, "svelte")) { flag |= BOOL_DEFAULT_FLAG_SVELTE; } // Sanity Check if (flag & (BOOL_DEFAULT_FLAG_SVELTE | BOOL_DEFAULT_FLAG_ENG)) { flag &= ~BOOL_DEFAULT_FLAG_TRUE_FALSE; flag |= BOOL_DEFAULT_TRUE; } if ((flag & BOOL_DEFAULT_FLAG_SVELTE) && property_get_bool("ro.config.low_ram", BOOL_DEFAULT_FALSE)) { return false; } if (flag & BOOL_DEFAULT_FLAG_ENG) { property_get("ro.debuggable", property, ""); if (strcmp(property, "1")) { return false; } } return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE; }
TEST_F(PropertiesTest, GetBool) { /** * TRUE */ const char *valuesTrue[] = { "1", "true", "y", "yes", "on", }; for (size_t i = 0; i < arraysize(valuesTrue); ++i) { ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesTrue[i])); bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false); EXPECT_TRUE(val) << "Property should've been TRUE for value: '" << valuesTrue[i] << "'"; } /** * FALSE */ const char *valuesFalse[] = { "0", "false", "n", "no", "off", }; for (size_t i = 0; i < arraysize(valuesFalse); ++i) { ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesFalse[i])); bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true); EXPECT_FALSE(val) << "Property shoud've been FALSE For string value: '" << valuesFalse[i] << "'"; } /** * NEITHER */ const char *valuesNeither[] = { "x0", "x1", "2", "-2", "True", "False", "garbage", "", " ", "+1", " 1 ", " true", " true ", " y ", " yes", "yes ", "+0", "-0", "00", " 00 ", " false", "false ", }; for (size_t i = 0; i < arraysize(valuesNeither); ++i) { ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesNeither[i])); // The default value should always be used bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true); EXPECT_TRUE(val) << "Property should've been NEITHER (true) for string value: '" << valuesNeither[i] << "'"; val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false); EXPECT_FALSE(val) << "Property should've been NEITHER (false) for string value: '" << valuesNeither[i] << "'"; } }
int do_powerctl(int nargs, char **args) { char command[PROP_VALUE_MAX]; int res; int len = 0; int cmd = 0; const char *reboot_target; void (*callback_on_ro_remount)(const struct mntent*) = NULL; res = expand_props(command, args[1], sizeof(command)); if (res) { ERROR("powerctl: cannot expand '%s'\n", args[1]); return -EINVAL; } if (strncmp(command, "shutdown", 8) == 0) { if (property_get_bool("init.shutdown_to_charging", false)) { return android_reboot(ANDROID_RB_RESTART2, 0, "charging"); } cmd = ANDROID_RB_POWEROFF; len = 8; callback_on_ro_remount = unmount_and_fsck; } else if (strncmp(command, "reboot", 6) == 0) { cmd = ANDROID_RB_RESTART2; len = 6; } else { ERROR("powerctl: unrecognized command '%s'\n", command); return -EINVAL; } if (command[len] == ',') { char prop_value[PROP_VALUE_MAX] = {0}; reboot_target = &command[len + 1]; if ((property_get("init.svc.recovery", prop_value) == 0) && (strncmp(reboot_target, "keys", 4) == 0)) { ERROR("powerctl: permission denied\n"); return -EINVAL; } } else if (command[len] == '\0') { reboot_target = ""; } else { ERROR("powerctl: unrecognized reboot target '%s'\n", &command[len]); return -EINVAL; } return android_reboot_with_callback(cmd, 0, reboot_target, callback_on_ro_remount); }
bool DrawProfiler::loadSystemProperties() { bool changed = false; ProfileType newType = loadRequestedProfileType(); if (newType != mType) { mType = newType; if (mType == kNone) { destroyData(); } else { createData(); } changed = true; } bool showDirty = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false); if (showDirty != mShowDirtyRegions) { mShowDirtyRegions = showDirty; changed = true; } return changed; }
static bool should_use_sdcardfs(void) { char property[PROPERTY_VALUE_MAX]; // Allow user to have a strong opinion about state property_get(PROP_SDCARDFS_USER, property, ""); if (!strcmp(property, "force_on")) { LOG(WARNING) << "User explicitly enabled sdcardfs"; return supports_sdcardfs(); } else if (!strcmp(property, "force_off")) { LOG(WARNING) << "User explicitly disabled sdcardfs"; return false; } // Fall back to device opinion about state if (property_get_bool(PROP_SDCARDFS_DEVICE, true)) { LOG(WARNING) << "Device explicitly enabled sdcardfs"; return supports_sdcardfs(); } else { LOG(WARNING) << "Device explicitly disabled sdcardfs"; return false; } }
// Foreground waits for exit of the main persistent threads // that are started here. The threads are created to manage // UNIX domain client sockets for writing, reading and // controlling the user space logger, and for any additional // logging plugins like auditd and restart control. Additional // transitory per-client threads are created for each reader. int main(int argc, char *argv[]) { int fdPmesg = -1; bool klogd = property_get_bool("logd.kernel", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE); if (klogd) { fdPmesg = open("/proc/kmsg", O_RDONLY | O_NDELAY); } fdDmesg = open("/dev/kmsg", O_WRONLY); // issue reinit command. KISS argument parsing. if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { int sock = TEMP_FAILURE_RETRY( socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM)); if (sock < 0) { return -errno; } static const char reinit[] = "reinit"; ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinit, sizeof(reinit))); if (ret < 0) { return -errno; } struct pollfd p; memset(&p, 0, sizeof(p)); p.fd = sock; p.events = POLLIN; ret = TEMP_FAILURE_RETRY(poll(&p, 1, 1000)); if (ret < 0) { return -errno; } if ((ret == 0) || !(p.revents & POLLIN)) { return -ETIME; } static const char success[] = "success"; char buffer[sizeof(success) - 1]; memset(buffer, 0, sizeof(buffer)); ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer))); if (ret < 0) { return -errno; } return strncmp(buffer, success, sizeof(success) - 1) != 0; } // Reinit Thread sem_init(&reinit, 0, 0); sem_init(&uidName, 0, 0); sem_init(&sem_name, 0, 1); pthread_attr_t attr; if (!pthread_attr_init(&attr)) { struct sched_param param; memset(¶m, 0, sizeof(param)); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setschedpolicy(&attr, SCHED_BATCH); if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { pthread_t thread; reinit_running = true; if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) { reinit_running = false; } } pthread_attr_destroy(&attr); } if (drop_privs() != 0) { return -1; } // Serves the purpose of managing the last logs times read on a // socket connection, and as a reader lock on a range of log // entries. LastLogTimes *times = new LastLogTimes(); // LogBuffer is the object which is responsible for holding all // log entries. logBuf = new LogBuffer(times); signal(SIGHUP, reinit_signal_handler); if (property_get_bool("logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST | BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE)) { logBuf->enableStatistics(); } // LogReader listens on /dev/socket/logdr. When a client // connects, log entries in the LogBuffer are written to the client. LogReader *reader = new LogReader(logBuf); if (reader->startListener()) { exit(1); } // LogListener listens on /dev/socket/logdw for client // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. LogListener *swl = new LogListener(logBuf, reader); // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value if (swl->startListener(600)) { exit(1); } // Command listener listens on /dev/socket/logd for incoming logd // administrative commands. CommandListener *cl = new CommandListener(logBuf, reader, swl); if (cl->startListener()) { exit(1); } // LogAudit listens on NETLINK_AUDIT socket for selinux // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. bool auditd = property_get_bool("logd.auditd", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST); LogAudit *al = NULL; if (auditd) { al = new LogAudit(logBuf, reader, property_get_bool("logd.auditd.dmesg", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST) ? fdDmesg : -1); } LogKlog *kl = NULL; if (klogd) { kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != NULL); } readDmesg(al, kl); // failure is an option ... messages are in dmesg (required by standard) if (kl && kl->startListener()) { delete kl; } if (al && al->startListener()) { delete al; } TEMP_FAILURE_RETRY(pause()); exit(0); }
int adbd_main(int server_port) { umask(0); signal(SIGPIPE, SIG_IGN); init_transport_registration(); // We need to call this even if auth isn't enabled because the file // descriptor will always be open. adbd_cloexec_auth_socket(); if (ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) { auth_required = false; } adbd_auth_init(); // Our external storage path may be different than apps, since // we aren't able to bind mount after dropping root. const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE"); if (adb_external_storage != nullptr) { setenv("EXTERNAL_STORAGE", adb_external_storage, 1); } else { D("Warning: ADB_EXTERNAL_STORAGE is not set. Leaving EXTERNAL_STORAGE" " unchanged.\n"); } drop_privileges(server_port); bool is_usb = false; if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) { // Listen on USB. usb_init(); is_usb = true; } // If one of these properties is set, also listen on that port. // If one of the properties isn't set and we couldn't listen on usb, listen // on the default port. char prop_port[PROPERTY_VALUE_MAX]; property_get("service.adb.tcp.port", prop_port, ""); if (prop_port[0] == '\0') { property_get("persist.adb.tcp.port", prop_port, ""); } int port; if (sscanf(prop_port, "%d", &port) == 1 && port > 0) { D("using port=%d", port); // Listen on TCP port specified by service.adb.tcp.port property. local_init(port); } else if (!is_usb) { // Listen on default port. local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); } D("adbd_main(): pre init_jdwp()"); init_jdwp(); D("adbd_main(): post init_jdwp()"); D("Event loop starting"); fdevent_loop(); return 0; }
static bool should_attach_gdb(const debugger_request_t& request) { if (request.action == DEBUGGER_ACTION_CRASH) { return property_get_bool("debug.debuggerd.wait_for_gdb", false); } return false; }
status_t WifiDisplaySource::onReceiveM3Response( int32_t sessionID, const sp<ParsedMessage> &msg) { int32_t statusCode; if (!msg->getStatusCode(&statusCode)) { return ERROR_MALFORMED; } if (statusCode != 200) { return ERROR_UNSUPPORTED; } sp<Parameters> params = Parameters::Parse(msg->getContent(), strlen(msg->getContent())); if (params == NULL) { return ERROR_MALFORMED; } AString value; if (!params->findParameter("wfd_client_rtp_ports", &value)) { ALOGE("Sink doesn't report its choice of wfd_client_rtp_ports."); return ERROR_MALFORMED; } unsigned port0 = 0, port1 = 0; if (sscanf(value.c_str(), "RTP/AVP/UDP;unicast %u %u mode=play", &port0, &port1) == 2 || sscanf(value.c_str(), "RTP/AVP/TCP;unicast %u %u mode=play", &port0, &port1) == 2) { if (port0 == 0 || port0 > 65535 || port1 != 0) { ALOGE("Sink chose its wfd_client_rtp_ports poorly (%s)", value.c_str()); return ERROR_MALFORMED; } } else if (strcmp(value.c_str(), "RTP/AVP/TCP;interleaved mode=play")) { ALOGE("Unsupported value for wfd_client_rtp_ports (%s)", value.c_str()); return ERROR_UNSUPPORTED; } mWfdClientRtpPorts = value; mChosenRTPPort = port0; if (!params->findParameter("wfd_video_formats", &value)) { ALOGE("Sink doesn't report its choice of wfd_video_formats."); return ERROR_MALFORMED; } mSinkSupportsVideo = false; if (!(value == "none")) { mSinkSupportsVideo = true; if (!mSupportedSinkVideoFormats.parseFormatSpec(value.c_str())) { ALOGE("Failed to parse sink provided wfd_video_formats (%s)", value.c_str()); return ERROR_MALFORMED; } if (!VideoFormats::PickBestFormat( mSupportedSinkVideoFormats, mSupportedSourceVideoFormats, &mChosenVideoResolutionType, &mChosenVideoResolutionIndex, &mChosenVideoProfile, &mChosenVideoLevel)) { ALOGE("Sink and source share no commonly supported video " "formats."); return ERROR_UNSUPPORTED; } size_t width, height, framesPerSecond; bool interlaced; CHECK(VideoFormats::GetConfiguration( mChosenVideoResolutionType, mChosenVideoResolutionIndex, &width, &height, &framesPerSecond, &interlaced)); ALOGI("Picked video resolution %zu x %zu %c%zu", width, height, interlaced ? 'i' : 'p', framesPerSecond); ALOGI("Picked AVC profile %d, level %d", mChosenVideoProfile, mChosenVideoLevel); } else { ALOGI("Sink doesn't support video at all."); } if (!params->findParameter("wfd_audio_codecs", &value)) { ALOGE("Sink doesn't report its choice of wfd_audio_codecs."); return ERROR_MALFORMED; } mSinkSupportsAudio = false; if (!(value == "none")) { mSinkSupportsAudio = true; uint32_t modes; GetAudioModes(value.c_str(), "AAC", &modes); bool supportsAAC = (modes & 1) != 0; // AAC 2ch 48kHz GetAudioModes(value.c_str(), "LPCM", &modes); bool supportsPCM = (modes & 2) != 0; // LPCM 2ch 48kHz if (supportsPCM && property_get_bool("media.wfd.use-pcm-audio", false)) { ALOGI("Using PCM audio."); mUsingPCMAudio = true; } else if (supportsAAC) { ALOGI("Using AAC audio."); mUsingPCMAudio = false; } else if (supportsPCM) { ALOGI("Using PCM audio."); mUsingPCMAudio = true; } else { ALOGI("Sink doesn't support an audio format we do."); return ERROR_UNSUPPORTED; } } else { ALOGI("Sink doesn't support audio at all."); } if (!mSinkSupportsVideo && !mSinkSupportsAudio) { ALOGE("Sink supports neither video nor audio..."); return ERROR_UNSUPPORTED; } mUsingHDCP = false; if (!params->findParameter("wfd_content_protection", &value)) { ALOGI("Sink doesn't appear to support content protection."); } else if (value == "none") { ALOGI("Sink does not support content protection."); } else { mUsingHDCP = true; bool isHDCP2_0 = false; if (value.startsWith("HDCP2.0 ")) { isHDCP2_0 = true; } else if (!value.startsWith("HDCP2.1 ")) { ALOGE("malformed wfd_content_protection: '%s'", value.c_str()); return ERROR_MALFORMED; } int32_t hdcpPort; if (!ParsedMessage::GetInt32Attribute( value.c_str() + 8, "port", &hdcpPort) || hdcpPort < 1 || hdcpPort > 65535) { return ERROR_MALFORMED; } mIsHDCP2_0 = isHDCP2_0; mHDCPPort = hdcpPort; status_t err = makeHDCP(); if (err != OK) { ALOGE("Unable to instantiate HDCP component. " "Not using HDCP after all."); mUsingHDCP = false; } } return sendM4(sessionID); }
int adb_main(int is_daemon, int server_port) { #if !ADB_HOST int port; char value[PROPERTY_VALUE_MAX]; umask(000); #endif atexit(adb_cleanup); #if defined(_WIN32) SetConsoleCtrlHandler( ctrlc_handler, TRUE ); #else // No SIGCHLD. Let the service subproc handle its children. signal(SIGPIPE, SIG_IGN); #endif init_transport_registration(); #if ADB_HOST HOST = 1; #ifdef WORKAROUND_BUG6558362 if(is_daemon) adb_set_affinity(); #endif usb_init(); local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); adb_auth_init(); std::string local_name = android::base::StringPrintf("tcp:%d", server_port); if (install_listener(local_name, "*smartsocket*", NULL, 0)) { exit(1); } #else // We need to call this even if auth isn't enabled because the file // descriptor will always be open. adbd_cloexec_auth_socket(); // Override auth in factory test mode if ((ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) || (property_get_bool("ro.boot.ftm", 0) == 1)) { auth_required = false; } adbd_auth_init(); // Our external storage path may be different than apps, since // we aren't able to bind mount after dropping root. const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE"); if (NULL != adb_external_storage) { setenv("EXTERNAL_STORAGE", adb_external_storage, 1); } else { D("Warning: ADB_EXTERNAL_STORAGE is not set. Leaving EXTERNAL_STORAGE" " unchanged.\n"); } /* add extra groups: ** AID_ADB to access the USB driver ** AID_LOG to read system logs (adb logcat) ** AID_INPUT to diagnose input issues (getevent) ** AID_INET to diagnose network issues (ping) ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump) ** AID_SDCARD_R to allow reading from the SD card ** AID_SDCARD_RW to allow writing to the SD card ** AID_NET_BW_STATS to read out qtaguid statistics */ gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW, AID_NET_BW_STATS }; if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { exit(1); } /* don't listen on a port (default 5037) if running in secure mode */ /* don't run as root if we are running in secure mode */ if (should_drop_privileges()) { drop_capabilities_bounding_set_if_needed(); /* then switch user and group to "shell" */ if (setgid(AID_SHELL) != 0) { exit(1); } if (setuid(AID_SHELL) != 0) { exit(1); } D("Local port disabled\n"); } else { if ((root_seclabel != NULL) && (is_selinux_enabled() > 0)) { // b/12587913: fix setcon to allow const pointers if (setcon((char *)root_seclabel) < 0) { exit(1); } } std::string local_name = android::base::StringPrintf("tcp:%d", server_port); if (install_listener(local_name, "*smartsocket*", NULL, 0)) { exit(1); } } int usb = 0; if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) { // listen on USB usb_init(); usb = 1; } // If one of these properties is set, also listen on that port // If one of the properties isn't set and we couldn't listen on usb, // listen on the default port. property_get("service.adb.tcp.port", value, ""); if (!value[0]) { property_get("persist.adb.tcp.port", value, ""); } if (sscanf(value, "%d", &port) == 1 && port > 0) { printf("using port=%d\n", port); // listen on TCP port specified by service.adb.tcp.port property local_init(port); } else if (!usb) { // listen on default port local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); } D("adb_main(): pre init_jdwp()\n"); init_jdwp(); D("adb_main(): post init_jdwp()\n"); #endif if (is_daemon) { // inform our parent that we are up and running. #if defined(_WIN32) DWORD count; WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL ); #else fprintf(stderr, "OK\n"); #endif start_logging(); } D("Event loop starting\n"); fdevent_loop(); usb_cleanup(); return 0; }
// Foreground waits for exit of the main persistent threads // that are started here. The threads are created to manage // UNIX domain client sockets for writing, reading and // controlling the user space logger, and for any additional // logging plugins like auditd and restart control. Additional // transitory per-client threads are created for each reader. int main(int argc, char *argv[]) { fdDmesg = open("/dev/kmsg", O_WRONLY); // issue reinit command. KISS argument parsing. if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) { int sock = TEMP_FAILURE_RETRY( socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM)); if (sock < 0) { return -errno; } static const char reinit[] = "reinit"; ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinit, sizeof(reinit))); if (ret < 0) { return -errno; } struct pollfd p; memset(&p, 0, sizeof(p)); p.fd = sock; p.events = POLLIN; ret = TEMP_FAILURE_RETRY(poll(&p, 1, 100)); if (ret < 0) { return -errno; } if ((ret == 0) || !(p.revents & POLLIN)) { return -ETIME; } static const char success[] = "success"; char buffer[sizeof(success) - 1]; memset(buffer, 0, sizeof(buffer)); ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer))); if (ret < 0) { return -errno; } return strncmp(buffer, success, sizeof(success) - 1) != 0; } // Reinit Thread sem_init(&reinit, 0, 0); sem_init(&uidName, 0, 0); pthread_attr_t attr; if (!pthread_attr_init(&attr)) { struct sched_param param; memset(¶m, 0, sizeof(param)); pthread_attr_setschedparam(&attr, ¶m); pthread_attr_setschedpolicy(&attr, SCHED_BATCH); if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { pthread_t thread; reinit_running = true; if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) { reinit_running = false; } } pthread_attr_destroy(&attr); } if (drop_privs() != 0) { return -1; } // Serves the purpose of managing the last logs times read on a // socket connection, and as a reader lock on a range of log // entries. LastLogTimes *times = new LastLogTimes(); // LogBuffer is the object which is responsible for holding all // log entries. logBuf = new LogBuffer(times); signal(SIGHUP, reinit_signal_handler); { char property[PROPERTY_VALUE_MAX]; property_get("ro.build.type", property, ""); if (property_get_bool("logd.statistics", !!strcmp(property, "user") && !property_get_bool("ro.config.low_ram", false))) { logBuf->enableStatistics(); } } // LogReader listens on /dev/socket/logdr. When a client // connects, log entries in the LogBuffer are written to the client. LogReader *reader = new LogReader(logBuf); if (reader->startListener()) { exit(1); } // LogListener listens on /dev/socket/logdw for client // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. LogListener *swl = new LogListener(logBuf, reader); // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value if (swl->startListener(300)) { exit(1); } // Command listener listens on /dev/socket/logd for incoming logd // administrative commands. CommandListener *cl = new CommandListener(logBuf, reader, swl); if (cl->startListener()) { exit(1); } // LogAudit listens on NETLINK_AUDIT socket for selinux // initiated log messages. New log entries are added to LogBuffer // and LogReader is notified to send updates to connected clients. bool auditd = property_get_bool("logd.auditd", true); if (auditd) { bool dmesg = property_get_bool("logd.auditd.dmesg", true); // failure is an option ... messages are in dmesg (required by standard) LogAudit *al = new LogAudit(logBuf, reader, dmesg ? fdDmesg : -1); int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0); if (len > 0) { len++; char buf[len]; int rc = klogctl(KLOG_READ_ALL, buf, len); if (rc >= 0) { buf[len - 1] = '\0'; for (char *ptr, *tok = buf; (tok = strtok_r(tok, "\r\n", &ptr)); tok = NULL) { al->log(tok); } } } if (al->startListener()) { delete al; } } TEMP_FAILURE_RETRY(pause()); exit(0); }
bool Properties::load() { char property[PROPERTY_VALUE_MAX]; bool prevDebugLayersUpdates = debugLayersUpdates; bool prevDebugOverdraw = debugOverdraw; StencilClipDebug prevDebugStencilClip = debugStencilClip; debugOverdraw = false; if (property_get(PROPERTY_DEBUG_OVERDRAW, property, nullptr) > 0) { INIT_LOGD(" Overdraw debug enabled: %s", property); if (!strcmp(property, "show")) { debugOverdraw = true; overdrawColorSet = OverdrawColorSet::Default; } else if (!strcmp(property, "show_deuteranomaly")) { debugOverdraw = true; overdrawColorSet = OverdrawColorSet::Deuteranomaly; } } // See Properties.h for valid values if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, nullptr) > 0) { INIT_LOGD(" Stencil clip debug enabled: %s", property); if (!strcmp(property, "hide")) { debugStencilClip = StencilClipDebug::Hide; } else if (!strcmp(property, "highlight")) { debugStencilClip = StencilClipDebug::ShowHighlight; } else if (!strcmp(property, "region")) { debugStencilClip = StencilClipDebug::ShowRegion; } } else { debugStencilClip = StencilClipDebug::Hide; } sProfileType = ProfileType::None; if (property_get(PROPERTY_PROFILE, property, "") > 0) { if (!strcmp(property, PROPERTY_PROFILE_VISUALIZE_BARS)) { sProfileType = ProfileType::Bars; } else if (!strcmp(property, "true")) { sProfileType = ProfileType::Console; } } debugLayersUpdates = property_get_bool(PROPERTY_DEBUG_LAYERS_UPDATES, false); INIT_LOGD(" Layers updates debug enabled: %d", debugLayersUpdates); drawDeferDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_DEFER, false); INIT_LOGD(" Draw defer %s", drawDeferDisabled ? "disabled" : "enabled"); drawReorderDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_REORDER, false); INIT_LOGD(" Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled"); showDirtyRegions = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false); debugLevel = kDebugDisabled; if (property_get(PROPERTY_DEBUG, property, nullptr) > 0) { debugLevel = (DebugLevel) atoi(property); } skipEmptyFrames = property_get_bool(PROPERTY_SKIP_EMPTY_DAMAGE, true); swapBuffersWithDamage = property_get_bool(PROPERTY_SWAP_WITH_DAMAGE, true); return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw) || (prevDebugStencilClip != debugStencilClip); }
int main(int argc, char *argv[]) { base::CommandLine::Init(argc, argv); base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); int32_t port = kDefaultPort; if (cl->HasSwitch(kPort)) { std::string value = cl->GetSwitchValueASCII(kPort); base::StringToInt(value, &port); } // Puch a TCP hole to accept connection FwDaemon daemon(std::unique_ptr<FirewallInterface>{new FirewalldFirewall()}, (uint16_t)port); daemon.Run(); std::unique_ptr<Socket> server = Socket::NewServer(Socket::Protocol::kTcp, port); if (server == nullptr) { ALOGE("Failed to create fastbootd service."); return 1; } int fastbootd_reboot = 0; if (property_get_bool("persist.sys.fastbootd.reboot", 1)) { pthread_t hreboot; pthread_create(&hreboot, NULL, thread_reboot, &fastbootd_reboot); fastbootd_reboot = 1; } // Check if in demo mode if (fastbootd_reboot == 1) { struct stat st; int result = stat("/boot/DEMO", &st); if (result == 0 && S_ISREG(st.st_mode)) { fastbootd_reboot = 0; } } std::string handshake_message(android::base::StringPrintf("FB%02d", kProtocolVersion)); while (true) { std::unique_ptr<Socket> client = server->Accept(); if (client == nullptr) { ALOGE("Failed to accept client connection."); continue; } char buffer[4]; ssize_t bytes = client->Receive(buffer, sizeof(buffer), 500); if (bytes != 4) { ALOGE("Failed to get client version."); continue; } if (memcmp(buffer, "FB01", 4) != 0) { ALOGE("Unsupported client: %c%c%c%c", buffer[0], buffer[1], buffer[2], buffer[3]); continue; } if (fastbootd_reboot) { fastbootd_reboot = 0; property_set("persist.sys.fastbootd.reboot", "0"); } if (!client->Send(handshake_message.c_str(), kHandshakeLength)) { ALOGE("Failed to send handshake."); continue; } command_loop(client.get()); } return 0; }