aidl_test_service.cpp revision fc465468a55047324dd5ecef9282ff41f3d8b542
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 <sstream>
19#include <string>
20#include <vector>
21
22#include <unistd.h>
23
24#include <binder/IInterface.h>
25#include <binder/IPCThreadState.h>
26#include <binder/IServiceManager.h>
27#include <binder/ProcessState.h>
28#include <binder/Status.h>
29#include <nativehelper/ScopedFd.h>
30#include <utils/Errors.h>
31#include <utils/Log.h>
32#include <utils/Looper.h>
33#include <utils/StrongPointer.h>
34
35#include "android/aidl/tests/BnTestService.h"
36#include "android/aidl/tests/ITestService.h"
37
38#include "android/aidl/tests/BnNamedCallback.h"
39#include "android/aidl/tests/INamedCallback.h"
40
41// Used implicitly.
42#undef LOG_TAG
43#define LOG_TAG "aidl_native_service"
44
45// libutils:
46using android::Looper;
47using android::LooperCallback;
48using android::OK;
49using android::sp;
50using android::String16;
51
52// libbinder:
53using android::BnInterface;
54using android::defaultServiceManager;
55using android::IInterface;
56using android::IPCThreadState;
57using android::Parcel;
58using android::ProcessState;
59using android::binder::Status;
60
61// Generated code:
62using android::aidl::tests::BnNamedCallback;
63using android::aidl::tests::BnTestService;
64using android::aidl::tests::INamedCallback;
65using android::aidl::tests::SimpleParcelable;
66using android::os::PersistableBundle;
67
68// Standard library
69using std::map;
70using std::unique_ptr;
71using std::vector;
72
73namespace android {
74namespace generated {
75namespace {
76
77class BinderCallback : public LooperCallback {
78 public:
79  BinderCallback() {}
80  ~BinderCallback() override {}
81
82  int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
83    IPCThreadState::self()->handlePolledCommands();
84    return 1;  // Continue receiving callbacks.
85  }
86};
87
88class NamedCallback : public BnNamedCallback {
89 public:
90  NamedCallback(String16 name) : name_(name) {}
91
92  Status GetName(String16* ret) {
93    *ret = name_;
94    return Status::ok();
95  }
96
97 private:
98  String16 name_;
99};
100
101class NativeService : public BnTestService {
102 public:
103  NativeService() {}
104  virtual ~NativeService() = default;
105
106  void LogRepeatedStringToken(const String16& token) {
107    ALOGI("Repeating '%s' of length=%zu", android::String8(token).string(),
108          token.size());
109  }
110
111  template <typename T>
112  void LogRepeatedToken(const T& token) {
113    std::ostringstream token_str;
114    token_str << token;
115    ALOGI("Repeating token %s", token_str.str().c_str());
116  }
117
118  Status RepeatBoolean(bool token, bool* _aidl_return) override {
119    LogRepeatedToken(token ? 1 : 0);
120    *_aidl_return = token;
121    return Status::ok();
122  }
123  Status RepeatByte(int8_t token, int8_t* _aidl_return) override {
124    LogRepeatedToken(token);
125    *_aidl_return = token;
126    return Status::ok();
127  }
128  Status RepeatChar(char16_t token, char16_t* _aidl_return) override {
129    LogRepeatedStringToken(String16(&token, 1));
130    *_aidl_return = token;
131    return Status::ok();
132  }
133  Status RepeatInt(int32_t token, int32_t* _aidl_return) override {
134    LogRepeatedToken(token);
135    *_aidl_return = token;
136    return Status::ok();
137  }
138  Status RepeatLong(int64_t token, int64_t* _aidl_return) override {
139    LogRepeatedToken(token);
140    *_aidl_return = token;
141    return Status::ok();
142  }
143  Status RepeatFloat(float token, float* _aidl_return) override {
144    LogRepeatedToken(token);
145    *_aidl_return = token;
146    return Status::ok();
147  }
148  Status RepeatDouble(double token, double* _aidl_return) override {
149    LogRepeatedToken(token);
150    *_aidl_return = token;
151    return Status::ok();
152  }
153  Status RepeatString(const String16& token, String16* _aidl_return) override {
154    LogRepeatedStringToken(token);
155    *_aidl_return = token;
156    return Status::ok();
157  }
158
159  Status RepeatSimpleParcelable(const SimpleParcelable& input,
160                                SimpleParcelable* repeat,
161                                SimpleParcelable* _aidl_return) override {
162    ALOGI("Repeated a SimpleParcelable %s", input.toString().c_str());
163    *repeat = input;
164    *_aidl_return = input;
165    return Status::ok();
166  }
167
168  Status RepeatPersistableBundle(const PersistableBundle& input,
169                                 PersistableBundle* _aidl_return) override {
170    ALOGI("Repeated a PersistableBundle");
171    *_aidl_return = input;
172    return Status::ok();
173  }
174
175  template <typename T>
176  Status ReverseArray(const vector<T>& input, vector<T>* repeated,
177                      vector<T>* _aidl_return) {
178    ALOGI("Reversing array of length %zu", input.size());
179    *repeated = input;
180    *_aidl_return = input;
181    std::reverse(_aidl_return->begin(), _aidl_return->end());
182    return Status::ok();
183  }
184
185  template<typename T>
186  Status RepeatNullable(const unique_ptr<T>& input,
187                        unique_ptr<T>* _aidl_return) {
188    ALOGI("Repeating nullable value");
189
190    _aidl_return->reset();
191    if (input) {
192      _aidl_return->reset(new T(*input));
193    }
194
195    return Status::ok();
196  }
197
198  Status ReverseBoolean(const vector<bool>& input,
199                        vector<bool>* repeated,
200                        vector<bool>* _aidl_return) override {
201    return ReverseArray(input, repeated, _aidl_return);
202  }
203  Status ReverseByte(const vector<int8_t>& input,
204                     vector<int8_t>* repeated,
205                     vector<int8_t>* _aidl_return) override {
206    return ReverseArray(input, repeated, _aidl_return);
207  }
208  Status ReverseChar(const vector<char16_t>& input,
209                     vector<char16_t>* repeated,
210                     vector<char16_t>* _aidl_return) override {
211    return ReverseArray(input, repeated, _aidl_return);
212  }
213  Status ReverseInt(const vector<int32_t>& input,
214                    vector<int32_t>* repeated,
215                    vector<int32_t>* _aidl_return) override {
216    return ReverseArray(input, repeated, _aidl_return);
217  }
218  Status ReverseLong(const vector<int64_t>& input,
219                     vector<int64_t>* repeated,
220                     vector<int64_t>* _aidl_return) override {
221    return ReverseArray(input, repeated, _aidl_return);
222  }
223  Status ReverseFloat(const vector<float>& input,
224                      vector<float>* repeated,
225                      vector<float>* _aidl_return) override {
226    return ReverseArray(input, repeated, _aidl_return);
227  }
228  Status ReverseDouble(const vector<double>& input,
229                       vector<double>* repeated,
230                       vector<double>* _aidl_return) override {
231    return ReverseArray(input, repeated, _aidl_return);
232  }
233  Status ReverseString(const vector<String16>& input,
234                       vector<String16>* repeated,
235                       vector<String16>* _aidl_return) override {
236    return ReverseArray(input, repeated, _aidl_return);
237  }
238  Status ReverseSimpleParcelables(
239      const vector<SimpleParcelable>& input,
240      vector<SimpleParcelable>* repeated,
241      vector<SimpleParcelable>* _aidl_return) override {
242    return ReverseArray(input, repeated, _aidl_return);
243  }
244  Status ReversePersistableBundles(
245      const vector<PersistableBundle>& input,
246      vector<PersistableBundle>* repeated,
247      vector<PersistableBundle>* _aidl_return) override {
248    return ReverseArray(input, repeated, _aidl_return);
249  }
250
251  Status GetOtherTestService(const String16& name,
252                             sp<INamedCallback>* returned_service) override {
253    if (service_map_.find(name) == service_map_.end()) {
254      sp<INamedCallback> new_item(new NamedCallback(name));
255      service_map_[name] = new_item;
256    }
257
258    *returned_service = service_map_[name];
259    return Status::ok();
260  }
261
262  Status VerifyName(const sp<INamedCallback>& service, const String16& name,
263                    bool* returned_value) override {
264    String16 foundName;
265    Status status = service->GetName(&foundName);
266
267    if (status.isOk()) {
268      *returned_value = foundName == name;
269    }
270
271    return status;
272  }
273
274  Status ReverseStringList(const vector<String16>& input,
275                           vector<String16>* repeated,
276                           vector<String16>* _aidl_return) override {
277    return ReverseArray(input, repeated, _aidl_return);
278  }
279
280  Status ReverseNamedCallbackList(const vector<sp<IBinder>>& input,
281                                  vector<sp<IBinder>>* repeated,
282                                  vector<sp<IBinder>>* _aidl_return) override {
283    return ReverseArray(input, repeated, _aidl_return);
284  }
285
286  Status RepeatFileDescriptor(const ScopedFd& read,
287                              ScopedFd* _aidl_return) override {
288    ALOGE("Repeating file descriptor");
289    *_aidl_return = ScopedFd(dup(read.get()));
290    return Status::ok();
291  }
292
293  Status ReverseFileDescriptorArray(const vector<ScopedFd>& input,
294                                    vector<ScopedFd>* repeated,
295                                    vector<ScopedFd>* _aidl_return) override {
296    ALOGI("Reversing descriptor array of length %zu", input.size());
297    for (const auto& item : input) {
298      repeated->push_back(ScopedFd(dup(item.get())));
299      _aidl_return->push_back(ScopedFd(dup(item.get())));
300    }
301    std::reverse(_aidl_return->begin(), _aidl_return->end());
302    return Status::ok();
303  }
304
305  Status ThrowServiceException(int code) override {
306    return Status::fromServiceSpecificError(code);
307  }
308
309  Status RepeatNullableIntArray(const unique_ptr<vector<int32_t>>& input,
310                                unique_ptr<vector<int32_t>>* _aidl_return) {
311    return RepeatNullable(input, _aidl_return);
312  }
313
314  Status RepeatNullableStringList(
315             const unique_ptr<vector<unique_ptr<String16>>>& input,
316             unique_ptr<vector<unique_ptr<String16>>>* _aidl_return) {
317    ALOGI("Repeating nullable string list");
318    if (!input) {
319      _aidl_return->reset();
320      return Status::ok();
321    }
322
323    _aidl_return->reset(new vector<unique_ptr<String16>>);
324
325    for (const auto& item : *input) {
326      if (!item) {
327        (*_aidl_return)->emplace_back(nullptr);
328      } else {
329        (*_aidl_return)->emplace_back(new String16(*item));
330      }
331    }
332
333    return Status::ok();
334  }
335
336  Status RepeatNullableString(const unique_ptr<String16>& input,
337                              unique_ptr<String16>* _aidl_return) {
338    return RepeatNullable(input, _aidl_return);
339  }
340
341  Status RepeatNullableParcelable(const unique_ptr<SimpleParcelable>& input,
342                              unique_ptr<SimpleParcelable>* _aidl_return) {
343    return RepeatNullable(input, _aidl_return);
344  }
345
346 private:
347  map<String16, sp<INamedCallback>> service_map_;
348};
349
350}  // namespace
351
352int Run() {
353  android::sp<android::generated::NativeService> service =
354      new android::generated::NativeService;
355  sp<Looper> looper(Looper::prepare(0 /* opts */));
356
357  int binder_fd = -1;
358  ProcessState::self()->setThreadPoolMaxThreadCount(0);
359  IPCThreadState::self()->disableBackgroundScheduling(true);
360  IPCThreadState::self()->setupPolling(&binder_fd);
361  ALOGI("Got binder FD %d", binder_fd);
362  if (binder_fd < 0) return -1;
363
364  sp<BinderCallback> cb(new BinderCallback);
365  if (looper->addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
366                    nullptr) != 1) {
367    ALOGE("Failed to add binder FD to Looper");
368    return -1;
369  }
370
371  defaultServiceManager()->addService(service->getInterfaceDescriptor(),
372                                      service);
373
374  ALOGI("Entering loop");
375  while (true) {
376    const int result = looper->pollAll(-1 /* timeoutMillis */);
377    ALOGI("Looper returned %d", result);
378  }
379  return 0;
380}
381
382}  // namespace generated
383}  // namespace android
384
385int main(int /* argc */, char* /* argv */ []) {
386  return android::generated::Run();
387}
388