• 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     // Should only be called by the create() factory.
67     explicit ShellSubscriberClient(int out,
68                                    const std::shared_ptr<IStatsSubscriptionCallback>& callback,
69                                    const std::vector<SimpleAtomMatcher>& pushedMatchers,
70                                    const std::vector<PullInfo>& pulledInfo, int64_t timeoutSec,
71                                    int64_t startTimeSec, const sp<UidMap>& uidMap,
72                                    const sp<StatsPullerManager>& pullerMgr);
73 
74     void onLogEvent(const LogEvent& event);
75 
76     int64_t pullAndSendHeartbeatsIfNeeded(int64_t nowSecs, int64_t nowMillis, int64_t nowNanos);
77 
78     // Should only be called when mCallback is not nullptr.
79     void flush();
80 
81     // Should only be called when mCallback is not nullptr.
82     void onUnsubscribe();
83 
isAlive()84     bool isAlive() const {
85         return mClientAlive;
86     }
87 
hasCallback(const std::shared_ptr<IStatsSubscriptionCallback> & callback)88     bool hasCallback(const std::shared_ptr<IStatsSubscriptionCallback>& callback) const {
89         return mCallback != nullptr && callback != nullptr &&
90                callback->asBinder() == mCallback->asBinder();
91     }
92 
getMaxSizeKb()93     static size_t getMaxSizeKb() {
94         return kMaxSizeKb;
95     }
96 
97     void addAllAtomIds(LogEventFilter::AtomIdSet& allAtomIds) const;
98 
99     // Minimum pull interval for callback subscriptions.
100     static constexpr int64_t kMinCallbackPullIntervalMs = 60'000;  // 60 seconds.
101 
102     // Minimum sleep for the pull thread for callback subscriptions.
103     static constexpr int64_t kMinCallbackSleepIntervalMs = 2000;  // 2 seconds.
104 private:
105     int64_t pullIfNeeded(int64_t nowSecs, int64_t nowMillis, int64_t nowNanos);
106 
107     void writePulledAtomsLocked(const vector<std::shared_ptr<LogEvent>>& data,
108                                 const SimpleAtomMatcher& matcher);
109 
110     void attemptWriteToPipeLocked();
111 
112     void getUidsForPullAtom(vector<int32_t>* uids, const PullInfo& pullInfo);
113 
114     void flushProtoIfNeeded();
115 
116     bool writeEventToProtoIfMatched(const LogEvent& event, const SimpleAtomMatcher& matcher,
117                                     const sp<UidMap>& uidMap);
118 
119     void clearCache();
120 
121     void triggerFdFlush();
122 
123     void triggerCallback(StatsSubscriptionCallbackReason reason);
124 
125     const int32_t DEFAULT_PULL_UID = AID_SYSTEM;
126 
127     const sp<UidMap> mUidMap;
128 
129     const sp<StatsPullerManager> mPullerMgr;
130 
131     android::base::unique_fd mDupOut;
132 
133     const std::vector<SimpleAtomMatcher> mPushedMatchers;
134 
135     std::vector<PullInfo> mPulledInfo;
136 
137     std::shared_ptr<IStatsSubscriptionCallback> mCallback;
138 
139     const int64_t mTimeoutSec;
140 
141     const int64_t mStartTimeSec;
142 
143     bool mClientAlive = true;
144 
145     int64_t mLastWriteMs;
146 
147     // Stores Atom proto messages for events along with their respective timestamps.
148     ProtoOutputStream mProtoOut;
149 
150     // Stores the total approximate encoded proto byte-size for cached Atom events in
151     // mEventTimestampNs and mProtoOut.
152     size_t mCacheSize;
153 
154     static constexpr int64_t kMsBetweenHeartbeats = 1000;
155 
156     // Cap the buffer size of configs to guard against bad allocations
157     static constexpr size_t kMaxSizeKb = 50;
158 
159     static constexpr size_t kMaxCacheSizeBytes = 2 * 1024;  // 2 KB
160 
161     static constexpr int64_t kMsBetweenCallbacks = 70'000;  // 70 seconds.
162 };
163 
164 }  // namespace statsd
165 }  // namespace os
166 }  // namespace android
167