1 /*
2 * Copyright 2023 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 <log/log.h>
18
19 #include "bluetooth/log.h"
20 #include "truncating_buffer.h"
21
22 namespace bluetooth::log_internal {
23
24 static constexpr std::string_view kAndroidRepoLocation =
25 "packages/modules/Bluetooth/";
26
27 static constexpr size_t kBufferSize = 1024;
28
vlog(Level level,char const * tag,source_location location,fmt::string_view fmt,fmt::format_args vargs)29 void vlog(Level level, char const* tag, source_location location,
30 fmt::string_view fmt, fmt::format_args vargs) {
31 // Check if log is enabled.
32 if (!__android_log_is_loggable(level, "bluetooth", ANDROID_LOG_INFO)) {
33 return;
34 }
35
36 // Strip prefix of file_name to remove kAndroidRepoLocation if present
37 const char* file_name = location.file_name;
38 if (strncmp(kAndroidRepoLocation.data(), location.file_name,
39 kAndroidRepoLocation.size()) == 0) {
40 file_name = location.file_name + kAndroidRepoLocation.size();
41 }
42
43 // Format to stack buffer.
44 // liblog uses a different default depending on the execution context
45 // (host or device); the file and line are not systematically included.
46 // In order to have consistent logs we include it manually in the log
47 // message.
48 truncating_buffer<kBufferSize> buffer;
49 fmt::format_to(std::back_insert_iterator(buffer), "{}:{} {}: ", file_name,
50 location.line, location.function_name);
51 fmt::vformat_to(std::back_insert_iterator(buffer), fmt, vargs);
52
53 // Send message to liblog.
54 struct __android_log_message message = {
55 .struct_size = sizeof(__android_log_message),
56 .buffer_id = LOG_ID_MAIN,
57 .priority = static_cast<android_LogPriority>(level),
58 .tag = tag,
59 .file = nullptr,
60 .line = 0,
61 .message = buffer.c_str(),
62 };
63 __android_log_write_log_message(&message);
64
65 if (level == Level::kFatal) {
66 // Log assertion failures to stderr for the benefit of "adb shell" users
67 // and gtests (http://b/23675822).
68 char const* buf = buffer.c_str();
69 TEMP_FAILURE_RETRY(write(2, buf, strlen(buf)));
70 TEMP_FAILURE_RETRY(write(2, "\n", 1));
71 __android_log_call_aborter(buf);
72 }
73 }
74
75 } // namespace bluetooth::log_internal
76