blob: f912e4b2cd2432fd8ae83a525b85cb9d6b416f38 [file] [log] [blame]
Bookatzc6977972018-01-16 16:55:05 -08001/*
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#define DEBUG false // STOPSHIP if true
18#include "Log.h"
19
20#include "SubscriberReporter.h"
21
22using android::IBinder;
23using std::lock_guard;
24using std::unordered_map;
25
26namespace android {
27namespace os {
28namespace statsd {
29
30void SubscriberReporter::setBroadcastSubscriber(const ConfigKey& configKey,
31 int64_t subscriberId,
32 const sp<IBinder>& intentSender) {
33 VLOG("SubscriberReporter::setBroadcastSubscriber called.");
34 lock_guard<std::mutex> lock(mLock);
35 mIntentMap[configKey][subscriberId] = intentSender;
36}
37
38void SubscriberReporter::unsetBroadcastSubscriber(const ConfigKey& configKey,
39 int64_t subscriberId) {
40 VLOG("SubscriberReporter::unsetBroadcastSubscriber called.");
41 lock_guard<std::mutex> lock(mLock);
42 auto subscriberMapIt = mIntentMap.find(configKey);
43 if (subscriberMapIt != mIntentMap.end()) {
44 subscriberMapIt->second.erase(subscriberId);
45 if (subscriberMapIt->second.empty()) {
46 mIntentMap.erase(configKey);
47 }
48 }
49}
50
51void SubscriberReporter::removeConfig(const ConfigKey& configKey) {
52 VLOG("SubscriberReporter::removeConfig called.");
53 lock_guard<std::mutex> lock(mLock);
54 mIntentMap.erase(configKey);
55}
56
57void SubscriberReporter::alertBroadcastSubscriber(const ConfigKey& configKey,
58 const Subscription& subscription,
59 const HashableDimensionKey& dimKey) const {
60 // Reminder about ids:
61 // subscription id - name of the Subscription (that ties the Alert to the broadcast)
62 // subscription rule_id - the name of the Alert (that triggers the broadcast)
63 // subscriber_id - name of the PendingIntent to use to send the broadcast
64 // config uid - the uid that uploaded the config (and therefore gave the PendingIntent,
65 // although the intent may be to broadcast to a different uid)
66 // config id - the name of this config (for this particular uid)
67
68 VLOG("SubscriberReporter::alertBroadcastSubscriber called.");
69 lock_guard<std::mutex> lock(mLock);
70
71 if (!subscription.has_broadcast_subscriber_details()
72 || !subscription.broadcast_subscriber_details().has_subscriber_id()) {
73 ALOGE("Broadcast subscriber does not have an id.");
74 return;
75 }
76 int64_t subscriberId = subscription.broadcast_subscriber_details().subscriber_id();
77
78 auto it1 = mIntentMap.find(configKey);
79 if (it1 == mIntentMap.end()) {
80 ALOGW("Cannot inform subscriber for missing config key %s ", configKey.ToString().c_str());
81 return;
82 }
83 auto it2 = it1->second.find(subscriberId);
84 if (it2 == it1->second.end()) {
85 ALOGW("Cannot inform subscriber of config %s for missing subscriberId %lld ",
86 configKey.ToString().c_str(), (long long)subscriberId);
87 return;
88 }
89 sendBroadcastLocked(it2->second, configKey, subscription, dimKey);
90}
91
92void SubscriberReporter::sendBroadcastLocked(const sp<IBinder>& intentSender,
93 const ConfigKey& configKey,
94 const Subscription& subscription,
95 const HashableDimensionKey& dimKey) const {
96 VLOG("SubscriberReporter::sendBroadcastLocked called.");
97 if (mStatsCompanionService == nullptr) {
98 ALOGW("Failed to send subscriber broadcast: could not access StatsCompanionService.");
99 return;
100 }
101 mStatsCompanionService->sendSubscriberBroadcast(intentSender,
102 configKey.GetUid(),
103 configKey.GetId(),
104 subscription.id(),
105 subscription.rule_id(),
106 protoToStatsDimensionsValue(dimKey));
107}
108
109StatsDimensionsValue SubscriberReporter::protoToStatsDimensionsValue(
110 const HashableDimensionKey& dimKey) {
111 return protoToStatsDimensionsValue(dimKey.getDimensionsValue());
112}
113
114StatsDimensionsValue SubscriberReporter::protoToStatsDimensionsValue(
115 const DimensionsValue& protoDimsVal) {
116 int32_t field = protoDimsVal.field();
117
118 switch (protoDimsVal.value_case()) {
119 case DimensionsValue::ValueCase::kValueStr:
120 return StatsDimensionsValue(field, String16(protoDimsVal.value_str().c_str()));
121 case DimensionsValue::ValueCase::kValueInt:
122 return StatsDimensionsValue(field, static_cast<int32_t>(protoDimsVal.value_int()));
123 case DimensionsValue::ValueCase::kValueLong:
124 return StatsDimensionsValue(field, static_cast<int64_t>(protoDimsVal.value_long()));
125 case DimensionsValue::ValueCase::kValueBool:
126 return StatsDimensionsValue(field, static_cast<bool>(protoDimsVal.value_bool()));
127 case DimensionsValue::ValueCase::kValueFloat:
128 return StatsDimensionsValue(field, static_cast<float>(protoDimsVal.value_float()));
129 case DimensionsValue::ValueCase::kValueTuple:
130 {
131 int sz = protoDimsVal.value_tuple().dimensions_value_size();
132 std::vector<StatsDimensionsValue> sdvVec(sz);
133 for (int i = 0; i < sz; i++) {
134 sdvVec[i] = protoToStatsDimensionsValue(
135 protoDimsVal.value_tuple().dimensions_value(i));
136 }
137 return StatsDimensionsValue(field, sdvVec);
138 }
139 default:
140 ALOGW("protoToStatsDimensionsValue failed: illegal type.");
141 return StatsDimensionsValue();
142 }
143}
144
145} // namespace statsd
146} // namespace os
147} // namespace android