1 /* 2 * Copyright (C) 2018 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 DEBUG false // STOPSHIP if true 18 #include "Log.h" 19 20 #include "anomaly/AlarmTracker.h" 21 #include "anomaly/subscriber_util.h" 22 #include "HashableDimensionKey.h" 23 #include "stats_util.h" 24 #include "storage/StorageManager.h" 25 26 #include <statslog.h> 27 #include <time.h> 28 29 namespace android { 30 namespace os { 31 namespace statsd { 32 33 AlarmTracker::AlarmTracker(const int64_t startMillis, 34 const int64_t currentMillis, 35 const Alarm& alarm, const ConfigKey& configKey, 36 const sp<AlarmMonitor>& alarmMonitor) 37 : mAlarmConfig(alarm), 38 mConfigKey(configKey), 39 mAlarmMonitor(alarmMonitor) { 40 VLOG("AlarmTracker() called"); 41 mAlarmSec = (startMillis + mAlarmConfig.offset_millis()) / MS_PER_SEC; 42 // startMillis is the time statsd is created. We need to find the 1st alarm timestamp after 43 // the config is added to statsd. 44 mAlarmSec = findNextAlarmSec(currentMillis / MS_PER_SEC); // round up 45 mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)}; 46 VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec); 47 if (mAlarmMonitor != nullptr) { 48 mAlarmMonitor->add(mInternalAlarm); 49 } 50 } 51 52 AlarmTracker::~AlarmTracker() { 53 VLOG("~AlarmTracker() called"); 54 if (mInternalAlarm != nullptr && mAlarmMonitor != nullptr) { 55 mAlarmMonitor->remove(mInternalAlarm); 56 } 57 } 58 59 void AlarmTracker::addSubscription(const Subscription& subscription) { 60 mSubscriptions.push_back(subscription); 61 } 62 63 int64_t AlarmTracker::findNextAlarmSec(int64_t currentTimeSec) { 64 if (currentTimeSec <= mAlarmSec) { 65 return mAlarmSec; 66 } 67 int64_t periodsForward = 68 ((currentTimeSec - mAlarmSec) * MS_PER_SEC - 1) / mAlarmConfig.period_millis() + 1; 69 return mAlarmSec + periodsForward * mAlarmConfig.period_millis() / MS_PER_SEC; 70 } 71 72 void AlarmTracker::informAlarmsFired( 73 const int64_t& timestampNs, 74 unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) { 75 if (firedAlarms.empty() || mInternalAlarm == nullptr || 76 firedAlarms.find(mInternalAlarm) == firedAlarms.end()) { 77 return; 78 } 79 if (!mSubscriptions.empty()) { 80 VLOG("AlarmTracker triggers the subscribers."); 81 triggerSubscribers(mAlarmConfig.id(), 0 /*metricId N/A*/, DEFAULT_METRIC_DIMENSION_KEY, 82 0 /* metricValue N/A */, mConfigKey, mSubscriptions); 83 } 84 firedAlarms.erase(mInternalAlarm); 85 mAlarmSec = findNextAlarmSec((timestampNs-1) / NS_PER_SEC + 1); // round up 86 mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)}; 87 VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec); 88 if (mAlarmMonitor != nullptr) { 89 mAlarmMonitor->add(mInternalAlarm); 90 } 91 } 92 93 } // namespace statsd 94 } // namespace os 95 } // namespace android 96