1 /*
2  * Copyright (C) 2017 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 <android/os/IStatsCompanionService.h>
20 #include <binder/IServiceManager.h>
21 #include <utils/RefBase.h>
22 #include <utils/threads.h>
23 #include <string>
24 #include <unordered_map>
25 #include <vector>
26 #include <list>
27 #include "PullDataReceiver.h"
28 #include "StatsPuller.h"
29 #include "logd/LogEvent.h"
30 
31 namespace android {
32 namespace os {
33 namespace statsd {
34 
35 typedef struct {
36   // The field numbers of the fields that need to be summed when merging
37   // isolated uid with host uid.
38   std::vector<int> additiveFields;
39   // The field numbers of the fields that can't be merged when merging
40   // data belong to isolated uid and host uid.
41   std::vector<int> nonAdditiveFields;
42   // How long should the puller wait before doing an actual pull again. Default
43   // 1 sec. Set this to 0 if this is handled elsewhere.
44   int64_t coolDownNs = 1 * NS_PER_SEC;
45   // The actual puller
46   sp<StatsPuller> puller;
47 } PullAtomInfo;
48 
49 class StatsPullerManagerImpl : public virtual RefBase {
50 public:
51     static StatsPullerManagerImpl& GetInstance();
52 
53     void RegisterReceiver(int tagId, wp<PullDataReceiver> receiver, int64_t nextPullTimeNs,
54                           int64_t intervalNs);
55 
56     void UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver);
57 
58     // Verify if we know how to pull for this matcher
59     bool PullerForMatcherExists(int tagId) const;
60 
61     void OnAlarmFired(const int64_t timeNs);
62 
63     bool Pull(const int tagId, const int64_t timeNs, vector<std::shared_ptr<LogEvent>>* data);
64 
65     int ForceClearPullerCache();
66 
67     int ClearPullerCacheIfNecessary(int64_t timestampNs);
68 
69     void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
70 
71     const static std::map<int, PullAtomInfo> kAllPullAtomInfo;
72 
73    private:
74     StatsPullerManagerImpl();
75 
76     sp<IStatsCompanionService> mStatsCompanionService = nullptr;
77 
78     typedef struct {
79         int64_t nextPullTimeNs;
80         int64_t intervalNs;
81         wp<PullDataReceiver> receiver;
82     } ReceiverInfo;
83 
84     // mapping from simple matcher tagId to receivers
85     std::map<int, std::list<ReceiverInfo>> mReceivers;
86 
87     // locks for data receiver and StatsCompanionService changes
88     Mutex mLock;
89 
90     void updateAlarmLocked();
91 
92     int64_t mNextPullTimeNs;
93 
94     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
95     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
96     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
97     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
98 };
99 
100 }  // namespace statsd
101 }  // namespace os
102 }  // namespace android
103