1 /* 2 * Copyright (C) 2019, 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 STATSD_DEBUG false // STOPSHIP if true 18 #include "Log.h" 19 20 #include "StateManager.h" 21 22 #include <private/android_filesystem_config.h> 23 24 namespace android { 25 namespace os { 26 namespace statsd { 27 StateManager()28 StateManager::StateManager() 29 : mAllowedPkg({ 30 "com.android.systemui", 31 }) { 32 } 33 getInstance()34 StateManager& StateManager::getInstance() { 35 static StateManager sStateManager; 36 return sStateManager; 37 } 38 clear()39 void StateManager::clear() { 40 mStateTrackers.clear(); 41 } 42 onLogEvent(const LogEvent & event)43 void StateManager::onLogEvent(const LogEvent& event) { 44 // Only process state events from uids in AID_* and packages that are whitelisted in 45 // mAllowedPkg. 46 // Allowlisted AIDs are AID_ROOT and all AIDs in [1000, 2000) which is [AID_SYSTEM, AID_SHELL) 47 if (event.GetUid() == AID_ROOT || 48 (event.GetUid() >= AID_SYSTEM && event.GetUid() < AID_SHELL) || 49 mAllowedLogSources.find(event.GetUid()) != mAllowedLogSources.end()) { 50 if (mStateTrackers.find(event.GetTagId()) != mStateTrackers.end()) { 51 mStateTrackers[event.GetTagId()]->onLogEvent(event); 52 } 53 } 54 } 55 registerListener(const int32_t atomId,const wp<StateListener> & listener)56 void StateManager::registerListener(const int32_t atomId, const wp<StateListener>& listener) { 57 // Check if state tracker already exists. 58 if (mStateTrackers.find(atomId) == mStateTrackers.end()) { 59 mStateTrackers[atomId] = new StateTracker(atomId); 60 } 61 mStateTrackers[atomId]->registerListener(listener); 62 } 63 unregisterListener(const int32_t atomId,const wp<StateListener> & listener)64 void StateManager::unregisterListener(const int32_t atomId, const wp<StateListener>& listener) { 65 std::unique_lock<std::mutex> lock(mMutex); 66 67 // Hold the sp<> until the lock is released so that ~StateTracker() is 68 // not called while the lock is held. 69 sp<StateTracker> toRemove; 70 71 // Unregister listener from correct StateTracker 72 auto it = mStateTrackers.find(atomId); 73 if (it != mStateTrackers.end()) { 74 it->second->unregisterListener(listener); 75 76 // Remove the StateTracker if it has no listeners 77 if (it->second->getListenersCount() == 0) { 78 toRemove = it->second; 79 mStateTrackers.erase(it); 80 } 81 } else { 82 ALOGE("StateManager cannot unregister listener, StateTracker for atom %d does not exist", 83 atomId); 84 } 85 lock.unlock(); 86 } 87 getStateValue(const int32_t atomId,const HashableDimensionKey & key,FieldValue * output) const88 bool StateManager::getStateValue(const int32_t atomId, const HashableDimensionKey& key, 89 FieldValue* output) const { 90 auto it = mStateTrackers.find(atomId); 91 if (it != mStateTrackers.end()) { 92 return it->second->getStateValue(key, output); 93 } 94 ALOGE("StateManager cannot get state value, no StateTracker for atom %d", atomId); 95 return false; 96 } 97 updateLogSources(const sp<UidMap> & uidMap)98 void StateManager::updateLogSources(const sp<UidMap>& uidMap) { 99 mAllowedLogSources.clear(); 100 for (const auto& pkg : mAllowedPkg) { 101 auto uids = uidMap->getAppUid(pkg); 102 mAllowedLogSources.insert(uids.begin(), uids.end()); 103 } 104 } 105 notifyAppChanged(const string & apk,const sp<UidMap> & uidMap)106 void StateManager::notifyAppChanged(const string& apk, const sp<UidMap>& uidMap) { 107 if (mAllowedPkg.find(apk) != mAllowedPkg.end()) { 108 updateLogSources(uidMap); 109 } 110 } 111 addAllAtomIds(LogEventFilter::AtomIdSet & allIds) const112 void StateManager::addAllAtomIds(LogEventFilter::AtomIdSet& allIds) const { 113 for (const auto& stateTracker : mStateTrackers) { 114 allIds.insert(stateTracker.first); 115 } 116 } 117 118 } // namespace statsd 119 } // namespace os 120 } // namespace android 121