1 /* 2 * Copyright (C) 2020 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 "daemon/logging.h" 18 19 #include <mutex> 20 #include <optional> 21 #include <string_view> 22 23 #include <android-base/no_destructor.h> 24 #include <android-base/properties.h> 25 #include <android-base/strings.h> 26 #include <android-base/thread_annotations.h> 27 28 #if defined(__ANDROID__) 29 struct LogStatus { 30 bool enabled[static_cast<size_t>(adb::LogType::COUNT)]; 31 32 bool& operator[](adb::LogType type) { return enabled[static_cast<size_t>(type)]; } 33 }; 34 35 using android::base::CachedProperty; 36 using android::base::NoDestructor; 37 38 static NoDestructor<std::mutex> log_mutex; 39 static NoDestructor<CachedProperty> log_property GUARDED_BY(log_mutex)("debug.adbd.logging"); 40 static std::optional<LogStatus> cached_log_status GUARDED_BY(log_mutex); 41 42 static NoDestructor<CachedProperty> persist_log_property 43 GUARDED_BY(log_mutex)("persist.debug.adbd.logging"); 44 static std::optional<LogStatus> cached_persist_log_status GUARDED_BY(log_mutex); 45 46 static LogStatus ParseLogStatus(std::string_view str) { 47 LogStatus result = {}; 48 for (const auto& part : android::base::Split(std::string(str), ",")) { 49 if (part == "cnxn") { 50 result[adb::LogType::Connection] = true; 51 } else if (part == "service") { 52 result[adb::LogType::Service] = true; 53 } else if (part == "shell") { 54 result[adb::LogType::Shell] = true; 55 } else if (part == "all") { 56 result[adb::LogType::Connection] = true; 57 result[adb::LogType::Service] = true; 58 result[adb::LogType::Shell] = true; 59 } 60 } 61 return result; 62 } 63 64 static LogStatus GetLogStatus(android::base::CachedProperty* property, 65 std::optional<LogStatus>* cached_status) REQUIRES(log_mutex) { 66 bool changed; 67 const char* value = property->Get(&changed); 68 if (changed || !*cached_status) { 69 **cached_status = ParseLogStatus(value); 70 } 71 return **cached_status; 72 } 73 74 namespace adb { 75 bool is_logging_enabled(LogType type) { 76 std::lock_guard<std::mutex> lock(*log_mutex); 77 return GetLogStatus(log_property.get(), &cached_log_status)[type] || 78 GetLogStatus(persist_log_property.get(), &cached_persist_log_status)[type]; 79 } 80 } // namespace adb 81 82 #else 83 84 namespace adb { 85 bool is_logging_enabled(LogType type) { 86 return false; 87 } 88 } // namespace adb 89 #endif 90