1 /* 2 * Copyright (C) 2022 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 <aidl/android/os/IStatsSubscriptionCallback.h> 20 #include <aidl/android/os/StatsSubscriptionCallbackReason.h> 21 #include <android-base/file.h> 22 #include <android/util/ProtoOutputStream.h> 23 #include <private/android_filesystem_config.h> 24 25 #include <memory> 26 27 #include "external/StatsPullerManager.h" 28 #include "logd/LogEvent.h" 29 #include "packages/UidMap.h" 30 #include "socket/LogEventFilter.h" 31 #include "src/shell/shell_config.pb.h" 32 #include "src/statsd_config.pb.h" 33 34 using aidl::android::os::IStatsSubscriptionCallback; 35 using aidl::android::os::StatsSubscriptionCallbackReason; 36 37 namespace android { 38 namespace os { 39 namespace statsd { 40 41 // ShellSubscriberClient is not thread-safe. All calls must be 42 // guarded by the mutex in ShellSubscriber.h 43 class ShellSubscriberClient { 44 public: 45 struct PullInfo { 46 PullInfo(const SimpleAtomMatcher& matcher, int64_t startTimeMs, int64_t interval, 47 const std::vector<std::string>& packages, const std::vector<int32_t>& uids); 48 49 const SimpleAtomMatcher mPullerMatcher; 50 const int64_t mIntervalMs; 51 int64_t mPrevPullElapsedRealtimeMs; 52 const std::vector<std::string> mPullPackages; 53 const std::vector<int32_t> mPullUids; 54 }; 55 56 static std::unique_ptr<ShellSubscriberClient> create(int in, int out, int64_t timeoutSec, 57 int64_t startTimeSec, 58 const sp<UidMap>& uidMap, 59 const sp<StatsPullerManager>& pullerMgr); 60 61 static std::unique_ptr<ShellSubscriberClient> create( 62 const std::vector<uint8_t>& subscriptionConfig, 63 const std::shared_ptr<IStatsSubscriptionCallback>& callback, int64_t startTimeSec, 64 const sp<UidMap>& uidMap, const sp<StatsPullerManager>& pullerMgr); 65 66 void onLogEvent(const LogEvent& event); 67 68 int64_t pullAndSendHeartbeatsIfNeeded(int64_t nowSecs, int64_t nowMillis, int64_t nowNanos); 69 70 // Should only be called when mCallback is not nullptr. 71 void flush(); 72 73 // Should only be called when mCallback is not nullptr. 74 void onUnsubscribe(); 75 isAlive()76 bool isAlive() const { 77 return mClientAlive; 78 } 79 hasCallback(const std::shared_ptr<IStatsSubscriptionCallback> & callback)80 bool hasCallback(const std::shared_ptr<IStatsSubscriptionCallback>& callback) const { 81 return mCallback != nullptr && callback != nullptr && 82 callback->asBinder() == mCallback->asBinder(); 83 } 84 getMaxSizeKb()85 static size_t getMaxSizeKb() { 86 return kMaxSizeKb; 87 } 88 89 void addAllAtomIds(LogEventFilter::AtomIdSet& allAtomIds) const; 90 91 // Minimum pull interval for callback subscriptions. 92 static constexpr int64_t kMinCallbackPullIntervalMs = 60'000; // 60 seconds. 93 94 // Minimum sleep for the pull thread for callback subscriptions. 95 static constexpr int64_t kMinCallbackSleepIntervalMs = 2000; // 2 seconds. 96 private: 97 // Should only be called by the create() factory which has access to implementation. 98 explicit ShellSubscriberClient(int id, int out, 99 const std::shared_ptr<IStatsSubscriptionCallback>& callback, 100 const std::vector<SimpleAtomMatcher>& pushedMatchers, 101 const std::vector<PullInfo>& pulledInfo, int64_t timeoutSec, 102 int64_t startTimeSec, const sp<UidMap>& uidMap, 103 const sp<StatsPullerManager>& pullerMgr); 104 setCollectUids(bool doCollect)105 void setCollectUids(bool doCollect) { 106 mDoCollectUids = doCollect; 107 } 108 109 int64_t pullIfNeeded(int64_t nowSecs, int64_t nowMillis, int64_t nowNanos); 110 111 void writePulledAtomsLocked(const vector<std::shared_ptr<LogEvent>>& data, 112 const SimpleAtomMatcher& matcher); 113 114 void attemptWriteToPipeLocked(); 115 116 void getUidsForPullAtom(vector<int32_t>* uids, const PullInfo& pullInfo); 117 118 void flushProtoIfNeeded(); 119 120 bool writeEventToProtoIfMatched(const LogEvent& event, const SimpleAtomMatcher& matcher, 121 const sp<UidMap>& uidMap); 122 123 void clearCache(); 124 125 void triggerFdFlush(); 126 127 void triggerCallback(StatsSubscriptionCallbackReason reason); 128 129 const int32_t DEFAULT_PULL_UID = AID_SYSTEM; 130 131 // Unique ID for this subscription for StatsdStats. 132 const int mId; 133 134 const sp<UidMap> mUidMap; 135 136 const sp<StatsPullerManager> mPullerMgr; 137 138 android::base::unique_fd mDupOut; 139 140 const std::vector<SimpleAtomMatcher> mPushedMatchers; 141 142 std::vector<PullInfo> mPulledInfo; 143 144 std::shared_ptr<IStatsSubscriptionCallback> mCallback; 145 146 const int64_t mTimeoutSec; 147 148 const int64_t mStartTimeSec; 149 150 bool mClientAlive = true; 151 152 int64_t mLastWriteMs; 153 154 // Stores Atom proto messages for events along with their respective timestamps. 155 ProtoOutputStream mProtoOut; 156 157 // Stores the total approximate encoded proto byte-size for cached Atom events in 158 // mEventTimestampNs and mProtoOut. 159 size_t mCacheSize; 160 161 bool mDoCollectUids = false; 162 163 static constexpr int64_t kMsBetweenHeartbeats = 1000; 164 165 // Cap the buffer size of configs to guard against bad allocations 166 static constexpr size_t kMaxSizeKb = 50; 167 168 static constexpr size_t kMaxCacheSizeBytes = 2 * 1024; // 2 KB 169 170 static constexpr int64_t kMsBetweenCallbacks = 70'000; // 70 seconds. 171 }; 172 173 } // namespace statsd 174 } // namespace os 175 } // namespace android 176