1 /* 2 * Copyright (C) 2018 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 #pragma once 18 19 #include "logd/LogEvent.h" 20 21 #include <android/util/ProtoOutputStream.h> 22 #include <binder/IResultReceiver.h> 23 #include <condition_variable> 24 #include <mutex> 25 #include <thread> 26 #include "external/StatsPullerManager.h" 27 #include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h" 28 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" 29 #include "packages/UidMap.h" 30 31 namespace android { 32 namespace os { 33 namespace statsd { 34 35 /** 36 * Handles atoms subscription via shell cmd. 37 * 38 * A shell subscription lasts *until shell exits*. Unlike config based clients, a shell client 39 * communicates with statsd via file descriptors. They can subscribe pushed and pulled atoms. 40 * The atoms are sent back to the client in real time, as opposed to 41 * keeping the data in memory. Shell clients do not subscribe aggregated metrics, as they are 42 * responsible for doing the aggregation after receiving the atom events. 43 * 44 * Shell client pass ShellSubscription in the proto binary format. Client can update the 45 * subscription by sending a new subscription. The new subscription would replace the old one. 46 * Input data stream format is: 47 * 48 * |size_t|subscription proto|size_t|subscription proto|.... 49 * 50 * statsd sends the events back in Atom proto binary format. Each Atom message is preceded 51 * with sizeof(size_t) bytes indicating the size of the proto message payload. 52 * 53 * The stream would be in the following format: 54 * |size_t|shellData proto|size_t|shellData proto|.... 55 * 56 * Only one shell subscriber allowed at a time, because each shell subscriber blocks one thread 57 * until it exits. 58 */ 59 class ShellSubscriber : public virtual IBinder::DeathRecipient { 60 public: ShellSubscriber(sp<UidMap> uidMap,sp<StatsPullerManager> pullerMgr)61 ShellSubscriber(sp<UidMap> uidMap, sp<StatsPullerManager> pullerMgr) 62 : mUidMap(uidMap), mPullerMgr(pullerMgr){}; 63 64 /** 65 * Start a new subscription. 66 */ 67 void startNewSubscription(int inFd, int outFd, sp<IResultReceiver> resultReceiver, 68 int timeoutSec); 69 70 void binderDied(const wp<IBinder>& who); 71 72 void onLogEvent(const LogEvent& event); 73 74 private: 75 struct PullInfo { PullInfoPullInfo76 PullInfo(const SimpleAtomMatcher& matcher, int64_t interval) 77 : mPullerMatcher(matcher), mInterval(interval), mPrevPullElapsedRealtimeMs(0) { 78 } 79 SimpleAtomMatcher mPullerMatcher; 80 int64_t mInterval; 81 int64_t mPrevPullElapsedRealtimeMs; 82 }; 83 void readConfig(int in); 84 85 void updateConfig(const ShellSubscription& config); 86 87 void startPull(int64_t token, int64_t intervalMillis); 88 89 void cleanUpLocked(); 90 91 void writeToOutputLocked(const vector<std::shared_ptr<LogEvent>>& data, 92 const SimpleAtomMatcher& matcher); 93 94 sp<UidMap> mUidMap; 95 96 sp<StatsPullerManager> mPullerMgr; 97 98 android::util::ProtoOutputStream mProto; 99 100 mutable std::mutex mMutex; 101 102 std::condition_variable mShellDied; // semaphore for waiting until shell exits. 103 104 int mInput; // The input file descriptor 105 106 int mOutput; // The output file descriptor 107 108 sp<IResultReceiver> mResultReceiver; 109 110 std::vector<SimpleAtomMatcher> mPushedMatchers; 111 112 std::vector<PullInfo> mPulledInfo; 113 114 int64_t mPullToken = 0; // A unique token to identify a puller thread. 115 }; 116 117 } // namespace statsd 118 } // namespace os 119 } // namespace android 120