1 /*
2  * Copyright (C) 2018 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 "utils/base/logging_raw.h"
18 
19 #include <stdio.h>
20 
21 #include <string>
22 
23 #define TC3_RETURN_IF_NOT_ERROR_OR_FATAL        \
24   if (severity != ERROR && severity != FATAL) { \
25     return;                                     \
26   }
27 
28 // NOTE: this file contains two implementations: one for Android, one for all
29 // other cases.  We always build exactly one implementation.
30 #if defined(__ANDROID__)
31 
32 // Compiled as part of Android.
33 #include <android/log.h>
34 
35 namespace libtextclassifier3 {
36 namespace logging {
37 
38 namespace {
39 // Converts LogSeverity to level for __android_log_write.
GetAndroidLogLevel(LogSeverity severity)40 int GetAndroidLogLevel(LogSeverity severity) {
41   switch (severity) {
42     case FATAL:
43       return ANDROID_LOG_FATAL;
44     case ERROR:
45       return ANDROID_LOG_ERROR;
46     case WARNING:
47       return ANDROID_LOG_WARN;
48     case INFO:
49       return ANDROID_LOG_INFO;
50     default:
51       return ANDROID_LOG_DEBUG;
52   }
53 }
54 }  // namespace
55 
LowLevelLogging(LogSeverity severity,const std::string & tag,const std::string & message)56 void LowLevelLogging(LogSeverity severity, const std::string& tag,
57                      const std::string& message) {
58 #if !defined(TC3_DEBUG_LOGGING)
59   TC3_RETURN_IF_NOT_ERROR_OR_FATAL
60 #endif
61   const int android_log_level = GetAndroidLogLevel(severity);
62   __android_log_write(android_log_level, tag.c_str(), message.c_str());
63 }
64 
65 }  // namespace logging
66 }  // namespace libtextclassifier3
67 
68 #else  // if defined(__ANDROID__)
69 
70 // Not on Android: implement LowLevelLogging to print to stderr (see below).
71 namespace libtextclassifier3 {
72 namespace logging {
73 
74 namespace {
75 // Converts LogSeverity to human-readable text.
LogSeverityToString(LogSeverity severity)76 const char *LogSeverityToString(LogSeverity severity) {
77   switch (severity) {
78     case INFO:
79       return "INFO";
80     case WARNING:
81       return "WARNING";
82     case ERROR:
83       return "ERROR";
84     case FATAL:
85       return "FATAL";
86     default:
87       return "UNKNOWN";
88   }
89 }
90 }  // namespace
91 
LowLevelLogging(LogSeverity severity,const std::string & tag,const std::string & message)92 void LowLevelLogging(LogSeverity severity, const std::string &tag,
93                      const std::string &message) {
94 #if !defined(TC3_DEBUG_LOGGING)
95   TC3_RETURN_IF_NOT_ERROR_OR_FATAL
96 #endif
97   fprintf(stderr, "[%s] %s : %s\n", LogSeverityToString(severity), tag.c_str(),
98           message.c_str());
99   fflush(stderr);
100 }
101 
102 }  // namespace logging
103 }  // namespace libtextclassifier3
104 
105 #endif  // if defined(__ANDROID__)
106