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