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
17 #include <map>
18 #include <optional>
19 #include <sstream>
20 #include <string>
21 #include <vector>
22
23 #include <unistd.h>
24
25 #include <android-base/unique_fd.h>
26 #include <binder/IInterface.h>
27 #include <binder/IPCThreadState.h>
28 #include <binder/IServiceManager.h>
29 #include <binder/ProcessState.h>
30 #include <binder/Status.h>
31 #include <utils/Errors.h>
32 #include <utils/Log.h>
33 #include <utils/Looper.h>
34 #include <utils/String8.h>
35 #include <utils/StrongPointer.h>
36
37 #include "android/aidl/tests/BackendType.h"
38 #include "android/aidl/tests/BnTestService.h"
39 #include "android/aidl/tests/ITestService.h"
40
41 #include "android/aidl/tests/BnNamedCallback.h"
42 #include "android/aidl/tests/INamedCallback.h"
43
44 #include "android/aidl/versioned/tests/BnFooInterface.h"
45 #include "android/aidl/versioned/tests/IFooInterface.h"
46
47 #include "android/aidl/tests/BnNewName.h"
48 #include "android/aidl/tests/BnOldName.h"
49
50 #include "android/aidl/tests/BnCppJavaTests.h"
51 #include "android/aidl/tests/ICppJavaTests.h"
52
53 #include "android/aidl/tests/Union.h"
54 #include "android/aidl/tests/extension/MyExt.h"
55 #include "android/aidl/tests/extension/MyExt2.h"
56
57 #include "android/aidl/tests/nested/BnNestedService.h"
58
59 #include "android/aidl/loggable/BnLoggableInterface.h"
60 #include "android/aidl/loggable/Data.h"
61
62 #include "android/aidl/fixedsizearray/FixedSizeArrayExample.h"
63
64 // Used implicitly.
65 #undef LOG_TAG
66 #define LOG_TAG "aidl_native_service"
67
68 // libbase
69 using android::base::unique_fd;
70
71 // libutils:
72 using android::Looper;
73 using android::LooperCallback;
74 using android::OK;
75 using android::sp;
76 using android::String16;
77 using android::String8;
78
79 // libbinder:
80 using android::BnInterface;
81 using android::defaultServiceManager;
82 using android::IInterface;
83 using android::IPCThreadState;
84 using android::Parcel;
85 using android::ProcessState;
86 using android::binder::Status;
87
88 // Generated code:
89 using android::aidl::tests::BackendType;
90 using android::aidl::tests::BadParcelable;
91 using android::aidl::tests::BnCppJavaTests;
92 using android::aidl::tests::BnNamedCallback;
93 using android::aidl::tests::BnNewName;
94 using android::aidl::tests::BnOldName;
95 using android::aidl::tests::BnTestService;
96 using android::aidl::tests::ByteEnum;
97 using android::aidl::tests::ConstantExpressionEnum;
98 using android::aidl::tests::GenericStructuredParcelable;
99 using android::aidl::tests::ICppJavaTests;
100 using android::aidl::tests::INamedCallback;
101 using android::aidl::tests::INewName;
102 using android::aidl::tests::IntEnum;
103 using android::aidl::tests::IOldName;
104 using android::aidl::tests::LongEnum;
105 using android::aidl::tests::RecursiveList;
106 using android::aidl::tests::SimpleParcelable;
107 using android::aidl::tests::StructuredParcelable;
108 using android::aidl::tests::Union;
109 using android::os::ParcelFileDescriptor;
110 using android::os::PersistableBundle;
111
112 // Standard library
113 using std::map;
114 using std::optional;
115 using std::string;
116 using std::vector;
117
118 namespace {
119
120 class BinderCallback : public LooperCallback {
121 public:
BinderCallback()122 BinderCallback() {}
~BinderCallback()123 ~BinderCallback() override {}
124
handleEvent(int,int,void *)125 int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
126 IPCThreadState::self()->handlePolledCommands();
127 return 1; // Continue receiving callbacks.
128 }
129 };
130
131 class NamedCallback : public BnNamedCallback {
132 public:
NamedCallback(String16 name)133 explicit NamedCallback(String16 name) : name_(name) {}
134
GetName(String16 * ret)135 Status GetName(String16* ret) {
136 *ret = name_;
137 return Status::ok();
138 }
139
140 private:
141 String16 name_;
142 };
143
144 class OldName : public BnOldName {
145 public:
146 OldName() = default;
147 ~OldName() = default;
148
RealName(String16 * output)149 Status RealName(String16* output) override {
150 *output = String16("OldName");
151 return Status::ok();
152 }
153 };
154
155 class NewName : public BnNewName {
156 public:
157 NewName() = default;
158 ~NewName() = default;
159
RealName(String16 * output)160 Status RealName(String16* output) override {
161 *output = String16("NewName");
162 return Status::ok();
163 }
164 };
165
166 template <typename T>
ReverseArray(const vector<T> & input,vector<T> * repeated,vector<T> * _aidl_return)167 Status ReverseArray(const vector<T>& input, vector<T>* repeated, vector<T>* _aidl_return) {
168 ALOGI("Reversing array of length %zu", input.size());
169 *repeated = input;
170 *_aidl_return = input;
171 std::reverse(_aidl_return->begin(), _aidl_return->end());
172 return Status::ok();
173 }
174
175 template <typename T>
RepeatNullable(const optional<T> & input,optional<T> * _aidl_return)176 Status RepeatNullable(const optional<T>& input, optional<T>* _aidl_return) {
177 ALOGI("Repeating nullable value");
178 *_aidl_return = input;
179 return Status::ok();
180 }
181
182 class CppJavaTests : public BnCppJavaTests {
183 public:
184 CppJavaTests() = default;
185 ~CppJavaTests() = default;
186
RepeatBadParcelable(const BadParcelable & input,BadParcelable * _aidl_return)187 Status RepeatBadParcelable(const BadParcelable& input, BadParcelable* _aidl_return) override {
188 *_aidl_return = input;
189 return Status::ok();
190 }
191
RepeatSimpleParcelable(const SimpleParcelable & input,SimpleParcelable * repeat,SimpleParcelable * _aidl_return)192 Status RepeatSimpleParcelable(const SimpleParcelable& input, SimpleParcelable* repeat,
193 SimpleParcelable* _aidl_return) override {
194 ALOGI("Repeated a SimpleParcelable %s", input.toString().c_str());
195 *repeat = input;
196 *_aidl_return = input;
197 return Status::ok();
198 }
199
RepeatGenericParcelable(const GenericStructuredParcelable<int32_t,StructuredParcelable,IntEnum> & input,GenericStructuredParcelable<int32_t,StructuredParcelable,IntEnum> * repeat,GenericStructuredParcelable<int32_t,StructuredParcelable,IntEnum> * _aidl_return)200 Status RepeatGenericParcelable(
201 const GenericStructuredParcelable<int32_t, StructuredParcelable, IntEnum>& input,
202 GenericStructuredParcelable<int32_t, StructuredParcelable, IntEnum>* repeat,
203 GenericStructuredParcelable<int32_t, StructuredParcelable, IntEnum>* _aidl_return) {
204 ALOGI("Repeating Generic Parcelable");
205 *repeat = input;
206 *_aidl_return = input;
207 return Status::ok();
208 }
209
RepeatPersistableBundle(const PersistableBundle & input,PersistableBundle * _aidl_return)210 Status RepeatPersistableBundle(const PersistableBundle& input,
211 PersistableBundle* _aidl_return) override {
212 ALOGI("Repeated a PersistableBundle");
213 *_aidl_return = input;
214 return Status::ok();
215 }
216
ReverseSimpleParcelables(const vector<SimpleParcelable> & input,vector<SimpleParcelable> * repeated,vector<SimpleParcelable> * _aidl_return)217 Status ReverseSimpleParcelables(const vector<SimpleParcelable>& input,
218 vector<SimpleParcelable>* repeated,
219 vector<SimpleParcelable>* _aidl_return) override {
220 return ReverseArray(input, repeated, _aidl_return);
221 }
ReversePersistableBundles(const vector<PersistableBundle> & input,vector<PersistableBundle> * repeated,vector<PersistableBundle> * _aidl_return)222 Status ReversePersistableBundles(const vector<PersistableBundle>& input,
223 vector<PersistableBundle>* repeated,
224 vector<PersistableBundle>* _aidl_return) override {
225 return ReverseArray(input, repeated, _aidl_return);
226 }
ReverseUnion(const Union & input,Union * repeated,Union * _aidl_return)227 Status ReverseUnion(const Union& input, Union* repeated, Union* _aidl_return) override {
228 ALOGI("Repeated a Union");
229 *repeated = input;
230 *_aidl_return = input;
231 auto reverse = [](auto& reversible) {
232 std::reverse(std::begin(reversible), std::end(reversible));
233 };
234 switch (input.getTag()) {
235 case Union::ns: // int[]
236 reverse(_aidl_return->get<Union::ns>());
237 break;
238 case Union::s: // String
239 reverse(_aidl_return->get<Union::s>());
240 break;
241 case Union::ss: // List<String>
242 reverse(_aidl_return->get<Union::ss>());
243 break;
244 default:
245 break;
246 }
247 return Status::ok();
248 }
ReverseNamedCallbackList(const vector<sp<IBinder>> & input,vector<sp<IBinder>> * repeated,vector<sp<IBinder>> * _aidl_return)249 Status ReverseNamedCallbackList(const vector<sp<IBinder>>& input, vector<sp<IBinder>>* repeated,
250 vector<sp<IBinder>>* _aidl_return) override {
251 return ReverseArray(input, repeated, _aidl_return);
252 }
253
RepeatFileDescriptor(unique_fd read,unique_fd * _aidl_return)254 Status RepeatFileDescriptor(unique_fd read, unique_fd* _aidl_return) override {
255 ALOGE("Repeating file descriptor");
256 *_aidl_return = unique_fd(dup(read.get()));
257 return Status::ok();
258 }
259
ReverseFileDescriptorArray(const vector<unique_fd> & input,vector<unique_fd> * repeated,vector<unique_fd> * _aidl_return)260 Status ReverseFileDescriptorArray(const vector<unique_fd>& input, vector<unique_fd>* repeated,
261 vector<unique_fd>* _aidl_return) override {
262 ALOGI("Reversing descriptor array of length %zu", input.size());
263 repeated->clear();
264 for (const auto& item : input) {
265 repeated->push_back(unique_fd(dup(item.get())));
266 _aidl_return->push_back(unique_fd(dup(item.get())));
267 }
268 std::reverse(_aidl_return->begin(), _aidl_return->end());
269 return Status::ok();
270 }
271 };
272
273 class NativeService : public BnTestService {
274 public:
NativeService()275 NativeService() {}
276 virtual ~NativeService() = default;
277
LogRepeatedStringToken(const String16 & token)278 void LogRepeatedStringToken(const String16& token) {
279 ALOGI("Repeating '%s' of length=%zu", android::String8(token).string(),
280 token.size());
281 }
282
283 template <typename T>
LogRepeatedToken(const T & token)284 void LogRepeatedToken(const T& token) {
285 std::ostringstream token_str;
286 token_str << token;
287 ALOGI("Repeating token %s", token_str.str().c_str());
288 }
289
TestOneway()290 Status TestOneway() override { return Status::fromStatusT(android::UNKNOWN_ERROR); }
291
Deprecated()292 Status Deprecated() override { return Status::ok(); }
293
RepeatBoolean(bool token,bool * _aidl_return)294 Status RepeatBoolean(bool token, bool* _aidl_return) override {
295 LogRepeatedToken(token ? 1 : 0);
296 *_aidl_return = token;
297 return Status::ok();
298 }
RepeatByte(int8_t token,int8_t * _aidl_return)299 Status RepeatByte(int8_t token, int8_t* _aidl_return) override {
300 LogRepeatedToken(token);
301 *_aidl_return = token;
302 return Status::ok();
303 }
RepeatChar(char16_t token,char16_t * _aidl_return)304 Status RepeatChar(char16_t token, char16_t* _aidl_return) override {
305 LogRepeatedStringToken(String16(&token, 1));
306 *_aidl_return = token;
307 return Status::ok();
308 }
RepeatInt(int32_t token,int32_t * _aidl_return)309 Status RepeatInt(int32_t token, int32_t* _aidl_return) override {
310 LogRepeatedToken(token);
311 *_aidl_return = token;
312 return Status::ok();
313 }
RepeatLong(int64_t token,int64_t * _aidl_return)314 Status RepeatLong(int64_t token, int64_t* _aidl_return) override {
315 LogRepeatedToken(token);
316 *_aidl_return = token;
317 return Status::ok();
318 }
RepeatFloat(float token,float * _aidl_return)319 Status RepeatFloat(float token, float* _aidl_return) override {
320 LogRepeatedToken(token);
321 *_aidl_return = token;
322 return Status::ok();
323 }
RepeatDouble(double token,double * _aidl_return)324 Status RepeatDouble(double token, double* _aidl_return) override {
325 LogRepeatedToken(token);
326 *_aidl_return = token;
327 return Status::ok();
328 }
RepeatString(const String16 & token,String16 * _aidl_return)329 Status RepeatString(const String16& token, String16* _aidl_return) override {
330 LogRepeatedStringToken(token);
331 *_aidl_return = token;
332 return Status::ok();
333 }
RepeatByteEnum(ByteEnum token,ByteEnum * _aidl_return)334 Status RepeatByteEnum(ByteEnum token, ByteEnum* _aidl_return) override {
335 ALOGI("Repeating ByteEnum token %s", toString(token).c_str());
336 *_aidl_return = token;
337 return Status::ok();
338 }
RepeatIntEnum(IntEnum token,IntEnum * _aidl_return)339 Status RepeatIntEnum(IntEnum token, IntEnum* _aidl_return) override {
340 ALOGI("Repeating IntEnum token %s", toString(token).c_str());
341 *_aidl_return = token;
342 return Status::ok();
343 }
RepeatLongEnum(LongEnum token,LongEnum * _aidl_return)344 Status RepeatLongEnum(LongEnum token, LongEnum* _aidl_return) override {
345 ALOGI("Repeating LongEnum token %s", toString(token).c_str());
346 *_aidl_return = token;
347 return Status::ok();
348 }
349
ReverseBoolean(const vector<bool> & input,vector<bool> * repeated,vector<bool> * _aidl_return)350 Status ReverseBoolean(const vector<bool>& input,
351 vector<bool>* repeated,
352 vector<bool>* _aidl_return) override {
353 return ReverseArray(input, repeated, _aidl_return);
354 }
ReverseByte(const vector<uint8_t> & input,vector<uint8_t> * repeated,vector<uint8_t> * _aidl_return)355 Status ReverseByte(const vector<uint8_t>& input,
356 vector<uint8_t>* repeated,
357 vector<uint8_t>* _aidl_return) override {
358 return ReverseArray(input, repeated, _aidl_return);
359 }
ReverseChar(const vector<char16_t> & input,vector<char16_t> * repeated,vector<char16_t> * _aidl_return)360 Status ReverseChar(const vector<char16_t>& input,
361 vector<char16_t>* repeated,
362 vector<char16_t>* _aidl_return) override {
363 return ReverseArray(input, repeated, _aidl_return);
364 }
ReverseInt(const vector<int32_t> & input,vector<int32_t> * repeated,vector<int32_t> * _aidl_return)365 Status ReverseInt(const vector<int32_t>& input,
366 vector<int32_t>* repeated,
367 vector<int32_t>* _aidl_return) override {
368 return ReverseArray(input, repeated, _aidl_return);
369 }
ReverseLong(const vector<int64_t> & input,vector<int64_t> * repeated,vector<int64_t> * _aidl_return)370 Status ReverseLong(const vector<int64_t>& input,
371 vector<int64_t>* repeated,
372 vector<int64_t>* _aidl_return) override {
373 return ReverseArray(input, repeated, _aidl_return);
374 }
ReverseFloat(const vector<float> & input,vector<float> * repeated,vector<float> * _aidl_return)375 Status ReverseFloat(const vector<float>& input,
376 vector<float>* repeated,
377 vector<float>* _aidl_return) override {
378 return ReverseArray(input, repeated, _aidl_return);
379 }
ReverseDouble(const vector<double> & input,vector<double> * repeated,vector<double> * _aidl_return)380 Status ReverseDouble(const vector<double>& input,
381 vector<double>* repeated,
382 vector<double>* _aidl_return) override {
383 return ReverseArray(input, repeated, _aidl_return);
384 }
ReverseString(const vector<String16> & input,vector<String16> * repeated,vector<String16> * _aidl_return)385 Status ReverseString(const vector<String16>& input,
386 vector<String16>* repeated,
387 vector<String16>* _aidl_return) override {
388 return ReverseArray(input, repeated, _aidl_return);
389 }
ReverseByteEnum(const vector<ByteEnum> & input,vector<ByteEnum> * repeated,vector<ByteEnum> * _aidl_return)390 Status ReverseByteEnum(const vector<ByteEnum>& input, vector<ByteEnum>* repeated,
391 vector<ByteEnum>* _aidl_return) override {
392 return ReverseArray(input, repeated, _aidl_return);
393 }
ReverseIntEnum(const vector<IntEnum> & input,vector<IntEnum> * repeated,vector<IntEnum> * _aidl_return)394 Status ReverseIntEnum(const vector<IntEnum>& input, vector<IntEnum>* repeated,
395 vector<IntEnum>* _aidl_return) override {
396 return ReverseArray(input, repeated, _aidl_return);
397 }
ReverseLongEnum(const vector<LongEnum> & input,vector<LongEnum> * repeated,vector<LongEnum> * _aidl_return)398 Status ReverseLongEnum(const vector<LongEnum>& input, vector<LongEnum>* repeated,
399 vector<LongEnum>* _aidl_return) override {
400 return ReverseArray(input, repeated, _aidl_return);
401 }
402
GetOtherTestService(const String16 & name,sp<INamedCallback> * returned_service)403 Status GetOtherTestService(const String16& name,
404 sp<INamedCallback>* returned_service) override {
405 if (service_map_.find(name) == service_map_.end()) {
406 sp<INamedCallback> new_item(new NamedCallback(name));
407 service_map_[name] = new_item;
408 }
409
410 *returned_service = service_map_[name];
411 return Status::ok();
412 }
413
VerifyName(const sp<INamedCallback> & service,const String16 & name,bool * returned_value)414 Status VerifyName(const sp<INamedCallback>& service, const String16& name,
415 bool* returned_value) override {
416 String16 foundName;
417 Status status = service->GetName(&foundName);
418
419 if (status.isOk()) {
420 *returned_value = foundName == name;
421 }
422
423 return status;
424 }
425
GetInterfaceArray(const vector<String16> & names,vector<sp<INamedCallback>> * _aidl_return)426 Status GetInterfaceArray(const vector<String16>& names,
427 vector<sp<INamedCallback>>* _aidl_return) override {
428 vector<sp<INamedCallback>> services(names.size());
429 for (size_t i = 0; i < names.size(); i++) {
430 if (auto st = GetOtherTestService(names[i], &services[i]); !st.isOk()) {
431 return st;
432 }
433 }
434 *_aidl_return = std::move(services);
435 return Status::ok();
436 }
437
VerifyNamesWithInterfaceArray(const vector<sp<INamedCallback>> & services,const vector<String16> & names,bool * _aidl_ret)438 Status VerifyNamesWithInterfaceArray(const vector<sp<INamedCallback>>& services,
439 const vector<String16>& names, bool* _aidl_ret) override {
440 if (services.size() == names.size()) {
441 for (size_t i = 0; i < services.size(); i++) {
442 if (auto st = VerifyName(services[i], names[i], _aidl_ret); !st.isOk() || !*_aidl_ret) {
443 return st;
444 }
445 }
446 *_aidl_ret = true;
447 } else {
448 *_aidl_ret = false;
449 }
450 return Status::ok();
451 }
452
GetNullableInterfaceArray(const optional<vector<optional<String16>>> & names,optional<vector<sp<INamedCallback>>> * _aidl_ret)453 Status GetNullableInterfaceArray(const optional<vector<optional<String16>>>& names,
454 optional<vector<sp<INamedCallback>>>* _aidl_ret) override {
455 vector<sp<INamedCallback>> services;
456 if (names.has_value()) {
457 for (const auto& name : *names) {
458 if (name.has_value()) {
459 sp<INamedCallback> ret;
460 if (auto st = GetOtherTestService(*name, &ret); !st.isOk()) {
461 return st;
462 }
463 services.push_back(std::move(ret));
464 } else {
465 services.emplace_back();
466 }
467 }
468 }
469 *_aidl_ret = std::move(services);
470 return Status::ok();
471 }
472
VerifyNamesWithNullableInterfaceArray(const optional<vector<sp<INamedCallback>>> & services,const optional<vector<optional<String16>>> & names,bool * _aidl_ret)473 Status VerifyNamesWithNullableInterfaceArray(const optional<vector<sp<INamedCallback>>>& services,
474 const optional<vector<optional<String16>>>& names,
475 bool* _aidl_ret) override {
476 if (services.has_value() && names.has_value()) {
477 if (services->size() == names->size()) {
478 for (size_t i = 0; i < services->size(); i++) {
479 if (services->at(i).get() && names->at(i).has_value()) {
480 if (auto st = VerifyName(services->at(i), names->at(i).value(), _aidl_ret);
481 !st.isOk() || !*_aidl_ret) {
482 return st;
483 }
484 } else if (services->at(i).get() || names->at(i).has_value()) {
485 *_aidl_ret = false;
486 return Status::ok();
487 } else {
488 // ok if service=null && name=null
489 }
490 }
491 *_aidl_ret = true;
492 } else {
493 *_aidl_ret = false;
494 }
495 } else {
496 *_aidl_ret = services.has_value() == names.has_value();
497 }
498 return Status::ok();
499 }
500
GetInterfaceList(const optional<vector<optional<String16>>> & names,optional<vector<sp<INamedCallback>>> * _aidl_ret)501 Status GetInterfaceList(const optional<vector<optional<String16>>>& names,
502 optional<vector<sp<INamedCallback>>>* _aidl_ret) override {
503 return GetNullableInterfaceArray(names, _aidl_ret);
504 }
505
VerifyNamesWithInterfaceList(const optional<vector<sp<INamedCallback>>> & services,const optional<vector<optional<String16>>> & names,bool * _aidl_ret)506 Status VerifyNamesWithInterfaceList(const optional<vector<sp<INamedCallback>>>& services,
507 const optional<vector<optional<String16>>>& names,
508 bool* _aidl_ret) override {
509 return VerifyNamesWithNullableInterfaceArray(services, names, _aidl_ret);
510 }
511
ReverseStringList(const vector<String16> & input,vector<String16> * repeated,vector<String16> * _aidl_return)512 Status ReverseStringList(const vector<String16>& input,
513 vector<String16>* repeated,
514 vector<String16>* _aidl_return) override {
515 return ReverseArray(input, repeated, _aidl_return);
516 }
517
RepeatParcelFileDescriptor(const ParcelFileDescriptor & read,ParcelFileDescriptor * _aidl_return)518 Status RepeatParcelFileDescriptor(const ParcelFileDescriptor& read,
519 ParcelFileDescriptor* _aidl_return) override {
520 ALOGE("Repeating parcel file descriptor");
521 _aidl_return->reset(unique_fd(dup(read.get())));
522 return Status::ok();
523 }
524
ReverseParcelFileDescriptorArray(const vector<ParcelFileDescriptor> & input,vector<ParcelFileDescriptor> * repeated,vector<ParcelFileDescriptor> * _aidl_return)525 Status ReverseParcelFileDescriptorArray(const vector<ParcelFileDescriptor>& input,
526 vector<ParcelFileDescriptor>* repeated,
527 vector<ParcelFileDescriptor>* _aidl_return) override {
528 ALOGI("Reversing parcel descriptor array of length %zu", input.size());
529 for (const auto& item : input) {
530 repeated->push_back(ParcelFileDescriptor(unique_fd(dup(item.get()))));
531 }
532
533 for (auto i = input.rbegin(); i != input.rend(); i++) {
534 _aidl_return->push_back(ParcelFileDescriptor(unique_fd(dup(i->get()))));
535 }
536 return Status::ok();
537 }
538
ThrowServiceException(int code)539 Status ThrowServiceException(int code) override {
540 return Status::fromServiceSpecificError(code);
541 }
542
RepeatNullableIntArray(const optional<vector<int32_t>> & input,optional<vector<int32_t>> * _aidl_return)543 Status RepeatNullableIntArray(const optional<vector<int32_t>>& input,
544 optional<vector<int32_t>>* _aidl_return) {
545 return RepeatNullable(input, _aidl_return);
546 }
547
RepeatNullableByteEnumArray(const optional<vector<ByteEnum>> & input,optional<vector<ByteEnum>> * _aidl_return)548 Status RepeatNullableByteEnumArray(const optional<vector<ByteEnum>>& input,
549 optional<vector<ByteEnum>>* _aidl_return) {
550 return RepeatNullable(input, _aidl_return);
551 }
552
RepeatNullableIntEnumArray(const optional<vector<IntEnum>> & input,optional<vector<IntEnum>> * _aidl_return)553 Status RepeatNullableIntEnumArray(const optional<vector<IntEnum>>& input,
554 optional<vector<IntEnum>>* _aidl_return) {
555 return RepeatNullable(input, _aidl_return);
556 }
557
RepeatNullableLongEnumArray(const optional<vector<LongEnum>> & input,optional<vector<LongEnum>> * _aidl_return)558 Status RepeatNullableLongEnumArray(const optional<vector<LongEnum>>& input,
559 optional<vector<LongEnum>>* _aidl_return) {
560 return RepeatNullable(input, _aidl_return);
561 }
562
RepeatNullableStringList(const optional<vector<optional<String16>>> & input,optional<vector<optional<String16>>> * _aidl_return)563 Status RepeatNullableStringList(const optional<vector<optional<String16>>>& input,
564 optional<vector<optional<String16>>>* _aidl_return) {
565 ALOGI("Repeating nullable string list");
566 return RepeatNullable(input, _aidl_return);
567 }
568
RepeatNullableString(const optional<String16> & input,optional<String16> * _aidl_return)569 Status RepeatNullableString(const optional<String16>& input, optional<String16>* _aidl_return) {
570 return RepeatNullable(input, _aidl_return);
571 }
572
RepeatNullableParcelable(const optional<ITestService::Empty> & input,optional<ITestService::Empty> * _aidl_return)573 Status RepeatNullableParcelable(const optional<ITestService::Empty>& input,
574 optional<ITestService::Empty>* _aidl_return) {
575 return RepeatNullable(input, _aidl_return);
576 }
577
RepeatNullableParcelableList(const optional<vector<optional<ITestService::Empty>>> & input,optional<vector<optional<ITestService::Empty>>> * _aidl_return)578 Status RepeatNullableParcelableList(
579 const optional<vector<optional<ITestService::Empty>>>& input,
580 optional<vector<optional<ITestService::Empty>>>* _aidl_return) {
581 return RepeatNullable(input, _aidl_return);
582 }
583
RepeatNullableParcelableArray(const optional<vector<optional<ITestService::Empty>>> & input,optional<vector<optional<ITestService::Empty>>> * _aidl_return)584 Status RepeatNullableParcelableArray(
585 const optional<vector<optional<ITestService::Empty>>>& input,
586 optional<vector<optional<ITestService::Empty>>>* _aidl_return) {
587 return RepeatNullable(input, _aidl_return);
588 }
589
TakesAnIBinder(const sp<IBinder> & input)590 Status TakesAnIBinder(const sp<IBinder>& input) override {
591 (void)input;
592 return Status::ok();
593 }
TakesANullableIBinder(const sp<IBinder> & input)594 Status TakesANullableIBinder(const sp<IBinder>& input) {
595 (void)input;
596 return Status::ok();
597 }
TakesAnIBinderList(const vector<sp<IBinder>> & input)598 Status TakesAnIBinderList(const vector<sp<IBinder>>& input) override {
599 (void)input;
600 return Status::ok();
601 }
TakesANullableIBinderList(const optional<vector<sp<IBinder>>> & input)602 Status TakesANullableIBinderList(const optional<vector<sp<IBinder>>>& input) {
603 (void)input;
604 return Status::ok();
605 }
606
RepeatUtf8CppString(const string & token,string * _aidl_return)607 Status RepeatUtf8CppString(const string& token,
608 string* _aidl_return) override {
609 ALOGI("Repeating utf8 string '%s' of length=%zu", token.c_str(), token.size());
610 *_aidl_return = token;
611 return Status::ok();
612 }
613
RepeatNullableUtf8CppString(const optional<string> & token,optional<string> * _aidl_return)614 Status RepeatNullableUtf8CppString(const optional<string>& token,
615 optional<string>* _aidl_return) override {
616 if (!token) {
617 ALOGI("Received null @utf8InCpp string");
618 return Status::ok();
619 }
620 ALOGI("Repeating utf8 string '%s' of length=%zu",
621 token->c_str(), token->size());
622 *_aidl_return = token;
623 return Status::ok();
624 }
625
ReverseUtf8CppString(const vector<string> & input,vector<string> * repeated,vector<string> * _aidl_return)626 Status ReverseUtf8CppString(const vector<string>& input,
627 vector<string>* repeated,
628 vector<string>* _aidl_return) {
629 return ReverseArray(input, repeated, _aidl_return);
630 }
631
ReverseNullableUtf8CppString(const optional<vector<optional<string>>> & input,optional<vector<optional<string>>> * repeated,optional<vector<optional<string>>> * _aidl_return)632 Status ReverseNullableUtf8CppString(const optional<vector<optional<string>>>& input,
633 optional<vector<optional<string>>>* repeated,
634 optional<vector<optional<string>>>* _aidl_return) {
635 return ReverseUtf8CppStringList(input, repeated, _aidl_return);
636 }
637
ReverseUtf8CppStringList(const optional<vector<optional<string>>> & input,optional<vector<optional<string>>> * repeated,optional<vector<optional<string>>> * _aidl_return)638 Status ReverseUtf8CppStringList(const optional<vector<optional<string>>>& input,
639 optional<vector<optional<string>>>* repeated,
640 optional<vector<optional<string>>>* _aidl_return) {
641 if (!input) {
642 ALOGI("Received null list of utf8 strings");
643 return Status::ok();
644 }
645 *_aidl_return = input;
646 *repeated = input;
647 std::reverse((*_aidl_return)->begin(), (*_aidl_return)->end());
648 return Status::ok();
649 }
650
GetCallback(bool return_null,sp<INamedCallback> * ret)651 Status GetCallback(bool return_null, sp<INamedCallback>* ret) {
652 if (!return_null) {
653 return GetOtherTestService(String16("ABT: always be testing"), ret);
654 }
655 return Status::ok();
656 }
657
FillOutStructuredParcelable(StructuredParcelable * parcelable)658 virtual ::android::binder::Status FillOutStructuredParcelable(StructuredParcelable* parcelable) {
659 parcelable->shouldBeJerry = "Jerry";
660 parcelable->shouldContainThreeFs = {parcelable->f, parcelable->f, parcelable->f};
661 parcelable->shouldBeByteBar = ByteEnum::BAR;
662 parcelable->shouldBeIntBar = IntEnum::BAR;
663 parcelable->shouldBeLongBar = LongEnum::BAR;
664 parcelable->shouldContainTwoByteFoos = {ByteEnum::FOO, ByteEnum::FOO};
665 parcelable->shouldContainTwoIntFoos = {IntEnum::FOO, IntEnum::FOO};
666 parcelable->shouldContainTwoLongFoos = {LongEnum::FOO, LongEnum::FOO};
667
668 parcelable->const_exprs_1 = ConstantExpressionEnum::decInt32_1;
669 parcelable->const_exprs_2 = ConstantExpressionEnum::decInt32_2;
670 parcelable->const_exprs_3 = ConstantExpressionEnum::decInt64_1;
671 parcelable->const_exprs_4 = ConstantExpressionEnum::decInt64_2;
672 parcelable->const_exprs_5 = ConstantExpressionEnum::decInt64_3;
673 parcelable->const_exprs_6 = ConstantExpressionEnum::decInt64_4;
674 parcelable->const_exprs_7 = ConstantExpressionEnum::hexInt32_1;
675 parcelable->const_exprs_8 = ConstantExpressionEnum::hexInt32_2;
676 parcelable->const_exprs_9 = ConstantExpressionEnum::hexInt32_3;
677 parcelable->const_exprs_10 = ConstantExpressionEnum::hexInt64_1;
678
679 parcelable->shouldSetBit0AndBit2 = StructuredParcelable::BIT0 | StructuredParcelable::BIT2;
680
681 parcelable->u = Union::make<Union::ns>({1, 2, 3});
682 parcelable->shouldBeConstS1 = Union::S1();
683 return Status::ok();
684 }
685
RepeatExtendableParcelable(const::android::aidl::tests::extension::ExtendableParcelable & ep,::android::aidl::tests::extension::ExtendableParcelable * ep2)686 ::android::binder::Status RepeatExtendableParcelable(
687 const ::android::aidl::tests::extension::ExtendableParcelable& ep,
688 ::android::aidl::tests::extension::ExtendableParcelable* ep2) {
689 ep2->a = ep.a;
690 ep2->b = ep.b;
691 std::shared_ptr<android::aidl::tests::extension::MyExt> myExt;
692 ep.ext.getParcelable(&myExt);
693 ep2->ext.setParcelable(myExt);
694
695 return Status::ok();
696 }
697
ReverseList(const RecursiveList & list,RecursiveList * ret)698 ::android::binder::Status ReverseList(const RecursiveList& list, RecursiveList* ret) override {
699 std::unique_ptr<RecursiveList> reversed;
700 const RecursiveList* cur = &list;
701 while (cur) {
702 auto node = std::make_unique<RecursiveList>();
703 node->value = cur->value;
704 node->next = std::move(reversed);
705 reversed = std::move(node);
706 cur = cur->next.get();
707 }
708 *ret = std::move(*reversed);
709 return Status::ok();
710 }
711
ReverseIBinderArray(const vector<sp<IBinder>> & input,vector<sp<IBinder>> * repeated,vector<sp<IBinder>> * _aidl_return)712 Status ReverseIBinderArray(const vector<sp<IBinder>>& input, vector<sp<IBinder>>* repeated,
713 vector<sp<IBinder>>* _aidl_return) override {
714 *repeated = input;
715 *_aidl_return = input;
716 std::reverse(_aidl_return->begin(), _aidl_return->end());
717 return Status::ok();
718 }
719
ReverseNullableIBinderArray(const std::optional<vector<sp<IBinder>>> & input,std::optional<vector<sp<IBinder>>> * repeated,std::optional<vector<sp<IBinder>>> * _aidl_return)720 Status ReverseNullableIBinderArray(const std::optional<vector<sp<IBinder>>>& input,
721 std::optional<vector<sp<IBinder>>>* repeated,
722 std::optional<vector<sp<IBinder>>>* _aidl_return) override {
723 *repeated = input;
724 *_aidl_return = input;
725 if (*_aidl_return) {
726 std::reverse((*_aidl_return)->begin(), (*_aidl_return)->end());
727 }
728 return Status::ok();
729 }
730
UnimplementedMethod(int32_t,int32_t *)731 Status UnimplementedMethod(int32_t /* arg */, int32_t* /* _aidl_return */) override {
732 LOG_ALWAYS_FATAL("UnimplementedMethod shouldn't be called");
733 }
734
GetOldNameInterface(sp<IOldName> * ret)735 Status GetOldNameInterface(sp<IOldName>* ret) {
736 *ret = new OldName;
737 return Status::ok();
738 }
739
GetNewNameInterface(sp<INewName> * ret)740 Status GetNewNameInterface(sp<INewName>* ret) {
741 *ret = new NewName;
742 return Status::ok();
743 }
744
GetUnionTags(const std::vector<Union> & input,std::vector<Union::Tag> * _aidl_return)745 Status GetUnionTags(const std::vector<Union>& input,
746 std::vector<Union::Tag>* _aidl_return) override {
747 std::vector<Union::Tag> tags;
748 std::transform(input.begin(), input.end(), std::back_inserter(tags),
749 std::mem_fn(&Union::getTag));
750 *_aidl_return = std::move(tags);
751 return Status::ok();
752 }
753
GetCppJavaTests(sp<IBinder> * ret)754 Status GetCppJavaTests(sp<IBinder>* ret) {
755 *ret = new CppJavaTests;
756 return Status::ok();
757 }
758
getBackendType(BackendType * _aidl_return)759 Status getBackendType(BackendType* _aidl_return) override {
760 *_aidl_return = BackendType::CPP;
761 return Status::ok();
762 }
763
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)764 android::status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
765 uint32_t flags) override {
766 if (code == ::android::IBinder::FIRST_CALL_TRANSACTION + 0 /* UnimplementedMethod */) {
767 // pretend that UnimplementedMethod isn't implemented by this service.
768 return android::UNKNOWN_TRANSACTION;
769 } else {
770 return BnTestService::onTransact(code, data, reply, flags);
771 }
772 }
773
774 private:
775 map<String16, sp<INamedCallback>> service_map_;
776 };
777
778 class VersionedService : public android::aidl::versioned::tests::BnFooInterface {
779 public:
VersionedService()780 VersionedService() {}
781 virtual ~VersionedService() = default;
782
originalApi()783 Status originalApi() override { return Status::ok(); }
acceptUnionAndReturnString(const::android::aidl::versioned::tests::BazUnion & u,std::string * _aidl_return)784 Status acceptUnionAndReturnString(const ::android::aidl::versioned::tests::BazUnion& u,
785 std::string* _aidl_return) override {
786 switch (u.getTag()) {
787 case ::android::aidl::versioned::tests::BazUnion::intNum:
788 *_aidl_return =
789 std::to_string(u.get<::android::aidl::versioned::tests::BazUnion::intNum>());
790 break;
791 }
792 return Status::ok();
793 }
returnsLengthOfFooArray(const vector<::android::aidl::versioned::tests::Foo> & foos,int32_t * ret)794 Status returnsLengthOfFooArray(const vector<::android::aidl::versioned::tests::Foo>& foos,
795 int32_t* ret) override {
796 *ret = static_cast<int32_t>(foos.size());
797 return Status::ok();
798 }
ignoreParcelablesAndRepeatInt(const::android::aidl::versioned::tests::Foo & inFoo,::android::aidl::versioned::tests::Foo * inoutFoo,::android::aidl::versioned::tests::Foo * outFoo,int32_t value,int32_t * ret)799 Status ignoreParcelablesAndRepeatInt(const ::android::aidl::versioned::tests::Foo& inFoo,
800 ::android::aidl::versioned::tests::Foo* inoutFoo,
801 ::android::aidl::versioned::tests::Foo* outFoo,
802 int32_t value, int32_t* ret) override {
803 (void)inFoo;
804 (void)inoutFoo;
805 (void)outFoo;
806 *ret = value;
807 return Status::ok();
808 }
809 };
810
811 class LoggableInterfaceService : public android::aidl::loggable::BnLoggableInterface {
812 public:
LoggableInterfaceService()813 LoggableInterfaceService() {}
814 virtual ~LoggableInterfaceService() = default;
815
LogThis(bool,vector<bool> *,int8_t,vector<uint8_t> *,char16_t,vector<char16_t> *,int32_t,vector<int32_t> *,int64_t,vector<int64_t> *,float,vector<float> *,double,vector<double> *,const String16 &,vector<String16> *,vector<String16> *,const android::aidl::loggable::Data &,const sp<IBinder> &,optional<ParcelFileDescriptor> *,vector<ParcelFileDescriptor> *,vector<String16> * _aidl_return)816 virtual Status LogThis(bool, vector<bool>*, int8_t, vector<uint8_t>*, char16_t, vector<char16_t>*,
817 int32_t, vector<int32_t>*, int64_t, vector<int64_t>*, float,
818 vector<float>*, double, vector<double>*, const String16&,
819 vector<String16>*, vector<String16>*, const android::aidl::loggable::Data&,
820 const sp<IBinder>&, optional<ParcelFileDescriptor>*,
821 vector<ParcelFileDescriptor>*, vector<String16>* _aidl_return) override {
822 *_aidl_return = vector<String16>{String16("loggable")};
823 return Status::ok();
824 }
825 };
826
827 using namespace android::aidl::tests::nested;
828 class NestedService : public BnNestedService {
829 public:
NestedService()830 NestedService() {}
831 virtual ~NestedService() = default;
832
flipStatus(const ParcelableWithNested & p,INestedService::Result * _aidl_return)833 virtual Status flipStatus(const ParcelableWithNested& p, INestedService::Result* _aidl_return) {
834 if (p.status == ParcelableWithNested::Status::OK) {
835 _aidl_return->status = ParcelableWithNested::Status::NOT_OK;
836 } else {
837 _aidl_return->status = ParcelableWithNested::Status::OK;
838 }
839 return Status::ok();
840 }
flipStatusWithCallback(ParcelableWithNested::Status status,const sp<INestedService::ICallback> & cb)841 virtual Status flipStatusWithCallback(ParcelableWithNested::Status status,
842 const sp<INestedService::ICallback>& cb) {
843 if (status == ParcelableWithNested::Status::OK) {
844 return cb->done(ParcelableWithNested::Status::NOT_OK);
845 } else {
846 return cb->done(ParcelableWithNested::Status::OK);
847 }
848 }
849 };
850
851 using android::aidl::fixedsizearray::FixedSizeArrayExample;
852 class FixedSizeArrayService : public FixedSizeArrayExample::BnRepeatFixedSizeArray {
853 public:
FixedSizeArrayService()854 FixedSizeArrayService() {}
855 virtual ~FixedSizeArrayService() = default;
856
RepeatBytes(const std::array<uint8_t,3> & in_input,std::array<uint8_t,3> * out_repeated,std::array<uint8_t,3> * _aidl_return)857 Status RepeatBytes(const std::array<uint8_t, 3>& in_input, std::array<uint8_t, 3>* out_repeated,
858 std::array<uint8_t, 3>* _aidl_return) override {
859 *out_repeated = in_input;
860 *_aidl_return = in_input;
861 return Status::ok();
862 }
RepeatInts(const std::array<int32_t,3> & in_input,std::array<int32_t,3> * out_repeated,std::array<int32_t,3> * _aidl_return)863 Status RepeatInts(const std::array<int32_t, 3>& in_input, std::array<int32_t, 3>* out_repeated,
864 std::array<int32_t, 3>* _aidl_return) override {
865 *out_repeated = in_input;
866 *_aidl_return = in_input;
867 return Status::ok();
868 }
RepeatBinders(const std::array<sp<IBinder>,3> & in_input,std::array<sp<IBinder>,3> * out_repeated,std::array<sp<IBinder>,3> * _aidl_return)869 Status RepeatBinders(const std::array<sp<IBinder>, 3>& in_input,
870 std::array<sp<IBinder>, 3>* out_repeated,
871 std::array<sp<IBinder>, 3>* _aidl_return) override {
872 *out_repeated = in_input;
873 *_aidl_return = in_input;
874 return Status::ok();
875 }
RepeatParcelables(const std::array<FixedSizeArrayExample::IntParcelable,3> & in_input,std::array<FixedSizeArrayExample::IntParcelable,3> * out_repeated,std::array<FixedSizeArrayExample::IntParcelable,3> * _aidl_return)876 Status RepeatParcelables(
877 const std::array<FixedSizeArrayExample::IntParcelable, 3>& in_input,
878 std::array<FixedSizeArrayExample::IntParcelable, 3>* out_repeated,
879 std::array<FixedSizeArrayExample::IntParcelable, 3>* _aidl_return) override {
880 *out_repeated = in_input;
881 *_aidl_return = in_input;
882 return Status::ok();
883 }
Repeat2dBytes(const std::array<std::array<uint8_t,3>,2> & in_input,std::array<std::array<uint8_t,3>,2> * out_repeated,std::array<std::array<uint8_t,3>,2> * _aidl_return)884 Status Repeat2dBytes(const std::array<std::array<uint8_t, 3>, 2>& in_input,
885 std::array<std::array<uint8_t, 3>, 2>* out_repeated,
886 std::array<std::array<uint8_t, 3>, 2>* _aidl_return) override {
887 *out_repeated = in_input;
888 *_aidl_return = in_input;
889 return Status::ok();
890 }
Repeat2dInts(const std::array<std::array<int32_t,3>,2> & in_input,std::array<std::array<int32_t,3>,2> * out_repeated,std::array<std::array<int32_t,3>,2> * _aidl_return)891 Status Repeat2dInts(const std::array<std::array<int32_t, 3>, 2>& in_input,
892 std::array<std::array<int32_t, 3>, 2>* out_repeated,
893 std::array<std::array<int32_t, 3>, 2>* _aidl_return) override {
894 *out_repeated = in_input;
895 *_aidl_return = in_input;
896 return Status::ok();
897 }
Repeat2dBinders(const std::array<std::array<sp<IBinder>,3>,2> & in_input,std::array<std::array<sp<IBinder>,3>,2> * out_repeated,std::array<std::array<sp<IBinder>,3>,2> * _aidl_return)898 Status Repeat2dBinders(const std::array<std::array<sp<IBinder>, 3>, 2>& in_input,
899 std::array<std::array<sp<IBinder>, 3>, 2>* out_repeated,
900 std::array<std::array<sp<IBinder>, 3>, 2>* _aidl_return) override {
901 *out_repeated = in_input;
902 *_aidl_return = in_input;
903 return Status::ok();
904 }
Repeat2dParcelables(const std::array<std::array<FixedSizeArrayExample::IntParcelable,3>,2> & in_input,std::array<std::array<FixedSizeArrayExample::IntParcelable,3>,2> * out_repeated,std::array<std::array<FixedSizeArrayExample::IntParcelable,3>,2> * _aidl_return)905 Status Repeat2dParcelables(
906 const std::array<std::array<FixedSizeArrayExample::IntParcelable, 3>, 2>& in_input,
907 std::array<std::array<FixedSizeArrayExample::IntParcelable, 3>, 2>* out_repeated,
908 std::array<std::array<FixedSizeArrayExample::IntParcelable, 3>, 2>* _aidl_return) override {
909 *out_repeated = in_input;
910 *_aidl_return = in_input;
911 return Status::ok();
912 }
913 };
914
Run()915 int Run() {
916 android::sp<NativeService> service = new NativeService;
917 sp<Looper> looper(Looper::prepare(0 /* opts */));
918
919 int binder_fd = -1;
920 ProcessState::self()->setThreadPoolMaxThreadCount(0);
921 IPCThreadState::self()->disableBackgroundScheduling(true);
922 IPCThreadState::self()->setupPolling(&binder_fd);
923 ALOGI("Got binder FD %d", binder_fd);
924 if (binder_fd < 0) return -1;
925
926 sp<BinderCallback> cb(new BinderCallback);
927 if (looper->addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
928 nullptr) != 1) {
929 ALOGE("Failed to add binder FD to Looper");
930 return -1;
931 }
932
933 auto status = defaultServiceManager()->addService(service->getInterfaceDescriptor(), service);
934 if (status != OK) {
935 ALOGE("Failed to add service %s", String8(service->getInterfaceDescriptor()).c_str());
936 return -1;
937 }
938
939 android::sp<VersionedService> versionedService = new VersionedService;
940 status = defaultServiceManager()->addService(versionedService->getInterfaceDescriptor(),
941 versionedService);
942 if (status != OK) {
943 ALOGE("Failed to add service %s", String8(versionedService->getInterfaceDescriptor()).c_str());
944 return -1;
945 }
946
947 android::sp<LoggableInterfaceService> loggableInterfaceService = new LoggableInterfaceService;
948 status = defaultServiceManager()->addService(loggableInterfaceService->getInterfaceDescriptor(),
949 loggableInterfaceService);
950 if (status != OK) {
951 ALOGE("Failed to add service %s",
952 String8(loggableInterfaceService->getInterfaceDescriptor()).c_str());
953 return -1;
954 }
955
956 android::sp<NestedService> nestedService = new NestedService;
957 status =
958 defaultServiceManager()->addService(nestedService->getInterfaceDescriptor(), nestedService);
959 if (status != OK) {
960 ALOGE("Failed to add service %s", String8(nestedService->getInterfaceDescriptor()).c_str());
961 return -1;
962 }
963
964 android::sp<FixedSizeArrayService> fixedSizeArrayService = new FixedSizeArrayService;
965 status = defaultServiceManager()->addService(fixedSizeArrayService->getInterfaceDescriptor(),
966 fixedSizeArrayService);
967 if (status != OK) {
968 ALOGE("Failed to add service %s",
969 String8(fixedSizeArrayService->getInterfaceDescriptor()).c_str());
970 return -1;
971 }
972
973 ALOGI("Entering loop");
974 while (true) {
975 const int result = looper->pollAll(-1 /* timeoutMillis */);
976 ALOGI("Looper returned %d", result);
977 }
978 return 0;
979 }
980
981 } // namespace
982
main(int,char * [])983 int main(int /* argc */, char* /* argv */ []) {
984 return Run();
985 }
986