1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <errno.h>
2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <fcntl.h>
3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <unistd.h>
4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <array>
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <cstdint>
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <memory>
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <numeric>
9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <string>
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <thread>
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <gtest/gtest.h>
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/channel_handle.h>
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/client.h>
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/rpc/remote_method.h>
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/rpc/serializable.h>
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service.h>
18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/client_channel.h>
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/client_channel_factory.h>
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/service_dispatcher.h>
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/service_endpoint.h>
22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::BorrowedHandle;
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Channel;
25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::ClientBase;
261f8fa907745eddeaa0220355a6c115793158e68cCorey Tabakausing android::pdx::ErrorStatus;
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalChannelHandle;
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalHandle;
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Message;
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::RemoteChannelHandle;
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::RemoteHandle;
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::ServiceBase;
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::ServiceDispatcher;
34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Status;
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::uds::Endpoint;
36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing namespace android::pdx::rpc;
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace {
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
401f8fa907745eddeaa0220355a6c115793158e68cCorey Tabakastd::string Rot13(const std::string& s) {
411f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  std::string text = s;
421f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  std::transform(std::begin(text), std::end(text), std::begin(text),
431f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka                 [](char c) -> char {
441f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka                   if (!std::isalpha(c)) {
451f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka                     return c;
461f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka                   } else {
471f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka                     const char pivot = std::isupper(c) ? 'A' : 'a';
481f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka                     return (c - pivot + 13) % 26 + pivot;
491f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka                   }
501f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka                 });
511f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  return text;
521f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka}
531f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka
54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Defines a serializable user type that may be transferred between client and
55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// service.
56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct TestType {
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int a;
58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  float b;
59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::string c;
60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestType() {}
62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestType(int a, float b, const std::string& c) : a(a), b(b), c(c) {}
63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Make gtest expressions simpler by defining equality operator. This is not
65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // needed for serialization.
66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  bool operator==(const TestType& other) const {
67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return a == other.a && b == other.b && c == other.c;
68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_SERIALIZABLE_MEMBERS(TestType, a, b, c);
72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct DerivedTestType : public TestType {
75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  DerivedTestType() : TestType() {}
76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  DerivedTestType(int a, float b) : TestType(a, b, "constant") {}
77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Defines a serializable user type with a LocalHandle member.
80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct TestFdType {
81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int a;
82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  LocalHandle fd;
83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestFdType() {}
85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestFdType(int a, LocalHandle fd) : a(a), fd(std::move(fd)) {}
86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_SERIALIZABLE_MEMBERS(TestFdType, a, fd);
89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Defines a serializable user template type with a FileHandle member.
92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotemplate <typename FileHandleType>
93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct TestTemplateType {
94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  FileHandleType fd;
95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestTemplateType() {}
97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_SERIALIZABLE_MEMBERS(TestTemplateType<FileHandleType>, fd);
101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct BasicStruct {
104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int a;
105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int b;
106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::string c;
107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_SERIALIZABLE_MEMBERS(BasicStruct, a, b, c);
110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing BasicStructTraits = SerializableTraits<BasicStruct>;
113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct NonSerializableType {
115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int a;
116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int b;
117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::string c;
118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct IncorrectlyDefinedSerializableType {
121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int a;
122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int b;
123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  using SerializableMembers = std::tuple<int, int>;
126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Defines the contract between the client and service, including ServiceFS
129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// endpoint path, method opcodes, and remote method signatures.
130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostruct TestInterface final {
131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Service path.
132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  static constexpr char kClientPath[] = "socket_test";
133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Op codes.
135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  enum {
136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpAdd = 0,
137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpFoo,
138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpConcatenate,
139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpWriteBuffer,
140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpStringLength,
141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpSendTestType,
142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpSendBasicStruct,
143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpSendVector,
144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpRot13,
145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpNoArgs,
146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpSendFile,
147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpGetFile,
148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpGetTestFdType,
149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpOpenFiles,
150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpReadFile,
151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    kOpPushChannel,
1521f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka    kOpPositive,
153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  };
154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Methods.
156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(Add, kOpAdd, int(int, int));
157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(Foo, kOpFoo, int(int, const std::string&));
158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(Concatenate, kOpConcatenate,
159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                    std::string(const std::string&, const std::string&));
160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(SumVector, kOpWriteBuffer, int(const std::vector<int>&));
161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(StringLength, kOpStringLength, int(const std::string&));
162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(SendTestType, kOpSendTestType, TestType(const TestType&));
163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(SendBasicStruct, kOpSendBasicStruct,
164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                    BasicStruct(const BasicStruct&));
165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(SendVector, kOpSendVector,
166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                    std::string(const std::vector<TestType>&));
167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(Rot13, kOpRot13, std::string(const std::string&));
168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(NoArgs, kOpNoArgs, int(Void));
169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(SendFile, kOpSendFile, int(const LocalHandle& fd));
170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(GetFile, kOpGetFile, LocalHandle(const std::string&, int));
171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(GetTestFdType, kOpGetTestFdType,
172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                    TestFdType(int, const std::string&, int));
173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(OpenFiles, kOpOpenFiles,
174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                    std::vector<LocalHandle>(
175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                        const std::vector<std::pair<std::string, int>>&));
176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(ReadFile, kOpReadFile,
177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                    std::pair<int, BufferWrapper<std::uint8_t*>>(
178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                        const std::string&, int, std::size_t));
179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_METHOD(PushChannel, kOpPushChannel, LocalChannelHandle(Void));
1801f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  PDX_REMOTE_METHOD(Positive, kOpPositive, void(int));
181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  PDX_REMOTE_API(API, Add, Foo, Concatenate, SumVector, StringLength,
183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                 SendTestType, SendVector, Rot13, NoArgs, SendFile, GetFile,
1841f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka                 GetTestFdType, OpenFiles, PushChannel, Positive);
185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconstexpr char TestInterface::kClientPath[];
188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Test client to send messages to the test service.
190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass TestClient : public ClientBase<TestClient> {
191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public:
192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int Add(int a, int b) {
193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::Add>(a, b));
194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int Foo(int a, const std::string& b) {
197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::Foo>(a, b));
198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::string Concatenate(const std::string& a, const std::string& b) {
201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::string return_value;
202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Status<std::string> status =
204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::Concatenate>(a, b);
205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!status)
206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return std::string("[Error]");
207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return status.take();
209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int SumVector(const int* buffer, std::size_t size) {
212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReturnStatusOrError(
213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::SumVector>(WrapArray(buffer, size)));
214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int SumVector(const std::vector<int>& buffer) {
217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReturnStatusOrError(
218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::SumVector>(buffer));
219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int StringLength(const char* string, std::size_t size) {
222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::StringLength>(
223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        WrapString(string, size)));
224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int StringLength(const std::string& string) {
227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReturnStatusOrError(
228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::StringLength>(string));
229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestType SendTestType(const TestType& tt) {
232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Status<TestType> status =
233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::SendTestType>(tt);
234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!status)
235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return TestType(0, 0.0, "[Error]");
236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return status.take();
238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  BasicStruct SendBasicStruct(const BasicStruct& bs) {
241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Status<BasicStruct> status =
242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::SendBasicStruct>(bs);
243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!status)
244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return BasicStruct{0, 0, "[Error]"};
245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return status.take();
247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::string SendVector(const std::vector<TestType>& v) {
250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Status<std::string> status =
251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::SendVector>(v);
252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!status)
253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return "[Error]";
254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return status.take();
256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::string Rot13(const std::string& string) {
259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Status<std::string> status =
260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::Rot13>(string);
261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return status ? status.get() : string;
262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int NoArgs() {
265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::NoArgs>());
266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int SendFile(const LocalHandle& fd) {
269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::SendFile>(fd));
270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  LocalHandle GetFile(const std::string& path, int mode) {
273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Status<LocalHandle> status =
274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::GetFile>(path, mode);
275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!status)
276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return LocalHandle(-status.error());
277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return status.take();
279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int GetFile(const std::string& path, int mode, LocalHandle* fd_out) {
282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Status<void> status =
283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethodInPlace<TestInterface::GetFile>(fd_out, path, mode);
284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return status ? 0 : -status.error();
285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestFdType GetTestFdType(int a, const std::string& path, int mode) {
288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Status<TestFdType> status =
289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::GetTestFdType>(a, path, mode);
290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!status)
291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return {};
292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return status.take();
294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::vector<LocalHandle> OpenFiles(
297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      const std::vector<std::pair<std::string, int>>& file_specs) {
298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Status<std::vector<LocalHandle>> status =
299e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        InvokeRemoteMethod<TestInterface::OpenFiles>(file_specs);
300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!status)
301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return {};
302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    else
303e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return status.take();
304e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int ReadFile(void* buffer, std::size_t size, const std::string& path,
307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               int mode) {
308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    auto buffer_wrapper = WrapBuffer(buffer, size);
309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    auto return_value = std::make_pair(-1, buffer_wrapper);
310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Status<void> status = InvokeRemoteMethodInPlace<TestInterface::ReadFile>(
312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        &return_value, path, mode, size);
313e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return status ? return_value.first : -status.error();
314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int PushChannel(LocalChannelHandle* fd_out) {
317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    auto status = InvokeRemoteMethodInPlace<TestInterface::PushChannel>(fd_out);
318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return status ? 0 : -status.error();
319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
3211f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  bool Positive(int test_value) {
3221f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka    auto status = InvokeRemoteMethod<TestInterface::Positive>(test_value);
3231f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka    return status.ok();
3241f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  }
3251f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka
326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int GetFd() const { return event_fd(); }
327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
328e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
329e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  friend BASE;
330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
331e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestClient(LocalChannelHandle channel_handle)
332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      : BASE{android::pdx::uds::ClientChannel::Create(
333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            std::move(channel_handle))} {}
334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestClient()
335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      : BASE{android::pdx::uds::ClientChannelFactory::Create(
336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            TestInterface::kClientPath)} {}
337e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestClient(const TestClient&) = delete;
339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void operator=(const TestClient&) = delete;
340e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
342e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Test service that encodes/decodes messages from clients.
343e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass TestService : public ServiceBase<TestService> {
344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public:
345f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko  Status<void> HandleMessage(Message& message) override {
346e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    switch (message.GetOp()) {
347e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::Add::Opcode:
348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::Add>(*this, &TestService::OnAdd,
349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                                 message);
350f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
351e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::Foo::Opcode:
353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::Foo>(*this, &TestService::OnFoo,
354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                                 message);
355f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::Concatenate::Opcode:
358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::Concatenate>(
359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnConcatenate, message);
360f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
362e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::SumVector::Opcode:
363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::SumVector>(
364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnSumVector, message);
365f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
366e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::StringLength::Opcode:
368e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::StringLength>(
369e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnStringLength, message);
370f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
372e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::SendTestType::Opcode:
373e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::SendTestType>(
374e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnSendTestType, message);
375f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::SendVector::Opcode:
378e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::SendVector>(
379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnSendVector, message);
380f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
381e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
382e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::Rot13::Opcode:
383e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::Rot13>(*this, &TestService::OnRot13,
384e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                                                   message);
385f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
386e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
387e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::NoArgs::Opcode:
388e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::NoArgs>(
389e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnNoArgs, message);
390f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
391e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
392e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::SendFile::Opcode:
393e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::SendFile>(
394e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnSendFile, message);
395f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
396e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
397e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::GetFile::Opcode:
398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::GetFile>(
399e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnGetFile, message);
400f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
402e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::GetTestFdType::Opcode:
403e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::GetTestFdType>(
404e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnGetTestFdType, message);
405f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
406e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
407e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::OpenFiles::Opcode:
408e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::OpenFiles>(
409e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnOpenFiles, message);
410f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
411e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
412e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::ReadFile::Opcode:
413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::ReadFile>(
414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnReadFile, message);
415f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
416e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
417e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      case TestInterface::PushChannel::Opcode:
418e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        DispatchRemoteMethod<TestInterface::PushChannel>(
419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko            *this, &TestService::OnPushChannel, message);
420f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
421e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4221f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka      case TestInterface::Positive::Opcode:
4231f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka        DispatchRemoteMethod<TestInterface::Positive>(
4241f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka            *this, &TestService::OnPositive, message);
425f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko        return {};
4261f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka
427e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      default:
428e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return Service::DefaultHandleMessage(message);
429e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
430e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
431e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
432e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private:
433e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  friend BASE;
434e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
435e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestService()
436f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko      : BASE("TestService",
437f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko             Endpoint::CreateAndBindSocket(TestInterface::kClientPath)) {}
438e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
439e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int OnAdd(Message&, int a, int b) { return a + b; }
440e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
441e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int OnFoo(Message&, int a, const std::string& b) { return a + b.length(); }
442e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
443e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::string OnConcatenate(Message&, const std::string& a,
444e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                            const std::string& b) {
445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return a + b;
446e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
447e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
448e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int OnSumVector(Message&, const std::vector<int>& vector) {
449e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return std::accumulate(vector.begin(), vector.end(), 0);
450e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
451e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
452e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int OnStringLength(Message&, const std::string& string) {
453e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return string.length();
454e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
455e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
456e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestType OnSendTestType(Message&, const TestType& tt) {
457e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return TestType(tt.a + 20, tt.b - 2.0, tt.c + "foo");
458e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
459e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
460e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::string OnSendVector(Message&, const std::vector<TestType>& v) {
461e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::string return_value = "";
462e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
463e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    for (const auto& tt : v)
464e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return_value += tt.c;
465e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
466e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return return_value;
467e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
468e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
4691f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  Status<std::string> OnRot13(Message&, const std::string& s) {
4701f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka    return {Rot13(s)};
471e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
472e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
473e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int OnNoArgs(Message&) { return 1; }
474e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
475e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int OnSendFile(Message&, const LocalHandle& fd) { return fd.Get(); }
476e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
477e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  LocalHandle OnGetFile(Message& message, const std::string& path, int mode) {
478e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    LocalHandle fd(path.c_str(), mode);
479e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!fd)
480e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      message.ReplyError(errno);
481e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return fd;
482e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
483e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
484e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestFdType OnGetTestFdType(Message& message, int a, const std::string& path,
485e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             int mode) {
486e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    TestFdType return_value(a, LocalHandle(path, mode));
487e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!return_value.fd)
488e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      message.ReplyError(errno);
489e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return return_value;
490e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
491e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
492e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::vector<LocalHandle> OnOpenFiles(
493e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      Message&, const std::vector<std::pair<std::string, int>>& file_specs) {
494e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::vector<LocalHandle> return_value;
495e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    for (auto& spec : file_specs) {
496e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      LocalHandle fd(spec.first, spec.second);
497e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      if (fd)
498e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return_value.emplace_back(std::move(fd));
499e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      else
500e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        return_value.emplace_back(-errno);
501e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
502e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return return_value;
503e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
504e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
505e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::pair<int, BufferWrapper<std::vector<std::uint8_t>>> OnReadFile(
506e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      Message& message, const std::string& path, int mode, std::size_t length) {
507e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    std::pair<int, BufferWrapper<std::vector<std::uint8_t>>> return_value;
508e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    LocalHandle fd(path, mode);
509e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!fd) {
510e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      message.ReplyError(errno);
511e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return return_value;
512e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
513e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
514e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return_value.second.reserve(length);
515e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    const int ret = read(fd.Get(), return_value.second.data(), length);
516e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (ret < 0) {
517e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      message.ReplyError(errno);
518e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return return_value;
519e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
520e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
521e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return_value.second.resize(ret);
522e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return_value.first = ret;
523e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return return_value;
524e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
525e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
526e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  RemoteChannelHandle OnPushChannel(Message& message) {
527e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    auto status = message.PushChannel(0, nullptr, nullptr);
528e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (!status) {
529e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      message.ReplyError(status.error());
530e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      return {};
531e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
532e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    return status.take();
533e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
534e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
5351f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  Status<void> OnPositive(Message& /*message*/, int test_value) {
5361f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka    if (test_value >= 0)
5371f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka      return {};
5381f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka    else
5391f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka      return ErrorStatus(EINVAL);
5401f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  }
5411f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka
542e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestService(const TestService&) = delete;
543e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void operator=(const TestService&) = delete;
544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
545e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
546e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}  // anonymous namespace
547e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
548e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Use a test fixture to ensure proper order of cleanup between clients,
549e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// services, and the dispatcher. As these objects are cleaned up in the same
550e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// thread, either the service or client must be destroyed before stopping the
551e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// dispatcher. The reason for this is that clients send blocking "close"
552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// messages to their respective services on destruction. If this happens after
553e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// stopping the dispatcher the client destructor will get blocked waiting for a
554e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// reply that will never come. In normal use of the service framework this is
555e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// never an issue because clients and the dispatcher for the same service are
556e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// never destructed in the same thread (they live in different processes).
557e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass RemoteMethodTest : public ::testing::Test {
558e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko protected:
559e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::unique_ptr<ServiceDispatcher> dispatcher_;
560e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::thread dispatch_thread_;
561e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
562e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void SetUp() override {
563e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Create a dispatcher to handle messages to services.
564e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    dispatcher_ = android::pdx::uds::ServiceDispatcher::Create();
565e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    ASSERT_NE(nullptr, dispatcher_);
566e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
567e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    // Start the message dispatch loop in a separate thread.
568e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    dispatch_thread_ = std::thread(
569e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko        std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get()));
570e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
571e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
572e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  void TearDown() override {
573e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    if (dispatcher_) {
574e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      // Cancel the dispatcher and wait for the thread to terminate.
575e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      // Explicitly
576e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      // join the thread so that destruction doesn't deallocate the
577e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      // dispatcher
578e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      // before the thread finishes.
579e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      dispatcher_->SetCanceled(true);
580e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      dispatch_thread_.join();
581e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    }
582e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  }
583e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko};
584e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
585e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Test basic operation of TestService/TestClient classes.
586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(RemoteMethodTest, BasicClientService) {
587e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a test service and add it to the dispatcher.
588e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
589e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto service = TestService::Create();
590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, service);
591e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_EQ(0, dispatcher_->AddService(service));
592e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
593e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a client to service.
594e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto client = TestClient::Create();
595e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, client);
596e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
597e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const int sum = client->Add(10, 25);
598e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_GE(35, sum);
599e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
600e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto cat = client->Concatenate("This is a string", ", that it is.");
601e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ("This is a string, that it is.", cat);
602e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
6031f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
6041f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  const auto rot13_alphabet = client->Rot13(alphabet);
6051f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  EXPECT_EQ(Rot13(alphabet), rot13_alphabet);
6061f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka
607e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto length = client->Foo(10, "123");
608e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(13, length);
609e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
610e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const std::vector<int> vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
611e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const int vector_sum = client->SumVector(vector.data(), vector.size());
612e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const int vector_sum2 = client->SumVector(vector);
613e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(std::accumulate(vector.begin(), vector.end(), 0), vector_sum);
614e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(std::accumulate(vector.begin(), vector.end(), 0), vector_sum2);
615e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
616e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto string_length1 = client->StringLength("This is a string");
617e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(16, string_length1);
618e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
619e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto string_length2 = client->StringLength("1234567890");
620e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(10, string_length2);
621e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
622e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::string string = "1234567890";
623e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto string_length3 =
624e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      client->StringLength(string.c_str(), string.length());
625e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(10, string_length3);
626e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
627e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestType tt{10, 0.0, "string"};
628e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const auto tt_result = client->SendTestType(tt);
629e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(TestType(30, -2.0, "stringfoo"), tt_result);
630e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
631e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::vector<TestType> ttv = {TestType(0, 0.0, "abc"),
632e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                               TestType(0, 0.0, "123")};
633e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const std::string string_result = client->SendVector(ttv);
634e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ("abc123", string_result);
635e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
636e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const int int_result = client->NoArgs();
637e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(1, int_result);
638e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
639e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
640e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(RemoteMethodTest, LocalHandle) {
641e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a test service and add it to the dispatcher.
642e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto service = TestService::Create();
643e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, service);
644e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_EQ(0, dispatcher_->AddService(service));
645e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
646e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a client to service.
647e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto client = TestClient::Create();
648e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, client);
649e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
650e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  LocalHandle fd("/dev/zero", O_RDONLY);
651e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_TRUE(fd.IsValid());
652e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
653e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int fd_result = client->SendFile(fd);
654e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_LE(0, fd_result);
655e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_NE(fd.Get(), fd_result);
656e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  fd = LocalHandle(-3);
657e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  fd_result = client->SendFile(fd);
658e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(fd.Get(), fd_result);
659e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
660e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  fd = client->GetFile("/dev/zero", O_RDONLY);
661e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_TRUE(fd.IsValid()) << "Error code: " << fd.Get();
662e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
663e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::array<uint8_t, 10> buffer;
664e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  buffer.fill(1);
665e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(10, read(fd.Get(), buffer.data(), buffer.size()));
666e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(buffer, decltype(buffer){{0}});
667e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  fd.Close();
668e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
669e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const int error = client->GetFile("/dev/zero", O_RDONLY, &fd);
670e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(0, error);
671e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(fd.IsValid());
672e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
673e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  buffer.fill(1);
674e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(10, read(fd.Get(), buffer.data(), buffer.size()));
675e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(buffer, decltype(buffer){{0}});
676e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
677e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  /*
678e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    Seg fault.
679e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    fd = client->GetFile("/dev/foobar", O_RDONLY);
680e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    EXPECT_FALSE(fd.IsValid());
681e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko   */
682e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
683e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
684e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(RemoteMethodTest, PushChannel) {
685e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a test service and add it to the dispatcher.
686e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto service = TestService::Create();
687e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, service);
688e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_EQ(0, dispatcher_->AddService(service));
689e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
690e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a client to service.
691e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto client = TestClient::Create();
692e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, client);
693e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
694e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Get a new channel as an fd.
695e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  LocalChannelHandle channel;
696e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const int ret = client->PushChannel(&channel);
697e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(0, ret);
698e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(channel.valid());
699e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
700e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a new client from the channel.
701e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto client2 = TestClient::Create(std::move(channel));
702e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, client2);
703e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
704e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Test that the new channel works.
705e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const int sum = client2->Add(10, 25);
706e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_GE(35, sum);
707e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
708e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
7091f8fa907745eddeaa0220355a6c115793158e68cCorey TabakaTEST_F(RemoteMethodTest, Positive) {
7101f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  // Create a test service and add it to the dispatcher.
7111f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  auto service = TestService::Create();
7121f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  ASSERT_NE(nullptr, service);
7131f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  ASSERT_EQ(0, dispatcher_->AddService(service));
7141f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka
7151f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  // Create a client to service.
7161f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  auto client = TestClient::Create();
7171f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  ASSERT_NE(nullptr, client);
7181f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka
7191f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  ASSERT_TRUE(client->Positive(0));
7201f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  ASSERT_TRUE(client->Positive(1));
7211f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka  ASSERT_FALSE(client->Positive(-1));
7221f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka}
7231f8fa907745eddeaa0220355a6c115793158e68cCorey Tabaka
724e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(RemoteMethodTest, AggregateLocalHandle) {
725e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a test service and add it to the dispatcher.
726e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto service = TestService::Create();
727e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, service);
728e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_EQ(0, dispatcher_->AddService(service));
729e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
730e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a client to service.
731e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto client = TestClient::Create();
732e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, client);
733e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
734e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  TestFdType result = client->GetTestFdType(10, "/dev/zero", O_RDONLY);
735e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(result.fd.IsValid());
736e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(10, result.a);
737e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
738e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::vector<LocalHandle> files =
739e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      client->OpenFiles({{{"/dev/zero", O_RDONLY},
740e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                          {"/dev/null", O_WRONLY},
741e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                          {"/dev/zero", O_RDONLY}}});
742e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_EQ(3u, files.size());
743e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(files[0].IsValid());
744e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(files[1].IsValid());
745e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(files[2].IsValid());
746e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
747e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
748e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(RemoteMethodTest, BufferWrapper) {
749e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a test service and add it to the dispatcher.
750e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto service = TestService::Create();
751e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, service);
752e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_EQ(0, dispatcher_->AddService(service));
753e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
754e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Create a client to service.
755e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  auto client = TestClient::Create();
756e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  ASSERT_NE(nullptr, client);
757e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
758e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  const int buffer_size = 20;
759e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::vector<std::uint8_t> buffer(buffer_size, 'x');
760e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  std::vector<std::uint8_t> expected(buffer_size, 0);
761e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  int ret =
762e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      client->ReadFile(buffer.data(), buffer.size(), "/dev/zero", O_RDONLY);
763e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(buffer_size, ret);
764e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(expected, buffer);
765e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
766e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
767e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//
768e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// RemoteMethodFramework: Tests the type-based framework that remote method
769e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// support is built upon.
770e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko//
771e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
772e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Test logical And template.
773e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST(RemoteMethodFramework, And) {
774e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((And<std::true_type, std::true_type>::value));
775e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((And<std::true_type, std::false_type>::value));
776e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((And<std::false_type, std::true_type>::value));
777e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((And<std::false_type, std::false_type>::value));
778e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
779e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((And<std::true_type, std::true_type, std::true_type>::value));
780e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((And<std::true_type, std::true_type, std::false_type>::value));
781e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((And<std::true_type, std::false_type, std::true_type>::value));
782e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((And<std::true_type, std::false_type, std::false_type>::value));
783e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((And<std::false_type, std::true_type, std::true_type>::value));
784e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((And<std::false_type, std::true_type, std::false_type>::value));
785e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((And<std::false_type, std::false_type, std::true_type>::value));
786e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((And<std::false_type, std::false_type, std::false_type>::value));
787e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
788e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
789e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Test convertible type constraints.
790e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST(RemoteMethodFramework, IsConvertible) {
791e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // std::pair.
792e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(
793e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::pair<int, float>, std::pair<int, float>>::value));
794e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
795e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::pair<int, float>, std::pair<float, float>>::value));
796e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
797e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::pair<int, float>, std::pair<float, int>>::value));
798e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
799e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Nested std::pair.
800e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<std::pair<std::pair<int, float>, float>,
801e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             std::pair<std::pair<int, float>, float>>::value));
802e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::pair<std::pair<int, float>, float>,
803e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::pair<std::pair<float, int>, float>>::value));
804e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
805e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // std::tuple and std::pair.
806e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(
807e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::pair<int, float>, std::tuple<int, float>>::value));
808e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(
809e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::tuple<int, float>, std::pair<int, float>>::value));
810e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
811e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::pair<float, float>, std::tuple<int, float>>::value));
812e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
813e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::tuple<float, float>, std::pair<int, float>>::value));
814e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
815e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::pair<int, int>, std::tuple<int, float>>::value));
816e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
817e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::tuple<int, int>, std::pair<int, float>>::value));
818e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
819e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::pair<int, int>, std::tuple<int, int, int>>::value));
820e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
821e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::tuple<int, int, int>, std::pair<int, int>>::value));
822e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
823e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // std::vector.
824e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<std::vector<int>, std::vector<int>>::value));
825e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::vector<int>, std::vector<float>>::value));
826e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
827e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Nested std::vector.
828e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<std::vector<std::pair<int, int>>,
829e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             std::vector<std::pair<int, int>>>::value));
830e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>,
831e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::vector<std::pair<int, float>>>::value));
832e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>,
833e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::vector<std::pair<float, int>>>::value));
834e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>,
835e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::vector<std::pair<float, float>>>::value));
836e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
837e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // std::vector with nested convertible types.
838e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<std::vector<StringWrapper<char>>,
839e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             std::vector<std::string>>::value));
840e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
841e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // std::map and std::unordered_map.
842e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<std::map<int, float>,
843e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             std::unordered_map<int, float>>::value));
844e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::map<float, float>,
845e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::unordered_map<int, float>>::value));
846e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::map<float, float>,
847e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::unordered_map<float, int>>::value));
848e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::map<float, float>,
849e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::unordered_map<int, int>>::value));
850e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<std::unordered_map<int, float>,
851e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             std::map<int, float>>::value));
852e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>,
853e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::map<int, float>>::value));
854e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>,
855e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::map<float, int>>::value));
856e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>,
857e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::map<int, int>>::value));
858e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
859e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // std::map with nested convertible types.
860e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<std::map<int, std::string>,
861e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             std::map<int, StringWrapper<char>>>::value));
862e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(
863e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::map<std::tuple<int, int>, std::string>,
864e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     std::map<std::pair<int, int>, std::string>>::value));
865e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
866e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // std::unordered_map with nested convertible types.
867e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(
868e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<std::unordered_map<int, std::string>,
869e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                     std::unordered_map<int, StringWrapper<char>>>::value));
870e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<
871e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               std::unordered_map<std::tuple<int, int>, std::string>,
872e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko               std::unordered_map<std::pair<int, int>, std::string>>::value));
873e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
874e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // std::string.
875e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<std::string, std::string>::value));
876e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::string, int>::value));
877e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<int, std::string>::value));
878e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
879e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Nested std::string.
880e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<std::pair<std::string, std::string>,
881e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             std::pair<std::string, std::string>>::value));
882e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>,
883e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::pair<std::string, int>>::value));
884e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>,
885e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::pair<int, std::string>>::value));
886e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>,
887e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              std::pair<int, int>>::value));
888e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
889e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // StringWrapper.
890e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<StringWrapper<char>, StringWrapper<char>>::value));
891e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<StringWrapper<char>, std::string>::value));
892e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<std::string, StringWrapper<char>>::value));
893e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<StringWrapper<char>, int>::value));
894e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
895e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<StringWrapper<char>, BufferWrapper<char*>>::value));
896e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
897e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // BufferWrapper.
898e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(
899e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<BufferWrapper<char*>, BufferWrapper<char*>>::value));
900e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(
901e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<BufferWrapper<char*>, BufferWrapper<const char*>>::value));
902e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
903e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      (IsConvertible<BufferWrapper<char*>, BufferWrapper<int*>>::value));
904e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<BufferWrapper<char*>,
905e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             BufferWrapper<std::vector<char>>>::value));
906e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
907e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // RemoteHandle and BorrowedHandle.
908e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<LocalHandle, RemoteHandle>::value));
909e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<LocalHandle, BorrowedHandle>::value));
910e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
911e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // Test rewriting user defined types.
912e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<TestTemplateType<LocalHandle>,
913e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             TestTemplateType<RemoteHandle>>::value));
914e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE((IsConvertible<TestTemplateType<LocalHandle>,
915e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                             TestTemplateType<BorrowedHandle>>::value));
916e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<TestTemplateType<RemoteHandle>,
917e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              TestTemplateType<LocalHandle>>::value));
918e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE((IsConvertible<TestTemplateType<BorrowedHandle>,
919e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                              TestTemplateType<LocalHandle>>::value));
920e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
921e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  // TODO(eieio): More thorough testing of convertible types.
922e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
923e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
924e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST(RemoteMethodFramework, SerializableMembers) {
925e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<LocalHandle>>::value);
926e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<RemoteHandle>>::value);
927e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<BorrowedHandle>>::value);
928e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
929e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers<
930e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                  TestTemplateType<LocalHandle>>>::value);
931e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers<
932e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                  TestTemplateType<RemoteHandle>>>::value);
933e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers<
934e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko                  TestTemplateType<BorrowedHandle>>>::value);
935e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
936e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(HasSerializableMembers<DerivedTestType>::value);
937e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
938e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(HasSerializableMembers<BasicStruct>::value);
939e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(HasSerializableMembers<TestType>::value);
940e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<LocalHandle>>::value);
941e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<RemoteHandle>>::value);
942e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<BorrowedHandle>>::value);
943e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_TRUE(HasSerializableMembers<DerivedTestType>::value);
944e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(HasSerializableMembers<NonSerializableType>::value);
945e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_FALSE(
946e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko      HasSerializableMembers<IncorrectlyDefinedSerializableType>::value);
947e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
948e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
949e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST(RemoteMethodFramework, RemoteAPITypes) {
950e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko  EXPECT_EQ(0u, TestInterface::API::MethodIndex<TestInterface::Add>());
951e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}
952