• 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 <android/binder_auto_utils.h>
18 #include <android/binder_manager.h>
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 #include <aidl/android/aidl/tests/ITestService.h>
23 
24 using aidl::android::aidl::tests::BackendType;
25 using aidl::android::aidl::tests::ITestService;
26 using testing::Eq;
27 
28 struct AidlTest : testing::Test {
29   template <typename T>
getServiceAidlTest30   std::shared_ptr<T> getService() {
31     ndk::SpAIBinder binder = ndk::SpAIBinder(AServiceManager_getService(T::descriptor));
32     return T::fromBinder(binder);
33   }
SetUpAidlTest34   void SetUp() override {
35     service = getService<ITestService>();
36     auto status = service->getBackendType(&backend);
37     ASSERT_TRUE(status.isOk()) << status.getDescription();
38   }
39   std::shared_ptr<ITestService> service;
40   BackendType backend;
41 };
42 
TEST_F(AidlTest,repeatUtf8String)43 TEST_F(AidlTest, repeatUtf8String) {
44   const std::vector<std::string> utf8_inputs = {
45       std::string("Deliver us from evil."),
46       std::string(),
47       std::string("\0\0", 2),
48       // Similarly, the utf8 encodings of the small letter yee and euro sign.
49       std::string("\xF0\x90\x90\xB7\xE2\x82\xAC"),
50       ITestService::STRING_TEST_CONSTANT_UTF8,
51   };
52 
53   for (const auto& input : utf8_inputs) {
54     std::string reply;
55     auto status = service->RepeatUtf8CppString(input, &reply);
56     ASSERT_TRUE(status.isOk());
57     ASSERT_THAT(reply, Eq(input));
58   }
59 
60   std::optional<std::string> reply;
61   auto status = service->RepeatNullableUtf8CppString(std::nullopt, &reply);
62   ASSERT_TRUE(status.isOk());
63   ASSERT_FALSE(reply.has_value());
64 
65   for (const auto& input : utf8_inputs) {
66     std::optional<std::string> reply;
67     auto status = service->RepeatNullableUtf8CppString(input, &reply);
68     ASSERT_TRUE(status.isOk());
69     ASSERT_TRUE(reply.has_value());
70     ASSERT_THAT(*reply, Eq(input));
71   }
72 }
73 
TEST_F(AidlTest,reverseUtf8StringArray)74 TEST_F(AidlTest, reverseUtf8StringArray) {
75   std::vector<std::string> input = {"a", "", "\xc3\xb8"};
76   decltype(input) repeated;
77   if (backend == BackendType::JAVA) {
78     repeated = decltype(input)(input.size());
79   }
80   decltype(input) reversed;
81 
82   auto status = service->ReverseUtf8CppString(input, &repeated, &reversed);
83   ASSERT_TRUE(status.isOk()) << status.getDescription();
84   ASSERT_THAT(repeated, Eq(input));
85 
86   decltype(input) reversed_input(input);
87   std::reverse(reversed_input.begin(), reversed_input.end());
88   ASSERT_THAT(reversed, Eq(reversed_input));
89 }
90 
91 struct AidlStringArrayTest : public AidlTest {
DoTestAidlStringArrayTest92   void DoTest(::ndk::ScopedAStatus (ITestService::*func)(
93       const std::optional<std::vector<std::optional<std::string>>>&,
94       std::optional<std::vector<std::optional<std::string>>>*,
95       std::optional<std::vector<std::optional<std::string>>>*)) {
96     std::optional<std::vector<std::optional<std::string>>> input;
97     decltype(input) repeated;
98     decltype(input) reversed;
99 
100     auto status = (*service.*func)(input, &repeated, &reversed);
101     ASSERT_TRUE(status.isOk()) << status.getDescription();
102 
103     if (func == &ITestService::ReverseUtf8CppStringList && backend == BackendType::JAVA) {
104       // Java cannot clear the input variable to return a null value. It can
105       // only ever fill out a list.
106       ASSERT_TRUE(repeated.has_value());
107     } else {
108       ASSERT_FALSE(repeated.has_value());
109     }
110 
111     ASSERT_FALSE(reversed.has_value());
112 
113     input = std::vector<std::optional<std::string>>();
114     input->push_back("Deliver us from evil.");
115     input->push_back(std::nullopt);
116     input->push_back("\xF0\x90\x90\xB7\xE2\x82\xAC");
117 
118     // usable size needs to be initialized for Java
119     repeated = std::vector<std::optional<std::string>>(input->size());
120 
121     status = (*service.*func)(input, &repeated, &reversed);
122     ASSERT_TRUE(status.isOk()) << status.getDescription();
123     ASSERT_TRUE(reversed.has_value());
124     ASSERT_TRUE(repeated.has_value());
125     ASSERT_THAT(reversed->size(), Eq(input->size()));
126     ASSERT_THAT(repeated->size(), Eq(input->size()));
127 
128     for (size_t i = 0; i < input->size(); i++) {
129       auto input_str = (*input)[i];
130       auto repeated_str = (*repeated)[i];
131       auto reversed_str = (*reversed)[(reversed->size() - 1) - i];
132       if (!input_str) {
133         ASSERT_FALSE(repeated_str.has_value());
134         ASSERT_FALSE(reversed_str.has_value());
135         // 3 nullptrs to strings.  No need to compare values.
136         continue;
137       }
138       ASSERT_TRUE(repeated_str.has_value());
139       ASSERT_TRUE(reversed_str.has_value());
140 
141       ASSERT_THAT(*repeated_str, Eq(*input_str));
142       ASSERT_THAT(*reversed_str, Eq(*input_str));
143     }
144   }
145 };
146 
TEST_F(AidlStringArrayTest,nullableList)147 TEST_F(AidlStringArrayTest, nullableList) {
148   DoTest(&ITestService::ReverseUtf8CppStringList);
149 }
150 
TEST_F(AidlStringArrayTest,nullableArray)151 TEST_F(AidlStringArrayTest, nullableArray) {
152   DoTest(&ITestService::ReverseNullableUtf8CppString);
153 }
154