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