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 
19 #include <aidl/android/os/IPendingIntentRef.h>
20 #include <utils/RefBase.h>
21 #include <utils/String16.h>
22 
23 #include "config/ConfigKey.h"
24 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // subscription
25 #include "HashableDimensionKey.h"
26 
27 #include <mutex>
28 #include <unordered_map>
29 #include <vector>
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     shared_ptr<IPendingIntentRef> getBroadcastSubscriber(const ConfigKey& configKey,
78                                                          int64_t subscriberId);
79 
80 private:
81     SubscriberReporter();
82 
83     mutable mutex mLock;
84 
85     /** Maps <ConfigKey, SubscriberId> -> IPendingIntentRef (which represents a PendingIntent). */
86     unordered_map<ConfigKey, unordered_map<int64_t, shared_ptr<IPendingIntentRef>>> mIntentMap;
87 
88     /**
89      * Sends a broadcast via the given intentSender (using mStatsCompanionService), along
90      * with the information in the other parameters.
91      */
92     void sendBroadcastLocked(const shared_ptr<IPendingIntentRef>& pir,
93                              const ConfigKey& configKey,
94                              const Subscription& subscription,
95                              const vector<string>& cookies,
96                              const MetricDimensionKey& dimKey) const;
97 
98     ::ndk::ScopedAIBinder_DeathRecipient mBroadcastSubscriberDeathRecipient;
99 
100     /**
101      * Death recipient callback that is called when a broadcast subscriber dies.
102      * The cookie is a pointer to a BroadcastSubscriberDeathCookie.
103      */
104     static void broadcastSubscriberDied(void* cookie);
105 };
106 
107 }  // namespace statsd
108 }  // namespace os
109 }  // namespace android
110