Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8e3f826 authored by bohu's avatar bohu Committed by android-build-merger
Browse files

Merge "Emulator: enhance logcat -Q to handle qemu pipe device" am: a14b5bbd

am: 1284bbbb

Change-Id: I81a4558f9381c2442fd291ed63546f64b13065f5
parents 0508ebf9 1284bbbb
Loading
Loading
Loading
Loading
+54 −11
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include <vector>

#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cutils/sched_policy.h>
@@ -1195,39 +1196,71 @@ static int __logcat(android_logcat_context_internal* context) {
            } break;

            case 'Q':
#define KERNEL_OPTION "androidboot.logcat="
#define LOGCAT_FILTER "androidboot.logcat="
#define CONSOLE_PIPE_OPTION "androidboot.consolepipe="
#define CONSOLE_OPTION "androidboot.console="
#define QEMU_PROPERTY "ro.kernel.qemu"
#define QEMU_CMDLINE "qemu.cmdline"
                // This is a *hidden* option used to start a version of logcat
                // in an emulated device only.  It basically looks for
                // androidboot.logcat= on the kernel command line.  If
                // something is found, it extracts a log filter and uses it to
                // run the program.  If nothing is found, the program should
                // quit immediately.
                // run the program. The logcat output will go to consolepipe if
                // androiboot.consolepipe (e.g. qemu_pipe) is given, otherwise,
                // it goes to androidboot.console (e.g. tty)
                {
                    std::string cmdline;
                    // if not in emulator, exit quietly
                    if (false == android::base::GetBoolProperty(QEMU_PROPERTY, false)) {
                        context->retval = EXIT_SUCCESS;
                        goto exit;
                    }

                    std::string cmdline = android::base::GetProperty(QEMU_CMDLINE, "");
                    if (cmdline.empty()) {
                        android::base::ReadFileToString("/proc/cmdline", &cmdline);
                    }

                    const char* logcat = strstr(cmdline.c_str(), KERNEL_OPTION);
                    const char* logcatFilter = strstr(cmdline.c_str(), LOGCAT_FILTER);
                    // if nothing found or invalid filters, exit quietly
                    if (!logcat) {
                    if (!logcatFilter) {
                        context->retval = EXIT_SUCCESS;
                        goto exit;
                    }

                    const char* p = logcat + strlen(KERNEL_OPTION);
                    const char* p = logcatFilter + strlen(LOGCAT_FILTER);
                    const char* q = strpbrk(p, " \t\n\r");
                    if (!q) q = p + strlen(p);
                    forceFilters = std::string(p, q);

                    // redirect our output to the emulator console
                    // redirect our output to the emulator console pipe or console
                    const char* consolePipe =
                        strstr(cmdline.c_str(), CONSOLE_PIPE_OPTION);
                    const char* console =
                        strstr(cmdline.c_str(), CONSOLE_OPTION);
                    if (!console) break;

                    if (consolePipe) {
                        p = consolePipe + strlen(CONSOLE_PIPE_OPTION);
                    } else if (console) {
                        p = console + strlen(CONSOLE_OPTION);
                    } else {
                        context->retval = EXIT_FAILURE;
                        goto exit;
                    }

                    q = strpbrk(p, " \t\n\r");
                    int len = q ? q - p : strlen(p);
                    std::string devname = "/dev/" + std::string(p, len);
                    std::string pipePurpose("pipe:logcat");
                    if (consolePipe) {
                        // example: "qemu_pipe,pipe:logcat"
                        // upon opening of /dev/qemu_pipe, the "pipe:logcat"
                        // string with trailing '\0' should be written to the fd
                        size_t pos = devname.find(",");
                        if (pos != std::string::npos) {
                            pipePurpose = devname.substr(pos + 1);
                            devname = devname.substr(0, pos);
                        }
                    }
                    cmdline.erase();

                    if (context->error) {
@@ -1239,6 +1272,16 @@ static int __logcat(android_logcat_context_internal* context) {
                    devname.erase();
                    if (!fp) break;

                    if (consolePipe) {
                        // need the trailing '\0'
                        if(!android::base::WriteFully(fileno(fp), pipePurpose.c_str(),
                                    pipePurpose.size() + 1)) {
                            fclose(fp);
                            context->retval = EXIT_FAILURE;
                            goto exit;
                        }
                    }

                    // close output and error channels, replace with console
                    android::close_output(context);
                    android::close_error(context);