Adb: use VLOG() to replace D() for verbose logging.

As there are too many D(), we can keep both VLOG() and D() now, and get
rid of D() gradually.

Change-Id: I2f1cb70bcab3e82c99fed939341d03f6b2216076
diff --git a/adb/adb_trace.cpp b/adb/adb_trace.cpp
new file mode 100644
index 0000000..04b82f6
--- /dev/null
+++ b/adb/adb_trace.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sysdeps.h"
+#include "adb_trace.h"
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <base/logging.h>
+#include <base/strings.h>
+
+#include "adb.h"
+
+#if !ADB_HOST
+#include <cutils/properties.h>
+#endif
+
+#if !ADB_HOST
+const char* adb_device_banner = "device";
+static android::base::LogdLogger gLogdLogger;
+#else
+const char* adb_device_banner = "host";
+#endif
+
+void AdbLogger(android::base::LogId id, android::base::LogSeverity severity,
+               const char* tag, const char* file, unsigned int line,
+               const char* message) {
+    android::base::StderrLogger(id, severity, tag, file, line, message);
+#if !ADB_HOST
+    gLogdLogger(id, severity, tag, file, line, message);
+#endif
+}
+
+
+#if !ADB_HOST
+static std::string get_log_file_name() {
+    struct tm now;
+    time_t t;
+    tzset();
+    time(&t);
+    localtime_r(&t, &now);
+
+    char timestamp[PATH_MAX];
+    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now);
+
+    return android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp,
+                                       getpid());
+}
+
+void start_device_log(void) {
+    int fd = unix_open(get_log_file_name().c_str(),
+                       O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
+    if (fd == -1) {
+        return;
+    }
+
+    // Redirect stdout and stderr to the log file.
+    dup2(fd, STDOUT_FILENO);
+    dup2(fd, STDERR_FILENO);
+    fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
+    unix_close(fd);
+}
+#endif
+
+int adb_trace_mask;
+
+std::string get_trace_setting_from_env() {
+    const char* setting = getenv("ADB_TRACE");
+    if (setting == nullptr) {
+        setting = "";
+    }
+
+    return std::string(setting);
+}
+
+#if !ADB_HOST
+std::string get_trace_setting_from_prop() {
+    char buf[PROPERTY_VALUE_MAX];
+    property_get("persist.adb.trace_mask", buf, "");
+    return std::string(buf);
+}
+#endif
+
+std::string get_trace_setting() {
+#if ADB_HOST
+    return get_trace_setting_from_env();
+#else
+    return get_trace_setting_from_prop();
+#endif
+}
+
+// Split the space separated list of tags from the trace setting and build the
+// trace mask from it. note that '1' and 'all' are special cases to enable all
+// tracing.
+//
+// adb's trace setting comes from the ADB_TRACE environment variable, whereas
+// adbd's comes from the system property persist.adb.trace_mask.
+static void setup_trace_mask() {
+    const std::string trace_setting = get_trace_setting();
+    if (trace_setting.empty()) {
+        return;
+    }
+
+    std::unordered_map<std::string, int> trace_flags = {
+        {"1", 0},
+        {"all", 0},
+        {"adb", ADB},
+        {"sockets", SOCKETS},
+        {"packets", PACKETS},
+        {"rwx", RWX},
+        {"usb", USB},
+        {"sync", SYNC},
+        {"sysdeps", SYSDEPS},
+        {"transport", TRANSPORT},
+        {"jdwp", JDWP},
+        {"services", SERVICES},
+        {"auth", AUTH},
+        {"fdevent", FDEVENT},
+        {"shell", SHELL}};
+
+    std::vector<std::string> elements = android::base::Split(trace_setting, " ");
+    for (const auto& elem : elements) {
+        const auto& flag = trace_flags.find(elem);
+        if (flag == trace_flags.end()) {
+            LOG(ERROR) << "Unknown trace flag: " << elem;
+            continue;
+        }
+
+        if (flag->second == 0) {
+            // 0 is used for the special values "1" and "all" that enable all
+            // tracing.
+            adb_trace_mask = ~0;
+            return;
+        } else {
+            adb_trace_mask |= 1 << flag->second;
+        }
+    }
+}
+
+void adb_trace_init(char** argv) {
+#if !ADB_HOST
+    // Don't open log file if no tracing, since this will block
+    // the crypto unmount of /data
+    if (!get_trace_setting().empty()) {
+        if (isatty(STDOUT_FILENO) == 0) {
+            start_device_log();
+        }
+    }
+#endif
+
+    android::base::InitLogging(argv, AdbLogger);
+    setup_trace_mask();
+
+    VLOG(ADB) << adb_version();
+}
+
+void adb_trace_enable(AdbTrace trace_tag) {
+    adb_trace_mask |= (1 << trace_tag);
+}