1 /* 2 * Copyright (C) 2017 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 #define DEBUG false // STOPSHIP if true 18 #include "Log.h" 19 20 #include "StatsService.h" 21 #include "logd/LogReader.h" 22 #include "socket/StatsSocketListener.h" 23 24 #include <binder/IInterface.h> 25 #include <binder/IPCThreadState.h> 26 #include <binder/IServiceManager.h> 27 #include <binder/ProcessState.h> 28 #include <binder/Status.h> 29 #include <utils/Looper.h> 30 #include <utils/StrongPointer.h> 31 32 #include <stdio.h> 33 #include <sys/stat.h> 34 #include <sys/types.h> 35 #include <unistd.h> 36 37 using namespace android; 38 using namespace android::os::statsd; 39 40 const bool kUseLogd = false; 41 const bool kUseStatsdSocket = true; 42 43 /** 44 * Thread function data. 45 */ 46 struct log_reader_thread_data { 47 sp<StatsService> service; 48 }; 49 50 /** 51 * Thread func for where the log reader runs. 52 */ 53 static void* log_reader_thread_func(void* cookie) { 54 log_reader_thread_data* data = static_cast<log_reader_thread_data*>(cookie); 55 sp<LogReader> reader = new LogReader(data->service); 56 57 // Run the read loop. Never returns. 58 reader->Run(); 59 60 ALOGW("statsd LogReader.Run() is not supposed to return."); 61 62 delete data; 63 return NULL; 64 } 65 66 /** 67 * Creates and starts the thread to own the LogReader. 68 */ 69 static status_t start_log_reader_thread(const sp<StatsService>& service) { 70 status_t err; 71 pthread_attr_t attr; 72 pthread_t thread; 73 74 // Thread data. 75 log_reader_thread_data* data = new log_reader_thread_data(); 76 data->service = service; 77 78 // Create the thread 79 err = pthread_attr_init(&attr); 80 if (err != NO_ERROR) { 81 return err; 82 } 83 // TODO: Do we need to tweak thread priority? 84 err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 85 if (err != NO_ERROR) { 86 pthread_attr_destroy(&attr); 87 return err; 88 } 89 err = pthread_create(&thread, &attr, log_reader_thread_func, static_cast<void*>(data)); 90 if (err != NO_ERROR) { 91 pthread_attr_destroy(&attr); 92 return err; 93 } 94 pthread_attr_destroy(&attr); 95 96 return NO_ERROR; 97 } 98 99 int main(int /*argc*/, char** /*argv*/) { 100 // Set up the looper 101 sp<Looper> looper(Looper::prepare(0 /* opts */)); 102 103 // Set up the binder 104 sp<ProcessState> ps(ProcessState::self()); 105 ps->setThreadPoolMaxThreadCount(9); 106 ps->startThreadPool(); 107 ps->giveThreadPoolName(); 108 IPCThreadState::self()->disableBackgroundScheduling(true); 109 110 // Create the service 111 sp<StatsService> service = new StatsService(looper); 112 if (defaultServiceManager()->addService(String16("stats"), service) != 0) { 113 ALOGE("Failed to add service"); 114 return -1; 115 } 116 service->sayHiToStatsCompanion(); 117 118 service->Startup(); 119 120 sp<StatsSocketListener> socketListener = new StatsSocketListener(service); 121 122 if (kUseLogd) { 123 ALOGI("using logd"); 124 // Start the log reader thread 125 status_t err = start_log_reader_thread(service); 126 if (err != NO_ERROR) { 127 return 1; 128 } 129 } 130 131 if (kUseStatsdSocket) { 132 ALOGI("using statsd socket"); 133 // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value 134 if (socketListener->startListener(600)) { 135 exit(1); 136 } 137 } 138 139 // Loop forever -- the reports run on this thread in a handler, and the 140 // binder calls remain responsive in their pool of one thread. 141 while (true) { 142 looper->pollAll(-1 /* timeoutMillis */); 143 } 144 ALOGW("statsd escaped from its loop."); 145 146 return 1; 147 } 148