1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
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
16 #include <ohos_errno.h>
17 #include "gtest/gtest.h"
18 #include "utils/SamgrTestBase.h"
19
20 using namespace testing::ext;
21
22 static const char *SERVICE_NAME = "S_iunknown";
23 static const char *FEATURE_NAME = "F_iunknown";
24
25 struct DemoApi {
26 INHERIT_IUNKNOWN;
27 };
28
29 struct DemoFeature {
30 INHERIT_FEATURE;
31 INHERIT_IUNKNOWNENTRY(DemoApi);
32 Identity identity;
33 };
34
GetName(Service * service)35 static const char *GetName(Service *service)
36 {
37 (void)service;
38 return SERVICE_NAME;
39 }
40
41 struct ExampleService {
42 INHERIT_SERVICE;
43 Identity identity;
44 };
45
Initialize(Service * service,Identity identity)46 static BOOL Initialize(Service *service, Identity identity)
47 {
48 ExampleService *example = (ExampleService *)service;
49 example->identity = identity;
50 return TRUE;
51 }
52
MessageHandle(Service * service,Request * msg)53 static BOOL MessageHandle(Service *service, Request *msg)
54 {
55 (void)service;
56 (void)msg;
57 return FALSE;
58 }
59
GetTaskConfig(Service * service)60 static TaskConfig GetTaskConfig(Service *service)
61 {
62 (void)service;
63 TaskConfig config = {
64 LEVEL_HIGH,
65 PRI_ABOVE_NORMAL,
66 0x800,
67 20,
68 SHARED_TASK
69 };
70 return config;
71 }
72
73 static ExampleService g_service = {
74 .GetName = GetName,
75 .Initialize = Initialize,
76 .MessageHandle = MessageHandle,
77 .GetTaskConfig = GetTaskConfig,
78 .identity = {-1, -1, nullptr},
79 };
80
FEATURE_GetName(Feature * feature)81 static const char *FEATURE_GetName(Feature *feature)
82 {
83 (void)feature;
84 return FEATURE_NAME;
85 }
FEATURE_OnInitialize(Feature * feature,Service * parent,Identity identity)86 static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity)
87 {
88 DemoFeature *demoFeature = (DemoFeature *)feature;
89 demoFeature->identity = identity;
90 }
FEATURE_OnStop(Feature * feature,Identity identity)91 static void FEATURE_OnStop(Feature *feature, Identity identity)
92 {
93 (void)feature;
94 (void)identity;
95 }
96
FEATURE_OnMessage(Feature * feature,Request * request)97 static BOOL FEATURE_OnMessage(Feature *feature, Request *request)
98 {
99 (void)feature;
100 (void)request;
101 return TRUE;
102 }
103
104 static DemoFeature g_feature = {
105 .GetName = FEATURE_GetName,
106 .OnInitialize = FEATURE_OnInitialize,
107 .OnStop = FEATURE_OnStop,
108 .OnMessage = FEATURE_OnMessage,
109 .ver = DEFAULT_VERSION,
110 .ref = 1,
111 .iUnknown = {
112 DEFAULT_IUNKNOWN_IMPL,
113 },
114 .identity = {-1, -1, nullptr},
115 };
116
117 static DemoApi g_api = {
118 .QueryInterface = IUNKNOWN_QueryInterface,
119 .AddRef = IUNKNOWN_AddRef,
120 .Release = IUNKNOWN_Release,
121 };
122
123 class IUnknownTest : public testing::Test {
124 protected:
125 // SetUpTestCase: Testsuit setup, run before 1st testcase
SetUpTestCase(void)126 static void SetUpTestCase(void)
127 {
128 SystemInitProxy();
129 }
130 // TearDownTestCase: Testsuit teardown, run after last testcase
TearDownTestCase(void)131 static void TearDownTestCase(void)
132 {
133 }
134 // Testcase setup
SetUp()135 virtual void SetUp()
136 {
137 BOOL result1 = SAMGR_GetInstance()->RegisterService((Service *)&g_service);
138 BOOL result2 = SAMGR_GetInstance()->RegisterFeature(SERVICE_NAME, (Feature *)&g_feature);
139 if (result1 == FALSE && result2 == FALSE) {
140 printf("[hctest]E failed to register service or feature \n");
141 }
142 }
143 // Testcase teardown
TearDown()144 virtual void TearDown()
145 {
146 Feature *feature = SAMGR_GetInstance()->UnregisterFeature(SERVICE_NAME, FEATURE_NAME);
147 if (feature == nullptr) {
148 printf("[hctest]E failed to unregister feature \n");
149 }
150 Service *service = SAMGR_GetInstance()->UnregisterService(SERVICE_NAME);
151 if (service == nullptr) {
152 printf("[hctest]E failed to unregister service \n");
153 }
154 }
155 };
156
157 /**
158 * @tc.number : DMSLite_SAMGR_GetIUnknown_0010
159 * @tc.name : Use this macro GET_IUNKNOWN user can obtain the IUnknown interface from the subclass object.
160 * @tc.desc : [C- SOFTWARE -0200]
161 */
162 HWTEST_F(IUnknownTest, testGetIUnknown0010, Function | MediumTest | Level2) {
163 IUnknown *iUnknown = GET_IUNKNOWN(g_feature);
164 ASSERT_EQ(iUnknown != nullptr, TRUE);
165 }
166
167 /**
168 * @tc.number : DMSLite_SAMGR_GetObject_0010
169 * @tc.name : Use this macro GET_OBJECT user can obtain an outside object.
170 * @tc.desc : [C- SOFTWARE -0200]
171 */
172 HWTEST_F(IUnknownTest, testGetObject0010, Function | MediumTest | Level2) {
173 IUnknown *iUnknown = GET_IUNKNOWN(g_feature);
174 IUnknownEntry *entry = GET_OBJECT(iUnknown, IUnknownEntry, iUnknown);
175 ASSERT_EQ(entry->ver == DEFAULT_VERSION, TRUE);
176 ASSERT_EQ(entry->ref, 1);
177 }
178
179 /**
180 * @tc.number : DMSLite_SAMGR_QueryInterface_0010
181 * @tc.name : Use this api QueryInterface user can convert the object to the required subclass type.
182 * @tc.desc : [C- SOFTWARE -0200]
183 */
184 HWTEST_F(IUnknownTest, testQueryInterface0010, Function | MediumTest | Level2) {
185 SAMGR_GetInstance()->RegisterFeatureApi(SERVICE_NAME, FEATURE_NAME, GET_IUNKNOWN(g_feature));
186
187 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(SERVICE_NAME, FEATURE_NAME);
188 DemoApi *demoApi = nullptr;
189 int resultQuery = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&demoApi);
190 ASSERT_EQ(EC_SUCCESS, resultQuery);
191 ASSERT_EQ(TRUE, demoApi != nullptr);
192
193 int resultAdd = iUnknown->AddRef(iUnknown);
194 int resultRelease = iUnknown->Release(iUnknown);
195 ASSERT_EQ(1, resultAdd - resultRelease);
196
197 (void)iUnknown->Release(iUnknown);
198
199 SAMGR_GetInstance()->UnregisterFeatureApi(SERVICE_NAME, FEATURE_NAME);
200 }
201
202 /**
203 * @tc.number : DMSLite_SAMGR_QueryInterface_0020
204 * @tc.name : User can not get the required subclass type if the version does not have permission.
205 * @tc.desc : [C- SOFTWARE -0200]
206 */
207 HWTEST_F(IUnknownTest, testQueryInterface0020, Function | MediumTest | Level2) {
208 SAMGR_GetInstance()->RegisterFeatureApi(SERVICE_NAME, FEATURE_NAME, GET_IUNKNOWN(g_feature));
209
210 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(SERVICE_NAME, FEATURE_NAME);
211 DemoApi *demoApi = nullptr;
212 int resultQuery = iUnknown->QueryInterface(iUnknown, 0x30, (void **)&demoApi);
213 ASSERT_EQ(EC_INVALID, resultQuery);
214
215 SAMGR_GetInstance()->UnregisterFeatureApi(SERVICE_NAME, FEATURE_NAME);
216 }
217
218 /**
219 * @tc.number : DMSLite_SAMGR_QueryInterface_0030
220 * @tc.name : User can rewrite this api QueryInterface.
221 * @tc.desc : [C- SOFTWARE -0200]
222 */
223 HWTEST_F(IUnknownTest, testQueryInterface0030, Function | MediumTest | Level2) {
224 SAMGR_GetInstance()->RegisterFeatureApi(SERVICE_NAME, FEATURE_NAME, (IUnknown *)&g_api);
225 IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(SERVICE_NAME, FEATURE_NAME);
226 DemoApi *demoApi = nullptr;
227 int resultQuery = iUnknown->QueryInterface(iUnknown, 0, (void **)&demoApi);
228 ASSERT_EQ(EC_SUCCESS, resultQuery);
229 ASSERT_EQ(TRUE, demoApi != nullptr);
230
231 SAMGR_GetInstance()->UnregisterFeatureApi(SERVICE_NAME, FEATURE_NAME);
232 }