• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "test_base.h"
18 
19 #include <gtest/gtest.h>
20 
21 #include <cstdint>
22 #include <optional>
23 #include <thread>
24 
25 #include "chre/core/event_loop_manager.h"
26 #include "chre/core/host_endpoint_manager.h"
27 #include "chre/platform/log.h"
28 #include "chre_api/chre/event.h"
29 #include "test_event_queue.h"
30 #include "test_util.h"
31 
32 namespace chre {
33 
34 namespace {
35 
36 class HostEndpointNotificationTest : public TestBase {};
37 
38 //! The host endpoint ID to use for this test.
39 constexpr uint16_t kHostEndpointId = 123;
40 
41 //! Helper function to get Host Endpoint Manager from Event Loop Manager
getHostEndpointManager()42 HostEndpointManager &getHostEndpointManager() {
43   return EventLoopManagerSingleton::get()->getHostEndpointManager();
44 }
45 
46 /**
47  * Verifies basic functionality of chreConfigureHostEndpointNotifications.
48  */
TEST_F(HostEndpointNotificationTest,HostEndpointDisconnectedTest)49 TEST_F(HostEndpointNotificationTest, HostEndpointDisconnectedTest) {
50   CREATE_CHRE_TEST_EVENT(SETUP_NOTIFICATION, 0);
51 
52   struct Config {
53     bool enable;
54     uint16_t endpointId;
55   };
56 
57   class App : public TestNanoapp {
58    public:
59     void handleEvent(uint32_t, uint16_t eventType,
60                      const void *eventData) override {
61       switch (eventType) {
62         case CHRE_EVENT_HOST_ENDPOINT_NOTIFICATION: {
63           auto notification = *(struct chreHostEndpointNotification *)eventData;
64           TestEventQueueSingleton::get()->pushEvent(
65               CHRE_EVENT_HOST_ENDPOINT_NOTIFICATION, notification);
66         } break;
67 
68         case CHRE_EVENT_TEST_EVENT: {
69           auto event = static_cast<const TestEvent *>(eventData);
70           switch (event->type) {
71             case SETUP_NOTIFICATION: {
72               auto config = static_cast<const Config *>(event->data);
73               const bool success = chreConfigureHostEndpointNotifications(
74                   config->endpointId, config->enable);
75               TestEventQueueSingleton::get()->pushEvent(SETUP_NOTIFICATION,
76                                                         success);
77             }
78           }
79         }
80       }
81     }
82   };
83 
84   struct chreHostEndpointInfo info;
85   info.hostEndpointId = kHostEndpointId;
86   info.hostEndpointType = CHRE_HOST_ENDPOINT_TYPE_FRAMEWORK;
87   info.isNameValid = true;
88   strcpy(&info.endpointName[0], "Test endpoint name");
89   info.isTagValid = true;
90   strcpy(&info.endpointTag[0], "Test tag");
91   getHostEndpointManager().postHostEndpointConnected(info);
92 
93   uint64_t appId = loadNanoapp(MakeUnique<App>());
94 
95   Config config = {.enable = true, .endpointId = kHostEndpointId};
96 
97   sendEventToNanoapp(appId, SETUP_NOTIFICATION, config);
98   bool success;
99   waitForEvent(SETUP_NOTIFICATION, &success);
100   EXPECT_TRUE(success);
101 
102   struct chreHostEndpointInfo retrievedInfo;
103   ASSERT_TRUE(getHostEndpointManager().getHostEndpointInfo(kHostEndpointId,
104                                                            &retrievedInfo));
105   ASSERT_EQ(retrievedInfo.hostEndpointId, info.hostEndpointId);
106   ASSERT_EQ(retrievedInfo.hostEndpointType, info.hostEndpointType);
107   ASSERT_EQ(retrievedInfo.isNameValid, info.isNameValid);
108   ASSERT_EQ(strcmp(&retrievedInfo.endpointName[0], &info.endpointName[0]), 0);
109   ASSERT_EQ(retrievedInfo.isTagValid, info.isTagValid);
110   ASSERT_EQ(strcmp(&retrievedInfo.endpointTag[0], &info.endpointTag[0]), 0);
111 
112   struct chreHostEndpointNotification notification;
113   getHostEndpointManager().postHostEndpointDisconnected(kHostEndpointId);
114   waitForEvent(CHRE_EVENT_HOST_ENDPOINT_NOTIFICATION, &notification);
115 
116   ASSERT_EQ(notification.hostEndpointId, kHostEndpointId);
117   ASSERT_EQ(notification.notificationType,
118             HOST_ENDPOINT_NOTIFICATION_TYPE_DISCONNECT);
119   ASSERT_EQ(notification.reserved, 0);
120 
121   ASSERT_FALSE(EventLoopManagerSingleton::get()
122                    ->getHostEndpointManager()
123                    .getHostEndpointInfo(kHostEndpointId, &retrievedInfo));
124 }
125 
TEST_F(HostEndpointNotificationTest,HostEndpointNotRegisteredTest)126 TEST_F(HostEndpointNotificationTest, HostEndpointNotRegisteredTest) {
127   struct chreHostEndpointInfo retrievedInfo;
128   ASSERT_FALSE(getHostEndpointManager().getHostEndpointInfo(kHostEndpointId,
129                                                             &retrievedInfo));
130 }
131 
TEST_F(HostEndpointNotificationTest,HostEndpointDisconnectedTwiceTest)132 TEST_F(HostEndpointNotificationTest, HostEndpointDisconnectedTwiceTest) {
133   struct chreHostEndpointInfo info;
134   info.hostEndpointId = kHostEndpointId;
135   info.hostEndpointType = CHRE_HOST_ENDPOINT_TYPE_FRAMEWORK;
136   info.isNameValid = false;
137   info.isTagValid = false;
138   getHostEndpointManager().postHostEndpointConnected(info);
139 
140   getHostEndpointManager().postHostEndpointDisconnected(kHostEndpointId);
141   // The second invocation should be a silent no-op.
142   getHostEndpointManager().postHostEndpointDisconnected(kHostEndpointId);
143 }
144 
145 }  // anonymous namespace
146 }  // namespace chre
147