0f29cbc750
Test: test_adb.py Test: test_device.py Test: $ANDROID_HOST_OUT/nativetest64/adb_test/adb_test Test: adb shell /data/nativetest64/adbd_test/adbd_test Change-Id: Ieecc9b1b7f2111f4da45d4bbd1b7703535fe7d4d
195 lines
5.4 KiB
C++
195 lines
5.4 KiB
C++
/*
|
|
* 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 <android-base/logging.h>
|
|
#include <android-base/strings.h>
|
|
|
|
#include "adb.h"
|
|
|
|
#if !ADB_HOST
|
|
#include <android-base/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 defined(_WIN32)
|
|
// stderr can be buffered on Windows (and setvbuf doesn't seem to work), so explicitly flush.
|
|
fflush(stderr);
|
|
#endif
|
|
|
|
#if !ADB_HOST
|
|
// Only print logs of INFO or higher to logcat, so that `adb logcat` with adbd tracing on
|
|
// doesn't result in exponential logging.
|
|
if (severity >= android::base::INFO) {
|
|
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(), 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);
|
|
}
|
|
|
|
std::string get_trace_setting() {
|
|
#if ADB_HOST
|
|
return get_trace_setting_from_env();
|
|
#else
|
|
return android::base::GetProperty("persist.adb.trace_mask", "");
|
|
#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", -1},
|
|
{"all", -1},
|
|
{"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 == -1) {
|
|
// -1 is used for the special values "1" and "all" that enable all
|
|
// tracing.
|
|
adb_trace_mask = ~0;
|
|
break;
|
|
} else {
|
|
adb_trace_mask |= 1 << flag->second;
|
|
}
|
|
}
|
|
|
|
if (adb_trace_mask != 0) {
|
|
android::base::SetMinimumLogSeverity(android::base::VERBOSE);
|
|
}
|
|
}
|
|
|
|
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 (unix_isatty(STDOUT_FILENO) == 0) {
|
|
start_device_log();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if ADB_HOST && !defined(_WIN32)
|
|
// adb historically ignored $ANDROID_LOG_TAGS but passed it through to logcat.
|
|
// If set, move it out of the way so that libbase logging doesn't try to parse it.
|
|
std::string log_tags;
|
|
char* ANDROID_LOG_TAGS = getenv("ANDROID_LOG_TAGS");
|
|
if (ANDROID_LOG_TAGS) {
|
|
log_tags = ANDROID_LOG_TAGS;
|
|
unsetenv("ANDROID_LOG_TAGS");
|
|
}
|
|
#endif
|
|
|
|
android::base::InitLogging(argv, &AdbLogger);
|
|
|
|
#if ADB_HOST && !defined(_WIN32)
|
|
// Put $ANDROID_LOG_TAGS back so we can pass it to logcat.
|
|
if (!log_tags.empty()) setenv("ANDROID_LOG_TAGS", log_tags.c_str(), 1);
|
|
#endif
|
|
|
|
setup_trace_mask();
|
|
|
|
VLOG(ADB) << adb_version();
|
|
}
|
|
|
|
void adb_trace_enable(AdbTrace trace_tag) {
|
|
adb_trace_mask |= (1 << trace_tag);
|
|
}
|