blob: d73de957881aa4c9911be8946c8fb9a3fd897ca7 [file] [log] [blame]
Bookatz486d1cf2017-09-01 13:10:41 -07001/*
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#define LOG_TAG "AnomalyMonitor"
18#define DEBUG true
19
20#include <AnomalyMonitor.h>
21
22#include <binder/IServiceManager.h>
23#include <cutils/log.h>
24
25namespace statsd {
26
27AnomalyMonitor::AnomalyMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec)
28 : mRegisteredAlarmTimeSec(0),
29 mMinUpdateTimeSec(minDiffToUpdateRegisteredAlarmTimeSec) {
30}
31
32AnomalyMonitor::~AnomalyMonitor() {
33}
34
35void AnomalyMonitor::add(sp<const AnomalyAlarm> alarm) {
36 if (alarm == nullptr) {
37 ALOGW("Asked to add a null alarm.");
38 return;
39 }
40 if (alarm->timestampSec < 1) {
41 // forbidden since a timestamp 0 is used to indicate no alarm registered
42 ALOGW("Asked to add a 0-time alarm.");
43 return;
44 }
45 std::lock_guard<std::mutex> lock(mLock);
46 // TODO: Ensure that refractory period is respected.
47 if (DEBUG) ALOGD("Adding alarm with time %u", alarm->timestampSec);
48 mPq.push(alarm);
49 if (mRegisteredAlarmTimeSec < 1 ||
50 alarm->timestampSec + mMinUpdateTimeSec < mRegisteredAlarmTimeSec) {
51 updateRegisteredAlarmTime(alarm->timestampSec);
52 }
53}
54
55void AnomalyMonitor::remove(sp<const AnomalyAlarm> alarm) {
56 if (alarm == nullptr) {
57 ALOGW("Asked to remove a null alarm.");
58 return;
59 }
60 std::lock_guard<std::mutex> lock(mLock);
61 if (DEBUG) ALOGD("Removing alarm with time %u", alarm->timestampSec);
Bookatz0e959092017-09-07 17:39:37 -070062 mPq.remove(alarm);
Bookatz486d1cf2017-09-01 13:10:41 -070063 if (mPq.empty()) {
64 if (DEBUG) ALOGD("Queue is empty. Cancel any alarm.");
65 mRegisteredAlarmTimeSec = 0;
66 // TODO: Make this resistant to doing work when companion is not ready yet
67 sp<IStatsCompanionService> statsCompanionService = getStatsCompanion_l();
68 if (statsCompanionService != nullptr) {
69 statsCompanionService->cancelAnomalyAlarm();
70 }
71 return;
72 }
73 uint32_t soonestAlarmTimeSec = mPq.top()->timestampSec;
74 if (DEBUG) ALOGD("Soonest alarm is %u", soonestAlarmTimeSec);
75 if (soonestAlarmTimeSec > mRegisteredAlarmTimeSec + mMinUpdateTimeSec) {
76 updateRegisteredAlarmTime(soonestAlarmTimeSec);
77 }
78}
79
80void AnomalyMonitor::updateRegisteredAlarmTime(uint32_t timestampSec) {
81 if (DEBUG) ALOGD("Updating reg alarm time to %u", timestampSec);
82 mRegisteredAlarmTimeSec = timestampSec;
83 sp<IStatsCompanionService> statsCompanionService = getStatsCompanion_l();
84 if (statsCompanionService != nullptr) {
85 statsCompanionService->setAnomalyAlarm(secToMs(mRegisteredAlarmTimeSec));
86 }
87}
88
89sp<IStatsCompanionService> AnomalyMonitor::getStatsCompanion_l() {
90 if (mStatsCompanion != nullptr) {
91 return mStatsCompanion;
92 }
93 // Get statscompanion service from service manager
94 const sp<IServiceManager> sm(defaultServiceManager());
95 if (sm != nullptr) {
96 const String16 name("statscompanion");
97 mStatsCompanion =
98 interface_cast<IStatsCompanionService>(sm->checkService(name));
99 if (mStatsCompanion == nullptr) {
100 ALOGW("statscompanion service unavailable!");
101 return nullptr;
102 }
103 }
104 return mStatsCompanion;
105}
106
107int64_t AnomalyMonitor::secToMs(uint32_t timeSec) {
108 return ((int64_t) timeSec) * 1000;
109}
110
111} // namespace statsd