blob: 37477dc50e4e88ee90aaea0a1f55e7d4b3531838 [file] [log] [blame]
Joe Onorato5dcbc6c2017-08-29 15:13:58 -07001/*
2 * Copyright (C) 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#define LOG_TAG "statsd"
18
19#include "LogEntryPrinter.h"
20#include "LogReader.h"
Yao Chenab273e22017-09-06 12:53:50 -070021#include "StatsLogProcessor.h"
Yao Chenef99c4f2017-09-22 16:26:54 -070022#include "StatsService.h"
David Chende701692017-10-05 13:16:02 -070023#include "UidMap.h"
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070024
25#include <binder/IInterface.h>
26#include <binder/IPCThreadState.h>
27#include <binder/IServiceManager.h>
28#include <binder/ProcessState.h>
29#include <binder/Status.h>
30#include <cutils/log.h>
31#include <utils/Looper.h>
32#include <utils/StrongPointer.h>
33
34#include <stdio.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070035#include <sys/stat.h>
Yao Chenef99c4f2017-09-22 16:26:54 -070036#include <sys/types.h>
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070037#include <unistd.h>
38
39using namespace android;
Bookatz906a35c2017-09-20 15:26:44 -070040using namespace android::os::statsd;
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070041
42// ================================================================================
43/**
44 * Thread function data.
45 */
46struct log_reader_thread_data {
47 sp<StatsService> service;
48};
49
50/**
51 * Thread func for where the log reader runs.
52 */
Yao Chenef99c4f2017-09-22 16:26:54 -070053static void* log_reader_thread_func(void* cookie) {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070054 log_reader_thread_data* data = static_cast<log_reader_thread_data*>(cookie);
55
56 sp<LogReader> reader = new LogReader();
57
58 // Put the printer one first, so it will print before the real ones.
Yao Chenab273e22017-09-06 12:53:50 -070059 reader->AddListener(new LogEntryPrinter(STDOUT_FILENO));
David Chende701692017-10-05 13:16:02 -070060 sp<StatsLogProcessor> main_processor = new StatsLogProcessor(data->service->getUidMap());
David Chen0656b7a2017-09-13 15:53:39 -070061 data->service->setProcessor(main_processor);
62 reader->AddListener(main_processor);
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070063
64 // TODO: Construct and add real LogListners here.
65
66 reader->Run();
67
68 ALOGW("statsd LogReader.Run() is not supposed to return.");
69
70 delete data;
71 return NULL;
72}
73
74/**
75 * Creates and starts the thread to own the LogReader.
76 */
Yao Chenef99c4f2017-09-22 16:26:54 -070077static status_t start_log_reader_thread(const sp<StatsService>& service) {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -070078 status_t err;
79 pthread_attr_t attr;
80 pthread_t thread;
81
82 // Thread data.
83 log_reader_thread_data* data = new log_reader_thread_data();
84 data->service = service;
85
86 // Create the thread
87 err = pthread_attr_init(&attr);
88 if (err != NO_ERROR) {
89 return err;
90 }
91 // TODO: Do we need to tweak thread priority?
92 err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
93 if (err != NO_ERROR) {
94 pthread_attr_destroy(&attr);
95 return err;
96 }
97 err = pthread_create(&thread, &attr, log_reader_thread_func, static_cast<void*>(data));
98 if (err != NO_ERROR) {
99 pthread_attr_destroy(&attr);
100 return err;
101 }
102 pthread_attr_destroy(&attr);
103
104 return NO_ERROR;
105}
106
107// ================================================================================
Yao Chenef99c4f2017-09-22 16:26:54 -0700108int main(int /*argc*/, char** /*argv*/) {
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700109 status_t err;
110
111 // Set up the looper
112 sp<Looper> looper(Looper::prepare(0 /* opts */));
113
114 // Set up the binder
115 sp<ProcessState> ps(ProcessState::self());
Yao Chenef99c4f2017-09-22 16:26:54 -0700116 ps->setThreadPoolMaxThreadCount(1); // everything is oneway, let it queue and save ram
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700117 ps->startThreadPool();
118 ps->giveThreadPoolName();
119 IPCThreadState::self()->disableBackgroundScheduling(true);
120
121 // Create the service
122 sp<StatsService> service = new StatsService(looper);
123 if (defaultServiceManager()->addService(String16("stats"), service) != 0) {
124 ALOGE("Failed to add service");
125 return -1;
126 }
127
Bookatzb487b552017-09-18 11:26:01 -0700128 // TODO: This line is temporary, since statsd doesn't start up automatically (and therefore
129 // the call in StatsService::SystemRunning() won't ever be called right now).
130 service->sayHiToStatsCompanion();
131
Joe Onorato5dcbc6c2017-08-29 15:13:58 -0700132 // Start the log reader thread
133 err = start_log_reader_thread(service);
134 if (err != NO_ERROR) {
135 return 1;
136 }
137
138 // Loop forever -- the reports run on this thread in a handler, and the
139 // binder calls remain responsive in their pool of one thread.
140 while (true) {
141 looper->pollAll(-1 /* timeoutMillis */);
142 }
143 ALOGW("statsd escaped from its loop.");
144
145 return 1;
146}