• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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