blob: 8338d5026b4600ea691476262872b3eb2f3eb5dd [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);
62 // TODO: make priority queue able to have items removed from it !!!
63 // mPq.remove(alarm);
64 if (mPq.empty()) {
65 if (DEBUG) ALOGD("Queue is empty. Cancel any alarm.");
66 mRegisteredAlarmTimeSec = 0;
67 // TODO: Make this resistant to doing work when companion is not ready yet
68 sp<IStatsCompanionService> statsCompanionService = getStatsCompanion_l();
69 if (statsCompanionService != nullptr) {
70 statsCompanionService->cancelAnomalyAlarm();
71 }
72 return;
73 }
74 uint32_t soonestAlarmTimeSec = mPq.top()->timestampSec;
75 if (DEBUG) ALOGD("Soonest alarm is %u", soonestAlarmTimeSec);
76 if (soonestAlarmTimeSec > mRegisteredAlarmTimeSec + mMinUpdateTimeSec) {
77 updateRegisteredAlarmTime(soonestAlarmTimeSec);
78 }
79}
80
81void AnomalyMonitor::updateRegisteredAlarmTime(uint32_t timestampSec) {
82 if (DEBUG) ALOGD("Updating reg alarm time to %u", timestampSec);
83 mRegisteredAlarmTimeSec = timestampSec;
84 sp<IStatsCompanionService> statsCompanionService = getStatsCompanion_l();
85 if (statsCompanionService != nullptr) {
86 statsCompanionService->setAnomalyAlarm(secToMs(mRegisteredAlarmTimeSec));
87 }
88}
89
90sp<IStatsCompanionService> AnomalyMonitor::getStatsCompanion_l() {
91 if (mStatsCompanion != nullptr) {
92 return mStatsCompanion;
93 }
94 // Get statscompanion service from service manager
95 const sp<IServiceManager> sm(defaultServiceManager());
96 if (sm != nullptr) {
97 const String16 name("statscompanion");
98 mStatsCompanion =
99 interface_cast<IStatsCompanionService>(sm->checkService(name));
100 if (mStatsCompanion == nullptr) {
101 ALOGW("statscompanion service unavailable!");
102 return nullptr;
103 }
104 }
105 return mStatsCompanion;
106}
107
108int64_t AnomalyMonitor::secToMs(uint32_t timeSec) {
109 return ((int64_t) timeSec) * 1000;
110}
111
112} // namespace statsd