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 #include "gtest/gtest.h"
17 
18 /* Shared Client/Service includes */
19 #include <aidl/android/aidl/test/trunk/BnTrunkStableTest.h>
20 #include <aidl/android/aidl/test/trunk/ITrunkStableTest.h>
21 #include <android-base/logging.h>
22 #include <android/binder_manager.h>
23 #include <sys/prctl.h>
24 
25 /* AIDL Client includes */
26 
27 /* AIDL Service includes */
28 #include <android/binder_process.h>
29 
30 #ifndef AIDL_TEST_TRUNK_VER
31 #define AIDL_TEST_TRUNK_VER 2
32 #endif
33 
34 using ::aidl::android::aidl::test::trunk::ITrunkStableTest;
35 using ndk::ScopedAStatus;
36 
37 /* AIDL Client definition */
38 class MyCallback : public ITrunkStableTest::BnMyCallback {
39  public:
repeatParcelable(const ITrunkStableTest::MyParcelable & in_input,ITrunkStableTest::MyParcelable * _aidl_return)40   ScopedAStatus repeatParcelable(const ITrunkStableTest::MyParcelable& in_input,
41                                  ITrunkStableTest::MyParcelable* _aidl_return) override {
42     *_aidl_return = in_input;
43     repeatParcelableCalled = true;
44     return ScopedAStatus::ok();
45   }
repeatEnum(const ITrunkStableTest::MyEnum in_input,ITrunkStableTest::MyEnum * _aidl_return)46   ScopedAStatus repeatEnum(const ITrunkStableTest::MyEnum in_input,
47                            ITrunkStableTest::MyEnum* _aidl_return) override {
48     *_aidl_return = in_input;
49     repeatEnumCalled = true;
50     return ScopedAStatus::ok();
51   }
repeatUnion(const ITrunkStableTest::MyUnion & in_input,ITrunkStableTest::MyUnion * _aidl_return)52   ScopedAStatus repeatUnion(const ITrunkStableTest::MyUnion& in_input,
53                             ITrunkStableTest::MyUnion* _aidl_return) override {
54     *_aidl_return = in_input;
55     repeatUnionCalled = true;
56     return ScopedAStatus::ok();
57   }
58 
59 #if AIDL_TEST_TRUNK_VER >= 2
repeatOtherParcelable(const ITrunkStableTest::MyOtherParcelable & in_input,ITrunkStableTest::MyOtherParcelable * _aidl_return)60   ScopedAStatus repeatOtherParcelable(const ITrunkStableTest::MyOtherParcelable& in_input,
61                                       ITrunkStableTest::MyOtherParcelable* _aidl_return) override {
62     *_aidl_return = in_input;
63     repeatOtherParcelableCalled = true;
64     return ScopedAStatus::ok();
65   }
66 
67   bool repeatOtherParcelableCalled = false;
68 #endif
69 
70   bool repeatParcelableCalled = false;
71   bool repeatEnumCalled = false;
72   bool repeatUnionCalled = false;
73 };
74 
75 class ClientTest : public testing::Test {
76  public:
SetUp()77   void SetUp() override {
78     mService = ITrunkStableTest::fromBinder(
79         ndk::SpAIBinder(AServiceManager_waitForService(ITrunkStableTest::descriptor)));
80     ASSERT_NE(nullptr, mService);
81   }
82 
83   std::shared_ptr<ITrunkStableTest> mService;
84 };
85 
TEST_F(ClientTest,SanityCheck)86 TEST_F(ClientTest, SanityCheck) {
87   ITrunkStableTest::MyParcelable a, b;
88   a.a = 12;
89   a.b = 13;
90 #if AIDL_TEST_TRUNK_VER >= 2
91   a.c = 14;
92 #endif
93   auto status = mService->repeatParcelable(a, &b);
94   EXPECT_TRUE(status.isOk());
95   EXPECT_EQ(a, b);
96 }
97 
TEST_F(ClientTest,Callback)98 TEST_F(ClientTest, Callback) {
99   auto cb = ndk::SharedRefBase::make<MyCallback>();
100   auto status = mService->callMyCallback(cb);
101   EXPECT_TRUE(status.isOk());
102   EXPECT_TRUE(cb->repeatParcelableCalled);
103   EXPECT_TRUE(cb->repeatEnumCalled);
104   EXPECT_TRUE(cb->repeatUnionCalled);
105 #if AIDL_TEST_TRUNK_VER >= 2
106   EXPECT_TRUE(cb->repeatOtherParcelableCalled);
107 #endif
108 }
109 
110 #if AIDL_TEST_TRUNK_VER >= 2
TEST_F(ClientTest,CallV2Method)111 TEST_F(ClientTest, CallV2Method) {
112   ITrunkStableTest::MyOtherParcelable a, b;
113   a.a = 12;
114   a.b = 13;
115   auto status = mService->repeatOtherParcelable(a, &b);
116   EXPECT_TRUE(status.isOk());
117   EXPECT_EQ(a, b);
118 }
119 #endif
120 
121 /* AIDL service definition */
122 using ::aidl::android::aidl::test::trunk::BnTrunkStableTest;
123 class TrunkStableTest : public BnTrunkStableTest {
repeatParcelable(const MyParcelable & in_input,MyParcelable * _aidl_return)124   ScopedAStatus repeatParcelable(const MyParcelable& in_input,
125                                  MyParcelable* _aidl_return) override {
126     *_aidl_return = in_input;
127     return ScopedAStatus::ok();
128   }
repeatEnum(const MyEnum in_input,MyEnum * _aidl_return)129   ScopedAStatus repeatEnum(const MyEnum in_input, MyEnum* _aidl_return) override {
130     *_aidl_return = in_input;
131     return ScopedAStatus::ok();
132   }
repeatUnion(const MyUnion & in_input,MyUnion * _aidl_return)133   ScopedAStatus repeatUnion(const MyUnion& in_input, MyUnion* _aidl_return) override {
134     *_aidl_return = in_input;
135     return ScopedAStatus::ok();
136   }
callMyCallback(const std::shared_ptr<IMyCallback> & in_cb)137   ScopedAStatus callMyCallback(const std::shared_ptr<IMyCallback>& in_cb) override {
138     MyParcelable a, b;
139     MyEnum c = MyEnum::ZERO, d = MyEnum::ZERO;
140     MyUnion e, f;
141     auto status = in_cb->repeatParcelable(a, &b);
142     if (!status.isOk()) {
143       return status;
144     }
145     status = in_cb->repeatEnum(c, &d);
146     if (!status.isOk()) {
147       return status;
148     }
149     status = in_cb->repeatUnion(e, &f);
150 #if AIDL_TEST_TRUNK_VER >= 2
151     if (!status.isOk()) {
152       return status;
153     }
154     MyOtherParcelable g, h;
155     status = in_cb->repeatOtherParcelable(g, &h);
156 #endif
157     return status;
158   }
159 #if AIDL_TEST_TRUNK_VER >= 2
repeatOtherParcelable(const ITrunkStableTest::MyOtherParcelable & in_input,ITrunkStableTest::MyOtherParcelable * _aidl_return)160   ScopedAStatus repeatOtherParcelable(const ITrunkStableTest::MyOtherParcelable& in_input,
161                                       ITrunkStableTest::MyOtherParcelable* _aidl_return) override {
162     *_aidl_return = in_input;
163     return ScopedAStatus::ok();
164   }
165 #endif
166 };
167 
run_service()168 int run_service() {
169   auto trunk = ndk::SharedRefBase::make<TrunkStableTest>();
170   binder_status_t status =
171       AServiceManager_addService(trunk->asBinder().get(), TrunkStableTest::descriptor);
172   CHECK_EQ(status, STATUS_OK);
173 
174   ABinderProcess_joinThreadPool();
175   return EXIT_FAILURE;  // should not reach
176 }
177 
main(int argc,char * argv[])178 int main(int argc, char* argv[]) {
179   if (fork() == 0) {
180     prctl(PR_SET_PDEATHSIG, SIGHUP);
181     run_service();
182   }
183   ::testing::InitGoogleTest(&argc, argv);
184   return RUN_ALL_TESTS();
185 }
186