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 <aidl/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 aidl::android::os::IStatsCompanionService; 30 using std::function; 31 using std::shared_ptr; 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 explicit 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 function<void(const shared_ptr<IStatsCompanionService>&, int64_t)>& 70 updateAlarm, 71 const function<void(const shared_ptr<IStatsCompanionService>&)>& cancelAlarm); 72 ~AlarmMonitor(); 73 74 /** 75 * Tells AnomalyMonitor what IStatsCompanionService to use and, if 76 * applicable, immediately registers an existing alarm with it. 77 * If nullptr, AnomalyMonitor will continue to add/remove alarms, but won't 78 * update IStatsCompanionService (until such time as it is set non-null). 79 */ 80 void setStatsCompanionService(shared_ptr<IStatsCompanionService> statsCompanionService); 81 82 /** 83 * Adds the given alarm (reference) to the queue. 84 */ 85 void add(sp<const InternalAlarm> alarm); 86 87 /** 88 * Removes the given alarm (reference) from the queue. 89 * Note that alarm comparison is reference-based; if another alarm exists 90 * with the same timestampSec, that alarm will still remain in the queue. 91 */ 92 void remove(sp<const InternalAlarm> alarm); 93 94 /** 95 * Returns and removes all alarms whose timestamp <= the given timestampSec. 96 * Always updates the registered alarm if return is non-empty. 97 */ 98 unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> popSoonerThan( 99 uint32_t timestampSec); 100 101 /** 102 * Returns the projected alarm timestamp that is registered with 103 * StatsCompanionService. This may not be equal to the soonest alarm, 104 * but should be within minDiffToUpdateRegisteredAlarmTimeSec of it. 105 */ getRegisteredAlarmTimeSec()106 uint32_t getRegisteredAlarmTimeSec() const { 107 return mRegisteredAlarmTimeSec; 108 } 109 110 private: 111 std::mutex mLock; 112 113 /** 114 * Timestamp (seconds since epoch) of the alarm registered with 115 * StatsCompanionService. This, in general, may not be equal to the soonest 116 * alarm stored in mPq, but should be within minUpdateTimeSec of it. 117 * A value of 0 indicates that no alarm is currently registered. 118 */ 119 uint32_t mRegisteredAlarmTimeSec; 120 121 /** 122 * Priority queue of alarms, prioritized by soonest alarm.timestampSec. 123 */ 124 indexed_priority_queue<InternalAlarm, InternalAlarm::SmallerTimestamp> mPq; 125 126 /** 127 * Binder interface for communicating with StatsCompanionService. 128 */ 129 shared_ptr<IStatsCompanionService> mStatsCompanionService = nullptr; 130 131 /** 132 * Amount by which the soonest projected alarm must differ from 133 * mRegisteredAlarmTimeSec before updateRegisteredAlarmTime_l is called. 134 */ 135 uint32_t mMinUpdateTimeSec; 136 137 /** 138 * Updates the alarm registered with StatsCompanionService to the given time. 139 * Also correspondingly updates mRegisteredAlarmTimeSec. 140 */ 141 void updateRegisteredAlarmTime_l(uint32_t timestampSec); 142 143 /** 144 * Cancels the alarm registered with StatsCompanionService. 145 * Also correspondingly sets mRegisteredAlarmTimeSec to 0. 146 */ 147 void cancelRegisteredAlarmTime_l(); 148 149 /** Converts uint32 timestamp in seconds to a Java long in msec. */ 150 int64_t secToMs(uint32_t timeSec); 151 152 // Callback function to update the alarm via StatsCompanionService. 153 std::function<void(const shared_ptr<IStatsCompanionService>, int64_t)> mUpdateAlarm; 154 155 // Callback function to cancel the alarm via StatsCompanionService. 156 std::function<void(const shared_ptr<IStatsCompanionService>)> mCancelAlarm; 157 158 }; 159 160 } // namespace statsd 161 } // namespace os 162 } // namespace android 163