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 #pragma once 18 #include <aidl/android/os/IPendingIntentRef.h> 19 #include <gtest/gtest_prod.h> 20 #include <utils/RefBase.h> 21 #include <utils/String16.h> 22 23 #include <mutex> 24 #include <unordered_map> 25 #include <vector> 26 27 #include "HashableDimensionKey.h" 28 #include "config/ConfigKey.h" 29 #include "src/statsd_config.pb.h" // subscription 30 31 using aidl::android::os::IPendingIntentRef; 32 using std::mutex; 33 using std::shared_ptr; 34 using std::string; 35 using std::unordered_map; 36 using std::vector; 37 38 namespace android { 39 namespace os { 40 namespace statsd { 41 42 // Reports information to subscribers. 43 // Single instance shared across the process. All methods are thread safe. 44 class SubscriberReporter { 45 public: 46 /** Get (singleton) instance of SubscriberReporter. */ getInstance()47 static SubscriberReporter& getInstance() { 48 static SubscriberReporter subscriberReporter; 49 return subscriberReporter; 50 } 51 ~SubscriberReporter()52 ~SubscriberReporter(){}; 53 SubscriberReporter(SubscriberReporter const&) = delete; 54 void operator=(SubscriberReporter const&) = delete; 55 56 /** 57 * Stores the given intentSender, associating it with the given (configKey, subscriberId) pair. 58 */ 59 void setBroadcastSubscriber(const ConfigKey& configKey, 60 int64_t subscriberId, 61 const shared_ptr<IPendingIntentRef>& pir); 62 63 /** 64 * Erases any intentSender information from the given (configKey, subscriberId) pair. 65 */ 66 void unsetBroadcastSubscriber(const ConfigKey& configKey, int64_t subscriberId); 67 68 /** 69 * Sends a broadcast via the intentSender previously stored for the 70 * given (configKey, subscriberId) pair by setBroadcastSubscriber. 71 * Information about the subscriber, as well as information extracted from the dimKey, is sent. 72 */ 73 void alertBroadcastSubscriber(const ConfigKey& configKey, 74 const Subscription& subscription, 75 const MetricDimensionKey& dimKey) const; 76 77 private: 78 SubscriberReporter(); 79 80 mutable mutex mLock; 81 82 /** Maps <ConfigKey, SubscriberId> -> IPendingIntentRef (which represents a PendingIntent). */ 83 unordered_map<ConfigKey, unordered_map<int64_t, shared_ptr<IPendingIntentRef>>> mIntentMap; 84 85 /** 86 * Sends a broadcast via the given intentSender (using mStatsCompanionService), along 87 * with the information in the other parameters. 88 */ 89 void sendBroadcastLocked(const shared_ptr<IPendingIntentRef>& pir, 90 const ConfigKey& configKey, 91 const Subscription& subscription, 92 const vector<string>& cookies, 93 const MetricDimensionKey& dimKey) const; 94 95 ::ndk::ScopedAIBinder_DeathRecipient mBroadcastSubscriberDeathRecipient; 96 97 /** 98 * Death recipient callback that is called when a broadcast subscriber dies. 99 * The cookie is a raw pointer to a PendingIntentReference. It is only used for identifying 100 * which binder has died and must not be dereferenced. 101 */ 102 static void broadcastSubscriberDied(void* cookie); 103 104 friend class SubscriberReporterTest; 105 FRIEND_TEST(SubscriberReporterTest, TestBroadcastSubscriberDeathRemovesPir); 106 FRIEND_TEST(SubscriberReporterTest, TestBroadcastSubscriberDeathRemovesPirAndConfigKey); 107 FRIEND_TEST(SubscriberReporterTest, TestBroadcastSubscriberDeathKeepsReplacedPir); 108 }; 109 110 } // namespace statsd 111 } // namespace os 112 } // namespace android 113