1 /*
2 * Copyright (C) 2023 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 <android/aidl/test/trunk/BnTrunkStableTest.h>
18 #include <android/aidl/test/trunk/ITrunkStableTest.h>
19 #include <binder/IServiceManager.h>
20 #include <binder/ProcessState.h>
21 #include <gtest/gtest.h>
22 #include <utils/String16.h>
23
24 #include "aidl_test_client.h"
25
26 #ifdef AIDL_USE_UNFROZEN
27 constexpr bool kUseUnfrozen = true;
28 #else
29 constexpr bool kUseUnfrozen = false;
30 #endif
31
32 using android::OK;
33 using android::sp;
34 using android::String16;
35 using android::aidl::test::trunk::ITrunkStableTest;
36 using android::binder::Status;
37 using MyParcelable = android::aidl::test::trunk::ITrunkStableTest::MyParcelable;
38 #ifdef AIDL_USE_V2_INTERFACE
39 using MyOtherParcelable = android::aidl::test::trunk::ITrunkStableTest::MyOtherParcelable;
40 #endif // AIDL_USE_V2_INTERFACE
41 using MyEnum = android::aidl::test::trunk::ITrunkStableTest::MyEnum;
42 using MyUnion = android::aidl::test::trunk::ITrunkStableTest::MyUnion;
43
44 class TrunkInterfaceTest : public AidlTest {
45 public:
SetUp()46 void SetUp() override {
47 android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
48 android::ProcessState::self()->startThreadPool();
49 service = android::waitForService<ITrunkStableTest>(ITrunkStableTest::descriptor);
50 ASSERT_NE(nullptr, service);
51
52 AidlTest::SetUp();
53 }
54
55 sp<ITrunkStableTest> service;
56 };
57
TEST_F(TrunkInterfaceTest,getInterfaceVersion)58 TEST_F(TrunkInterfaceTest, getInterfaceVersion) {
59 // TODO(b/292539129) this should be done with an annotation instead of ifdefs
60 // We have to match on a single char with #if, even though it is
61 // really "enabled"/"disabled"
62 if (kUseUnfrozen) {
63 EXPECT_EQ(2, service->getInterfaceVersion());
64 // Check the local version as well
65 #ifdef AIDL_USE_V2_INTERFACE
66 EXPECT_EQ(2, ITrunkStableTest::VERSION);
67 #else
68 // linked against V1 explicitly
69 EXPECT_EQ(1, ITrunkStableTest::VERSION);
70 #endif
71 } else {
72 EXPECT_EQ(1, service->getInterfaceVersion());
73 // Check the local version as well
74 EXPECT_EQ(1, ITrunkStableTest::VERSION);
75 }
76 }
77
TEST_F(TrunkInterfaceTest,getInterfaceHash)78 TEST_F(TrunkInterfaceTest, getInterfaceHash) {
79 if (kUseUnfrozen) {
80 EXPECT_EQ("notfrozen", service->getInterfaceHash());
81 // Check the local hash as well
82 #ifdef AIDL_USE_V2_INTERFACE
83 EXPECT_EQ("notfrozen", ITrunkStableTest::HASH);
84 #else
85 // linked against V1 explicitly
86 EXPECT_EQ("88311b9118fb6fe9eff4a2ca19121de0587f6d5f", ITrunkStableTest::HASH);
87 #endif
88 } else {
89 EXPECT_EQ("88311b9118fb6fe9eff4a2ca19121de0587f6d5f", service->getInterfaceHash());
90 // Check the local hash as well
91 EXPECT_EQ("88311b9118fb6fe9eff4a2ca19121de0587f6d5f", ITrunkStableTest::HASH);
92 }
93 }
94
95 // `c` is a new field that isn't read from the reply parcel
TEST_F(TrunkInterfaceTest,repeatParcelable)96 TEST_F(TrunkInterfaceTest, repeatParcelable) {
97 MyParcelable in, out;
98 in.a = 14;
99 in.b = 15;
100 #ifdef AIDL_USE_V2_INTERFACE
101 in.c = 16;
102 #endif // AIDL_USE_V2_INTERFACE
103 auto status = service->repeatParcelable(in, &out);
104 ASSERT_TRUE(status.isOk()) << status;
105 if (kUseUnfrozen) {
106 EXPECT_EQ(in.a, out.a);
107 EXPECT_EQ(in.b, out.b);
108 #ifdef AIDL_USE_V2_INTERFACE
109 EXPECT_EQ(in.c, out.c);
110 #endif // AIDL_USE_V2_INTERFACE
111 } else {
112 EXPECT_EQ(in.a, out.a);
113 EXPECT_EQ(in.b, out.b);
114 #ifdef AIDL_USE_V2_INTERFACE
115 EXPECT_NE(in.c, out.c);
116 EXPECT_EQ(0, out.c);
117 #endif // AIDL_USE_V2_INTERFACE
118 }
119 }
120
121 #ifdef AIDL_USE_V2_INTERFACE
122 // repeatOtherParcelable is a new API that isn't implemented
TEST_F(TrunkInterfaceTest,repeatOtherParcelable)123 TEST_F(TrunkInterfaceTest, repeatOtherParcelable) {
124 MyOtherParcelable in, out;
125 in.a = 14;
126 in.b = 15;
127
128 auto status = service->repeatOtherParcelable(in, &out);
129 if (kUseUnfrozen) {
130 ASSERT_TRUE(status.isOk()) << status;
131 EXPECT_EQ(in.a, out.a);
132 EXPECT_EQ(in.b, out.b);
133 } else {
134 EXPECT_FALSE(status.isOk()) << status;
135 EXPECT_EQ(::android::UNKNOWN_TRANSACTION, status.transactionError()) << status;
136 }
137 }
138 #endif // AIDL_USE_V2_INTERFACE
139
140 // enums aren't handled differently.
TEST_F(TrunkInterfaceTest,repeatEnum)141 TEST_F(TrunkInterfaceTest, repeatEnum) {
142 MyEnum in = MyEnum::TWO;
143 MyEnum out = MyEnum::ZERO;
144
145 auto status = service->repeatEnum(in, &out);
146 ASSERT_TRUE(status.isOk()) << status;
147 EXPECT_EQ(in, out);
148 }
149
150 // `c` is a new field that causes a failure if used
151 // `b` is from V1 and will cause no failure
TEST_F(TrunkInterfaceTest,repeatUnion)152 TEST_F(TrunkInterfaceTest, repeatUnion) {
153 MyUnion in_ok = MyUnion::make<MyUnion::b>(13);
154 ;
155 #ifdef AIDL_USE_V2_INTERFACE
156 MyUnion in_test = MyUnion::make<MyUnion::c>(12);
157 ;
158 #endif // AIDL_USE_V2_INTERFACE
159 MyUnion out;
160
161 auto status = service->repeatUnion(in_ok, &out);
162 ASSERT_TRUE(status.isOk()) << status;
163 EXPECT_EQ(in_ok, out);
164
165 #ifdef AIDL_USE_V2_INTERFACE
166 status = service->repeatUnion(in_test, &out);
167 if (kUseUnfrozen) {
168 ASSERT_TRUE(status.isOk()) << status;
169 EXPECT_EQ(in_test, out);
170 } else {
171 ASSERT_FALSE(status.isOk()) << status;
172 EXPECT_NE(in_test, out);
173 }
174 #endif // AIDL_USE_V2_INTERFACE
175 }
176
177 class MyCallback : public ITrunkStableTest::BnMyCallback {
178 public:
MyCallback()179 MyCallback() {}
180 virtual ~MyCallback() = default;
181
repeatParcelable(const MyParcelable & input,MyParcelable * _aidl_return)182 Status repeatParcelable(const MyParcelable& input, MyParcelable* _aidl_return) override {
183 *_aidl_return = input;
184 repeatParcelableCalled = true;
185 return Status::ok();
186 }
repeatEnum(MyEnum input,MyEnum * _aidl_return)187 Status repeatEnum(MyEnum input, MyEnum* _aidl_return) override {
188 *_aidl_return = input;
189 repeatEnumCalled = true;
190 return Status::ok();
191 }
repeatUnion(const MyUnion & input,MyUnion * _aidl_return)192 Status repeatUnion(const MyUnion& input, MyUnion* _aidl_return) override {
193 *_aidl_return = input;
194 repeatUnionCalled = true;
195 return Status::ok();
196 }
197 #ifdef AIDL_USE_V2_INTERFACE
repeatOtherParcelable(const MyOtherParcelable & input,MyOtherParcelable * _aidl_return)198 Status repeatOtherParcelable(const MyOtherParcelable& input,
199 MyOtherParcelable* _aidl_return) override {
200 *_aidl_return = input;
201 repeatOtherParcelableCalled = true;
202 return Status::ok();
203 }
204 #endif // AIDL_USE_V2_INTERFACE
205 bool repeatParcelableCalled = false;
206 bool repeatEnumCalled = false;
207 bool repeatUnionCalled = false;
208 #ifdef AIDL_USE_V2_INTERFACE
209 bool repeatOtherParcelableCalled = false;
210 #endif // AIDL_USE_V2_INTERFACE
211 };
212
213 // repeatOtherParcelable is new in V2, so it won't be called
TEST_F(TrunkInterfaceTest,callMyCallback)214 TEST_F(TrunkInterfaceTest, callMyCallback) {
215 sp<MyCallback> cb = sp<MyCallback>::make();
216
217 auto status = service->callMyCallback(cb);
218 ASSERT_TRUE(status.isOk()) << status;
219 if (kUseUnfrozen) {
220 EXPECT_TRUE(cb->repeatParcelableCalled);
221 EXPECT_TRUE(cb->repeatEnumCalled);
222 EXPECT_TRUE(cb->repeatUnionCalled);
223 #ifdef AIDL_USE_V2_INTERFACE
224 EXPECT_TRUE(cb->repeatOtherParcelableCalled);
225 #endif // AIDL_USE_V2_INTERFACE
226 } else {
227 EXPECT_TRUE(cb->repeatParcelableCalled);
228 EXPECT_TRUE(cb->repeatEnumCalled);
229 EXPECT_TRUE(cb->repeatUnionCalled);
230 #ifdef AIDL_USE_V2_INTERFACE
231 EXPECT_FALSE(cb->repeatOtherParcelableCalled);
232 #endif // AIDL_USE_V2_INTERFACE
233 }
234 }
235