123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- /*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include <HidlService.h>
- #include <android/hidl/manager/1.2/IClientCallback.h>
- #include <gmock/gmock.h>
- #include <gtest/gtest.h>
- using ::android::hardware::Return;
- using ::android::hardware::Void;
- using ::android::hidl::base::V1_0::IBase;
- using ::android::hidl::manager::implementation::HidlService;
- using ::android::hidl::manager::V1_2::IClientCallback;
- using ::android::sp;
- using ::testing::ElementsAre;
- using ::testing::Invoke;
- using ::testing::NiceMock;
- class RecordingClientCallback : public IClientCallback {
- public:
- Return<void> onClients(const sp<IBase>& /*base*/, bool clients) override {
- stream.push_back(clients);
- return Void();
- }
- std::vector<bool> stream;
- };
- class MockHidlService : public HidlService {
- public:
- MockHidlService() : HidlService("fqname", "instance") {}
- MOCK_METHOD0(getNodeStrongRefCount, ssize_t());
- };
- class HidlServiceLazyTest : public ::testing::Test {
- public:
- // Note that this should include one count for hwservicemanager. A count of
- // 1 indicates that hwservicemanager is the only process holding the service.
- void setReportedClientCount(ssize_t count) {
- mState.mInjectedReportCount = count;
- }
- // Essentially, the number of times the kernel API would be called
- size_t getNumTimesReported() {
- return mState.mInjectedTimes;
- }
- std::unique_ptr<HidlService> makeService() {
- auto service = std::make_unique<NiceMock<MockHidlService>>();
- ON_CALL(*service, getNodeStrongRefCount()).WillByDefault(Invoke([&]() {
- mState.mInjectedTimes++;
- return mState.mInjectedReportCount;
- }));
- return service;
- }
- protected:
- void SetUp() override {
- mState = TestState();
- }
- struct TestState {
- ssize_t mInjectedReportCount = -1;
- size_t mInjectedTimes = 0;
- } mState;
- };
- TEST_F(HidlServiceLazyTest, NoChange) {
- sp<RecordingClientCallback> cb = new RecordingClientCallback;
- std::unique_ptr<HidlService> service = makeService();
- service->addClientCallback(cb);
- setReportedClientCount(1);
- for (size_t i = 0; i < 100; i++) {
- service->handleClientCallbacks(true /*onInterval*/);
- }
- ASSERT_THAT(cb->stream, ElementsAre());
- }
- TEST_F(HidlServiceLazyTest, GetAndDrop) {
- sp<RecordingClientCallback> cb = new RecordingClientCallback;
- std::unique_ptr<HidlService> service = makeService();
- service->addClientCallback(cb);
- // some other process has the service
- setReportedClientCount(2);
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- // just hwservicemanager has the service
- setReportedClientCount(1);
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
- }
- TEST_F(HidlServiceLazyTest, GetGuarantee) {
- sp<RecordingClientCallback> cb = new RecordingClientCallback;
- std::unique_ptr<HidlService> service = makeService();
- service->addClientCallback(cb);
- service->guaranteeClient();
- setReportedClientCount(1);
- service->handleClientCallbacks(false /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
- }
- TEST_F(HidlServiceLazyTest, ManyUpdatesOffInterval) {
- sp<RecordingClientCallback> cb = new RecordingClientCallback;
- std::unique_ptr<HidlService> service = makeService();
- service->addClientCallback(cb);
- // Clients can appear and dissappear as many times as necessary, but they are only considered
- // dropped when the fixed interval stops.
- for (size_t i = 0; i < 100; i++) {
- setReportedClientCount(2);
- service->handleClientCallbacks(false /*onInterval*/);
- setReportedClientCount(1);
- service->handleClientCallbacks(false /*onInterval*/);
- }
- ASSERT_THAT(cb->stream, ElementsAre(true));
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
- }
- TEST_F(HidlServiceLazyTest, AcquisitionAfterGuarantee) {
- sp<RecordingClientCallback> cb = new RecordingClientCallback;
- std::unique_ptr<HidlService> service = makeService();
- service->addClientCallback(cb);
- setReportedClientCount(2);
- service->handleClientCallbacks(false /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- setReportedClientCount(1);
- service->guaranteeClient();
- service->handleClientCallbacks(false /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
- }
- TEST_F(HidlServiceLazyTest, NotificationSentForNewClientCallback) {
- sp<RecordingClientCallback> cb = new RecordingClientCallback;
- std::unique_ptr<HidlService> service = makeService();
- service->addClientCallback(cb);
- setReportedClientCount(2);
- service->handleClientCallbacks(false /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- sp<RecordingClientCallback> laterCb = new RecordingClientCallback;
- service->addClientCallback(laterCb);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- ASSERT_THAT(laterCb->stream, ElementsAre(true));
- setReportedClientCount(1);
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true));
- ASSERT_THAT(laterCb->stream, ElementsAre(true));
- service->handleClientCallbacks(true /*onInterval*/);
- ASSERT_THAT(cb->stream, ElementsAre(true, false)); // reported only after two intervals
- ASSERT_THAT(laterCb->stream, ElementsAre(true, false)); // reported only after two intervals
- }
- TEST_F(HidlServiceLazyTest, ClientWithoutLazy) {
- std::unique_ptr<HidlService> service = makeService();
- setReportedClientCount(2);
- service->handleClientCallbacks(false /*onInterval*/);
- // kernel API should not be called
- EXPECT_EQ(0u, getNumTimesReported());
- }
|