aidl_test_client_nullables.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * Copyright (C) 2015 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 "aidl_test_client_nullables.h"
  17. #include <utils/String16.h>
  18. #include <iostream>
  19. #include <memory>
  20. #include <string>
  21. #include <vector>
  22. // libutils:
  23. using android::sp;
  24. using android::String16;
  25. // libbinder:
  26. using android::binder::Status;
  27. // generated
  28. using android::aidl::tests::ITestService;
  29. using android::aidl::tests::SimpleParcelable;
  30. using std::string;
  31. using std::unique_ptr;
  32. using std::vector;
  33. using std::cout;
  34. using std::cerr;
  35. using std::endl;
  36. namespace android {
  37. namespace aidl {
  38. namespace tests {
  39. namespace client {
  40. namespace {
  41. template<typename T>
  42. bool ValuesEqual(const unique_ptr<T>& in, const unique_ptr<T>& out) {
  43. return *in == *out;
  44. }
  45. template<>
  46. bool ValuesEqual<vector<unique_ptr<String16>>>(
  47. const unique_ptr<vector<unique_ptr<String16>>>& in,
  48. const unique_ptr<vector<unique_ptr<String16>>>& out) {
  49. if (!in) {
  50. return !out;
  51. }
  52. if (!out) {
  53. return false;
  54. }
  55. if (in->size() != out->size()) {
  56. return false;
  57. }
  58. for (size_t i = 0; i < in->size(); i++) {
  59. const unique_ptr<String16>& a = (*in)[i];
  60. const unique_ptr<String16>& b = (*out)[i];
  61. if (!(a || b)) {
  62. continue;
  63. }
  64. if (!(a && b)) {
  65. return false;
  66. }
  67. if (*a != *b) {
  68. return false;
  69. }
  70. }
  71. return true;
  72. }
  73. template<typename T>
  74. bool ConfirmNullableType(const sp<ITestService>& s, const string& type_name,
  75. unique_ptr<T> in,
  76. Status(ITestService::*func)(const unique_ptr<T>&,
  77. unique_ptr<T>*)) {
  78. cout << "... Confirming nullables for " << type_name << " ..." << endl;
  79. Status status;
  80. unique_ptr<T> out;
  81. status = (*s.*func)(in, &out);
  82. if (!status.isOk()) {
  83. cerr << "Could not repeat nullable " << type_name << "." << endl;
  84. return false;
  85. }
  86. if (!out) {
  87. cerr << "Got back null when repeating " << type_name << "." << endl;
  88. return false;
  89. }
  90. if (!ValuesEqual(in, out)) {
  91. cerr << "Got back a non-matching value when repeating " << type_name
  92. << "." << endl;
  93. return false;
  94. }
  95. in.reset();
  96. status = (*s.*func)(in, &out);
  97. if (!status.isOk()) {
  98. cerr << "Could not repeat null as " << type_name << "." << endl;
  99. return false;
  100. }
  101. if (out) {
  102. cerr << "Got back a value when sent null for " << type_name << "."
  103. << endl;
  104. return false;
  105. }
  106. return true;
  107. }
  108. bool CheckAppropriateIBinderHandling(const sp<ITestService>& s) {
  109. Status status;
  110. sp<IBinder> binder = new BBinder();
  111. sp<IBinder> null_binder = nullptr;
  112. unique_ptr<vector<sp<IBinder>>> list_with_nulls(
  113. new vector<sp<IBinder>>{binder, null_binder});
  114. unique_ptr<vector<sp<IBinder>>> list_without_nulls(
  115. new vector<sp<IBinder>>{binder, binder});
  116. // Methods without @nullable throw up when given null binders
  117. if (s->TakesAnIBinder(null_binder).exceptionCode() !=
  118. binder::Status::EX_NULL_POINTER) {
  119. cerr << "Did not receive expected null exception on line: "
  120. << __LINE__ << endl;
  121. return false;
  122. }
  123. if (s->TakesAnIBinderList(*list_with_nulls).exceptionCode() !=
  124. binder::Status::EX_NULL_POINTER) {
  125. cerr << "Did not receive expected null exception on line: "
  126. << __LINE__ << endl;
  127. return false;
  128. }
  129. // But those same methods are fine with valid binders
  130. if (!s->TakesAnIBinder(binder).isOk()) {
  131. cerr << "Received unexpected exception on line "
  132. << __LINE__ << endl;
  133. return false;
  134. }
  135. if (!s->TakesAnIBinderList(*list_without_nulls).isOk()) {
  136. cerr << "Received unexpected exception on line "
  137. << __LINE__ << endl;
  138. return false;
  139. }
  140. // And methods with @nullable don't care.
  141. if (!s->TakesANullableIBinder(null_binder).isOk()) {
  142. cerr << "Received unexpected exception on line "
  143. << __LINE__ << endl;
  144. return false;
  145. }
  146. if (!s->TakesANullableIBinder(binder).isOk()) {
  147. cerr << "Received unexpected exception on line "
  148. << __LINE__ << endl;
  149. return false;
  150. }
  151. if (!s->TakesANullableIBinderList(list_with_nulls).isOk()) {
  152. cerr << "Received unexpected exception on line "
  153. << __LINE__ << endl;
  154. return false;
  155. }
  156. if (!s->TakesANullableIBinderList(list_without_nulls).isOk()) {
  157. cerr << "Received unexpected exception on line "
  158. << __LINE__ << endl;
  159. return false;
  160. }
  161. return true;
  162. }
  163. bool CheckAppropriateIInterfaceHandling(const sp<ITestService>& s) {
  164. sp<INamedCallback> callback;
  165. if (!s->GetCallback(false, &callback).isOk()) {
  166. cerr << "Received unexpected exception on line "
  167. << __LINE__ << endl;
  168. return false;
  169. }
  170. if (callback.get() == nullptr) {
  171. cerr << "Expected to receive a non-null binder on line: "
  172. << __LINE__ << endl;
  173. return false;
  174. }
  175. if (!s->GetCallback(true, &callback).isOk()) {
  176. cerr << "Received unexpected exception on line "
  177. << __LINE__ << endl;
  178. return false;
  179. }
  180. if (callback.get() != nullptr) {
  181. cerr << "Expected to receive a null binder on line: "
  182. << __LINE__ << endl;
  183. return false;
  184. }
  185. return true;
  186. }
  187. } // namespace
  188. bool ConfirmNullables(const sp<ITestService>& s) {
  189. Status status;
  190. cout << "Confirming passing and returning nullable values works." << endl;
  191. if (!ConfirmNullableType(s, "integer array",
  192. unique_ptr<vector<int32_t>>(
  193. new vector<int32_t>({1,2,3})),
  194. &ITestService::RepeatNullableIntArray)) {
  195. return false;
  196. }
  197. if (!ConfirmNullableType(s, "string",
  198. unique_ptr<String16>(new String16("Blooob")),
  199. &ITestService::RepeatNullableString)) {
  200. return false;
  201. }
  202. unique_ptr<vector<unique_ptr<String16>>> test_string_array(
  203. new vector<unique_ptr<String16>>());
  204. test_string_array->push_back(unique_ptr<String16>(new String16("Wat")));
  205. test_string_array->push_back(unique_ptr<String16>(
  206. new String16("Blooob")));
  207. test_string_array->push_back(unique_ptr<String16>(new String16("Wat")));
  208. test_string_array->push_back(unique_ptr<String16>(nullptr));
  209. test_string_array->push_back(unique_ptr<String16>(new String16("YEAH")));
  210. test_string_array->push_back(unique_ptr<String16>(
  211. new String16("OKAAAAY")));
  212. if (!ConfirmNullableType(s, "string array", std::move(test_string_array),
  213. &ITestService::RepeatNullableStringList)) {
  214. return false;
  215. }
  216. if (!ConfirmNullableType(s, "parcelable",
  217. unique_ptr<SimpleParcelable>(
  218. new SimpleParcelable("Booya", 42)),
  219. &ITestService::RepeatNullableParcelable)) {
  220. return false;
  221. }
  222. if (!CheckAppropriateIBinderHandling(s)) {
  223. cerr << "Handled null IBinders poorly." << endl;
  224. return false;
  225. }
  226. if (!CheckAppropriateIInterfaceHandling(s)) {
  227. cerr << "Handled nullable IInterface instances poorly." << endl;
  228. return false;
  229. }
  230. return true;
  231. }
  232. } // namespace client
  233. } // namespace tests
  234. } // namespace aidl
  235. } // namespace android