summaryrefslogtreecommitdiff
path: root/cmds/statsd/src/state/StateManager.cpp
diff options
context:
space:
mode:
authorSteven Laver <lavers@google.com>2019-11-05 13:42:59 -0800
committerSteven Laver <lavers@google.com>2019-11-09 01:16:30 +0000
commit7c6cc72e18cc1df5205fd2bc47664e6cc2534ad2 (patch)
treefc34e4ad6037cf231cccc3b56ccd13e82917520a /cmds/statsd/src/state/StateManager.cpp
parent8f4f93bf3ba75d8e83cb0a8618cb80f226ada5ac (diff)
parentda5e1bd24a9a0ca24e7e49fad9e604409e573376 (diff)
Merge RP1A.191024.001
Change-Id: I5cda3bba276e99d948b752be87d4599e9f882e0f
Diffstat (limited to 'cmds/statsd/src/state/StateManager.cpp')
-rw-r--r--cmds/statsd/src/state/StateManager.cpp91
1 files changed, 91 insertions, 0 deletions
diff --git a/cmds/statsd/src/state/StateManager.cpp b/cmds/statsd/src/state/StateManager.cpp
new file mode 100644
index 000000000000..95b2c7691803
--- /dev/null
+++ b/cmds/statsd/src/state/StateManager.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define DEBUG false // STOPSHIP if true
+#include "Log.h"
+
+#include "StateManager.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+StateManager& StateManager::getInstance() {
+ static StateManager sStateManager;
+ return sStateManager;
+}
+
+void StateManager::onLogEvent(const LogEvent& event) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mStateTrackers.find(event.GetTagId()) != mStateTrackers.end()) {
+ mStateTrackers[event.GetTagId()]->onLogEvent(event);
+ }
+}
+
+bool StateManager::registerListener(int atomId, wp<StateListener> listener) {
+ std::lock_guard<std::mutex> lock(mMutex);
+
+ // Check if state tracker already exists
+ if (mStateTrackers.find(atomId) == mStateTrackers.end()) {
+ // Create a new state tracker iff atom is a state atom
+ auto it = android::util::AtomsInfo::kStateAtomsFieldOptions.find(atomId);
+ if (it != android::util::AtomsInfo::kStateAtomsFieldOptions.end()) {
+ mStateTrackers[atomId] = new StateTracker(atomId, it->second);
+ } else {
+ ALOGE("StateManager cannot register listener, Atom %d is not a state atom", atomId);
+ return false;
+ }
+ }
+ mStateTrackers[atomId]->registerListener(listener);
+ return true;
+}
+
+void StateManager::unregisterListener(int atomId, wp<StateListener> listener) {
+ std::unique_lock<std::mutex> lock(mMutex);
+
+ // Hold the sp<> until the lock is released so that ~StateTracker() is
+ // not called while the lock is held.
+ sp<StateTracker> toRemove;
+
+ // Unregister listener from correct StateTracker
+ auto it = mStateTrackers.find(atomId);
+ if (it != mStateTrackers.end()) {
+ it->second->unregisterListener(listener);
+
+ // Remove the StateTracker if it has no listeners
+ if (it->second->getListenersCount() == 0) {
+ toRemove = it->second;
+ mStateTrackers.erase(it);
+ }
+ } else {
+ ALOGE("StateManager cannot unregister listener, StateTracker for atom %d does not exist",
+ atomId);
+ }
+ lock.unlock();
+}
+
+int StateManager::getStateValue(int atomId, const HashableDimensionKey& key) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mStateTrackers.find(atomId) != mStateTrackers.end()) {
+ return mStateTrackers[atomId]->getStateValue(key);
+ }
+
+ return StateTracker::kStateUnknown;
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android