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 "anomaly/indexed_priority_queue.h" 20 21 #include <android/os/IStatsCompanionService.h> 22 #include <utils/RefBase.h> 23 24 #include <queue> 25 #include <set> 26 #include <unordered_set> 27 #include <vector> 28 29 using namespace android; 30 31 using android::os::IStatsCompanionService; 32 using std::unordered_set; 33 34 namespace android { 35 namespace os { 36 namespace statsd { 37 38 /** 39 * Represents an alarm, associated with some aggregate metric, holding a 40 * projected time at which the metric is expected to exceed its anomaly 41 * threshold. 42 * Timestamps are in seconds since epoch in a uint32, so will fail in year 2106. 43 */ 44 struct InternalAlarm : public RefBase { InternalAlarmInternalAlarm45 InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) { 46 } 47 48 const uint32_t timestampSec; 49 50 /** InternalAlarm a is smaller (higher priority) than b if its timestamp is sooner. */ 51 struct SmallerTimestamp { operatorInternalAlarm::SmallerTimestamp52 bool operator()(sp<const InternalAlarm> a, sp<const InternalAlarm> b) const { 53 return (a->timestampSec < b->timestampSec); 54 } 55 }; 56 }; 57 58 /** 59 * Manages internal alarms that may get registered with the AlarmManager. 60 */ 61 class AlarmMonitor : public RefBase { 62 public: 63 /** 64 * @param minDiffToUpdateRegisteredAlarmTimeSec If the soonest alarm differs 65 * from the registered alarm by more than this amount, update the registered 66 * alarm. 67 */ 68 AlarmMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec, 69 const std::function<void(const sp<IStatsCompanionService>&, int64_t)>& updateAlarm, 70 const std::function<void(const sp<IStatsCompanionService>&)>& cancelAlarm); 71 ~AlarmMonitor(); 72 73 /** 74 * Tells AnomalyMonitor what IStatsCompanionService to use and, if 75 * applicable, immediately registers an existing alarm with it. 76 * If nullptr, AnomalyMonitor will continue to add/remove alarms, but won't 77 * update IStatsCompanionService (until such time as it is set non-null). 78 */ 79 void setStatsCompanionService(sp<IStatsCompanionService> statsCompanionService); 80 81 /** 82 * Adds the given alarm (reference) to the queue. 83 */ 84 void add(sp<const InternalAlarm> alarm); 85 86 /** 87 * Removes the given alarm (reference) from the queue. 88 * Note that alarm comparison is reference-based; if another alarm exists 89 * with the same timestampSec, that alarm will still remain in the queue. 90 */ 91 void remove(sp<const InternalAlarm> alarm); 92 93 /** 94 * Returns and removes all alarms whose timestamp <= the given timestampSec. 95 * Always updates the registered alarm if return is non-empty. 96 */ 97 unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> popSoonerThan( 98 uint32_t timestampSec); 99 100 /** 101 * Returns the projected alarm timestamp that is registered with 102 * StatsCompanionService. This may not be equal to the soonest alarm, 103 * but should be within minDiffToUpdateRegisteredAlarmTimeSec of it. 104 */ getRegisteredAlarmTimeSec()105 uint32_t getRegisteredAlarmTimeSec() const { 106 return mRegisteredAlarmTimeSec; 107 } 108 109 private: 110 std::mutex mLock; 111 112 /** 113 * Timestamp (seconds since epoch) of the alarm registered with 114 * StatsCompanionService. This, in general, may not be equal to the soonest 115 * alarm stored in mPq, but should be within minUpdateTimeSec of it. 116 * A value of 0 indicates that no alarm is currently registered. 117 */ 118 uint32_t mRegisteredAlarmTimeSec; 119 120 /** 121 * Priority queue of alarms, prioritized by soonest alarm.timestampSec. 122 */ 123 indexed_priority_queue<InternalAlarm, InternalAlarm::SmallerTimestamp> mPq; 124 125 /** 126 * Binder interface for communicating with StatsCompanionService. 127 */ 128 sp<IStatsCompanionService> mStatsCompanionService = nullptr; 129 130 /** 131 * Amount by which the soonest projected alarm must differ from 132 * mRegisteredAlarmTimeSec before updateRegisteredAlarmTime_l is called. 133 */ 134 uint32_t mMinUpdateTimeSec; 135 136 /** 137 * Updates the alarm registered with StatsCompanionService to the given time. 138 * Also correspondingly updates mRegisteredAlarmTimeSec. 139 */ 140 void updateRegisteredAlarmTime_l(uint32_t timestampSec); 141 142 /** 143 * Cancels the alarm registered with StatsCompanionService. 144 * Also correspondingly sets mRegisteredAlarmTimeSec to 0. 145 */ 146 void cancelRegisteredAlarmTime_l(); 147 148 /** Converts uint32 timestamp in seconds to a Java long in msec. */ 149 int64_t secToMs(uint32_t timeSec); 150 151 // Callback function to update the alarm via StatsCompanionService. 152 std::function<void(const sp<IStatsCompanionService>, int64_t)> mUpdateAlarm; 153 154 // Callback function to cancel the alarm via StatsCompanionService. 155 std::function<void(const sp<IStatsCompanionService>)> mCancelAlarm; 156 157 }; 158 159 } // namespace statsd 160 } // namespace os 161 } // namespace android 162