• 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 <aidl/android/aidl/loggable/ILoggableInterface.h>
18 
19 #include <functional>
20 
21 #include <android/binder_auto_utils.h>
22 #include <android/binder_manager.h>
23 #include <gtest/gtest.h>
24 
25 #include <aidl/android/aidl/fixedsizearray/FixedSizeArrayExample.h>
26 #include <aidl/android/aidl/tests/ITestService.h>
27 #include <aidl/android/aidl/tests/RecursiveList.h>
28 #include <aidl/android/aidl/tests/Union.h>
29 
30 using aidl::android::aidl::fixedsizearray::FixedSizeArrayExample;
31 using BnRepeatFixedSizeArray =
32     aidl::android::aidl::fixedsizearray::FixedSizeArrayExample::BnRepeatFixedSizeArray;
33 using BpRepeatFixedSizeArray =
34     aidl::android::aidl::fixedsizearray::FixedSizeArrayExample::BpRepeatFixedSizeArray;
35 using IntParcelable = aidl::android::aidl::fixedsizearray::FixedSizeArrayExample::IntParcelable;
36 using IRepeatFixedSizeArray =
37     aidl::android::aidl::fixedsizearray::FixedSizeArrayExample::IRepeatFixedSizeArray;
38 using BnEmptyInterface =
39     aidl::android::aidl::fixedsizearray::FixedSizeArrayExample::BnEmptyInterface;
40 using aidl::android::aidl::tests::BackendType;
41 using aidl::android::aidl::tests::ITestService;
42 using aidl::android::aidl::tests::RecursiveList;
43 using aidl::android::aidl::tests::Union;
44 using android::OK;
45 using ndk::AParcel_readData;
46 using ndk::AParcel_writeData;
47 using ndk::ScopedAStatus;
48 using ndk::SharedRefBase;
49 using ndk::SpAIBinder;
50 
51 struct AidlTest : testing::Test {
52   template <typename T>
getServiceAidlTest53   std::shared_ptr<T> getService() {
54     ndk::SpAIBinder binder = ndk::SpAIBinder(AServiceManager_getService(T::descriptor));
55     return T::fromBinder(binder);
56   }
57 };
58 
59 // TODO(b/196454897): copy more tests from aidl_test_client
60 
TEST_F(AidlTest,ReverseRecursiveList)61 TEST_F(AidlTest, ReverseRecursiveList) {
62   std::unique_ptr<RecursiveList> head;
63   for (int i = 0; i < 10; i++) {
64     auto node = std::make_unique<RecursiveList>();
65     node->value = i;
66     node->next = std::move(head);
67     head = std::move(node);
68   }
69   // head: [9, 8, ... 0]
70 
71   RecursiveList reversed;
72   auto status = getService<ITestService>()->ReverseList(*head, &reversed);
73   ASSERT_TRUE(status.isOk());
74 
75   // reversed should be [0, 1, .. 9]
76   RecursiveList* cur = &reversed;
77   for (int i = 0; i < 10; i++) {
78     EXPECT_EQ(i, cur->value);
79     cur = cur->next.get();
80   }
81   EXPECT_EQ(nullptr, cur);
82 }
83 
TEST_F(AidlTest,GetUnionTags)84 TEST_F(AidlTest, GetUnionTags) {
85   std::vector<Union> unions;
86   std::vector<Union::Tag> tags;
87   // test empty
88   auto status = getService<ITestService>()->GetUnionTags(unions, &tags);
89   ASSERT_TRUE(status.isOk());
90   EXPECT_EQ(tags, (std::vector<Union::Tag>{}));
91   // test non-empty
92   unions.push_back(Union::make<Union::n>());
93   unions.push_back(Union::make<Union::ns>());
94   status = getService<ITestService>()->GetUnionTags(unions, &tags);
95   ASSERT_TRUE(status.isOk());
96   EXPECT_EQ(tags, (std::vector<Union::Tag>{Union::n, Union::ns}));
97 }
98 
TEST_F(AidlTest,FixedSizeArray)99 TEST_F(AidlTest, FixedSizeArray) {
100   auto parcel = AParcel_create();
101 
102   FixedSizeArrayExample p;
103   p.byteMatrix[0][0] = 0;
104   p.byteMatrix[0][1] = 1;
105   p.byteMatrix[1][0] = 2;
106   p.byteMatrix[1][1] = 3;
107   p.floatMatrix[0][0] = 0.f;
108   p.floatMatrix[0][1] = 1.f;
109   p.floatMatrix[1][0] = 2.f;
110   p.floatMatrix[1][1] = 3.f;
111   EXPECT_EQ(OK, p.writeToParcel(parcel));
112 
113   AParcel_setDataPosition(parcel, 0);
114 
115   FixedSizeArrayExample q;
116   EXPECT_EQ(OK, q.readFromParcel(parcel));
117   EXPECT_EQ(p, q);
118 
119   AParcel_delete(parcel);
120 }
121 
TEST_F(AidlTest,FixedSizeArrayWithValuesAtNullableFields)122 TEST_F(AidlTest, FixedSizeArrayWithValuesAtNullableFields) {
123   auto parcel = AParcel_create();
124 
125   FixedSizeArrayExample p;
126   p.boolNullableArray = std::array<bool, 2>{true, false};
127   p.byteNullableArray = std::array<uint8_t, 2>{42, 0};
128   p.stringNullableArray = std::array<std::optional<std::string>, 2>{"hello", "world"};
129 
130   p.boolNullableMatrix.emplace();
131   p.boolNullableMatrix->at(0) = std::array<bool, 2>{true, false};
132   p.byteNullableMatrix.emplace();
133   p.byteNullableMatrix->at(0) = std::array<uint8_t, 2>{42, 0};
134   p.stringNullableMatrix.emplace();
135   p.stringNullableMatrix->at(0) = std::array<std::optional<std::string>, 2>{"hello", "world"};
136 
137   EXPECT_EQ(OK, p.writeToParcel(parcel));
138 
139   AParcel_setDataPosition(parcel, 0);
140 
141   FixedSizeArrayExample q;
142   EXPECT_EQ(OK, q.readFromParcel(parcel));
143   EXPECT_EQ(p, q);
144 
145   AParcel_delete(parcel);
146 }
147 
TEST_F(AidlTest,FixedSizeArrayOfBytesShouldBePacked)148 TEST_F(AidlTest, FixedSizeArrayOfBytesShouldBePacked) {
149   auto parcel = AParcel_create();
150 
151   std::array<std::array<uint8_t, 3>, 2> byte_array;
152   byte_array[0] = {1, 2, 3};
153   byte_array[1] = {4, 5, 6};
154   EXPECT_EQ(OK, AParcel_writeData(parcel, byte_array));
155 
156   AParcel_setDataPosition(parcel, 0);
157 
158   int32_t len;
159   EXPECT_EQ(OK, AParcel_readData(parcel, &len));
160   EXPECT_EQ(2, len);
161   std::vector<uint8_t> byte_vector;
162   EXPECT_EQ(OK, AParcel_readData(parcel, &byte_vector));
163   EXPECT_EQ(byte_vector, (std::vector<uint8_t>{1, 2, 3}));
164   EXPECT_EQ(OK, AParcel_readData(parcel, &byte_vector));
165   EXPECT_EQ(byte_vector, (std::vector<uint8_t>{4, 5, 6}));
166 
167   AParcel_delete(parcel);
168 }
169 
170 template <typename Service, typename MemFn, typename Input>
CheckRepeat(Service service,MemFn fn,Input input)171 void CheckRepeat(Service service, MemFn fn, Input input) {
172   Input out1, out2;
173   EXPECT_TRUE(std::invoke(fn, service, input, &out1, &out2).isOk());
174   EXPECT_EQ(input, out1);
175   EXPECT_EQ(input, out2);
176 }
177 
178 template <typename T>
Make2dArray(std::initializer_list<T> values)179 std::array<std::array<T, 3>, 2> Make2dArray(std::initializer_list<T> values) {
180   std::array<std::array<T, 3>, 2> arr = {};
181   auto it = std::begin(values);
182   for (auto& row : arr) {
183     for (auto& el : row) {
184       if (it == std::end(values)) break;
185       el = *it++;
186     }
187   }
188   return arr;
189 }
190 
TEST_F(AidlTest,FixedSizeArrayOverBinder)191 TEST_F(AidlTest, FixedSizeArrayOverBinder) {
192   auto service = getService<IRepeatFixedSizeArray>();
193 
194   CheckRepeat(service, &IRepeatFixedSizeArray::RepeatBytes, (std::array<uint8_t, 3>{1, 2, 3}));
195 
196   CheckRepeat(service, &IRepeatFixedSizeArray::RepeatInts, (std::array<int32_t, 3>{1, 2, 3}));
197 
198   auto binder1 = SharedRefBase::make<BnEmptyInterface>()->asBinder();
199   auto binder2 = SharedRefBase::make<BnEmptyInterface>()->asBinder();
200   auto binder3 = SharedRefBase::make<BnEmptyInterface>()->asBinder();
201   CheckRepeat(service, &IRepeatFixedSizeArray::RepeatBinders,
202               (std::array<SpAIBinder, 3>{binder1, binder2, binder3}));
203 
204   IntParcelable p1, p2, p3;
205   p1.value = 1;
206   p2.value = 2;
207   p3.value = 3;
208   CheckRepeat(service, &IRepeatFixedSizeArray::RepeatParcelables,
209               (std::array<IntParcelable, 3>{p1, p2, p3}));
210 
211   CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dBytes, Make2dArray<uint8_t>({1, 2, 3}));
212 
213   CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dInts, Make2dArray<int32_t>({1, 2, 3}));
214 
215   // Not-nullable
216   CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dBinders,
217               Make2dArray<SpAIBinder>({binder1, binder2, binder3, binder1, binder2, binder3}));
218 
219   CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dParcelables,
220               Make2dArray<IntParcelable>({p1, p2, p3}));
221 }
222