1/*
2 * Copyright (C) 2013-2016 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 <fcntl.h>
18#include <inttypes.h>
19#include <semaphore.h>
20#include <signal.h>
21#include <string.h>
22#include <sys/types.h>
23#include <unistd.h>
24
25#include <cutils/properties.h>
26#include <gtest/gtest.h>
27#include <log/log.h>
28#include <log/logger.h>
29#include <log/log_read.h>
30#include <log/logprint.h>
31#include <private/android_filesystem_config.h>
32#include <private/android_logger.h>
33
34// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
35// non-syscall libs. Since we are only using this in the emergency of
36// a signal to stuff a terminating code into the logs, we will spin rather
37// than try a usleep.
38#define LOG_FAILURE_RETRY(exp) ({  \
39    typeof (exp) _rc;              \
40    do {                           \
41        _rc = (exp);               \
42    } while (((_rc == -1)          \
43           && ((errno == EINTR)    \
44            || (errno == EAGAIN))) \
45          || (_rc == -EINTR)       \
46          || (_rc == -EAGAIN));    \
47    _rc; })
48
49TEST(liblog, __android_log_buf_print) {
50    EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,
51                                         "TEST__android_log_buf_print",
52                                         "radio"));
53    usleep(1000);
54    EXPECT_LT(0, __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
55                                         "TEST__android_log_buf_print",
56                                         "system"));
57    usleep(1000);
58    EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
59                                         "TEST__android_log_buf_print",
60                                         "main"));
61    usleep(1000);
62}
63
64TEST(liblog, __android_log_buf_write) {
65    EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,
66                                         "TEST__android_log_buf_write",
67                                         "radio"));
68    usleep(1000);
69    EXPECT_LT(0, __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
70                                         "TEST__android_log_buf_write",
71                                         "system"));
72    usleep(1000);
73    EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
74                                         "TEST__android_log_buf_write",
75                                         "main"));
76    usleep(1000);
77}
78
79TEST(liblog, __android_log_btwrite) {
80    int intBuf = 0xDEADBEEF;
81    EXPECT_LT(0, __android_log_btwrite(0,
82                                      EVENT_TYPE_INT,
83                                      &intBuf, sizeof(intBuf)));
84    long long longBuf = 0xDEADBEEFA55A5AA5;
85    EXPECT_LT(0, __android_log_btwrite(0,
86                                      EVENT_TYPE_LONG,
87                                      &longBuf, sizeof(longBuf)));
88    usleep(1000);
89    char Buf[] = "\20\0\0\0DeAdBeEfA55a5aA5";
90    EXPECT_LT(0, __android_log_btwrite(0,
91                                      EVENT_TYPE_STRING,
92                                      Buf, sizeof(Buf) - 1));
93    usleep(1000);
94}
95
96static void* ConcurrentPrintFn(void *arg) {
97    int ret = __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
98                                  "TEST__android_log_print", "Concurrent %" PRIuPTR,
99                                  reinterpret_cast<uintptr_t>(arg));
100    return reinterpret_cast<void*>(ret);
101}
102
103#define NUM_CONCURRENT 64
104#define _concurrent_name(a,n) a##__concurrent##n
105#define concurrent_name(a,n) _concurrent_name(a,n)
106
107TEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) {
108    pthread_t t[NUM_CONCURRENT];
109    int i;
110    for (i=0; i < NUM_CONCURRENT; i++) {
111        ASSERT_EQ(0, pthread_create(&t[i], NULL,
112                                    ConcurrentPrintFn,
113                                    reinterpret_cast<void *>(i)));
114    }
115    int ret = 0;
116    for (i=0; i < NUM_CONCURRENT; i++) {
117        void* result;
118        ASSERT_EQ(0, pthread_join(t[i], &result));
119        int this_result = reinterpret_cast<uintptr_t>(result);
120        if ((0 == ret) && (0 != this_result)) {
121            ret = this_result;
122        }
123    }
124    ASSERT_LT(0, ret);
125}
126
127TEST(liblog, __android_log_btwrite__android_logger_list_read) {
128    struct logger_list *logger_list;
129
130    pid_t pid = getpid();
131
132    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
133        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
134
135    // Check that we can close and reopen the logger
136    log_time ts(CLOCK_MONOTONIC);
137    ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
138    __android_log_close();
139
140    log_time ts1(CLOCK_MONOTONIC);
141    ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
142    usleep(1000000);
143
144    int count = 0;
145    int second_count = 0;
146
147    for (;;) {
148        log_msg log_msg;
149        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
150            break;
151        }
152
153        ASSERT_EQ(log_msg.entry.pid, pid);
154
155        if ((log_msg.entry.len != (4 + 1 + 8))
156         || (log_msg.id() != LOG_ID_EVENTS)) {
157            continue;
158        }
159
160        char *eventData = log_msg.msg();
161
162        if (eventData[4] != EVENT_TYPE_LONG) {
163            continue;
164        }
165
166        log_time tx(eventData + 4 + 1);
167        if (ts == tx) {
168            ++count;
169        } else if (ts1 == tx) {
170            ++second_count;
171        }
172    }
173
174    EXPECT_EQ(1, count);
175    EXPECT_EQ(1, second_count);
176
177    android_logger_list_close(logger_list);
178}
179
180static inline int32_t get4LE(const char* src)
181{
182    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
183}
184
185TEST(liblog, __android_log_bswrite) {
186    struct logger_list *logger_list;
187
188    pid_t pid = getpid();
189
190    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
191        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
192
193    static const char buffer[] = "Hello World";
194    log_time ts(android_log_clockid());
195
196    ASSERT_LT(0, __android_log_bswrite(0, buffer));
197    usleep(1000000);
198
199    int count = 0;
200
201    for (;;) {
202        log_msg log_msg;
203        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
204            break;
205        }
206
207        ASSERT_EQ(log_msg.entry.pid, pid);
208
209        if ((log_msg.entry.sec < (ts.tv_sec - 1))
210         || ((ts.tv_sec + 1) < log_msg.entry.sec)
211         || (log_msg.entry.len != (4 + 1 + 4 + sizeof(buffer) - 1))
212         || (log_msg.id() != LOG_ID_EVENTS)) {
213            continue;
214        }
215
216        char *eventData = log_msg.msg();
217
218        if (eventData[4] != EVENT_TYPE_STRING) {
219            continue;
220        }
221
222        int len = get4LE(eventData + 4 + 1);
223        if (len == (sizeof(buffer) - 1)) {
224            ++count;
225
226            AndroidLogFormat *logformat = android_log_format_new();
227            EXPECT_TRUE(NULL != logformat);
228            AndroidLogEntry entry;
229            char msgBuf[1024];
230            EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
231                                                            &entry,
232                                                            NULL,
233                                                            msgBuf,
234                                                            sizeof(msgBuf)));
235            fflush(stderr);
236            EXPECT_EQ(31, android_log_printLogLine(logformat, fileno(stderr), &entry));
237            android_log_format_free(logformat);
238        }
239    }
240
241    EXPECT_EQ(1, count);
242
243    android_logger_list_close(logger_list);
244}
245
246TEST(liblog, __android_log_bswrite__empty_string) {
247    struct logger_list *logger_list;
248
249    pid_t pid = getpid();
250
251    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
252        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
253
254    static const char buffer[] = "";
255    log_time ts(android_log_clockid());
256
257    ASSERT_LT(0, __android_log_bswrite(0, buffer));
258    usleep(1000000);
259
260    int count = 0;
261
262    for (;;) {
263        log_msg log_msg;
264        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
265            break;
266        }
267
268        ASSERT_EQ(log_msg.entry.pid, pid);
269
270        if ((log_msg.entry.sec < (ts.tv_sec - 1))
271         || ((ts.tv_sec + 1) < log_msg.entry.sec)
272         || (log_msg.entry.len != (4 + 1 + 4))
273         || (log_msg.id() != LOG_ID_EVENTS)) {
274            continue;
275        }
276
277        char *eventData = log_msg.msg();
278
279        if (eventData[4] != EVENT_TYPE_STRING) {
280            continue;
281        }
282
283        int len = get4LE(eventData + 4 + 1);
284        if (len == 0) {
285            ++count;
286
287            AndroidLogFormat *logformat = android_log_format_new();
288            EXPECT_TRUE(NULL != logformat);
289            AndroidLogEntry entry;
290            char msgBuf[1024];
291            EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
292                                                            &entry,
293                                                            NULL,
294                                                            msgBuf,
295                                                            sizeof(msgBuf)));
296            fflush(stderr);
297            EXPECT_EQ(20, android_log_printLogLine(logformat, fileno(stderr), &entry));
298            android_log_format_free(logformat);
299        }
300    }
301
302    EXPECT_EQ(1, count);
303
304    android_logger_list_close(logger_list);
305}
306
307TEST(liblog, __security) {
308    static const char persist_key[] = "persist.logd.security";
309    static const char readonly_key[] = "ro.device_owner";
310    static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_";
311    char persist[PROP_VALUE_MAX];
312    char readonly[PROP_VALUE_MAX];
313
314    property_get(persist_key, persist, "");
315    property_get(readonly_key, readonly, nothing_val);
316
317    if (!strcmp(readonly, nothing_val)) {
318        EXPECT_FALSE(__android_log_security());
319        fprintf(stderr, "Warning, setting ro.device_owner to a domain\n");
320        property_set(readonly_key, "com.google.android.SecOps.DeviceOwner");
321    } else if (!strcasecmp(readonly, "false") || !readonly[0]) {
322        EXPECT_FALSE(__android_log_security());
323        return;
324    }
325
326    if (!strcasecmp(persist, "true")) {
327        EXPECT_TRUE(__android_log_security());
328    } else {
329        EXPECT_FALSE(__android_log_security());
330    }
331    property_set(persist_key, "TRUE");
332    EXPECT_TRUE(__android_log_security());
333    property_set(persist_key, "FALSE");
334    EXPECT_FALSE(__android_log_security());
335    property_set(persist_key, "true");
336    EXPECT_TRUE(__android_log_security());
337    property_set(persist_key, "false");
338    EXPECT_FALSE(__android_log_security());
339    property_set(persist_key, "");
340    EXPECT_FALSE(__android_log_security());
341    property_set(persist_key, persist);
342}
343
344TEST(liblog, __security_buffer) {
345    struct logger_list *logger_list;
346    android_event_long_t buffer;
347
348    static const char persist_key[] = "persist.logd.security";
349    char persist[PROP_VALUE_MAX];
350    bool set_persist = false;
351    bool allow_security = false;
352
353    if (__android_log_security()) {
354        allow_security = true;
355    } else {
356        property_get(persist_key, persist, "");
357        if (strcasecmp(persist, "true")) {
358            property_set(persist_key, "TRUE");
359            if (__android_log_security()) {
360                allow_security = true;
361                set_persist = true;
362            } else {
363                property_set(persist_key, persist);
364            }
365        }
366    }
367
368    if (!allow_security) {
369        fprintf(stderr, "WARNING: "
370                "security buffer disabled, bypassing end-to-end test\n");
371
372        log_time ts(CLOCK_MONOTONIC);
373
374        buffer.type = EVENT_TYPE_LONG;
375        buffer.data = *(static_cast<uint64_t *>((void *)&ts));
376
377        // expect failure!
378        ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
379
380        return;
381    }
382
383    /* Matches clientHasLogCredentials() in logd */
384    uid_t uid = getuid();
385    gid_t gid = getgid();
386    bool clientHasLogCredentials = true;
387    if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)
388     && (gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
389        uid_t euid = geteuid();
390        if ((euid != AID_SYSTEM) && (euid != AID_ROOT) && (euid != AID_LOG)) {
391            gid_t egid = getegid();
392            if ((egid != AID_SYSTEM) && (egid != AID_ROOT) && (egid != AID_LOG)) {
393                int num_groups = getgroups(0, NULL);
394                if (num_groups > 0) {
395                    gid_t groups[num_groups];
396                    num_groups = getgroups(num_groups, groups);
397                    while (num_groups > 0) {
398                        if (groups[num_groups - 1] == AID_LOG) {
399                            break;
400                        }
401                        --num_groups;
402                    }
403                }
404                if (num_groups <= 0) {
405                    clientHasLogCredentials = false;
406                }
407            }
408        }
409    }
410    if (!clientHasLogCredentials) {
411        fprintf(stderr, "WARNING: "
412                "not in system context, bypassing end-to-end test\n");
413
414        log_time ts(CLOCK_MONOTONIC);
415
416        buffer.type = EVENT_TYPE_LONG;
417        buffer.data = *(static_cast<uint64_t *>((void *)&ts));
418
419        // expect failure!
420        ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
421
422        return;
423    }
424
425    pid_t pid = getpid();
426
427    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
428        LOG_ID_SECURITY, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
429        1000, pid)));
430
431    log_time ts(CLOCK_MONOTONIC);
432
433    buffer.type = EVENT_TYPE_LONG;
434    buffer.data = *(static_cast<uint64_t *>((void *)&ts));
435
436    ASSERT_LT(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
437    usleep(1000000);
438
439    int count = 0;
440
441    for (;;) {
442        log_msg log_msg;
443        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
444            break;
445        }
446
447        ASSERT_EQ(log_msg.entry.pid, pid);
448
449        if ((log_msg.entry.len != (4 + 1 + 8))
450         || (log_msg.id() != LOG_ID_SECURITY)) {
451            continue;
452        }
453
454        char *eventData = log_msg.msg();
455
456        if (eventData[4] != EVENT_TYPE_LONG) {
457            continue;
458        }
459
460        log_time tx(eventData + 4 + 1);
461        if (ts == tx) {
462            ++count;
463        }
464    }
465
466    if (set_persist) {
467        property_set(persist_key, persist);
468    }
469
470    android_logger_list_close(logger_list);
471
472    bool clientHasSecurityCredentials = (uid == AID_SYSTEM) || (gid == AID_SYSTEM);
473    if (!clientHasSecurityCredentials) {
474        fprintf(stderr, "WARNING: "
475                "not system, content submitted but can not check end-to-end\n");
476    }
477    EXPECT_EQ(clientHasSecurityCredentials ? 1 : 0, count);
478
479}
480
481static unsigned signaled;
482static log_time signal_time;
483
484/*
485 *  Strictly, we are not allowed to log messages in a signal context, but we
486 * do make an effort to keep the failure surface minimized, and this in-effect
487 * should catch any regressions in that effort. The odds of a logged message
488 * in a signal handler causing a lockup problem should be _very_ small.
489 */
490static void caught_blocking_signal(int /*signum*/)
491{
492    unsigned long long v = 0xDEADBEEFA55A0000ULL;
493
494    v += getpid() & 0xFFFF;
495
496    ++signaled;
497    if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {
498        signal_time = log_time(CLOCK_MONOTONIC);
499        signal_time.tv_sec += 2;
500    }
501
502    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
503}
504
505// Fill in current process user and system time in 10ms increments
506static void get_ticks(unsigned long long *uticks, unsigned long long *sticks)
507{
508    *uticks = *sticks = 0;
509
510    pid_t pid = getpid();
511
512    char buffer[512];
513    snprintf(buffer, sizeof(buffer), "/proc/%u/stat", pid);
514
515    FILE *fp = fopen(buffer, "r");
516    if (!fp) {
517        return;
518    }
519
520    char *cp = fgets(buffer, sizeof(buffer), fp);
521    fclose(fp);
522    if (!cp) {
523        return;
524    }
525
526    pid_t d;
527    char s[sizeof(buffer)];
528    char c;
529    long long ll;
530    unsigned long long ull;
531
532    if (15 != sscanf(buffer,
533      "%d %s %c %lld %lld %lld %lld %lld %llu %llu %llu %llu %llu %llu %llu ",
534      &d, s, &c, &ll, &ll, &ll, &ll, &ll, &ull, &ull, &ull, &ull, &ull,
535      uticks, sticks)) {
536        *uticks = *sticks = 0;
537    }
538}
539
540TEST(liblog, android_logger_list_read__cpu_signal) {
541    struct logger_list *logger_list;
542    unsigned long long v = 0xDEADBEEFA55A0000ULL;
543
544    pid_t pid = getpid();
545
546    v += pid & 0xFFFF;
547
548    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
549        LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid)));
550
551    int count = 0;
552
553    int signals = 0;
554
555    unsigned long long uticks_start;
556    unsigned long long sticks_start;
557    get_ticks(&uticks_start, &sticks_start);
558
559    const unsigned alarm_time = 10;
560
561    memset(&signal_time, 0, sizeof(signal_time));
562
563    signal(SIGALRM, caught_blocking_signal);
564    alarm(alarm_time);
565
566    signaled = 0;
567
568    do {
569        log_msg log_msg;
570        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
571            break;
572        }
573
574        alarm(alarm_time);
575
576        ++count;
577
578        ASSERT_EQ(log_msg.entry.pid, pid);
579
580        if ((log_msg.entry.len != (4 + 1 + 8))
581         || (log_msg.id() != LOG_ID_EVENTS)) {
582            continue;
583        }
584
585        char *eventData = log_msg.msg();
586
587        if (eventData[4] != EVENT_TYPE_LONG) {
588            continue;
589        }
590
591        unsigned long long l = eventData[4 + 1 + 0] & 0xFF;
592        l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;
593        l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;
594        l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;
595        l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;
596        l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;
597        l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;
598        l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;
599
600        if (l == v) {
601            ++signals;
602            break;
603        }
604    } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));
605    alarm(0);
606    signal(SIGALRM, SIG_DFL);
607
608    EXPECT_LE(1, count);
609
610    EXPECT_EQ(1, signals);
611
612    android_logger_list_close(logger_list);
613
614    unsigned long long uticks_end;
615    unsigned long long sticks_end;
616    get_ticks(&uticks_end, &sticks_end);
617
618    // Less than 1% in either user or system time, or both
619    const unsigned long long one_percent_ticks = alarm_time;
620    unsigned long long user_ticks = uticks_end - uticks_start;
621    unsigned long long system_ticks = sticks_end - sticks_start;
622    EXPECT_GT(one_percent_ticks, user_ticks);
623    EXPECT_GT(one_percent_ticks, system_ticks);
624    EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
625}
626
627/*
628 *  Strictly, we are not allowed to log messages in a signal context, the
629 * correct way to handle this is to ensure the messages are constructed in
630 * a thread; the signal handler should only unblock the thread.
631 */
632static sem_t thread_trigger;
633
634static void caught_blocking_thread(int /*signum*/)
635{
636    sem_post(&thread_trigger);
637}
638
639static void *running_thread(void *) {
640    unsigned long long v = 0xDEADBEAFA55A0000ULL;
641
642    v += getpid() & 0xFFFF;
643
644    struct timespec timeout;
645    clock_gettime(CLOCK_REALTIME, &timeout);
646    timeout.tv_sec += 55;
647    sem_timedwait(&thread_trigger, &timeout);
648
649    ++signaled;
650    if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {
651        signal_time = log_time(CLOCK_MONOTONIC);
652        signal_time.tv_sec += 2;
653    }
654
655    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
656
657    return NULL;
658}
659
660int start_thread()
661{
662    sem_init(&thread_trigger, 0, 0);
663
664    pthread_attr_t attr;
665    if (pthread_attr_init(&attr)) {
666        return -1;
667    }
668
669    struct sched_param param;
670
671    memset(&param, 0, sizeof(param));
672    pthread_attr_setschedparam(&attr, &param);
673    pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
674
675    if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
676        pthread_attr_destroy(&attr);
677        return -1;
678    }
679
680    pthread_t thread;
681    if (pthread_create(&thread, &attr, running_thread, NULL)) {
682        pthread_attr_destroy(&attr);
683        return -1;
684    }
685
686    pthread_attr_destroy(&attr);
687    return 0;
688}
689
690TEST(liblog, android_logger_list_read__cpu_thread) {
691    struct logger_list *logger_list;
692    unsigned long long v = 0xDEADBEAFA55A0000ULL;
693
694    pid_t pid = getpid();
695
696    v += pid & 0xFFFF;
697
698    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
699        LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid)));
700
701    int count = 0;
702
703    int signals = 0;
704
705    unsigned long long uticks_start;
706    unsigned long long sticks_start;
707    get_ticks(&uticks_start, &sticks_start);
708
709    const unsigned alarm_time = 10;
710
711    memset(&signal_time, 0, sizeof(signal_time));
712
713    signaled = 0;
714    EXPECT_EQ(0, start_thread());
715
716    signal(SIGALRM, caught_blocking_thread);
717    alarm(alarm_time);
718
719    do {
720        log_msg log_msg;
721        if (LOG_FAILURE_RETRY(android_logger_list_read(logger_list, &log_msg)) <= 0) {
722            break;
723        }
724
725        alarm(alarm_time);
726
727        ++count;
728
729        ASSERT_EQ(log_msg.entry.pid, pid);
730
731        if ((log_msg.entry.len != (4 + 1 + 8))
732         || (log_msg.id() != LOG_ID_EVENTS)) {
733            continue;
734        }
735
736        char *eventData = log_msg.msg();
737
738        if (eventData[4] != EVENT_TYPE_LONG) {
739            continue;
740        }
741
742        unsigned long long l = eventData[4 + 1 + 0] & 0xFF;
743        l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;
744        l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;
745        l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;
746        l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;
747        l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;
748        l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;
749        l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;
750
751        if (l == v) {
752            ++signals;
753            break;
754        }
755    } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));
756    alarm(0);
757    signal(SIGALRM, SIG_DFL);
758
759    EXPECT_LE(1, count);
760
761    EXPECT_EQ(1, signals);
762
763    android_logger_list_close(logger_list);
764
765    unsigned long long uticks_end;
766    unsigned long long sticks_end;
767    get_ticks(&uticks_end, &sticks_end);
768
769    // Less than 1% in either user or system time, or both
770    const unsigned long long one_percent_ticks = alarm_time;
771    unsigned long long user_ticks = uticks_end - uticks_start;
772    unsigned long long system_ticks = sticks_end - sticks_start;
773    EXPECT_GT(one_percent_ticks, user_ticks);
774    EXPECT_GT(one_percent_ticks, system_ticks);
775    EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
776}
777
778static const char max_payload_tag[] = "TEST_max_payload_XXXX";
779#define SIZEOF_MAX_PAYLOAD_BUF (LOGGER_ENTRY_MAX_PAYLOAD - \
780                                sizeof(max_payload_tag) - 1)
781static const char max_payload_buf[] = "LEONATO\n\
782I learn in this letter that Don Peter of Arragon\n\
783comes this night to Messina\n\
784MESSENGER\n\
785He is very near by this: he was not three leagues off\n\
786when I left him\n\
787LEONATO\n\
788How many gentlemen have you lost in this action?\n\
789MESSENGER\n\
790But few of any sort, and none of name\n\
791LEONATO\n\
792A victory is twice itself when the achiever brings\n\
793home full numbers. I find here that Don Peter hath\n\
794bestowed much honour on a young Florentine called Claudio\n\
795MESSENGER\n\
796Much deserved on his part and equally remembered by\n\
797Don Pedro: he hath borne himself beyond the\n\
798promise of his age, doing, in the figure of a lamb,\n\
799the feats of a lion: he hath indeed better\n\
800bettered expectation than you must expect of me to\n\
801tell you how\n\
802LEONATO\n\
803He hath an uncle here in Messina will be very much\n\
804glad of it.\n\
805MESSENGER\n\
806I have already delivered him letters, and there\n\
807appears much joy in him; even so much that joy could\n\
808not show itself modest enough without a badge of\n\
809bitterness.\n\
810LEONATO\n\
811Did he break out into tears?\n\
812MESSENGER\n\
813In great measure.\n\
814LEONATO\n\
815A kind overflow of kindness: there are no faces\n\
816truer than those that are so washed. How much\n\
817better is it to weep at joy than to joy at weeping!\n\
818BEATRICE\n\
819I pray you, is Signior Mountanto returned from the\n\
820wars or no?\n\
821MESSENGER\n\
822I know none of that name, lady: there was none such\n\
823in the army of any sort.\n\
824LEONATO\n\
825What is he that you ask for, niece?\n\
826HERO\n\
827My cousin means Signior Benedick of Padua.\n\
828MESSENGER\n\
829O, he's returned; and as pleasant as ever he was.\n\
830BEATRICE\n\
831He set up his bills here in Messina and challenged\n\
832Cupid at the flight; and my uncle's fool, reading\n\
833the challenge, subscribed for Cupid, and challenged\n\
834him at the bird-bolt. I pray you, how many hath he\n\
835killed and eaten in these wars? But how many hath\n\
836he killed? for indeed I promised to eat all of his killing.\n\
837LEONATO\n\
838Faith, niece, you tax Signior Benedick too much;\n\
839but he'll be meet with you, I doubt it not.\n\
840MESSENGER\n\
841He hath done good service, lady, in these wars.\n\
842BEATRICE\n\
843You had musty victual, and he hath holp to eat it:\n\
844he is a very valiant trencherman; he hath an\n\
845excellent stomach.\n\
846MESSENGER\n\
847And a good soldier too, lady.\n\
848BEATRICE\n\
849And a good soldier to a lady: but what is he to a lord?\n\
850MESSENGER\n\
851A lord to a lord, a man to a man; stuffed with all\n\
852honourable virtues.\n\
853BEATRICE\n\
854It is so, indeed; he is no less than a stuffed man:\n\
855but for the stuffing,--well, we are all mortal.\n\
856LEONATO\n\
857You must not, sir, mistake my niece. There is a\n\
858kind of merry war betwixt Signior Benedick and her:\n\
859they never meet but there's a skirmish of wit\n\
860between them.\n\
861BEATRICE\n\
862Alas! he gets nothing by that. In our last\n\
863conflict four of his five wits went halting off, and\n\
864now is the whole man governed with one: so that if\n\
865he have wit enough to keep himself warm, let him\n\
866bear it for a difference between himself and his\n\
867horse; for it is all the wealth that he hath left,\n\
868to be known a reasonable creature. Who is his\n\
869companion now? He hath every month a new sworn brother.\n\
870MESSENGER\n\
871Is't possible?\n\
872BEATRICE\n\
873Very easily possible: he wears his faith but as\n\
874the fashion of his hat; it ever changes with the\n\
875next block.\n\
876MESSENGER\n\
877I see, lady, the gentleman is not in your books.\n\
878BEATRICE\n\
879No; an he were, I would burn my study. But, I pray\n\
880you, who is his companion? Is there no young\n\
881squarer now that will make a voyage with him to the devil?\n\
882MESSENGER\n\
883He is most in the company of the right noble Claudio.\n\
884BEATRICE\n\
885O Lord, he will hang upon him like a disease: he\n\
886is sooner caught than the pestilence, and the taker\n\
887runs presently mad. God help the noble Claudio! if\n\
888he have caught the Benedick, it will cost him a\n\
889thousand pound ere a' be cured.\n\
890MESSENGER\n\
891I will hold friends with you, lady.\n\
892BEATRICE\n\
893Do, good friend.\n\
894LEONATO\n\
895You will never run mad, niece.\n\
896BEATRICE\n\
897No, not till a hot January.\n\
898MESSENGER\n\
899Don Pedro is approached.\n\
900Enter DON PEDRO, DON JOHN, CLAUDIO, BENEDICK, and BALTHASAR\n\
901\n\
902DON PEDRO\n\
903Good Signior Leonato, you are come to meet your\n\
904trouble: the fashion of the world is to avoid\n\
905cost, and you encounter it\n\
906LEONATO\n\
907Never came trouble to my house in the likeness of your grace,\n\
908for trouble being gone, comfort should remain, but\n\
909when you depart from me, sorrow abides and happiness\n\
910takes his leave.";
911
912TEST(liblog, max_payload) {
913    pid_t pid = getpid();
914    char tag[sizeof(max_payload_tag)];
915    memcpy(tag, max_payload_tag, sizeof(tag));
916    snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
917
918    LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
919                                              tag, max_payload_buf));
920    sleep(2);
921
922    struct logger_list *logger_list;
923
924    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
925        LOG_ID_SYSTEM, ANDROID_LOG_RDONLY, 100, 0)));
926
927    bool matches = false;
928    ssize_t max_len = 0;
929
930    for(;;) {
931        log_msg log_msg;
932        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
933            break;
934        }
935
936        if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
937            continue;
938        }
939
940        char *data = log_msg.msg() + 1;
941
942        if (strcmp(data, tag)) {
943            continue;
944        }
945
946        data += strlen(data) + 1;
947
948        const char *left = data;
949        const char *right = max_payload_buf;
950        while (*left && *right && (*left == *right)) {
951            ++left;
952            ++right;
953        }
954
955        if (max_len <= (left - data)) {
956            max_len = left - data + 1;
957        }
958
959        if (max_len > 512) {
960            matches = true;
961            break;
962        }
963    }
964
965    android_logger_list_close(logger_list);
966
967    EXPECT_EQ(true, matches);
968
969    EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len));
970}
971
972TEST(liblog, __android_log_buf_print__maxtag) {
973    struct logger_list *logger_list;
974
975    pid_t pid = getpid();
976
977    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
978        LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
979
980    log_time ts(android_log_clockid());
981
982    EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
983                                         max_payload_buf, max_payload_buf));
984    usleep(1000000);
985
986    int count = 0;
987
988    for (;;) {
989        log_msg log_msg;
990        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
991            break;
992        }
993
994        ASSERT_EQ(log_msg.entry.pid, pid);
995
996        if ((log_msg.entry.sec < (ts.tv_sec - 1))
997         || ((ts.tv_sec + 1) < log_msg.entry.sec)
998         || ((size_t)log_msg.entry.len < LOGGER_ENTRY_MAX_PAYLOAD)
999         || (log_msg.id() != LOG_ID_MAIN)) {
1000            continue;
1001        }
1002
1003        ++count;
1004
1005        AndroidLogFormat *logformat = android_log_format_new();
1006        EXPECT_TRUE(NULL != logformat);
1007        AndroidLogEntry entry;
1008        int processLogBuffer = android_log_processLogBuffer(&log_msg.entry_v1,
1009                                                            &entry);
1010        EXPECT_EQ(0, processLogBuffer);
1011        if (processLogBuffer == 0) {
1012            fflush(stderr);
1013            int printLogLine =
1014                    android_log_printLogLine(logformat, fileno(stderr), &entry);
1015            // Legacy tag truncation
1016            EXPECT_LE(128, printLogLine);
1017            // Measured maximum if we try to print part of the tag as message
1018            EXPECT_GT(LOGGER_ENTRY_MAX_PAYLOAD * 13 / 8, printLogLine);
1019        }
1020        android_log_format_free(logformat);
1021    }
1022
1023    EXPECT_EQ(1, count);
1024
1025    android_logger_list_close(logger_list);
1026}
1027
1028TEST(liblog, too_big_payload) {
1029    pid_t pid = getpid();
1030    static const char big_payload_tag[] = "TEST_big_payload_XXXX";
1031    char tag[sizeof(big_payload_tag)];
1032    memcpy(tag, big_payload_tag, sizeof(tag));
1033    snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
1034
1035    std::string longString(3266519, 'x');
1036
1037    ssize_t ret = LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM,
1038                                    ANDROID_LOG_INFO, tag, longString.c_str()));
1039
1040    struct logger_list *logger_list;
1041
1042    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1043        LOG_ID_SYSTEM, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 100, 0)));
1044
1045    ssize_t max_len = 0;
1046
1047    for(;;) {
1048        log_msg log_msg;
1049        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1050            break;
1051        }
1052
1053        if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
1054            continue;
1055        }
1056
1057        char *data = log_msg.msg() + 1;
1058
1059        if (strcmp(data, tag)) {
1060            continue;
1061        }
1062
1063        data += strlen(data) + 1;
1064
1065        const char *left = data;
1066        const char *right = longString.c_str();
1067        while (*left && *right && (*left == *right)) {
1068            ++left;
1069            ++right;
1070        }
1071
1072        if (max_len <= (left - data)) {
1073            max_len = left - data + 1;
1074        }
1075    }
1076
1077    android_logger_list_close(logger_list);
1078
1079    EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),
1080              static_cast<size_t>(max_len));
1081
1082    EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag)));
1083}
1084
1085TEST(liblog, dual_reader) {
1086    struct logger_list *logger_list1;
1087
1088    // >25 messages due to liblog.__android_log_buf_print__concurrentXX above.
1089    ASSERT_TRUE(NULL != (logger_list1 = android_logger_list_open(
1090        LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 25, 0)));
1091
1092    struct logger_list *logger_list2;
1093
1094    if (NULL == (logger_list2 = android_logger_list_open(
1095            LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 15, 0))) {
1096        android_logger_list_close(logger_list1);
1097        ASSERT_TRUE(NULL != logger_list2);
1098    }
1099
1100    int count1 = 0;
1101    bool done1 = false;
1102    int count2 = 0;
1103    bool done2 = false;
1104
1105    do {
1106        log_msg log_msg;
1107
1108        if (!done1) {
1109            if (android_logger_list_read(logger_list1, &log_msg) <= 0) {
1110                done1 = true;
1111            } else {
1112                ++count1;
1113            }
1114        }
1115
1116        if (!done2) {
1117            if (android_logger_list_read(logger_list2, &log_msg) <= 0) {
1118                done2 = true;
1119            } else {
1120                ++count2;
1121            }
1122        }
1123    } while ((!done1) || (!done2));
1124
1125    android_logger_list_close(logger_list1);
1126    android_logger_list_close(logger_list2);
1127
1128    EXPECT_EQ(25, count1);
1129    EXPECT_EQ(15, count2);
1130}
1131
1132TEST(liblog, android_logger_get_) {
1133    struct logger_list * logger_list = android_logger_list_alloc(ANDROID_LOG_WRONLY, 0, 0);
1134
1135    for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
1136        log_id_t id = static_cast<log_id_t>(i);
1137        const char *name = android_log_id_to_name(id);
1138        if (id != android_name_to_log_id(name)) {
1139            continue;
1140        }
1141        fprintf(stderr, "log buffer %s\r", name);
1142        struct logger * logger;
1143        EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id)));
1144        EXPECT_EQ(id, android_logger_get_id(logger));
1145        ssize_t get_log_size = android_logger_get_log_size(logger);
1146        /* security buffer is allowed to be denied */
1147        if (strcmp("security", name)) {
1148            EXPECT_LT(0, get_log_size);
1149            /* crash buffer is allowed to be empty, that is actually healthy! */
1150            EXPECT_LE((strcmp("crash", name)) != 0,
1151                      android_logger_get_log_readable_size(logger));
1152        } else {
1153            EXPECT_NE(0, get_log_size);
1154            if (get_log_size < 0) {
1155                EXPECT_GT(0, android_logger_get_log_readable_size(logger));
1156            } else {
1157                EXPECT_LE(0, android_logger_get_log_readable_size(logger));
1158            }
1159        }
1160        EXPECT_LT(0, android_logger_get_log_version(logger));
1161    }
1162
1163    android_logger_list_close(logger_list);
1164}
1165
1166static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {
1167    return android_log_shouldPrintLine(p_format, tag, pri)
1168        && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));
1169}
1170
1171TEST(liblog, filterRule) {
1172    static const char tag[] = "random";
1173
1174    AndroidLogFormat *p_format = android_log_format_new();
1175
1176    android_log_addFilterRule(p_format,"*:i");
1177
1178    EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
1179    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1180    android_log_addFilterRule(p_format, "*");
1181    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
1182    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1183    android_log_addFilterRule(p_format, "*:v");
1184    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
1185    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1186    android_log_addFilterRule(p_format, "*:i");
1187    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
1188    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1189
1190    android_log_addFilterRule(p_format, tag);
1191    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
1192    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1193    android_log_addFilterRule(p_format, "random:v");
1194    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
1195    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1196    android_log_addFilterRule(p_format, "random:d");
1197    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
1198    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1199    android_log_addFilterRule(p_format, "random:w");
1200    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
1201    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1202
1203    android_log_addFilterRule(p_format, "crap:*");
1204    EXPECT_TRUE (checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE));
1205    EXPECT_TRUE(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
1206
1207    // invalid expression
1208    EXPECT_TRUE (android_log_addFilterRule(p_format, "random:z") < 0);
1209    EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
1210    EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1211
1212    // Issue #550946
1213    EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0);
1214    EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
1215
1216    // note trailing space
1217    EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0);
1218    EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
1219
1220    EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0);
1221
1222#if 0 // bitrot, seek update
1223    char defaultBuffer[512];
1224
1225    android_log_formatLogLine(p_format,
1226        defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
1227        123, 123, tag, "nofile", strlen("Hello"), "Hello", NULL);
1228
1229    fprintf(stderr, "%s\n", defaultBuffer);
1230#endif
1231
1232    android_log_format_free(p_format);
1233}
1234
1235TEST(liblog, is_loggable) {
1236    static const char tag[] = "is_loggable";
1237    static const char log_namespace[] = "persist.log.tag.";
1238    static const size_t base_offset = 8; /* skip "persist." */
1239    // sizeof("string") = strlen("string") + 1
1240    char key[sizeof(log_namespace) + sizeof(tag) - 1];
1241    char hold[4][PROP_VALUE_MAX];
1242    static const struct {
1243        int level;
1244        char type;
1245    } levels[] = {
1246        { ANDROID_LOG_VERBOSE, 'v' },
1247        { ANDROID_LOG_DEBUG  , 'd' },
1248        { ANDROID_LOG_INFO   , 'i' },
1249        { ANDROID_LOG_WARN   , 'w' },
1250        { ANDROID_LOG_ERROR  , 'e' },
1251        { ANDROID_LOG_FATAL  , 'a' },
1252        { -1                 , 's' },
1253        { -2                 , 'g' }, // Illegal value, resort to default
1254    };
1255
1256    // Set up initial test condition
1257    memset(hold, 0, sizeof(hold));
1258    snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1259    property_get(key, hold[0], "");
1260    property_set(key, "");
1261    property_get(key + base_offset, hold[1], "");
1262    property_set(key + base_offset, "");
1263    strcpy(key, log_namespace);
1264    key[sizeof(log_namespace) - 2] = '\0';
1265    property_get(key, hold[2], "");
1266    property_set(key, "");
1267    property_get(key, hold[3], "");
1268    property_set(key + base_offset, "");
1269
1270    // All combinations of level and defaults
1271    for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
1272        if (levels[i].level == -2) {
1273            continue;
1274        }
1275        for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
1276            if (levels[j].level == -2) {
1277                continue;
1278            }
1279            fprintf(stderr, "i=%zu j=%zu\r", i, j);
1280            bool android_log_is_loggable = __android_log_is_loggable(
1281                levels[i].level, tag, levels[j].level);
1282            if ((levels[i].level < levels[j].level)
1283                    || (levels[j].level == -1)) {
1284                if (android_log_is_loggable) {
1285                    fprintf(stderr, "\n");
1286                }
1287                EXPECT_FALSE(android_log_is_loggable);
1288                for(size_t k = 10; k; --k) {
1289                    EXPECT_FALSE(__android_log_is_loggable(
1290                        levels[i].level, tag, levels[j].level));
1291                }
1292            } else {
1293                if (!android_log_is_loggable) {
1294                    fprintf(stderr, "\n");
1295                }
1296                EXPECT_TRUE(android_log_is_loggable);
1297                for(size_t k = 10; k; --k) {
1298                    EXPECT_TRUE(__android_log_is_loggable(
1299                        levels[i].level, tag, levels[j].level));
1300                }
1301            }
1302        }
1303    }
1304
1305    // All combinations of level and tag and global properties
1306    for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
1307        if (levels[i].level == -2) {
1308            continue;
1309        }
1310        for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
1311            char buf[2];
1312            buf[0] = levels[j].type;
1313            buf[1] = '\0';
1314
1315            snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1316            fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1317                    i, j, key, buf);
1318            property_set(key, buf);
1319            bool android_log_is_loggable = __android_log_is_loggable(
1320                levels[i].level, tag, ANDROID_LOG_DEBUG);
1321            if ((levels[i].level < levels[j].level)
1322                    || (levels[j].level == -1)
1323                    || ((levels[i].level < ANDROID_LOG_DEBUG)
1324                        && (levels[j].level == -2))) {
1325                if (android_log_is_loggable) {
1326                    fprintf(stderr, "\n");
1327                }
1328                EXPECT_FALSE(android_log_is_loggable);
1329                for(size_t k = 10; k; --k) {
1330                    EXPECT_FALSE(__android_log_is_loggable(
1331                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1332                }
1333            } else {
1334                if (!android_log_is_loggable) {
1335                    fprintf(stderr, "\n");
1336                }
1337                EXPECT_TRUE(android_log_is_loggable);
1338                for(size_t k = 10; k; --k) {
1339                    EXPECT_TRUE(__android_log_is_loggable(
1340                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1341                }
1342            }
1343            property_set(key, "");
1344
1345            fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1346                    i, j, key + base_offset, buf);
1347            property_set(key + base_offset, buf);
1348            android_log_is_loggable = __android_log_is_loggable(
1349                levels[i].level, tag, ANDROID_LOG_DEBUG);
1350            if ((levels[i].level < levels[j].level)
1351                    || (levels[j].level == -1)
1352                    || ((levels[i].level < ANDROID_LOG_DEBUG)
1353                        && (levels[j].level == -2))) {
1354                if (android_log_is_loggable) {
1355                    fprintf(stderr, "\n");
1356                }
1357                EXPECT_FALSE(android_log_is_loggable);
1358                for(size_t k = 10; k; --k) {
1359                    EXPECT_FALSE(__android_log_is_loggable(
1360                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1361                }
1362            } else {
1363                if (!android_log_is_loggable) {
1364                    fprintf(stderr, "\n");
1365                }
1366                EXPECT_TRUE(android_log_is_loggable);
1367                for(size_t k = 10; k; --k) {
1368                    EXPECT_TRUE(__android_log_is_loggable(
1369                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1370                }
1371            }
1372            property_set(key + base_offset, "");
1373
1374            strcpy(key, log_namespace);
1375            key[sizeof(log_namespace) - 2] = '\0';
1376            fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1377                    i, j, key, buf);
1378            property_set(key, buf);
1379            android_log_is_loggable = __android_log_is_loggable(
1380                levels[i].level, tag, ANDROID_LOG_DEBUG);
1381            if ((levels[i].level < levels[j].level)
1382                    || (levels[j].level == -1)
1383                    || ((levels[i].level < ANDROID_LOG_DEBUG)
1384                        && (levels[j].level == -2))) {
1385                if (android_log_is_loggable) {
1386                    fprintf(stderr, "\n");
1387                }
1388                EXPECT_FALSE(android_log_is_loggable);
1389                for(size_t k = 10; k; --k) {
1390                    EXPECT_FALSE(__android_log_is_loggable(
1391                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1392                }
1393            } else {
1394                if (!android_log_is_loggable) {
1395                    fprintf(stderr, "\n");
1396                }
1397                EXPECT_TRUE(android_log_is_loggable);
1398                for(size_t k = 10; k; --k) {
1399                    EXPECT_TRUE(__android_log_is_loggable(
1400                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1401                }
1402            }
1403            property_set(key, "");
1404
1405            fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1406                    i, j, key + base_offset, buf);
1407            property_set(key + base_offset, buf);
1408            android_log_is_loggable = __android_log_is_loggable(
1409                levels[i].level, tag, ANDROID_LOG_DEBUG);
1410            if ((levels[i].level < levels[j].level)
1411                    || (levels[j].level == -1)
1412                    || ((levels[i].level < ANDROID_LOG_DEBUG)
1413                        && (levels[j].level == -2))) {
1414                if (android_log_is_loggable) {
1415                    fprintf(stderr, "\n");
1416                }
1417                EXPECT_FALSE(android_log_is_loggable);
1418                for(size_t k = 10; k; --k) {
1419                    EXPECT_FALSE(__android_log_is_loggable(
1420                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1421                }
1422            } else {
1423                if (!android_log_is_loggable) {
1424                    fprintf(stderr, "\n");
1425                }
1426                EXPECT_TRUE(android_log_is_loggable);
1427                for(size_t k = 10; k; --k) {
1428                    EXPECT_TRUE(__android_log_is_loggable(
1429                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1430                }
1431            }
1432            property_set(key + base_offset, "");
1433        }
1434    }
1435
1436    // All combinations of level and tag properties, but with global set to INFO
1437    strcpy(key, log_namespace);
1438    key[sizeof(log_namespace) - 2] = '\0';
1439    property_set(key, "I");
1440    snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1441    for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
1442        if (levels[i].level == -2) {
1443            continue;
1444        }
1445        for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
1446            char buf[2];
1447            buf[0] = levels[j].type;
1448            buf[1] = '\0';
1449
1450            fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1451                    i, j, key, buf);
1452            property_set(key, buf);
1453            bool android_log_is_loggable = __android_log_is_loggable(
1454                levels[i].level, tag, ANDROID_LOG_DEBUG);
1455            if ((levels[i].level < levels[j].level)
1456                    || (levels[j].level == -1)
1457                    || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO
1458                        && (levels[j].level == -2))) {
1459                if (android_log_is_loggable) {
1460                    fprintf(stderr, "\n");
1461                }
1462                EXPECT_FALSE(android_log_is_loggable);
1463                for(size_t k = 10; k; --k) {
1464                    EXPECT_FALSE(__android_log_is_loggable(
1465                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1466                }
1467            } else {
1468                if (!android_log_is_loggable) {
1469                    fprintf(stderr, "\n");
1470                }
1471                EXPECT_TRUE(android_log_is_loggable);
1472                for(size_t k = 10; k; --k) {
1473                    EXPECT_TRUE(__android_log_is_loggable(
1474                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1475                }
1476            }
1477            property_set(key, "");
1478
1479            fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1480                    i, j, key + base_offset, buf);
1481            property_set(key + base_offset, buf);
1482            android_log_is_loggable = __android_log_is_loggable(
1483                levels[i].level, tag, ANDROID_LOG_DEBUG);
1484            if ((levels[i].level < levels[j].level)
1485                    || (levels[j].level == -1)
1486                    || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO
1487                        && (levels[j].level == -2))) {
1488                if (android_log_is_loggable) {
1489                    fprintf(stderr, "\n");
1490                }
1491                EXPECT_FALSE(android_log_is_loggable);
1492                for(size_t k = 10; k; --k) {
1493                    EXPECT_FALSE(__android_log_is_loggable(
1494                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1495                }
1496            } else {
1497                if (!android_log_is_loggable) {
1498                    fprintf(stderr, "\n");
1499                }
1500                EXPECT_TRUE(android_log_is_loggable);
1501                for(size_t k = 10; k; --k) {
1502                    EXPECT_TRUE(__android_log_is_loggable(
1503                        levels[i].level, tag, ANDROID_LOG_DEBUG));
1504                }
1505            }
1506            property_set(key + base_offset, "");
1507        }
1508    }
1509
1510    // reset parms
1511    snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1512    property_set(key, hold[0]);
1513    property_set(key + base_offset, hold[1]);
1514    strcpy(key, log_namespace);
1515    key[sizeof(log_namespace) - 2] = '\0';
1516    property_set(key, hold[2]);
1517    property_set(key + base_offset, hold[3]);
1518}
1519
1520TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) {
1521    const int TAG = 123456781;
1522    const char SUBTAG[] = "test-subtag";
1523    const int UID = -1;
1524    const int DATA_LEN = 200;
1525    struct logger_list *logger_list;
1526
1527    pid_t pid = getpid();
1528
1529    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1530        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1531
1532    ASSERT_LT(0, android_errorWriteWithInfoLog(
1533            TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));
1534
1535    sleep(2);
1536
1537    int count = 0;
1538
1539    for (;;) {
1540        log_msg log_msg;
1541        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1542            break;
1543        }
1544
1545        char *eventData = log_msg.msg();
1546
1547        // Tag
1548        int tag = get4LE(eventData);
1549        eventData += 4;
1550
1551        if (tag != TAG) {
1552            continue;
1553        }
1554
1555        // List type
1556        ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1557        eventData++;
1558
1559        // Number of elements in list
1560        ASSERT_EQ(3, eventData[0]);
1561        eventData++;
1562
1563        // Element #1: string type for subtag
1564        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1565        eventData++;
1566
1567        ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));
1568        eventData +=4;
1569
1570        if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {
1571            continue;
1572        }
1573        eventData += strlen(SUBTAG);
1574
1575        // Element #2: int type for uid
1576        ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);
1577        eventData++;
1578
1579        ASSERT_EQ(UID, get4LE(eventData));
1580        eventData += 4;
1581
1582        // Element #3: string type for data
1583        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1584        eventData++;
1585
1586        ASSERT_EQ(DATA_LEN, get4LE(eventData));
1587        eventData += 4;
1588
1589        if (memcmp(max_payload_buf, eventData, DATA_LEN)) {
1590            continue;
1591        }
1592
1593        ++count;
1594    }
1595
1596    EXPECT_EQ(1, count);
1597
1598    android_logger_list_close(logger_list);
1599}
1600
1601TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__data_too_large) {
1602    const int TAG = 123456782;
1603    const char SUBTAG[] = "test-subtag";
1604    const int UID = -1;
1605    const int DATA_LEN = sizeof(max_payload_buf);
1606    struct logger_list *logger_list;
1607
1608    pid_t pid = getpid();
1609
1610    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1611        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1612
1613    ASSERT_LT(0, android_errorWriteWithInfoLog(
1614            TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));
1615
1616    sleep(2);
1617
1618    int count = 0;
1619
1620    for (;;) {
1621        log_msg log_msg;
1622        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1623            break;
1624        }
1625
1626        char *eventData = log_msg.msg();
1627        char *original = eventData;
1628
1629        // Tag
1630        int tag = get4LE(eventData);
1631        eventData += 4;
1632
1633        if (tag != TAG) {
1634            continue;
1635        }
1636
1637        // List type
1638        ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1639        eventData++;
1640
1641        // Number of elements in list
1642        ASSERT_EQ(3, eventData[0]);
1643        eventData++;
1644
1645        // Element #1: string type for subtag
1646        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1647        eventData++;
1648
1649        ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));
1650        eventData +=4;
1651
1652        if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {
1653            continue;
1654        }
1655        eventData += strlen(SUBTAG);
1656
1657        // Element #2: int type for uid
1658        ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);
1659        eventData++;
1660
1661        ASSERT_EQ(UID, get4LE(eventData));
1662        eventData += 4;
1663
1664        // Element #3: string type for data
1665        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1666        eventData++;
1667
1668        size_t dataLen = get4LE(eventData);
1669        eventData += 4;
1670
1671        if (memcmp(max_payload_buf, eventData, dataLen)) {
1672            continue;
1673        }
1674        eventData += dataLen;
1675
1676        // 4 bytes for the tag, and max_payload_buf should be truncated.
1677        ASSERT_LE(4 + 512, eventData - original);      // worst expectations
1678        ASSERT_GT(4 + DATA_LEN, eventData - original); // must be truncated
1679
1680        ++count;
1681    }
1682
1683    EXPECT_EQ(1, count);
1684
1685    android_logger_list_close(logger_list);
1686}
1687
1688TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__null_data) {
1689    const int TAG = 123456783;
1690    const char SUBTAG[] = "test-subtag";
1691    const int UID = -1;
1692    const int DATA_LEN = 200;
1693    struct logger_list *logger_list;
1694
1695    pid_t pid = getpid();
1696
1697    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1698        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1699
1700    ASSERT_GT(0, android_errorWriteWithInfoLog(
1701            TAG, SUBTAG, UID, NULL, DATA_LEN));
1702
1703    sleep(2);
1704
1705    int count = 0;
1706
1707    for (;;) {
1708        log_msg log_msg;
1709        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1710            break;
1711        }
1712
1713        char *eventData = log_msg.msg();
1714
1715        // Tag
1716        int tag = get4LE(eventData);
1717        eventData += 4;
1718
1719        if (tag == TAG) {
1720            // This tag should not have been written because the data was null
1721            count++;
1722            break;
1723        }
1724    }
1725
1726    EXPECT_EQ(0, count);
1727
1728    android_logger_list_close(logger_list);
1729}
1730
1731TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long) {
1732    const int TAG = 123456784;
1733    const char SUBTAG[] = "abcdefghijklmnopqrstuvwxyz now i know my abc";
1734    const int UID = -1;
1735    const int DATA_LEN = 200;
1736    struct logger_list *logger_list;
1737
1738    pid_t pid = getpid();
1739
1740    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1741        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1742
1743    ASSERT_LT(0, android_errorWriteWithInfoLog(
1744            TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));
1745
1746    sleep(2);
1747
1748    int count = 0;
1749
1750    for (;;) {
1751        log_msg log_msg;
1752        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1753            break;
1754        }
1755
1756        char *eventData = log_msg.msg();
1757
1758        // Tag
1759        int tag = get4LE(eventData);
1760        eventData += 4;
1761
1762        if (tag != TAG) {
1763            continue;
1764        }
1765
1766        // List type
1767        ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1768        eventData++;
1769
1770        // Number of elements in list
1771        ASSERT_EQ(3, eventData[0]);
1772        eventData++;
1773
1774        // Element #1: string type for subtag
1775        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1776        eventData++;
1777
1778        // The subtag is longer than 32 and should be truncated to that.
1779        ASSERT_EQ(32, get4LE(eventData));
1780        eventData +=4;
1781
1782        if (memcmp(SUBTAG, eventData, 32)) {
1783            continue;
1784        }
1785        eventData += 32;
1786
1787        // Element #2: int type for uid
1788        ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);
1789        eventData++;
1790
1791        ASSERT_EQ(UID, get4LE(eventData));
1792        eventData += 4;
1793
1794        // Element #3: string type for data
1795        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1796        eventData++;
1797
1798        ASSERT_EQ(DATA_LEN, get4LE(eventData));
1799        eventData += 4;
1800
1801        if (memcmp(max_payload_buf, eventData, DATA_LEN)) {
1802            continue;
1803        }
1804
1805        ++count;
1806    }
1807
1808    EXPECT_EQ(1, count);
1809
1810    android_logger_list_close(logger_list);
1811}
1812
1813TEST(liblog, android_errorWriteLog__android_logger_list_read__success) {
1814    const int TAG = 123456785;
1815    const char SUBTAG[] = "test-subtag";
1816    struct logger_list *logger_list;
1817
1818    pid_t pid = getpid();
1819
1820    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1821        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1822
1823    ASSERT_LT(0, android_errorWriteLog(TAG, SUBTAG));
1824
1825    sleep(2);
1826
1827    int count = 0;
1828
1829    for (;;) {
1830        log_msg log_msg;
1831        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1832            break;
1833        }
1834
1835        char *eventData = log_msg.msg();
1836
1837        // Tag
1838        int tag = get4LE(eventData);
1839        eventData += 4;
1840
1841        if (tag != TAG) {
1842            continue;
1843        }
1844
1845        // List type
1846        ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1847        eventData++;
1848
1849        // Number of elements in list
1850        ASSERT_EQ(3, eventData[0]);
1851        eventData++;
1852
1853        // Element #1: string type for subtag
1854        ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1855        eventData++;
1856
1857        ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));
1858        eventData +=4;
1859
1860        if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {
1861            continue;
1862        }
1863        ++count;
1864    }
1865
1866    EXPECT_EQ(1, count);
1867
1868    android_logger_list_close(logger_list);
1869}
1870
1871TEST(liblog, android_errorWriteLog__android_logger_list_read__null_subtag) {
1872    const int TAG = 123456786;
1873    struct logger_list *logger_list;
1874
1875    pid_t pid = getpid();
1876
1877    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1878        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1879
1880    ASSERT_GT(0, android_errorWriteLog(TAG, NULL));
1881
1882    sleep(2);
1883
1884    int count = 0;
1885
1886    for (;;) {
1887        log_msg log_msg;
1888        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1889            break;
1890        }
1891
1892        char *eventData = log_msg.msg();
1893
1894        // Tag
1895        int tag = get4LE(eventData);
1896        eventData += 4;
1897
1898        if (tag == TAG) {
1899            // This tag should not have been written because the data was null
1900            count++;
1901            break;
1902        }
1903    }
1904
1905    EXPECT_EQ(0, count);
1906
1907    android_logger_list_close(logger_list);
1908}
1909
1910static int is_real_element(int type) {
1911    return ((type == EVENT_TYPE_INT) ||
1912            (type == EVENT_TYPE_LONG) ||
1913            (type == EVENT_TYPE_STRING) ||
1914            (type == EVENT_TYPE_FLOAT));
1915}
1916
1917int android_log_buffer_to_string(const char *msg, size_t len,
1918                                 char *strOut, size_t strOutLen) {
1919    android_log_context context = create_android_log_parser(msg, len);
1920    android_log_list_element elem;
1921    bool overflow = false;
1922    /* Reserve 1 byte for null terminator. */
1923    size_t origStrOutLen = strOutLen--;
1924
1925    if (!context) {
1926        return -EBADF;
1927    }
1928
1929    memset(&elem, 0, sizeof(elem));
1930
1931    size_t outCount;
1932
1933    do {
1934        elem = android_log_read_next(context);
1935        switch ((int)elem.type) {
1936        case EVENT_TYPE_LIST:
1937            if (strOutLen == 0) {
1938                overflow = true;
1939            } else {
1940                *strOut++ = '[';
1941                strOutLen--;
1942            }
1943            break;
1944
1945        case EVENT_TYPE_LIST_STOP:
1946            if (strOutLen == 0) {
1947                overflow = true;
1948            } else {
1949                *strOut++ = ']';
1950                strOutLen--;
1951            }
1952            break;
1953
1954        case EVENT_TYPE_INT:
1955            /*
1956             * snprintf also requires room for the null terminator, which
1957             * we don't care about  but we have allocated enough room for
1958             * that
1959             */
1960            outCount = snprintf(strOut, strOutLen + 1,
1961                                "%" PRId32, elem.data.int32);
1962            if (outCount <= strOutLen) {
1963                strOut += outCount;
1964                strOutLen -= outCount;
1965            } else {
1966                overflow = true;
1967            }
1968            break;
1969
1970        case EVENT_TYPE_LONG:
1971            /*
1972             * snprintf also requires room for the null terminator, which
1973             * we don't care about but we have allocated enough room for
1974             * that
1975             */
1976            outCount = snprintf(strOut, strOutLen + 1,
1977                                "%" PRId64, elem.data.int64);
1978            if (outCount <= strOutLen) {
1979                strOut += outCount;
1980                strOutLen -= outCount;
1981            } else {
1982                overflow = true;
1983            }
1984            break;
1985
1986        case EVENT_TYPE_FLOAT:
1987            /*
1988             * snprintf also requires room for the null terminator, which
1989             * we don't care about but we have allocated enough room for
1990             * that
1991             */
1992            outCount = snprintf(strOut, strOutLen + 1, "%f", elem.data.float32);
1993            if (outCount <= strOutLen) {
1994                strOut += outCount;
1995                strOutLen -= outCount;
1996            } else {
1997                overflow = true;
1998            }
1999            break;
2000
2001        default:
2002            elem.complete = true;
2003            break;
2004
2005        case EVENT_TYPE_UNKNOWN:
2006#if 0 // Ideal purity in the test, we want to complain about UNKNOWN showing up
2007            if (elem.complete) {
2008                break;
2009            }
2010#endif
2011            elem.data.string = const_cast<char *>("<unknown>");
2012            elem.len = strlen(elem.data.string);
2013            /* FALLTHRU */
2014        case EVENT_TYPE_STRING:
2015            if (elem.len <= strOutLen) {
2016                memcpy(strOut, elem.data.string, elem.len);
2017                strOut += elem.len;
2018                strOutLen -= elem.len;
2019            } else if (strOutLen > 0) {
2020                /* copy what we can */
2021                memcpy(strOut, elem.data.string, strOutLen);
2022                strOut += strOutLen;
2023                strOutLen = 0;
2024                overflow = true;
2025            }
2026            break;
2027        }
2028
2029        if (elem.complete) {
2030            break;
2031        }
2032        /* Determine whether to put a comma or not. */
2033        if (!overflow && (is_real_element(elem.type) ||
2034                (elem.type == EVENT_TYPE_LIST_STOP))) {
2035            android_log_list_element next = android_log_peek_next(context);
2036            if (!next.complete && (is_real_element(next.type) ||
2037                    (next.type == EVENT_TYPE_LIST))) {
2038                if (strOutLen == 0) {
2039                    overflow = true;
2040                } else {
2041                    *strOut++ = ',';
2042                    strOutLen--;
2043                }
2044            }
2045        }
2046    } while ((elem.type != EVENT_TYPE_UNKNOWN) && !overflow && !elem.complete);
2047
2048    android_log_destroy(&context);
2049
2050    if (overflow) {
2051        if (strOutLen < origStrOutLen) {
2052            /* leave an indicator */
2053            *(strOut-1) = '!';
2054        } else {
2055            /* nothing was written at all */
2056            *strOut++ = '!';
2057        }
2058    }
2059    *strOut++ = '\0';
2060
2061    if ((elem.type == EVENT_TYPE_UNKNOWN) && !elem.complete) {
2062        fprintf(stderr, "Binary log entry conversion failed\n");
2063        return -EINVAL;
2064    }
2065
2066    return 0;
2067}
2068
2069static const char *event_test_int32(uint32_t tag, size_t &expected_len) {
2070    android_log_context ctx;
2071
2072    EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2073    if (!ctx) {
2074        return NULL;
2075    }
2076    EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010));
2077    EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2078    EXPECT_LE(0, android_log_destroy(&ctx));
2079    EXPECT_TRUE(NULL == ctx);
2080
2081    expected_len = sizeof(uint32_t) +
2082                   sizeof(uint8_t) + sizeof(uint32_t);
2083
2084    return "1076895760";
2085}
2086
2087static const char *event_test_int64(uint32_t tag, size_t &expected_len) {
2088    android_log_context ctx;
2089
2090    EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2091    if (!ctx) {
2092        return NULL;
2093    }
2094    EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
2095    EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2096    EXPECT_LE(0, android_log_destroy(&ctx));
2097    EXPECT_TRUE(NULL == ctx);
2098
2099    expected_len = sizeof(uint32_t) +
2100                   sizeof(uint8_t) + sizeof(uint64_t);
2101
2102    return "-9191740941672636400";
2103}
2104
2105static const char *event_test_list_int64(uint32_t tag, size_t &expected_len) {
2106    android_log_context ctx;
2107
2108    EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2109    if (!ctx) {
2110        return NULL;
2111    }
2112    EXPECT_LE(0, android_log_write_list_begin(ctx));
2113    EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
2114    EXPECT_LE(0, android_log_write_list_end(ctx));
2115    EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2116    EXPECT_LE(0, android_log_destroy(&ctx));
2117    EXPECT_TRUE(NULL == ctx);
2118
2119    expected_len = sizeof(uint32_t) +
2120                   sizeof(uint8_t) + sizeof(uint8_t) +
2121                       sizeof(uint8_t) + sizeof(uint64_t);
2122
2123    return "[-9191740941672636400]";
2124}
2125
2126static const char *event_test_simple_automagic_list(uint32_t tag, size_t &expected_len) {
2127    android_log_context ctx;
2128
2129    EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2130    if (!ctx) {
2131        return NULL;
2132    }
2133    // The convenience API where we allow a simple list to be
2134    // created without explicit begin or end calls.
2135    EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010));
2136    EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
2137    EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2138    EXPECT_LE(0, android_log_destroy(&ctx));
2139    EXPECT_TRUE(NULL == ctx);
2140
2141    expected_len = sizeof(uint32_t) +
2142                   sizeof(uint8_t) + sizeof(uint8_t) +
2143                       sizeof(uint8_t) + sizeof(uint32_t) +
2144                       sizeof(uint8_t) + sizeof(uint64_t);
2145
2146    return "[1076895760,-9191740941672636400]";
2147}
2148
2149static const char *event_test_list_empty(uint32_t tag, size_t &expected_len) {
2150    android_log_context ctx;
2151
2152    EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2153    if (!ctx) {
2154        return NULL;
2155    }
2156    EXPECT_LE(0, android_log_write_list_begin(ctx));
2157    EXPECT_LE(0, android_log_write_list_end(ctx));
2158    EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2159    EXPECT_LE(0, android_log_destroy(&ctx));
2160    EXPECT_TRUE(NULL == ctx);
2161
2162    expected_len = sizeof(uint32_t) +
2163                   sizeof(uint8_t) + sizeof(uint8_t);
2164
2165    return "[]";
2166}
2167
2168static const char *event_test_complex_nested_list(uint32_t tag, size_t &expected_len) {
2169    android_log_context ctx;
2170
2171    EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2172    if (!ctx) {
2173        return NULL;
2174    }
2175
2176    EXPECT_LE(0, android_log_write_list_begin(ctx)); // [
2177    EXPECT_LE(0, android_log_write_int32(ctx, 0x01020304));
2178    EXPECT_LE(0, android_log_write_int64(ctx, 0x0102030405060708));
2179    EXPECT_LE(0, android_log_write_string8(ctx, "Hello World"));
2180    EXPECT_LE(0, android_log_write_list_begin(ctx)); // [
2181    EXPECT_LE(0, android_log_write_int32(ctx, 1));
2182    EXPECT_LE(0, android_log_write_int32(ctx, 2));
2183    EXPECT_LE(0, android_log_write_int32(ctx, 3));
2184    EXPECT_LE(0, android_log_write_int32(ctx, 4));
2185    EXPECT_LE(0, android_log_write_list_end(ctx));   // ]
2186    EXPECT_LE(0, android_log_write_float32(ctx, 1.0102030405060708));
2187    EXPECT_LE(0, android_log_write_list_end(ctx));   // ]
2188
2189    //
2190    // This one checks for the automagic list creation because a list
2191    // begin and end was missing for it! This is actually an <oops> corner
2192    // case, and not the behavior we morally support. The automagic API is to
2193    // allow for a simple case of a series of objects in a single list. e.g.
2194    //   int32,int32,int32,string -> [int32,int32,int32,string]
2195    //
2196    EXPECT_LE(0, android_log_write_string8(ctx, "dlroW olleH"));
2197
2198    EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2199    EXPECT_LE(0, android_log_destroy(&ctx));
2200    EXPECT_TRUE(NULL == ctx);
2201
2202    expected_len = sizeof(uint32_t) +
2203                   sizeof(uint8_t) + sizeof(uint8_t) +
2204                       sizeof(uint8_t) + sizeof(uint8_t) +
2205                           sizeof(uint8_t) + sizeof(uint32_t) +
2206                           sizeof(uint8_t) + sizeof(uint64_t) +
2207                           sizeof(uint8_t) + sizeof(uint32_t) +
2208                                             sizeof("Hello World") - 1 +
2209                           sizeof(uint8_t) + sizeof(uint8_t) +
2210                               4 * (sizeof(uint8_t) + sizeof(uint32_t)) +
2211                           sizeof(uint8_t) + sizeof(uint32_t) +
2212                       sizeof(uint8_t) + sizeof(uint32_t) +
2213                                         sizeof("dlroW olleH") - 1;
2214
2215    return "[[16909060,72623859790382856,Hello World,[1,2,3,4],1.010203],dlroW olleH]";
2216}
2217
2218static const char *event_test_7_level_prefix(uint32_t tag, size_t &expected_len) {
2219    android_log_context ctx;
2220
2221    EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2222    if (!ctx) {
2223        return NULL;
2224    }
2225    EXPECT_LE(0, android_log_write_list_begin(ctx));
2226    EXPECT_LE(0, android_log_write_list_begin(ctx));
2227    EXPECT_LE(0, android_log_write_list_begin(ctx));
2228    EXPECT_LE(0, android_log_write_list_begin(ctx));
2229    EXPECT_LE(0, android_log_write_list_begin(ctx));
2230    EXPECT_LE(0, android_log_write_list_begin(ctx));
2231    EXPECT_LE(0, android_log_write_list_begin(ctx));
2232    EXPECT_LE(0, android_log_write_int32(ctx, 1));
2233    EXPECT_LE(0, android_log_write_list_end(ctx));
2234    EXPECT_LE(0, android_log_write_int32(ctx, 2));
2235    EXPECT_LE(0, android_log_write_list_end(ctx));
2236    EXPECT_LE(0, android_log_write_int32(ctx, 3));
2237    EXPECT_LE(0, android_log_write_list_end(ctx));
2238    EXPECT_LE(0, android_log_write_int32(ctx, 4));
2239    EXPECT_LE(0, android_log_write_list_end(ctx));
2240    EXPECT_LE(0, android_log_write_int32(ctx, 5));
2241    EXPECT_LE(0, android_log_write_list_end(ctx));
2242    EXPECT_LE(0, android_log_write_int32(ctx, 6));
2243    EXPECT_LE(0, android_log_write_list_end(ctx));
2244    EXPECT_LE(0, android_log_write_int32(ctx, 7));
2245    EXPECT_LE(0, android_log_write_list_end(ctx));
2246    EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2247    EXPECT_LE(0, android_log_destroy(&ctx));
2248    EXPECT_TRUE(NULL == ctx);
2249
2250    expected_len = sizeof(uint32_t) + 7 *
2251      (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t));
2252
2253    return "[[[[[[[1],2],3],4],5],6],7]";
2254}
2255
2256static const char *event_test_7_level_suffix(uint32_t tag, size_t &expected_len) {
2257    android_log_context ctx;
2258
2259    EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2260    if (!ctx) {
2261        return NULL;
2262    }
2263    EXPECT_LE(0, android_log_write_list_begin(ctx));
2264    EXPECT_LE(0, android_log_write_int32(ctx, 1));
2265    EXPECT_LE(0, android_log_write_list_begin(ctx));
2266    EXPECT_LE(0, android_log_write_int32(ctx, 2));
2267    EXPECT_LE(0, android_log_write_list_begin(ctx));
2268    EXPECT_LE(0, android_log_write_int32(ctx, 3));
2269    EXPECT_LE(0, android_log_write_list_begin(ctx));
2270    EXPECT_LE(0, android_log_write_int32(ctx, 4));
2271    EXPECT_LE(0, android_log_write_list_begin(ctx));
2272    EXPECT_LE(0, android_log_write_int32(ctx, 5));
2273    EXPECT_LE(0, android_log_write_list_begin(ctx));
2274    EXPECT_LE(0, android_log_write_int32(ctx, 6));
2275    EXPECT_LE(0, android_log_write_list_end(ctx));
2276    EXPECT_LE(0, android_log_write_list_end(ctx));
2277    EXPECT_LE(0, android_log_write_list_end(ctx));
2278    EXPECT_LE(0, android_log_write_list_end(ctx));
2279    EXPECT_LE(0, android_log_write_list_end(ctx));
2280    EXPECT_LE(0, android_log_write_list_end(ctx));
2281    EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2282    EXPECT_LE(0, android_log_destroy(&ctx));
2283    EXPECT_TRUE(NULL == ctx);
2284
2285    expected_len = sizeof(uint32_t) + 6 *
2286      (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t));
2287
2288    return "[1,[2,[3,[4,[5,[6]]]]]]";
2289}
2290
2291static const char *event_test_android_log_error_write(uint32_t tag, size_t &expected_len) {
2292    EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, "dlroW olleH", 11));
2293
2294    expected_len = sizeof(uint32_t) +
2295      sizeof(uint8_t) + sizeof(uint8_t) +
2296          sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 +
2297          sizeof(uint8_t) + sizeof(uint32_t) +
2298          sizeof(uint8_t) + sizeof(uint32_t) + sizeof("dlroW olleH") - 1;
2299
2300    return "[Hello World,42,dlroW olleH]";
2301}
2302
2303static const char *event_test_android_log_error_write_null(uint32_t tag, size_t &expected_len) {
2304    EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, NULL, 0));
2305
2306    expected_len = sizeof(uint32_t) +
2307      sizeof(uint8_t) + sizeof(uint8_t) +
2308          sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 +
2309          sizeof(uint8_t) + sizeof(uint32_t) +
2310          sizeof(uint8_t) + sizeof(uint32_t) + sizeof("") - 1;
2311
2312    return "[Hello World,42,]";
2313}
2314
2315// make sure all user buffers are flushed
2316static void print_barrier() {
2317    std::cout.flush();
2318    fflush(stdout);
2319    std::cerr.flush();
2320    fflush(stderr); // everything else is paranoia ...
2321}
2322
2323static void create_android_logger(const char *(*fn)(uint32_t tag, size_t &expected_len)) {
2324    struct logger_list *logger_list;
2325
2326    pid_t pid = getpid();
2327
2328    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
2329        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
2330
2331    log_time ts(android_log_clockid());
2332
2333    size_t expected_len;
2334    const char *expected_string = (*fn)(1005, expected_len);
2335
2336    if (!expected_string) {
2337        android_logger_list_close(logger_list);
2338        return;
2339    }
2340
2341    usleep(1000000);
2342
2343    int count = 0;
2344
2345    for (;;) {
2346        log_msg log_msg;
2347        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
2348            break;
2349        }
2350
2351        ASSERT_EQ(log_msg.entry.pid, pid);
2352
2353        if ((log_msg.entry.sec < (ts.tv_sec - 1))
2354         || ((ts.tv_sec + 1) < log_msg.entry.sec)
2355         || ((size_t)log_msg.entry.len != expected_len)
2356         || (log_msg.id() != LOG_ID_EVENTS)) {
2357            continue;
2358        }
2359
2360        char *eventData = log_msg.msg();
2361
2362        ++count;
2363
2364        AndroidLogFormat *logformat = android_log_format_new();
2365        EXPECT_TRUE(NULL != logformat);
2366        AndroidLogEntry entry;
2367        char msgBuf[1024];
2368        int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
2369            &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
2370        EXPECT_EQ(0, processBinaryLogBuffer);
2371        if (processBinaryLogBuffer == 0) {
2372            print_barrier();
2373            int printLogLine = android_log_printLogLine(
2374                logformat, fileno(stderr), &entry);
2375            print_barrier();
2376            EXPECT_EQ(20 + (int)strlen(expected_string), printLogLine);
2377        }
2378        android_log_format_free(logformat);
2379
2380        // test buffer reading API
2381        snprintf(msgBuf, sizeof(msgBuf), "I/[%d]", get4LE(eventData));
2382        print_barrier();
2383        fprintf(stderr, "%-10s(%5u): ", msgBuf, pid);
2384        memset(msgBuf, 0, sizeof(msgBuf));
2385        int buffer_to_string = android_log_buffer_to_string(
2386            eventData + sizeof(uint32_t),
2387            log_msg.entry.len - sizeof(uint32_t),
2388            msgBuf, sizeof(msgBuf));
2389        fprintf(stderr, "%s\n", msgBuf);
2390        print_barrier();
2391        EXPECT_EQ(0, buffer_to_string);
2392        EXPECT_EQ(strlen(expected_string), strlen(msgBuf));
2393        EXPECT_EQ(0, strcmp(expected_string, msgBuf));
2394    }
2395
2396    EXPECT_EQ(1, count);
2397
2398    android_logger_list_close(logger_list);
2399}
2400
2401TEST(liblog, create_android_logger_int32) {
2402    create_android_logger(event_test_int32);
2403}
2404
2405TEST(liblog, create_android_logger_int64) {
2406    create_android_logger(event_test_int64);
2407}
2408
2409TEST(liblog, create_android_logger_list_int64) {
2410    create_android_logger(event_test_list_int64);
2411}
2412
2413TEST(liblog, create_android_logger_simple_automagic_list) {
2414    create_android_logger(event_test_simple_automagic_list);
2415}
2416
2417TEST(liblog, create_android_logger_list_empty) {
2418    create_android_logger(event_test_list_empty);
2419}
2420
2421TEST(liblog, create_android_logger_complex_nested_list) {
2422    create_android_logger(event_test_complex_nested_list);
2423}
2424
2425TEST(liblog, create_android_logger_7_level_prefix) {
2426    create_android_logger(event_test_7_level_prefix);
2427}
2428
2429TEST(liblog, create_android_logger_7_level_suffix) {
2430    create_android_logger(event_test_7_level_suffix);
2431}
2432
2433TEST(liblog, create_android_logger_android_log_error_write) {
2434    create_android_logger(event_test_android_log_error_write);
2435}
2436
2437TEST(liblog, create_android_logger_android_log_error_write_null) {
2438    create_android_logger(event_test_android_log_error_write_null);
2439}
2440
2441TEST(liblog, create_android_logger_overflow) {
2442    android_log_context ctx;
2443
2444    EXPECT_TRUE(NULL != (ctx = create_android_logger(1005)));
2445    if (ctx) {
2446        for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) {
2447            EXPECT_LE(0, android_log_write_list_begin(ctx));
2448        }
2449        EXPECT_GT(0, android_log_write_list_begin(ctx));
2450        /* One more for good measure, must be permanently unhappy */
2451        EXPECT_GT(0, android_log_write_list_begin(ctx));
2452        EXPECT_LE(0, android_log_destroy(&ctx));
2453        EXPECT_TRUE(NULL == ctx);
2454    }
2455
2456    ASSERT_TRUE(NULL != (ctx = create_android_logger(1005)));
2457    for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) {
2458        EXPECT_LE(0, android_log_write_list_begin(ctx));
2459        EXPECT_LE(0, android_log_write_int32(ctx, i));
2460    }
2461    EXPECT_GT(0, android_log_write_list_begin(ctx));
2462    /* One more for good measure, must be permanently unhappy */
2463    EXPECT_GT(0, android_log_write_list_begin(ctx));
2464    EXPECT_LE(0, android_log_destroy(&ctx));
2465    ASSERT_TRUE(NULL == ctx);
2466}
2467
2468static const char __pmsg_file[] =
2469        "/data/william-shakespeare/MuchAdoAboutNothing.txt";
2470
2471TEST(liblog, __android_log_pmsg_file_write) {
2472    EXPECT_LT(0, __android_log_pmsg_file_write(
2473            LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
2474            __pmsg_file, max_payload_buf, sizeof(max_payload_buf)));
2475    fprintf(stderr, "Reboot, ensure file %s matches\n"
2476                    "with liblog.__android_log_msg_file_read test\n",
2477                    __pmsg_file);
2478}
2479
2480ssize_t __pmsg_fn(log_id_t logId, char prio, const char *filename,
2481                  const char *buf, size_t len, void *arg) {
2482    EXPECT_TRUE(NULL == arg);
2483    EXPECT_EQ(LOG_ID_CRASH, logId);
2484    EXPECT_EQ(ANDROID_LOG_VERBOSE, prio);
2485    EXPECT_FALSE(NULL == strstr(__pmsg_file, filename));
2486    EXPECT_EQ(len, sizeof(max_payload_buf));
2487    EXPECT_EQ(0, strcmp(max_payload_buf, buf));
2488
2489    ++signaled;
2490    if ((len != sizeof(max_payload_buf)) ||
2491            strcmp(max_payload_buf, buf)) {
2492        fprintf(stderr, "comparison fails on content \"%s\"\n", buf);
2493    }
2494    return !arg ||
2495           (LOG_ID_CRASH != logId) ||
2496           (ANDROID_LOG_VERBOSE != prio) ||
2497           !strstr(__pmsg_file, filename) ||
2498           (len != sizeof(max_payload_buf)) ||
2499           !!strcmp(max_payload_buf, buf) ? -ENOEXEC : 1;
2500}
2501
2502TEST(liblog, __android_log_pmsg_file_read) {
2503    signaled = 0;
2504
2505    ssize_t ret = __android_log_pmsg_file_read(
2506            LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
2507            __pmsg_file, __pmsg_fn, NULL);
2508
2509    if (ret == -ENOENT) {
2510        fprintf(stderr,
2511            "No pre-boot results of liblog.__android_log_mesg_file_write to "
2512            "compare with,\n"
2513            "false positive test result.\n");
2514        return;
2515    }
2516
2517    EXPECT_LT(0, ret);
2518    EXPECT_EQ(1U, signaled);
2519}
2520