1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "sysdeps.h" 18#include "adb_trace.h" 19 20#include <string> 21#include <unordered_map> 22#include <vector> 23 24#include <android-base/logging.h> 25#include <android-base/strings.h> 26 27#include "adb.h" 28 29#if !ADB_HOST 30#include <cutils/properties.h> 31#endif 32 33#if !ADB_HOST 34const char* adb_device_banner = "device"; 35static android::base::LogdLogger gLogdLogger; 36#else 37const char* adb_device_banner = "host"; 38#endif 39 40void AdbLogger(android::base::LogId id, android::base::LogSeverity severity, 41 const char* tag, const char* file, unsigned int line, 42 const char* message) { 43 android::base::StderrLogger(id, severity, tag, file, line, message); 44#if !ADB_HOST 45 gLogdLogger(id, severity, tag, file, line, message); 46#endif 47} 48 49 50#if !ADB_HOST 51static std::string get_log_file_name() { 52 struct tm now; 53 time_t t; 54 tzset(); 55 time(&t); 56 localtime_r(&t, &now); 57 58 char timestamp[PATH_MAX]; 59 strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now); 60 61 return android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp, 62 getpid()); 63} 64 65void start_device_log(void) { 66 int fd = unix_open(get_log_file_name().c_str(), 67 O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640); 68 if (fd == -1) { 69 return; 70 } 71 72 // Redirect stdout and stderr to the log file. 73 dup2(fd, STDOUT_FILENO); 74 dup2(fd, STDERR_FILENO); 75 fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid()); 76 unix_close(fd); 77} 78#endif 79 80int adb_trace_mask; 81 82std::string get_trace_setting_from_env() { 83 const char* setting = getenv("ADB_TRACE"); 84 if (setting == nullptr) { 85 setting = ""; 86 } 87 88 return std::string(setting); 89} 90 91#if !ADB_HOST 92std::string get_trace_setting_from_prop() { 93 char buf[PROPERTY_VALUE_MAX]; 94 property_get("persist.adb.trace_mask", buf, ""); 95 return std::string(buf); 96} 97#endif 98 99std::string get_trace_setting() { 100#if ADB_HOST 101 return get_trace_setting_from_env(); 102#else 103 return get_trace_setting_from_prop(); 104#endif 105} 106 107// Split the space separated list of tags from the trace setting and build the 108// trace mask from it. note that '1' and 'all' are special cases to enable all 109// tracing. 110// 111// adb's trace setting comes from the ADB_TRACE environment variable, whereas 112// adbd's comes from the system property persist.adb.trace_mask. 113static void setup_trace_mask() { 114 const std::string trace_setting = get_trace_setting(); 115 if (trace_setting.empty()) { 116 return; 117 } 118 119 std::unordered_map<std::string, int> trace_flags = { 120 {"1", 0}, 121 {"all", 0}, 122 {"adb", ADB}, 123 {"sockets", SOCKETS}, 124 {"packets", PACKETS}, 125 {"rwx", RWX}, 126 {"usb", USB}, 127 {"sync", SYNC}, 128 {"sysdeps", SYSDEPS}, 129 {"transport", TRANSPORT}, 130 {"jdwp", JDWP}, 131 {"services", SERVICES}, 132 {"auth", AUTH}, 133 {"fdevent", FDEVENT}, 134 {"shell", SHELL}}; 135 136 std::vector<std::string> elements = android::base::Split(trace_setting, " "); 137 for (const auto& elem : elements) { 138 const auto& flag = trace_flags.find(elem); 139 if (flag == trace_flags.end()) { 140 LOG(ERROR) << "Unknown trace flag: " << elem; 141 continue; 142 } 143 144 if (flag->second == 0) { 145 // 0 is used for the special values "1" and "all" that enable all 146 // tracing. 147 adb_trace_mask = ~0; 148 return; 149 } else { 150 adb_trace_mask |= 1 << flag->second; 151 } 152 } 153} 154 155void adb_trace_init(char** argv) { 156#if !ADB_HOST 157 // Don't open log file if no tracing, since this will block 158 // the crypto unmount of /data 159 if (!get_trace_setting().empty()) { 160 if (unix_isatty(STDOUT_FILENO) == 0) { 161 start_device_log(); 162 } 163 } 164#endif 165 166 android::base::InitLogging(argv, &AdbLogger); 167 setup_trace_mask(); 168 169 VLOG(ADB) << adb_version(); 170} 171 172void adb_trace_enable(AdbTrace trace_tag) { 173 adb_trace_mask |= (1 << trace_tag); 174} 175