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