1 // Copyright (C) 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "subscriber/SubscriberReporter.h"
16 
17 #include <android/binder_interface_utils.h>
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include "tests/statsd_test_util.h"
22 
23 using namespace testing;
24 using ::ndk::SharedRefBase;
25 using std::unordered_map;
26 
27 #ifdef __ANDROID__
28 
29 namespace android {
30 namespace os {
31 namespace statsd {
32 
33 namespace {
34 
35 const ConfigKey configKey1(0, 12345);
36 const ConfigKey configKey2(0, 123456);
37 const int64_t subscriptionId1 = 1, subscriptionId2 = 2;
38 
39 }  // anonymous namespace
40 
41 class SubscriberReporterTest : public ::testing::Test {
42 public:
SubscriberReporterTest()43     SubscriberReporterTest() {
44     }
45     const shared_ptr<MockPendingIntentRef> pir1 =
46             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
47     const shared_ptr<MockPendingIntentRef> pir2 =
48             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
49     const shared_ptr<MockPendingIntentRef> pir3 =
50             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
51     // Two subscribers on config key 1, one on config key 2.
SetUp()52     void SetUp() override {
53         SubscriberReporter::getInstance().setBroadcastSubscriber(configKey1, subscriptionId1, pir1);
54         SubscriberReporter::getInstance().setBroadcastSubscriber(configKey1, subscriptionId2, pir2);
55         SubscriberReporter::getInstance().setBroadcastSubscriber(configKey2, subscriptionId1, pir3);
56     }
57 
TearDown()58     void TearDown() override {
59         SubscriberReporter::getInstance();
60         SubscriberReporter::getInstance().unsetBroadcastSubscriber(configKey1, subscriptionId1);
61         SubscriberReporter::getInstance().unsetBroadcastSubscriber(configKey1, subscriptionId2);
62         SubscriberReporter::getInstance().unsetBroadcastSubscriber(configKey2, subscriptionId1);
63         EXPECT_EQ(pir1.use_count(), 1);
64         EXPECT_EQ(pir2.use_count(), 1);
65         EXPECT_EQ(pir3.use_count(), 1);
66         ASSERT_TRUE(SubscriberReporter::getInstance().mIntentMap.empty());
67     }
68 };
69 
TEST_F(SubscriberReporterTest,TestBroadcastSubscriberDeathRemovesPir)70 TEST_F(SubscriberReporterTest, TestBroadcastSubscriberDeathRemovesPir) {
71     SubscriberReporter::broadcastSubscriberDied(pir1.get());
72     EXPECT_EQ(pir1.use_count(), 1);
73 
74     unordered_map<ConfigKey, unordered_map<int64_t, shared_ptr<IPendingIntentRef>>>
75             expectedIntentMap = {{configKey1, {{subscriptionId2, pir2}}},
76                                  {configKey2, {{subscriptionId1, pir3}}}};
77     EXPECT_THAT(SubscriberReporter::getInstance().mIntentMap, ContainerEq(expectedIntentMap));
78 }
79 
TEST_F(SubscriberReporterTest,TestBroadcastSubscriberDeathRemovesPirAndConfigKey)80 TEST_F(SubscriberReporterTest, TestBroadcastSubscriberDeathRemovesPirAndConfigKey) {
81     SubscriberReporter::broadcastSubscriberDied(pir3.get());
82 
83     EXPECT_EQ(pir3.use_count(), 1);
84     unordered_map<ConfigKey, unordered_map<int64_t, shared_ptr<IPendingIntentRef>>>
85             expectedIntentMap = {{configKey1, {{subscriptionId1, pir1}, {subscriptionId2, pir2}}}};
86     EXPECT_THAT(SubscriberReporter::getInstance().mIntentMap, ContainerEq(expectedIntentMap));
87 }
88 
TEST_F(SubscriberReporterTest,TestBroadcastSubscriberDeathKeepsReplacedPir)89 TEST_F(SubscriberReporterTest, TestBroadcastSubscriberDeathKeepsReplacedPir) {
90     const shared_ptr<MockPendingIntentRef> pir4 =
91             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
92     SubscriberReporter::getInstance().setBroadcastSubscriber(configKey1, subscriptionId1, pir4);
93 
94     // pir1 dies, but pir4 has replaced it with the same keys. The map should remain the same.
95     SubscriberReporter::broadcastSubscriberDied(pir1.get());
96 
97     unordered_map<ConfigKey, unordered_map<int64_t, shared_ptr<IPendingIntentRef>>>
98             expectedIntentMap = {{configKey1, {{subscriptionId1, pir4}, {subscriptionId2, pir2}}},
99                                  {configKey2, {{subscriptionId1, pir3}}}};
100     EXPECT_THAT(SubscriberReporter::getInstance().mIntentMap, ContainerEq(expectedIntentMap));
101 }
102 }  // namespace statsd
103 }  // namespace os
104 }  // namespace android
105 #else
106 GTEST_LOG_(INFO) << "This test does nothing.\n";
107 #endif
108