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