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 <android/binder_auto_utils.h>
20 #include <android/binder_manager.h>
21 #include <binder/ProcessState.h>
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 
25 #include <aidl/android/aidl/loggable/BpLoggableInterface.h>
26 #include <aidl/android/aidl/tests/BackendType.h>
27 #include <aidl/android/aidl/tests/ITestService.h>
28 
29 using aidl::android::aidl::loggable::BpLoggableInterface;
30 using aidl::android::aidl::loggable::Data;
31 using aidl::android::aidl::loggable::Enum;
32 using aidl::android::aidl::loggable::ILoggableInterface;
33 using aidl::android::aidl::tests::BackendType;
34 using aidl::android::aidl::tests::ITestService;
35 using std::optional;
36 using std::pair;
37 using std::shared_ptr;
38 using std::string;
39 using std::vector;
40 using testing::Eq;
41 
42 struct AidlTest : testing::Test {
43   template <typename T>
getServiceAidlTest44   std::shared_ptr<T> getService() {
45     android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
46     android::ProcessState::self()->startThreadPool();
47     ndk::SpAIBinder binder = ndk::SpAIBinder(AServiceManager_waitForService(T::descriptor));
48     return T::fromBinder(binder);
49   }
50 };
51 
TEST_F(AidlTest,LoggableInterface)52 TEST_F(AidlTest, LoggableInterface) {
53   std::shared_ptr<ITestService> service = getService<ITestService>();
54   ASSERT_NE(nullptr, service.get());
55 
56   BackendType backendType;
57   ndk::ScopedAStatus status = service->getBackendType(&backendType);
58   EXPECT_TRUE(status.isOk()) << status.getDescription();
59   if (backendType != BackendType::CPP) GTEST_SKIP();
60 
61   shared_ptr<ILoggableInterface> loggable = getService<ILoggableInterface>();
62   ASSERT_NE(nullptr, loggable.get());
63 
64   BpLoggableInterface::TransactionLog log;
65   BpLoggableInterface::logFunc = [&](const BpLoggableInterface::TransactionLog& tx) { log = tx; };
66 
67   bool boolValue = true;
68   vector<bool> boolArray{false, true};
69   int8_t byteValue = 41;
70   vector<uint8_t> byteArray{42, 43};
71   char16_t charValue = 'x';
72   vector<char16_t> charArray{'a', 'b', 'c'};
73   int32_t intValue{44};
74   vector<int32_t> intArray{45, 46};
75   int64_t longValue = 47;
76   vector<int64_t> longArray{48, 49};
77   float floatValue{50};
78   vector<float> floatArray{51, 52};
79   double doubleValue{52};
80   vector<double> doubleArray{53, 54};
81   string stringValue("def");
82   vector<string> stringArray{string("ghi"), string("jkl")};
83   vector<string> listValue{string("mno")};
84   Data dataValue;
85   dataValue.num = 42;
86   dataValue.str = "abc";
87   dataValue.nestedUnion = "def";
88   dataValue.nestedEnum = Enum::FOO;
89   ndk::SpAIBinder binderValue;
90   ndk::ScopedFileDescriptor pfdValue;
91   vector<ndk::ScopedFileDescriptor> pfdArray;
92   vector<string> _aidl_return;
93   status = loggable->LogThis(boolValue, &boolArray, byteValue, &byteArray, charValue, &charArray,
94                              intValue, &intArray, longValue, &longArray, floatValue, &floatArray,
95                              doubleValue, &doubleArray, stringValue, &stringArray, &listValue,
96                              dataValue, binderValue, &pfdValue, &pfdArray, &_aidl_return);
97   EXPECT_TRUE(status.isOk());
98   EXPECT_EQ(vector<string>{string("loggable")}, _aidl_return);
99 
100   // check the captured log
101   EXPECT_EQ("[loggable]", log.result);
102   EXPECT_EQ("android.aidl.loggable.ILoggableInterface", log.interface_name);
103   EXPECT_EQ("LogThis", log.method_name);
104   EXPECT_EQ(0, log.exception_code);
105   EXPECT_EQ("", log.exception_message);
106   EXPECT_EQ(0, log.transaction_error);
107   EXPECT_EQ(0, log.service_specific_error_code);
108   EXPECT_THAT(log.input_args,
109               Eq(vector<pair<string, string>>{
110                   {"in_boolValue", "true"},
111                   {"in_boolArray", "[false, true]"},
112                   {"in_byteValue", "41"},
113                   {"in_byteArray", "[42, 43]"},
114                   {"in_charValue", "x"},
115                   {"in_charArray", "[a, b, c]"},
116                   {"in_intValue", "44"},
117                   {"in_intArray", "[45, 46]"},
118                   {"in_longValue", "47"},
119                   {"in_longArray", "[48, 49]"},
120                   {"in_floatValue", "50.000000"},
121                   {"in_floatArray", "[51.000000, 52.000000]"},
122                   {"in_doubleValue", "52.000000"},
123                   {"in_doubleArray", "[53.000000, 54.000000]"},
124                   {"in_stringValue", "def"},
125                   {"in_stringArray", "[ghi, jkl]"},
126                   {"in_listValue", "[mno]"},
127                   {"in_dataValue",
128                    "Data{num: 42, str: abc, nestedUnion: Union{str: def}, nestedEnum: FOO}"},
129                   {"in_binderValue", "binder:0x0"},
130                   {"in_pfdValue", "fd:-1"},
131                   {"in_pfdArray", "[]"},
132               }));
133   EXPECT_THAT(log.output_args,
134               Eq(vector<pair<string, string>>{{"in_boolArray", "[false, true]"},
135                                               {"in_byteArray", "[42, 43]"},
136                                               {"in_charArray", "[a, b, c]"},
137                                               {"in_intArray", "[45, 46]"},
138                                               {"in_longArray", "[48, 49]"},
139                                               {"in_floatArray", "[51.000000, 52.000000]"},
140                                               {"in_doubleArray", "[53.000000, 54.000000]"},
141                                               {"in_stringArray", "[ghi, jkl]"},
142                                               {"in_listValue", "[mno]"},
143                                               {"in_pfdValue", "fd:-1"},
144                                               {"in_pfdArray", "[]"}}));
145 }
146