Krita Source Code Documentation
Loading...
Searching...
No Matches
KisAndroidLogHandler.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
8
9#include <QtGlobal>
10#include <QDebug>
11
12#ifndef Q_OS_ANDROID
13#error "KisAndroidLogHandler can only built on Android platform"
14#endif
15
16#include <config-android-stdio-forwarding.h>
17#ifdef ANDROID_ENABLE_STDIO_FORWARDING
18
19#include <android/log.h>
20#include <pthread.h>
21#include <unistd.h>
22
23namespace KisAndroidLogHandler {
24
25namespace detail {
26const char*const applicationName="krita";
27
28
34void kritaQtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
35{
36 QString report = msg;
37 if (context.file && !QString(context.file).isEmpty()) {
38 report+=" in file ";
39 report+=QString(context.file);
40 report+=" line ";
41 report+=QString::number(context.line);
42 }
43 if (context.function && !QString(context.function).isEmpty()) {
44 report+=+" function ";
45 report+=QString(context.function);
46 }
47
48 const QByteArray local8bit = report.toLocal8Bit();
49 const char *const local = local8bit.constData();
50 switch (type) {
51 case QtDebugMsg:
52 __android_log_write(ANDROID_LOG_DEBUG, applicationName, local);
53 break;
54 case QtInfoMsg:
55 __android_log_write(ANDROID_LOG_INFO, applicationName, local);
56 break;
57 case QtWarningMsg:
58 __android_log_write(ANDROID_LOG_WARN, applicationName, local);
59 break;
60 case QtCriticalMsg:
61 __android_log_write(ANDROID_LOG_ERROR, applicationName, local);
62 break;
63 case QtFatalMsg:
64 default:
65 __android_log_write(ANDROID_LOG_FATAL, applicationName, local);
66 abort();
67 }
68}
69
70static int pfd[2];
71static pthread_t loggingThread;
72
73static void *loggingFunction(void*) {
74 ssize_t readSize;
75 char buf[128];
76
77 while((readSize = read(pfd[0], buf, sizeof buf - 1)) > 0) {
78 if(buf[readSize - 1] == '\n') {
79 --readSize;
80 }
81
82 buf[readSize] = 0; // add null-terminator
83
84 __android_log_write(ANDROID_LOG_DEBUG, applicationName, buf); // Set any log level you want
85 }
86
87 return 0;
88}
89
90static int runStdioForwardingThread() { // run this function to redirect your output to android log
91 setvbuf(stdout, 0, _IOLBF, 0); // make stdout line-buffered
92 setvbuf(stderr, 0, _IONBF, 0); // make stderr unbuffered
93
94 /* create the pipe and redirect stdout and stderr */
95 pipe(pfd);
96 dup2(pfd[1], 1);
97 dup2(pfd[1], 2);
98
99 /* spawn the logging thread */
100 if(pthread_create(&loggingThread, 0, loggingFunction, 0) == -1) {
101 return -1;
102 }
103
104 pthread_detach(loggingThread);
105
106 return 0;
107}
108
109} // detail
110
111void handler_init()
112{
113 qInstallMessageHandler(&detail::kritaQtMessageHandler);
114 detail::runStdioForwardingThread();
115}
116
117}
118
119#else /* ANDROID_ENABLE_STDIO_FORWARDING */
120
123{
124 // do nothing
125}
126
127}
128
129#endif /* ANDROID_ENABLE_STDIO_FORWARDING */