xref: /aosp_15_r20/frameworks/av/media/libnblog/Writer.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "NBLog"
18*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*ec779b8eSAndroid Build Coastguard Worker 
20*ec779b8eSAndroid Build Coastguard Worker #include <stdarg.h>
21*ec779b8eSAndroid Build Coastguard Worker #include <stddef.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <sys/prctl.h>
23*ec779b8eSAndroid Build Coastguard Worker 
24*ec779b8eSAndroid Build Coastguard Worker #include <audio_utils/fifo.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <binder/IMemory.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <media/nblog/Entry.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/nblog/Events.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <media/nblog/Timeline.h>
29*ec779b8eSAndroid Build Coastguard Worker #include <media/nblog/Writer.h>
30*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
31*ec779b8eSAndroid Build Coastguard Worker #include <utils/Mutex.h>
32*ec779b8eSAndroid Build Coastguard Worker 
33*ec779b8eSAndroid Build Coastguard Worker namespace android {
34*ec779b8eSAndroid Build Coastguard Worker namespace NBLog {
35*ec779b8eSAndroid Build Coastguard Worker 
Writer(void * shared,size_t size)36*ec779b8eSAndroid Build Coastguard Worker Writer::Writer(void *shared, size_t size)
37*ec779b8eSAndroid Build Coastguard Worker     : mShared((Shared *) shared),
38*ec779b8eSAndroid Build Coastguard Worker       mFifo(mShared != NULL ?
39*ec779b8eSAndroid Build Coastguard Worker         new audio_utils_fifo(size, sizeof(uint8_t),
40*ec779b8eSAndroid Build Coastguard Worker             mShared->mBuffer, mShared->mRear, NULL /*throttlesFront*/) : NULL),
41*ec779b8eSAndroid Build Coastguard Worker       mFifoWriter(mFifo != NULL ? new audio_utils_fifo_writer(*mFifo) : NULL),
42*ec779b8eSAndroid Build Coastguard Worker       mEnabled(mFifoWriter != NULL)
43*ec779b8eSAndroid Build Coastguard Worker {
44*ec779b8eSAndroid Build Coastguard Worker     // caching pid and process name
45*ec779b8eSAndroid Build Coastguard Worker     pid_t id = ::getpid();
46*ec779b8eSAndroid Build Coastguard Worker     char procName[16];
47*ec779b8eSAndroid Build Coastguard Worker     int status = prctl(PR_GET_NAME, procName);
48*ec779b8eSAndroid Build Coastguard Worker     if (status) {  // error getting process name
49*ec779b8eSAndroid Build Coastguard Worker         procName[0] = '\0';
50*ec779b8eSAndroid Build Coastguard Worker     }
51*ec779b8eSAndroid Build Coastguard Worker     size_t length = strlen(procName);
52*ec779b8eSAndroid Build Coastguard Worker     mPidTagSize = length + sizeof(pid_t);
53*ec779b8eSAndroid Build Coastguard Worker     mPidTag = new char[mPidTagSize];
54*ec779b8eSAndroid Build Coastguard Worker     memcpy(mPidTag, &id, sizeof(pid_t));
55*ec779b8eSAndroid Build Coastguard Worker     memcpy(mPidTag + sizeof(pid_t), procName, length);
56*ec779b8eSAndroid Build Coastguard Worker }
57*ec779b8eSAndroid Build Coastguard Worker 
Writer(const sp<IMemory> & iMemory,size_t size)58*ec779b8eSAndroid Build Coastguard Worker Writer::Writer(const sp<IMemory>& iMemory, size_t size)
59*ec779b8eSAndroid Build Coastguard Worker     // TODO: Using unsecurePointer() has some associated security pitfalls
60*ec779b8eSAndroid Build Coastguard Worker     //       (see declaration for details).
61*ec779b8eSAndroid Build Coastguard Worker     //       Either document why it is safe in this case or address the
62*ec779b8eSAndroid Build Coastguard Worker     //       issue (e.g. by copying).
63*ec779b8eSAndroid Build Coastguard Worker     : Writer(iMemory != 0 ? (Shared *) iMemory->unsecurePointer() : NULL, size)
64*ec779b8eSAndroid Build Coastguard Worker {
65*ec779b8eSAndroid Build Coastguard Worker     mIMemory = iMemory;
66*ec779b8eSAndroid Build Coastguard Worker }
67*ec779b8eSAndroid Build Coastguard Worker 
~Writer()68*ec779b8eSAndroid Build Coastguard Worker Writer::~Writer()
69*ec779b8eSAndroid Build Coastguard Worker {
70*ec779b8eSAndroid Build Coastguard Worker     delete mFifoWriter;
71*ec779b8eSAndroid Build Coastguard Worker     delete mFifo;
72*ec779b8eSAndroid Build Coastguard Worker     delete[] mPidTag;
73*ec779b8eSAndroid Build Coastguard Worker }
74*ec779b8eSAndroid Build Coastguard Worker 
log(const char * string)75*ec779b8eSAndroid Build Coastguard Worker void Writer::log(const char *string)
76*ec779b8eSAndroid Build Coastguard Worker {
77*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
78*ec779b8eSAndroid Build Coastguard Worker         return;
79*ec779b8eSAndroid Build Coastguard Worker     }
80*ec779b8eSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(string == NULL, "Attempted to log NULL string");
81*ec779b8eSAndroid Build Coastguard Worker     size_t length = strlen(string);
82*ec779b8eSAndroid Build Coastguard Worker     if (length > Entry::kMaxLength) {
83*ec779b8eSAndroid Build Coastguard Worker         length = Entry::kMaxLength;
84*ec779b8eSAndroid Build Coastguard Worker     }
85*ec779b8eSAndroid Build Coastguard Worker     log(EVENT_STRING, string, length);
86*ec779b8eSAndroid Build Coastguard Worker }
87*ec779b8eSAndroid Build Coastguard Worker 
logf(const char * fmt,...)88*ec779b8eSAndroid Build Coastguard Worker void Writer::logf(const char *fmt, ...)
89*ec779b8eSAndroid Build Coastguard Worker {
90*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
91*ec779b8eSAndroid Build Coastguard Worker         return;
92*ec779b8eSAndroid Build Coastguard Worker     }
93*ec779b8eSAndroid Build Coastguard Worker     va_list ap;
94*ec779b8eSAndroid Build Coastguard Worker     va_start(ap, fmt);
95*ec779b8eSAndroid Build Coastguard Worker     Writer::logvf(fmt, ap);     // the Writer:: is needed to avoid virtual dispatch for LockedWriter
96*ec779b8eSAndroid Build Coastguard Worker     va_end(ap);
97*ec779b8eSAndroid Build Coastguard Worker }
98*ec779b8eSAndroid Build Coastguard Worker 
logTimestamp()99*ec779b8eSAndroid Build Coastguard Worker void Writer::logTimestamp()
100*ec779b8eSAndroid Build Coastguard Worker {
101*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
102*ec779b8eSAndroid Build Coastguard Worker         return;
103*ec779b8eSAndroid Build Coastguard Worker     }
104*ec779b8eSAndroid Build Coastguard Worker     struct timespec ts;
105*ec779b8eSAndroid Build Coastguard Worker     if (!clock_gettime(CLOCK_MONOTONIC, &ts)) {
106*ec779b8eSAndroid Build Coastguard Worker         log(EVENT_TIMESTAMP, &ts, sizeof(ts));
107*ec779b8eSAndroid Build Coastguard Worker     }
108*ec779b8eSAndroid Build Coastguard Worker }
109*ec779b8eSAndroid Build Coastguard Worker 
logFormat(const char * fmt,log_hash_t hash,...)110*ec779b8eSAndroid Build Coastguard Worker void Writer::logFormat(const char *fmt, log_hash_t hash, ...)
111*ec779b8eSAndroid Build Coastguard Worker {
112*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
113*ec779b8eSAndroid Build Coastguard Worker         return;
114*ec779b8eSAndroid Build Coastguard Worker     }
115*ec779b8eSAndroid Build Coastguard Worker     va_list ap;
116*ec779b8eSAndroid Build Coastguard Worker     va_start(ap, hash);
117*ec779b8eSAndroid Build Coastguard Worker     Writer::logVFormat(fmt, hash, ap);
118*ec779b8eSAndroid Build Coastguard Worker     va_end(ap);
119*ec779b8eSAndroid Build Coastguard Worker }
120*ec779b8eSAndroid Build Coastguard Worker 
logEventHistTs(Event event,log_hash_t hash)121*ec779b8eSAndroid Build Coastguard Worker void Writer::logEventHistTs(Event event, log_hash_t hash)
122*ec779b8eSAndroid Build Coastguard Worker {
123*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
124*ec779b8eSAndroid Build Coastguard Worker         return;
125*ec779b8eSAndroid Build Coastguard Worker     }
126*ec779b8eSAndroid Build Coastguard Worker     HistTsEntry data;
127*ec779b8eSAndroid Build Coastguard Worker     data.hash = hash;
128*ec779b8eSAndroid Build Coastguard Worker     data.ts = systemTime();
129*ec779b8eSAndroid Build Coastguard Worker     if (data.ts > 0) {
130*ec779b8eSAndroid Build Coastguard Worker         log(event, &data, sizeof(data));
131*ec779b8eSAndroid Build Coastguard Worker     } else {
132*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Failed to get timestamp");
133*ec779b8eSAndroid Build Coastguard Worker     }
134*ec779b8eSAndroid Build Coastguard Worker }
135*ec779b8eSAndroid Build Coastguard Worker 
isEnabled() const136*ec779b8eSAndroid Build Coastguard Worker bool Writer::isEnabled() const
137*ec779b8eSAndroid Build Coastguard Worker {
138*ec779b8eSAndroid Build Coastguard Worker     return mEnabled;
139*ec779b8eSAndroid Build Coastguard Worker }
140*ec779b8eSAndroid Build Coastguard Worker 
setEnabled(bool enabled)141*ec779b8eSAndroid Build Coastguard Worker bool Writer::setEnabled(bool enabled)
142*ec779b8eSAndroid Build Coastguard Worker {
143*ec779b8eSAndroid Build Coastguard Worker     bool old = mEnabled;
144*ec779b8eSAndroid Build Coastguard Worker     mEnabled = enabled && mShared != NULL;
145*ec779b8eSAndroid Build Coastguard Worker     return old;
146*ec779b8eSAndroid Build Coastguard Worker }
147*ec779b8eSAndroid Build Coastguard Worker 
log(const Entry & etr,bool trusted)148*ec779b8eSAndroid Build Coastguard Worker void Writer::log(const Entry &etr, bool trusted)
149*ec779b8eSAndroid Build Coastguard Worker {
150*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
151*ec779b8eSAndroid Build Coastguard Worker         return;
152*ec779b8eSAndroid Build Coastguard Worker     }
153*ec779b8eSAndroid Build Coastguard Worker     if (!trusted) {
154*ec779b8eSAndroid Build Coastguard Worker         log(etr.mEvent, etr.mData, etr.mLength);
155*ec779b8eSAndroid Build Coastguard Worker         return;
156*ec779b8eSAndroid Build Coastguard Worker     }
157*ec779b8eSAndroid Build Coastguard Worker     const size_t need = etr.mLength + Entry::kOverhead; // mEvent, mLength, data[mLength], mLength
158*ec779b8eSAndroid Build Coastguard Worker                                                         // need = number of bytes written to FIFO
159*ec779b8eSAndroid Build Coastguard Worker 
160*ec779b8eSAndroid Build Coastguard Worker     // FIXME optimize this using memcpy for the data part of the Entry.
161*ec779b8eSAndroid Build Coastguard Worker     // The Entry could have a method copyTo(ptr, offset, size) to optimize the copy.
162*ec779b8eSAndroid Build Coastguard Worker     // checks size of a single log Entry: type, length, data pointer and ending
163*ec779b8eSAndroid Build Coastguard Worker     uint8_t temp[Entry::kMaxLength + Entry::kOverhead];
164*ec779b8eSAndroid Build Coastguard Worker     // write this data to temp array
165*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < need; i++) {
166*ec779b8eSAndroid Build Coastguard Worker         temp[i] = etr.copyEntryDataAt(i);
167*ec779b8eSAndroid Build Coastguard Worker     }
168*ec779b8eSAndroid Build Coastguard Worker     // write to circular buffer
169*ec779b8eSAndroid Build Coastguard Worker     mFifoWriter->write(temp, need);
170*ec779b8eSAndroid Build Coastguard Worker }
171*ec779b8eSAndroid Build Coastguard Worker 
log(Event event,const void * data,size_t length)172*ec779b8eSAndroid Build Coastguard Worker void Writer::log(Event event, const void *data, size_t length)
173*ec779b8eSAndroid Build Coastguard Worker {
174*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
175*ec779b8eSAndroid Build Coastguard Worker         return;
176*ec779b8eSAndroid Build Coastguard Worker     }
177*ec779b8eSAndroid Build Coastguard Worker     if (data == NULL || length > Entry::kMaxLength) {
178*ec779b8eSAndroid Build Coastguard Worker         // TODO Perhaps it makes sense to display truncated data or at least a
179*ec779b8eSAndroid Build Coastguard Worker         //      message that the data is too long?  The current behavior can create
180*ec779b8eSAndroid Build Coastguard Worker         //      a confusion for a programmer debugging their code.
181*ec779b8eSAndroid Build Coastguard Worker         return;
182*ec779b8eSAndroid Build Coastguard Worker     }
183*ec779b8eSAndroid Build Coastguard Worker     // Ignore if invalid event
184*ec779b8eSAndroid Build Coastguard Worker     if (event == EVENT_RESERVED || event >= EVENT_UPPER_BOUND) {
185*ec779b8eSAndroid Build Coastguard Worker         return;
186*ec779b8eSAndroid Build Coastguard Worker     }
187*ec779b8eSAndroid Build Coastguard Worker     Entry etr(event, data, length);
188*ec779b8eSAndroid Build Coastguard Worker     log(etr, true /*trusted*/);
189*ec779b8eSAndroid Build Coastguard Worker }
190*ec779b8eSAndroid Build Coastguard Worker 
logvf(const char * fmt,va_list ap)191*ec779b8eSAndroid Build Coastguard Worker void Writer::logvf(const char *fmt, va_list ap)
192*ec779b8eSAndroid Build Coastguard Worker {
193*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
194*ec779b8eSAndroid Build Coastguard Worker         return;
195*ec779b8eSAndroid Build Coastguard Worker     }
196*ec779b8eSAndroid Build Coastguard Worker     char buffer[Entry::kMaxLength + 1 /*NUL*/];
197*ec779b8eSAndroid Build Coastguard Worker     int length = vsnprintf(buffer, sizeof(buffer), fmt, ap);
198*ec779b8eSAndroid Build Coastguard Worker     if (length >= (int) sizeof(buffer)) {
199*ec779b8eSAndroid Build Coastguard Worker         length = sizeof(buffer) - 1;
200*ec779b8eSAndroid Build Coastguard Worker         // NUL termination is not required
201*ec779b8eSAndroid Build Coastguard Worker         // buffer[length] = '\0';
202*ec779b8eSAndroid Build Coastguard Worker     }
203*ec779b8eSAndroid Build Coastguard Worker     if (length >= 0) {
204*ec779b8eSAndroid Build Coastguard Worker         log(EVENT_STRING, buffer, length);
205*ec779b8eSAndroid Build Coastguard Worker     }
206*ec779b8eSAndroid Build Coastguard Worker }
207*ec779b8eSAndroid Build Coastguard Worker 
logStart(const char * fmt)208*ec779b8eSAndroid Build Coastguard Worker void Writer::logStart(const char *fmt)
209*ec779b8eSAndroid Build Coastguard Worker {
210*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
211*ec779b8eSAndroid Build Coastguard Worker         return;
212*ec779b8eSAndroid Build Coastguard Worker     }
213*ec779b8eSAndroid Build Coastguard Worker     size_t length = strlen(fmt);
214*ec779b8eSAndroid Build Coastguard Worker     if (length > Entry::kMaxLength) {
215*ec779b8eSAndroid Build Coastguard Worker         length = Entry::kMaxLength;
216*ec779b8eSAndroid Build Coastguard Worker     }
217*ec779b8eSAndroid Build Coastguard Worker     log(EVENT_FMT_START, fmt, length);
218*ec779b8eSAndroid Build Coastguard Worker }
219*ec779b8eSAndroid Build Coastguard Worker 
logTimestampFormat()220*ec779b8eSAndroid Build Coastguard Worker void Writer::logTimestampFormat()
221*ec779b8eSAndroid Build Coastguard Worker {
222*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
223*ec779b8eSAndroid Build Coastguard Worker         return;
224*ec779b8eSAndroid Build Coastguard Worker     }
225*ec779b8eSAndroid Build Coastguard Worker     const nsecs_t ts = systemTime();
226*ec779b8eSAndroid Build Coastguard Worker     if (ts > 0) {
227*ec779b8eSAndroid Build Coastguard Worker         log(EVENT_FMT_TIMESTAMP, &ts, sizeof(ts));
228*ec779b8eSAndroid Build Coastguard Worker     } else {
229*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Failed to get timestamp");
230*ec779b8eSAndroid Build Coastguard Worker     }
231*ec779b8eSAndroid Build Coastguard Worker }
232*ec779b8eSAndroid Build Coastguard Worker 
logVFormat(const char * fmt,log_hash_t hash,va_list argp)233*ec779b8eSAndroid Build Coastguard Worker void Writer::logVFormat(const char *fmt, log_hash_t hash, va_list argp)
234*ec779b8eSAndroid Build Coastguard Worker {
235*ec779b8eSAndroid Build Coastguard Worker     if (!mEnabled) {
236*ec779b8eSAndroid Build Coastguard Worker         return;
237*ec779b8eSAndroid Build Coastguard Worker     }
238*ec779b8eSAndroid Build Coastguard Worker     Writer::logStart(fmt);
239*ec779b8eSAndroid Build Coastguard Worker     int i;
240*ec779b8eSAndroid Build Coastguard Worker     double d;
241*ec779b8eSAndroid Build Coastguard Worker     float f;
242*ec779b8eSAndroid Build Coastguard Worker     char* s;
243*ec779b8eSAndroid Build Coastguard Worker     size_t length;
244*ec779b8eSAndroid Build Coastguard Worker     int64_t t;
245*ec779b8eSAndroid Build Coastguard Worker     Writer::logTimestampFormat();
246*ec779b8eSAndroid Build Coastguard Worker     log(EVENT_FMT_HASH, &hash, sizeof(hash));
247*ec779b8eSAndroid Build Coastguard Worker     for (const char *p = fmt; *p != '\0'; p++) {
248*ec779b8eSAndroid Build Coastguard Worker         // TODO: implement more complex formatting such as %.3f
249*ec779b8eSAndroid Build Coastguard Worker         if (*p != '%') {
250*ec779b8eSAndroid Build Coastguard Worker             continue;
251*ec779b8eSAndroid Build Coastguard Worker         }
252*ec779b8eSAndroid Build Coastguard Worker         switch(*++p) {
253*ec779b8eSAndroid Build Coastguard Worker         case 's': // string
254*ec779b8eSAndroid Build Coastguard Worker             s = va_arg(argp, char *);
255*ec779b8eSAndroid Build Coastguard Worker             length = strlen(s);
256*ec779b8eSAndroid Build Coastguard Worker             if (length > Entry::kMaxLength) {
257*ec779b8eSAndroid Build Coastguard Worker                 length = Entry::kMaxLength;
258*ec779b8eSAndroid Build Coastguard Worker             }
259*ec779b8eSAndroid Build Coastguard Worker             log(EVENT_FMT_STRING, s, length);
260*ec779b8eSAndroid Build Coastguard Worker             break;
261*ec779b8eSAndroid Build Coastguard Worker 
262*ec779b8eSAndroid Build Coastguard Worker         case 't': // timestamp
263*ec779b8eSAndroid Build Coastguard Worker             t = va_arg(argp, int64_t);
264*ec779b8eSAndroid Build Coastguard Worker             log(EVENT_FMT_TIMESTAMP, &t, sizeof(t));
265*ec779b8eSAndroid Build Coastguard Worker             break;
266*ec779b8eSAndroid Build Coastguard Worker 
267*ec779b8eSAndroid Build Coastguard Worker         case 'd': // integer
268*ec779b8eSAndroid Build Coastguard Worker             i = va_arg(argp, int);
269*ec779b8eSAndroid Build Coastguard Worker             log(EVENT_FMT_INTEGER, &i, sizeof(i));
270*ec779b8eSAndroid Build Coastguard Worker             break;
271*ec779b8eSAndroid Build Coastguard Worker 
272*ec779b8eSAndroid Build Coastguard Worker         case 'f': // float
273*ec779b8eSAndroid Build Coastguard Worker             d = va_arg(argp, double); // float arguments are promoted to double in vararg lists
274*ec779b8eSAndroid Build Coastguard Worker             f = (float)d;
275*ec779b8eSAndroid Build Coastguard Worker             log(EVENT_FMT_FLOAT, &f, sizeof(f));
276*ec779b8eSAndroid Build Coastguard Worker             break;
277*ec779b8eSAndroid Build Coastguard Worker 
278*ec779b8eSAndroid Build Coastguard Worker         case 'p': // pid
279*ec779b8eSAndroid Build Coastguard Worker             log(EVENT_FMT_PID, mPidTag, mPidTagSize);
280*ec779b8eSAndroid Build Coastguard Worker             break;
281*ec779b8eSAndroid Build Coastguard Worker 
282*ec779b8eSAndroid Build Coastguard Worker         // the "%\0" case finishes parsing
283*ec779b8eSAndroid Build Coastguard Worker         case '\0':
284*ec779b8eSAndroid Build Coastguard Worker             --p;
285*ec779b8eSAndroid Build Coastguard Worker             break;
286*ec779b8eSAndroid Build Coastguard Worker 
287*ec779b8eSAndroid Build Coastguard Worker         case '%':
288*ec779b8eSAndroid Build Coastguard Worker             break;
289*ec779b8eSAndroid Build Coastguard Worker 
290*ec779b8eSAndroid Build Coastguard Worker         default:
291*ec779b8eSAndroid Build Coastguard Worker             ALOGW("NBLog Writer parsed invalid format specifier: %c", *p);
292*ec779b8eSAndroid Build Coastguard Worker             break;
293*ec779b8eSAndroid Build Coastguard Worker         }
294*ec779b8eSAndroid Build Coastguard Worker     }
295*ec779b8eSAndroid Build Coastguard Worker     Entry etr(EVENT_FMT_END, nullptr, 0);
296*ec779b8eSAndroid Build Coastguard Worker     log(etr, true);
297*ec779b8eSAndroid Build Coastguard Worker }
298*ec779b8eSAndroid Build Coastguard Worker 
299*ec779b8eSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
300*ec779b8eSAndroid Build Coastguard Worker 
LockedWriter(void * shared,size_t size)301*ec779b8eSAndroid Build Coastguard Worker LockedWriter::LockedWriter(void *shared, size_t size)
302*ec779b8eSAndroid Build Coastguard Worker     : Writer(shared, size)
303*ec779b8eSAndroid Build Coastguard Worker {
304*ec779b8eSAndroid Build Coastguard Worker }
305*ec779b8eSAndroid Build Coastguard Worker 
isEnabled() const306*ec779b8eSAndroid Build Coastguard Worker bool LockedWriter::isEnabled() const
307*ec779b8eSAndroid Build Coastguard Worker {
308*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(mLock);
309*ec779b8eSAndroid Build Coastguard Worker     return Writer::isEnabled();
310*ec779b8eSAndroid Build Coastguard Worker }
311*ec779b8eSAndroid Build Coastguard Worker 
setEnabled(bool enabled)312*ec779b8eSAndroid Build Coastguard Worker bool LockedWriter::setEnabled(bool enabled)
313*ec779b8eSAndroid Build Coastguard Worker {
314*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(mLock);
315*ec779b8eSAndroid Build Coastguard Worker     return Writer::setEnabled(enabled);
316*ec779b8eSAndroid Build Coastguard Worker }
317*ec779b8eSAndroid Build Coastguard Worker 
log(const Entry & entry,bool trusted)318*ec779b8eSAndroid Build Coastguard Worker void LockedWriter::log(const Entry &entry, bool trusted) {
319*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock _l(mLock);
320*ec779b8eSAndroid Build Coastguard Worker     Writer::log(entry, trusted);
321*ec779b8eSAndroid Build Coastguard Worker }
322*ec779b8eSAndroid Build Coastguard Worker 
323*ec779b8eSAndroid Build Coastguard Worker }   // namespace NBLog
324*ec779b8eSAndroid Build Coastguard Worker }   // namespace android
325