Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2019 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 | #include <HidlService.h> |
| 18 | |
| 19 | #include <android/hidl/manager/1.2/IClientCallback.h> |
| 20 | #include <gmock/gmock.h> |
| 21 | #include <gtest/gtest.h> |
| 22 | |
| 23 | using ::android::hardware::Return; |
| 24 | using ::android::hardware::Void; |
| 25 | using ::android::hidl::base::V1_0::IBase; |
| 26 | using ::android::hidl::manager::implementation::HidlService; |
| 27 | using ::android::hidl::manager::V1_2::IClientCallback; |
| 28 | using ::android::sp; |
| 29 | using ::testing::ElementsAre; |
| 30 | using ::testing::Invoke; |
| 31 | using ::testing::NiceMock; |
| 32 | |
| 33 | class RecordingClientCallback : public IClientCallback { |
| 34 | public: |
| 35 | Return<void> onClients(const sp<IBase>& /*base*/, bool clients) override { |
| 36 | stream.push_back(clients); |
| 37 | return Void(); |
| 38 | } |
| 39 | |
| 40 | std::vector<bool> stream; |
| 41 | }; |
| 42 | |
| 43 | class MockHidlService : public HidlService { |
| 44 | public: |
| 45 | MockHidlService() : HidlService("fqname", "instance") {} |
| 46 | MOCK_METHOD0(getNodeStrongRefCount, ssize_t()); |
| 47 | }; |
| 48 | |
| 49 | class HidlServiceLazyTest : public ::testing::Test { |
| 50 | public: |
| 51 | // Note that this should include one count for hwservicemanager. A count of |
| 52 | // 1 indicates that hwservicemanager is the only process holding the service. |
| 53 | void setReportedClientCount(ssize_t count) { |
Steven Moreland | e7cf142 | 2019-02-01 20:17:25 -0800 | [diff] [blame] | 54 | mState.mInjectedReportCount = count; |
| 55 | } |
| 56 | |
| 57 | // Essentially, the number of times the kernel API would be called |
| 58 | size_t getNumTimesReported() { |
| 59 | return mState.mInjectedTimes; |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 60 | } |
| 61 | |
| 62 | std::unique_ptr<HidlService> makeService() { |
| 63 | auto service = std::make_unique<NiceMock<MockHidlService>>(); |
Steven Moreland | e7cf142 | 2019-02-01 20:17:25 -0800 | [diff] [blame] | 64 | ON_CALL(*service, getNodeStrongRefCount()).WillByDefault(Invoke([&]() { |
| 65 | mState.mInjectedTimes++; |
| 66 | return mState.mInjectedReportCount; |
| 67 | })); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 68 | return service; |
| 69 | } |
| 70 | |
| 71 | protected: |
| 72 | void SetUp() override { |
Steven Moreland | e7cf142 | 2019-02-01 20:17:25 -0800 | [diff] [blame] | 73 | mState = TestState(); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 74 | } |
| 75 | |
Steven Moreland | e7cf142 | 2019-02-01 20:17:25 -0800 | [diff] [blame] | 76 | struct TestState { |
| 77 | ssize_t mInjectedReportCount = -1; |
| 78 | size_t mInjectedTimes = 0; |
| 79 | } mState; |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 80 | }; |
| 81 | |
| 82 | TEST_F(HidlServiceLazyTest, NoChange) { |
| 83 | sp<RecordingClientCallback> cb = new RecordingClientCallback; |
| 84 | |
| 85 | std::unique_ptr<HidlService> service = makeService(); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 86 | service->addClientCallback(cb, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 87 | |
| 88 | setReportedClientCount(1); |
| 89 | |
| 90 | for (size_t i = 0; i < 100; i++) { |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 91 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
| 92 | } |
| 93 | |
| 94 | ASSERT_THAT(cb->stream, ElementsAre()); |
| 95 | } |
| 96 | |
| 97 | TEST_F(HidlServiceLazyTest, NoChangeWithKnownClients) { |
| 98 | sp<RecordingClientCallback> cb = new RecordingClientCallback; |
| 99 | |
| 100 | std::unique_ptr<HidlService> service = makeService(); |
| 101 | service->addClientCallback(cb, 2 /*knownClients*/); |
| 102 | |
| 103 | setReportedClientCount(2); |
| 104 | |
| 105 | for (size_t i = 0; i < 100; i++) { |
| 106 | service->handleClientCallbacks(true /*onInterval*/, 2 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 107 | } |
| 108 | |
| 109 | ASSERT_THAT(cb->stream, ElementsAre()); |
| 110 | } |
| 111 | |
| 112 | TEST_F(HidlServiceLazyTest, GetAndDrop) { |
| 113 | sp<RecordingClientCallback> cb = new RecordingClientCallback; |
| 114 | |
| 115 | std::unique_ptr<HidlService> service = makeService(); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 116 | service->addClientCallback(cb, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 117 | |
| 118 | // some other process has the service |
| 119 | setReportedClientCount(2); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 120 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 121 | |
| 122 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 123 | |
| 124 | // just hwservicemanager has the service |
| 125 | setReportedClientCount(1); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 126 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 127 | |
| 128 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 129 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 130 | |
| 131 | ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals |
| 132 | } |
| 133 | |
| 134 | TEST_F(HidlServiceLazyTest, GetGuarantee) { |
| 135 | sp<RecordingClientCallback> cb = new RecordingClientCallback; |
| 136 | |
| 137 | std::unique_ptr<HidlService> service = makeService(); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 138 | service->addClientCallback(cb, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 139 | |
| 140 | service->guaranteeClient(); |
| 141 | |
| 142 | setReportedClientCount(1); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 143 | service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 144 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 145 | |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 146 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 147 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 148 | |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 149 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 150 | ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals |
| 151 | } |
| 152 | |
| 153 | TEST_F(HidlServiceLazyTest, ManyUpdatesOffInterval) { |
| 154 | sp<RecordingClientCallback> cb = new RecordingClientCallback; |
| 155 | |
| 156 | std::unique_ptr<HidlService> service = makeService(); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 157 | service->addClientCallback(cb, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 158 | |
| 159 | // Clients can appear and dissappear as many times as necessary, but they are only considered |
| 160 | // dropped when the fixed interval stops. |
| 161 | for (size_t i = 0; i < 100; i++) { |
| 162 | setReportedClientCount(2); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 163 | service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 164 | setReportedClientCount(1); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 165 | service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 166 | } |
| 167 | |
| 168 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 169 | |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 170 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 171 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 172 | |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 173 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 501bc8e | 2019-02-01 16:21:46 -0800 | [diff] [blame] | 174 | ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals |
| 175 | } |
Steven Moreland | 9cd9e88 | 2019-02-01 18:55:42 -0800 | [diff] [blame] | 176 | |
| 177 | TEST_F(HidlServiceLazyTest, AcquisitionAfterGuarantee) { |
| 178 | sp<RecordingClientCallback> cb = new RecordingClientCallback; |
| 179 | |
| 180 | std::unique_ptr<HidlService> service = makeService(); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 181 | service->addClientCallback(cb, 1 /*knownClients*/); |
Steven Moreland | 9cd9e88 | 2019-02-01 18:55:42 -0800 | [diff] [blame] | 182 | |
| 183 | setReportedClientCount(2); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 184 | service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 9cd9e88 | 2019-02-01 18:55:42 -0800 | [diff] [blame] | 185 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 186 | |
| 187 | setReportedClientCount(1); |
| 188 | service->guaranteeClient(); |
| 189 | |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 190 | service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 9cd9e88 | 2019-02-01 18:55:42 -0800 | [diff] [blame] | 191 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 192 | |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 193 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 9cd9e88 | 2019-02-01 18:55:42 -0800 | [diff] [blame] | 194 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 195 | |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 196 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 9cd9e88 | 2019-02-01 18:55:42 -0800 | [diff] [blame] | 197 | ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals |
| 198 | } |
Steven Moreland | 2fa0f55 | 2019-02-01 19:27:33 -0800 | [diff] [blame] | 199 | |
| 200 | TEST_F(HidlServiceLazyTest, NotificationSentForNewClientCallback) { |
| 201 | sp<RecordingClientCallback> cb = new RecordingClientCallback; |
| 202 | |
| 203 | std::unique_ptr<HidlService> service = makeService(); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 204 | service->addClientCallback(cb, 1 /*knownClients*/); |
Steven Moreland | 2fa0f55 | 2019-02-01 19:27:33 -0800 | [diff] [blame] | 205 | |
| 206 | setReportedClientCount(2); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 207 | service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 2fa0f55 | 2019-02-01 19:27:33 -0800 | [diff] [blame] | 208 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 209 | |
| 210 | sp<RecordingClientCallback> laterCb = new RecordingClientCallback; |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 211 | service->addClientCallback(laterCb, 1 /*knownClients*/); |
Steven Moreland | 2fa0f55 | 2019-02-01 19:27:33 -0800 | [diff] [blame] | 212 | |
| 213 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 214 | ASSERT_THAT(laterCb->stream, ElementsAre(true)); |
| 215 | |
| 216 | setReportedClientCount(1); |
| 217 | |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 218 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 2fa0f55 | 2019-02-01 19:27:33 -0800 | [diff] [blame] | 219 | ASSERT_THAT(cb->stream, ElementsAre(true)); |
| 220 | ASSERT_THAT(laterCb->stream, ElementsAre(true)); |
| 221 | |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 222 | service->handleClientCallbacks(true /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | 2fa0f55 | 2019-02-01 19:27:33 -0800 | [diff] [blame] | 223 | ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals |
| 224 | ASSERT_THAT(laterCb->stream, ElementsAre(true, false)); // reported only after two intervals |
| 225 | } |
Steven Moreland | e7cf142 | 2019-02-01 20:17:25 -0800 | [diff] [blame] | 226 | |
| 227 | TEST_F(HidlServiceLazyTest, ClientWithoutLazy) { |
| 228 | std::unique_ptr<HidlService> service = makeService(); |
| 229 | |
| 230 | setReportedClientCount(2); |
Steven Moreland | 105c58b | 2020-04-06 16:18:50 -0700 | [diff] [blame] | 231 | service->handleClientCallbacks(false /*onInterval*/, 1 /*knownClients*/); |
Steven Moreland | e7cf142 | 2019-02-01 20:17:25 -0800 | [diff] [blame] | 232 | |
| 233 | // kernel API should not be called |
| 234 | EXPECT_EQ(0u, getNumTimesReported()); |
| 235 | } |