Restricted metrics changed operation followups Resolved some todos, tests still to come 1. Return the current restricted metrics when the api is called 2. Re-register all pending intents when statsd comes up 3. Remove pending intents from statsd on binder transaction failures Test: TH Bug: 269419485 Ignore-AOSP-First: U feature Change-Id: I1cc8f856dd95aabd1645703eaabf50d1dbbd973c
diff --git a/statsd/src/config/ConfigManager.cpp b/statsd/src/config/ConfigManager.cpp index 3a9c69c..16c4e75 100644 --- a/statsd/src/config/ConfigManager.cpp +++ b/statsd/src/config/ConfigManager.cpp
@@ -177,11 +177,27 @@ } } +void ConfigManager::RemoveRestrictedMetricsChangedReceiver( + const ConfigKeyWithPackage& key, const int32_t delegateUid, + const shared_ptr<IPendingIntentRef>& pir) { + lock_guard<mutex> lock(mMutex); + const auto& it = mRestrictedMetricsChangedReceivers.find(key); + if (it != mRestrictedMetricsChangedReceivers.end()) { + const auto& pirIt = it->second.find(delegateUid); + if (pirIt != it->second.end() && pirIt->second == pir) { + it->second.erase(delegateUid); + if (it->second.empty()) { + mRestrictedMetricsChangedReceivers.erase(it); + } + } + } +} + void ConfigManager::SendRestrictedMetricsBroadcast(const set<string>& configPackages, const int64_t configId, const set<int32_t>& delegateUids, const vector<int64_t>& metricIds) { - set<shared_ptr<IPendingIntentRef>> intentsToSend; + map<ConfigKeyWithPackage, map<int32_t, shared_ptr<IPendingIntentRef>>> intentsToSend; { lock_guard<mutex> lock(mMutex); // Invoke the pending intent for all matching configs, as long as the listening delegates @@ -192,7 +208,7 @@ if (it != mRestrictedMetricsChangedReceivers.end()) { for (const auto& [delegateUid, pir] : it->second) { if (delegateUids.find(delegateUid) != delegateUids.end()) { - intentsToSend.insert(pir); + intentsToSend[key][delegateUid] = pir; } } } @@ -200,12 +216,18 @@ } // Invoke the pending intents without holding the lock. - for (const shared_ptr<IPendingIntentRef>& pir : intentsToSend) { - Status status = pir->sendRestrictedMetricsChangedBroadcast(metricIds); - if (status.isOk()) { - VLOG("ConfigManager::SendRestrictedMetricsBroadcast succeeded"); + for (const auto& [key, innerMap] : intentsToSend) { + for (const auto& [delegateUid, pir] : innerMap) { + Status status = pir->sendRestrictedMetricsChangedBroadcast(metricIds); + if (status.isOk()) { + VLOG("ConfigManager::SendRestrictedMetricsBroadcast succeeded"); + } + if (status.getExceptionCode() == EX_TRANSACTION_FAILED && + status.getStatus() == STATUS_DEAD_OBJECT) { + // Must also be called without the lock, since remove will acquire the lock. + RemoveRestrictedMetricsChangedReceiver(key, delegateUid, pir); + } } - // TODO (b/269419485): handle failures. } }