SlideShare a Scribd company logo
1 of 26
Dive into
Fuchsia IPC
Mechanism
Objectives
 FIDL overview
 Async Event Loop
 Connect to server
 IPC process
 Async call vs Sync call
 Fuchsia IPC vs Android IPC
FIDL overview
 FIDL (Fuchsia Interface Definition Language) is the IPC system for
Fuchsia.
 Why use FIDL (https://fuchsia.dev/fuchsia-src/concepts/fidl/overview#why_use_fidl)
“Fuchsia extensively relies on IPC since it has a microkernel
architecture wherein most functionality is implemented in user
space outside of the kernel, including privileged components such as
device drivers.”
 FIDL library
 The FIDL library is defined in a separate .fidl file.
 Example: //fuchsia/examples/fidl/fuchsia.examples/echo.fidl
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library fuchsia.examples;
const uint64 MAX_STRING_LENGTH = 32;
[Discoverable]
protocol Echo {
EchoString(string:MAX_STRING_LENGTH value) -> (string:MAX_STRING_LENGTH
response);
SendString(string:MAX_STRING_LENGTH value);
-> OnString(string:MAX_STRING_LENGTH response);
}
};
 Create a GN target for the FIDL library
 define a target for the FIDL library that other code can depend on.
 Example: //fuchsia/examples/fidl/fuchsia.examples/BUILD.gn
# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Import the fidl GN template.
import("//build/fidl/fidl.gni")
# Define a target for our FIDL library by passing it the FIDL source files
# that make up the library.
fidl("fuchsia.examples") {
sources = [
"echo.fidl",
"types.fidl",
]
}
 Compile FIDL
$ fx set core.x64 --with //examples/fidl/fuchsia.examples
$ fx build examples/fidl/fuchsia.examples
After fx build command to build the .fidl file and to check for syntax
errors, the real c/c++ interface is generated in the folder:
out/default/fidling/gen/examples/fidl/fuchsia.examples/fuchsia/examp
les/
…
Echo_Proxy::Echo_Proxy(::fidl::internal::ProxyController* controller)
: controller_(controller) {
(void)controller_;
}
void Echo_Proxy::EchoString(::std::string value, EchoStringCallback callback)
{
::fidl::Encoder _encoder(internal::kEcho_EchoString_Ordinal);
controller_->Send(&fuchsia_examples_EchoEchoStringRequestTable,
Echo_RequestEncoder::EchoString(&_encoder, &value),
Echo_EchoString_ResponseHandler(std::move(callback)));
}
void Echo_Proxy::SendString(::std::string value) {
::fidl::Encoder _encoder(internal::kEcho_SendString_Ordinal);
controller_->Send(&fuchsia_examples_EchoSendStringRequestTable,
Echo_RequestEncoder::SendString(&_encoder, &value),
nullptr);
}
Echo_Stub::Echo_Stub(Echo_clazz* impl) : impl_(impl) { (void)impl_; }
…
zx_status_t Echo_Stub::Dispatch_(::fidl::Message message,
::fidl::internal::PendingResponse response)
{
bool needs_response;
const fidl_type_t* request_type =
Echo_RequestDecoder::GetType(message.ordinal(), &needs_response);
if (request_type == nullptr) {
return ZX_ERR_NOT_SUPPORTED;
}
if (response.needs_response() != needs_response) {
if (needs_response) {
FIDL_REPORT_DECODING_ERROR(message, request_type,
"Message needing a response with no txid");
} else {
FIDL_REPORT_DECODING_ERROR(message, request_type,
"Message not needing a response with a
txid");
}
return ZX_ERR_INVALID_ARGS;
}
const char* error_msg = nullptr;
zx_status_t status = message.Decode(request_type, &error_msg);
if (status != ZX_OK) {
FIDL_REPORT_DECODING_ERROR(message, request_type, error_msg);
return status;
}
uint64_t ordinal = message.ordinal();
switch (ordinal) {
case internal::kEcho_EchoString_Ordinal: {
::fidl::Decoder decoder(std::move(message));
impl_->EchoString(::fidl::DecodeAs<::std::string>(&decoder, 16),
Echo_EchoString_Responder(std::move(response)));
break;
}
case internal::kEcho_SendString_Ordinal: {
::fidl::Decoder decoder(std::move(message));
impl_->SendString(::fidl::DecodeAs<::std::string>(&decoder, 16));
break;
}
default: {
status = ZX_ERR_NOT_SUPPORTED;
break;
}
}
return status;
}
……
Async Event Loop
 The use of an async loop
Both server side and client side need to initialize the async loop and
registers it as the default dispatcher for the current thread. After the
loop initialization, it should run the loop to wait the signal and
data.( https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/hlcpp/multiple_clients/)
int main(int argc, const char** argv) {
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
…
return loop.Run();
}
 Main Related classes and libraries
 loop.c (/zircon/system/ulib/async-loop)
 libasync (/zircon/system/ulib/async)
 Loop initialization
 async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread) is used for
initializing the loop and registering it as the default dispatcher for
the current thread.
 invoke async_loop_create(…) in loop.c to initialize the loop and some
related lists.
 port object is created via zx_port_create(…) in aync_loop_create
function.
 async_loop_ops supports message loop, irq and vmo.
 Loop run
 loop.Run() is used for running the loop to wait package data.
 invoke async_loop_run(loop,…) in loop.c.
 invoke the blocking call zx_port_wait(loop->port, deadline, &packet) to
wait signal and packet data.
 Once some signal happens, async_loop_dispatch_xxx() is invoked
according to the packet type. Different CallHandler() function is
invoked in async_loop_dispatch_xxx() function. (xxx can be wait,
irq and paged_vmo, etc.) We will take the function
async_loop_dispatch_wait() for an example.
 Another way to investigate the loop
Connect to server
 client needs to be connected to the server before sending
request.
 To demonstrate the process of how the client is connected to the
server, fuchsia gives us some examples in the project:
Client project:
/examples/fidl/hlcpp/multiple_clients/client
Server project:
/examples/fidl/hlcpp/multiple_clients/server
 Client side(/examples/fidl/hlcpp/multiple_clients/client/main.cc)
int main(int argc, const char** argv) {
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
…
fuchsia::examples::EchoPtr echo_proxy;
auto context = sys::ComponentContext::Create();
context->svc()->Connect(echo_proxy.NewRequest());
…
loop.Run();
}
● The echo_proxy is actually the InterfacePtr<Echo> type.
● Mechanism beneath the code
echo_proxy.NewRequest()invokes zx::channel::create() create a channel between
the clientand the server
echo_proxy.NewRequest() also invokes Bind() which will call zx_object_wait_async()
to designate the port and channel to be used.
echo_proxy.NewRequest()will return a InterfaceRequest<Interface>
Connect(fidl::InterfaceRequest<Interface> request) sends the InterfaceRequest via kernel.
 Server side(/examples/fidl/hlcpp/multiple_clients/server/main.cc)
● To support multiple clients, server has to keep track of multiple
fidl::Bindings (one for each client) using a fidl::BindingSet.
● The binding set has a GetHandler method which creates a new
Binding and stores it in the vector bindings.
// [START main]
int main(int argc, const char** argv) {
…
EchoImpl impl;
fidl::BindingSet<fuchsia::examples::Echo> bindings;
auto context = sys::ComponentContext::CreateAndServeOutgoingDirectory();
context->outgoing()->AddPublicService(bindings.GetHandler(&impl));
…
}
// [END main]
● Mechanism beneath the code
● The implementation of GetHandler method is a lambda
expression, which means when a new client tries to connect
the service, it will invoke AddBinding method.
/*
https://fuchsia.googlesource.com/fuchsia/+/master/sdk/lib/fidl/cpp/binding_set.h
*/
InterfaceRequestHandler<Interface> GetHandler(ImplPtr impl,
async_dispatcher_t*
dispatcher = nullptr) {
return [this, impl, dispatcher](InterfaceRequest<Interface> request) {
AddBinding(impl, std::move(request), dispatcher);
};
}
● The AddBinding method creates a new Binding, and push the
new Binding Object into the vector fidl::BindingSet.
/*
https://fuchsia.googlesource.com/fuchsia/+/master/sdk/lib/fidl/cpp/binding_set.h
*/
void AddBinding(ImplPtr impl, InterfaceRequest<Interface> request,
async_dispatcher_t* dispatcher = nullptr, ErrorHandler
handler = nullptr) {
bindings_.push_back(
std::make_unique<Binding>(std::forward<ImplPtr>(impl),
std::move(request), dispatcher));
auto* binding = bindings_.back().get();
…
}
● This AddBinding method creates a new Binding object with
the Binding constructor.
/*
https://fuchsia.googlesource.com/fuchsia/+/master/sdk/lib/fidl/cpp/binding.h
*/
Binding(ImplPtr impl, InterfaceRequest<Interface> request,
async_dispatcher_t* dispatcher = nullptr)
: Binding(std::forward<ImplPtr>(impl)) {
Bind(request.TakeChannel(), dispatcher);
}
● In the Binding constructor, it extracts the channel which is
created by client via request.TakeChannle() method.
● The Binding constructor finally calls zx_object_wait_async() to
designate the port and channel to be used .
IPC process
● Server must implement the fidl protocol
first.( /examples/fidl/hlcpp/multiple_clients/server/main.cc)
/*https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/hlcpp/multiple_clients/server
/main.cc
*/
class EchoImpl : public fuchsia::examples::Echo {
public:
void EchoString(std::string value, EchoStringCallback callback) override
{ callback(value); }
void SendString(std::string value) override {
…
}
fuchsia::examples::Echo_EventSender* event_sender_;
}
● The class EchoImpl subclasses the generated protocol class
fuchsia::examples::Echo and implement the virtual methods in the
protocol Echo.
● The Implementation for the method EchoString replies with the
request value by calling the callback on it.
● The implementation of the method SendString does not have a
response. It sends an event using the Echo_EventSender instead.
● In the main function, server needs to initialize the Binding after the
loop initialization.
/*
https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/hlcpp/multiple_clients/server/m
ain.cc
*/
int main(int argc, const char** argv) {
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
EchoImpl impl;
fidl::BindingSet<fuchsia::examples::Echo> bindings;
auto context = sys::ComponentContext::CreateAndServeOutgoingDirectory();
context->outgoing()->AddPublicService(bindings.GetHandler(&impl));
…
return loop.Run();
}
 EchoImpl is ImplPtr<Echo> type
 When the InterfaceRequest comes, it will create a new Binding to
handle messages on the channel according to the Echo protocol.
During the construction of the new Binding, impl_ is EchoImpl
actually.
/*
https://fuchsia.googlesource.com/fuchsia/+/master/sdk/lib/fidl/cpp/binding.h
*/
explicit Binding(ImplPtr impl) : impl_(std::forward<ImplPtr>(impl)),
stub_(&*this->impl()) {
controller_.set_stub(&stub_);
stub_.set_sender(&controller_);
}
 Client uses the echo_proxy to send request.
/*
https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/hlcpp/client/main.cc
*/
echo_proxy->EchoString("hello", [&](std::string response) {
printf("Got response %sn", response.c_str());
…
}
});
 The generated proxy
Echo_Proxy(out/default/fidling/gen/examples/fidl/fuchsia.examples
/fuchsia/examples/cpp/fidl.cc) uses a callback to handle the
response by default for the method EchoString.
void Echo_Proxy::EchoString(::std::string value, EchoStringCallback
callback) {
::fidl::Encoder _encoder(internal::kEcho_EchoString_Ordinal);
controller_->Send(&fuchsia_examples_EchoEchoStringRequestTable,
Echo_RequestEncoder::EchoString(&_encoder, &value),
Echo_EchoString_ResponseHandler(std::move(callback)));
}
 controller is actually ProxyController type.
 the parameter value is converted into Message type via
Echo_RequestEncoder::EchoString method.
static ::fidl::Message EchoString(::fidl::Encoder* _encoder,
::fidl::StringPtr* value) {
_encoder->Alloc(32 - sizeof(fidl_message_header_t));
::fidl::Encode(_encoder, value, 16);
return _encoder->GetMessage();
}
 the callback will be converted into Echo_EchoString_ResponseHandler
type which is SingleUseMessageHandler type essentially.
::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
Echo_EchoString_ResponseHandler(Echo::EchoStringCallback callback) {
return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
[callback_ = std::move(callback)](::fidl::Message message) {
const char* error_msg = nullptr;
zx_status_t status = message.Decode(
&fidl_examples_routing_echo_EchoEchoStringResponseTable,
&error_msg);
…
});
}
 ProxyController uses message to write the message into the
channel via the system call zx_channel_write() which is provided by
libzircon.so.
Async client vs Sync client
/*
https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/fuchsia.examples/echo.test.fidl
*/
[Discoverable]
protocol Echo {
EchoString(string:MAX_STRING_LENGTH value) -> (string:MAX_STRING_LENGTH
response);
};
 after compiling the fidl library, there are two types of proxy
/out/default/fidling/gen/examples/fidl/fuchsia.examples/fuchsia/examples
 fuchsia::examples::EchoPtr (by default)
 ::fidl::InterfacePtr<Echo> type
 Async call or callback
 client sends a request to server, but it doesn't block to
wait the reply. The reply is returned asynchronously
later.
 fuchsia::examples::EchoSyncPtr
 ::fidl::SynchronousInterfacePtr<Echo> type
 Sync call or Blocking call
 client sends a request to server and waits for reply
from the server side.
 Sync call
If the client chooses sync call for the method EchoString, it doesn’t
need to initialize and run the message loop.
/*
https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/hlcpp/client_sync/main.cc
*/
int main(int argc, const char** argv) {
fuchsia::examples::EchoSyncPtr echo_proxy;
auto context = sys::ComponentContext::Create();
context->svc()->Connect(echo_proxy.NewRequest());
std::string response;
ZX_ASSERT(echo_proxy->EchoString("hello", &response) == ZX_OK);
printf("Got response: %sn", response.c_str());
…
return 0;
}
 Mechanism beneath the EchoSyncPtr
The call to EchoString will block until it receives a reply message from
the server. It will return a zx_status_t indicating the result of the
method call.
zx_status_t Echo_SyncProxy::EchoString(::std::string value,::std::string*
out_response) {
::fidl::Encoder _encoder(internal::kEcho_EchoString_Ordinal);
::fidl::MessageBuffer buffer_;
::fidl::Message response_ = buffer_.CreateEmptyMessage();
zx_status_t status_ = proxy_.Call(
&fuchsia_examples_EchoEchoStringRequestTable,
&fuchsia_examples_EchoEchoStringResponseTable,
Echo_RequestEncoder::EchoString(&_encoder, &value), &response_);
if (status_ != ZX_OK) return status_;
::fidl::Decoder decoder_(std::move(response_));
*out_response = ::fidl::DecodeAs<::std::string>(&decoder_, 16);
return ZX_OK;
}
/*
https://fuchsia.googlesource.com/fuchsia/+/master/sdk/lib/fidl/cpp/internal/synchronous_proxy.c
c
*/
zx_status_t SynchronousProxy::Call(const fidl_type_t* request_type,
const fidl_type_t* response_type, Message
request,
Message* response) {
const char* error_msg = nullptr;
zx_status_t status = request.Validate(request_type, &error_msg);
if (status != ZX_OK) {
FIDL_REPORT_ENCODING_ERROR(request, request_type, error_msg);
return status;
}
status = request.Call(channel_.get(), 0, ZX_TIME_INFINITE, response);
if (status != ZX_OK)
return status;
status = response->Decode(response_type, &error_msg);
if (status != ZX_OK) {
FIDL_REPORT_DECODING_ERROR(*response, response_type, error_msg);
return status;
}
return ZX_OK;
}
zx_channel_call() is like a combined zx_channel_write(),
zx_object_wait_one(), and zx_channel_read(), and it blocks until it
reads data from zx_channel_read().
/*
https://fuchsia.googlesource.com/fuchsia/+/master/zircon/system/ulib/fidl/message.cc
*/
zx_status_t Message::Call(zx_handle_t channel, uint32_t flags, zx_time_t
deadline,
Message* response) {
zx_channel_call_args_t args;
args.wr_bytes = bytes_.data();
args.wr_handles = handles_.data();
args.rd_bytes = response->bytes_.data();
args.rd_handles = response->handles_.data();
args.wr_num_bytes = bytes_.actual();
args.wr_num_handles = handles_.actual();
args.rd_num_bytes = response->bytes_.capacity();
args.rd_num_handles = response->handles_.capacity();
uint32_t actual_bytes = 0u;
uint32_t actual_handles = 0u;
zx_status_t status =
zx_channel_call(channel, flags, deadline, &args, &actual_bytes,
&actual_handles);
ClearHandlesUnsafe();
if (status == ZX_OK) {
response->bytes_.set_actual(actual_bytes);
response->handles_.set_actual(actual_handles);
}
return status;
}
Fuchsia IPC vs Android IPC
 Interface
 AIDL
interface IMyAidlInterface {
void test1(int p1);
void test2(int p1, int p2);
}
 FIDL
/*
https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/fuchsia.examples/echo.test.fidl
*/
[Discoverable]
protocol Echo {
EchoString(string:MAX_STRING_LENGTH value)
-> (string:MAX_STRING_LENGTH response);
SendString(string:MAX_STRING_LENGTH value);
-> OnString(string:MAX_STRING_LENGTH response);
};
 IPC (Client)
 Android
The transact method is blocking call. The IBinder object
mRemote sends the Parcel object data and the code
Stub.TRANSACTION_test1 into Binder Driver and wait until the
Parcel object reply returns.
@Override public void test1(int p1) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(p1);
boolean _status = mRemote.transact(Stub.TRANSACTION_test1, _data,
_reply, 0);
…
_reply.readException();
}…
}
 Fuchsia
By default, it’s an async call. The ProxyController controller
will send the code kEcho_SendString_Ordinal and message into
channel, and then returns. The callback will return the
response.
void Echo_Proxy::EchoString(::fidl::StringPtr value,
EchoStringCallback callback) {
::fidl::Encoder _encoder(internal::kEcho_EchoString_GenOrdinal);
controller_->Send(&fidl_examples_routing_echo_EchoEchoStringRequestTable,
Echo_RequestEncoder::EchoString(&_encoder, &value),
Echo_EchoString_ResponseHandler(std::move(callback)));
}
 IPC (Server)
 Android
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel
reply, int flags) throws android.os.RemoteException
{…
switch (code)
{
case TRANSACTION_test1:
{
…
this.test1(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_test2:
{
…
this.test2(_arg0, _arg1);
reply.writeNoException();
return true;
}
 Fuchsia
zx_status_t Echo_Stub::Dispatch_(::fidl::Message message,
::fidl::internal::PendingResponse response)
{
…
uint64_t ordinal = message.ordinal();
switch (ordinal) {
case internal::kEcho_EchoString_Ordinal: {
::fidl::Decoder decoder(std::move(message));
impl_->EchoString(::fidl::DecodeAs<::std::string>(&decoder, 16),
Echo_EchoString_Responder(std::move(response)));
break;
}
case internal::kEcho_SendString_Ordinal: {
::fidl::Decoder decoder(std::move(message));
impl_->SendString(::fidl::DecodeAs<::std::string>(&decoder, 16));
break;
}…
}
 Message(Fuchsia) vs Parcel(Android)
 Message
[Discoverable]
protocol EchoTest {
EchoString(string:MAX_STRING_LENGTH value1,uint8
value2,string:MAX_STRING_LENGTH value3) ;
};
After fx build command, Fuchsia automatically generates
EchoString method which converts the input values into message.
The method id or ordinal number
internal::kEchoTest_EchoString_Ordinal is encapsulated into the
structure fidl_message_header_t which takes up 16 bytes.
static ::fidl::Message EchoString(::fidl::Encoder* _encoder,
::std::string* value1, uint8_t* value2,
::std::string* value3) {
_encoder->Alloc(56 - sizeof(fidl_message_header_t));
::fidl::Encode(_encoder, value1, 16);
::fidl::Encode(_encoder, value2, 32);
::fidl::Encode(_encoder, value3, 40);
return _encoder->GetMessage();
}
Main related classes :
/sdk/lib/fidl/cpp/encoder.cc
/sdk/lib/fidl/cpp/encoder.h
Message mainly has two parts: the method id and the basic data
type are put into the vector bytes_ , and the channel info is put into
the vector handles_.
std::vector<uint8_t> bytes_;
std::vector<zx_handle_t> handles_;
When encoding some handles, it needs to invoke EncodeHandle
method to save the handle’s value into the vector handles_.
 Parcel
/frameworks/native/libs/binder/Parcel.cpp
/frameworks/native/libs/binder/Parcel.h
@Override public void test1(int p1) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(p1);
boolean _status = mRemote.transact(Stub.TRANSACTION_test1,
_data, _reply, 0);
…
_reply.readException();
}…
}
The method id is not included in mData which is like bytes_ in
fuchsia.
When binder object or FileDescriptor needs to be parcelled, it needs
the vector mObjects to store offset of each flat_binder_object.
 Conclusion
Fuchsia Android
Interface Similar concept.
It provides method interface(s) to client.
Server needs to implement the method interface(s).
FIDL AIDL
defines virtual methods in Protocol defines virtual methods in Interface
Error Callback Client needs to register error callback
via set_error_handler method, error
message is not straightforward for
client.
Client doesn’t need to register error
callback, there is couples of callback
functions.
public void
onServiceConnected(ComponentName
className,IBinder service) { }
public void
onServiceDisconnected(ComponentN
ame arg0) { }
IPC call Both Fuchsia and Android adopt proxy/stub pattern.
Proxy sends the method id and parameter value to the stub.
Stub invoke the method implementation according to the method id.
Data is encapsulated during the transmission.
There are two types of call for client to
choose:
1.async call(by default), which means
client only needs to write the message
to the channel and then return.
2.sync call, which means client proxy
will wait until the server gives back the
response.
sync call(by default), which means
client proxy will wait until the server
gives back the response.
IPC data
encapsulation
Both Fuchsia and Android need to capsulate data in the proxy side and
decapsulate data in the stub side.
Encapsulation process is similar to each other.
Message Parcel
Method id is encapsulted into
message.
Method id is in
fidl_message_header_t.
Method id is not encapsulated into
parcel data.
Method id is taken by binder itself.
It first writes fidl_message_header_t
which is not InterfaceToken
It writes an InterfaceToken in the head
It allocates some fixed length space in
the head according to the type of
parameters.
Some parameter value (e.g., string) is
allocated after the fixed length space.
Parameter value is allocated one by
one.
InterfaceToken->param1->param2->…
It puts the value of handle(s) into the
vector handles_
It puts the offset of flat_binder_object
into the array mObjects
media Channel + port Binder
Language
supported
c/c++/Rust/Dart/Go Java/Kotlin

More Related Content

What's hot

Gerak pada tumbuhan SMP kelas 8
Gerak pada tumbuhan SMP kelas 8Gerak pada tumbuhan SMP kelas 8
Gerak pada tumbuhan SMP kelas 8Dian20121999
 
Ppt 1. gerak tumbuhan K13 by : Henie, S.Pd.
Ppt 1. gerak tumbuhan K13 by : Henie, S.Pd.Ppt 1. gerak tumbuhan K13 by : Henie, S.Pd.
Ppt 1. gerak tumbuhan K13 by : Henie, S.Pd.Henie Sondah
 
Past simple continuous
Past simple continuousPast simple continuous
Past simple continuousf2teacher
 
Ipa8 kd12-sifat cahaya dan proses pembentukan bayangan
Ipa8 kd12-sifat cahaya dan proses pembentukan bayanganIpa8 kd12-sifat cahaya dan proses pembentukan bayangan
Ipa8 kd12-sifat cahaya dan proses pembentukan bayanganSMPK Stella Maris
 
The Passive Causative
The Passive CausativeThe Passive Causative
The Passive CausativeJoyce Wilches
 
Ingilizce günlük konuşma
Ingilizce günlük konuşmaIngilizce günlük konuşma
Ingilizce günlük konuşmasctroasle
 
Pemetaan ki kd kelas xi kurikulum 2013
Pemetaan ki kd  kelas xi kurikulum 2013Pemetaan ki kd  kelas xi kurikulum 2013
Pemetaan ki kd kelas xi kurikulum 2013Jeny Hardiah
 

What's hot (8)

Gerak pada tumbuhan SMP kelas 8
Gerak pada tumbuhan SMP kelas 8Gerak pada tumbuhan SMP kelas 8
Gerak pada tumbuhan SMP kelas 8
 
Ppt 1. gerak tumbuhan K13 by : Henie, S.Pd.
Ppt 1. gerak tumbuhan K13 by : Henie, S.Pd.Ppt 1. gerak tumbuhan K13 by : Henie, S.Pd.
Ppt 1. gerak tumbuhan K13 by : Henie, S.Pd.
 
Past simple continuous
Past simple continuousPast simple continuous
Past simple continuous
 
Ipa8 kd12-sifat cahaya dan proses pembentukan bayangan
Ipa8 kd12-sifat cahaya dan proses pembentukan bayanganIpa8 kd12-sifat cahaya dan proses pembentukan bayangan
Ipa8 kd12-sifat cahaya dan proses pembentukan bayangan
 
The Passive Causative
The Passive CausativeThe Passive Causative
The Passive Causative
 
Stage 1 what i have done this year
Stage 1 what i have done this yearStage 1 what i have done this year
Stage 1 what i have done this year
 
Ingilizce günlük konuşma
Ingilizce günlük konuşmaIngilizce günlük konuşma
Ingilizce günlük konuşma
 
Pemetaan ki kd kelas xi kurikulum 2013
Pemetaan ki kd  kelas xi kurikulum 2013Pemetaan ki kd  kelas xi kurikulum 2013
Pemetaan ki kd kelas xi kurikulum 2013
 

Similar to Fidl analysis

神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)guregu
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
Symfony2 for Midgard Developers
Symfony2 for Midgard DevelopersSymfony2 for Midgard Developers
Symfony2 for Midgard DevelopersHenri Bergius
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSPVS-Studio
 
CODE FOR echo_client.c A simple echo client using TCP #inc.pdf
CODE FOR echo_client.c A simple echo client using TCP  #inc.pdfCODE FOR echo_client.c A simple echo client using TCP  #inc.pdf
CODE FOR echo_client.c A simple echo client using TCP #inc.pdfsecunderbadtirumalgi
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in GeckoChih-Hsuan Kuo
 
How we sleep well at night using Hystrix at Finn.no
How we sleep well at night using Hystrix at Finn.noHow we sleep well at night using Hystrix at Finn.no
How we sleep well at night using Hystrix at Finn.noHenning Spjelkavik
 
Finagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestFinagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestPavan Chitumalla
 
Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)dantleech
 
Build resource server &amp; client for OCF Cloud (2018.8.30)
Build resource server &amp; client for OCF Cloud (2018.8.30)Build resource server &amp; client for OCF Cloud (2018.8.30)
Build resource server &amp; client for OCF Cloud (2018.8.30)남균 김
 
JSR 82 (bluetooth obex)
JSR 82 (bluetooth obex)JSR 82 (bluetooth obex)
JSR 82 (bluetooth obex)SMIJava
 
Maxbox starter18
Maxbox starter18Maxbox starter18
Maxbox starter18Max Kleiner
 
Web Server and how we can design app in C#
Web Server and how we can design app  in C#Web Server and how we can design app  in C#
Web Server and how we can design app in C#caohansnnuedu
 

Similar to Fidl analysis (20)

PPT
PPTPPT
PPT
 
Php client libray
Php client librayPhp client libray
Php client libray
 
神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
Symfony2 for Midgard Developers
Symfony2 for Midgard DevelopersSymfony2 for Midgard Developers
Symfony2 for Midgard Developers
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMS
 
CODE FOR echo_client.c A simple echo client using TCP #inc.pdf
CODE FOR echo_client.c A simple echo client using TCP  #inc.pdfCODE FOR echo_client.c A simple echo client using TCP  #inc.pdf
CODE FOR echo_client.c A simple echo client using TCP #inc.pdf
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in Gecko
 
How we sleep well at night using Hystrix at Finn.no
How we sleep well at night using Hystrix at Finn.noHow we sleep well at night using Hystrix at Finn.no
How we sleep well at night using Hystrix at Finn.no
 
gRPC in Go
gRPC in GogRPC in Go
gRPC in Go
 
Finagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at PinterestFinagle and Java Service Framework at Pinterest
Finagle and Java Service Framework at Pinterest
 
Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)
 
Build resource server &amp; client for OCF Cloud (2018.8.30)
Build resource server &amp; client for OCF Cloud (2018.8.30)Build resource server &amp; client for OCF Cloud (2018.8.30)
Build resource server &amp; client for OCF Cloud (2018.8.30)
 
JSR 82 (bluetooth obex)
JSR 82 (bluetooth obex)JSR 82 (bluetooth obex)
JSR 82 (bluetooth obex)
 
Maxbox starter18
Maxbox starter18Maxbox starter18
Maxbox starter18
 
Python, do you even async?
Python, do you even async?Python, do you even async?
Python, do you even async?
 
Python networking
Python networkingPython networking
Python networking
 
Socket System Calls
Socket System CallsSocket System Calls
Socket System Calls
 
Web Server and how we can design app in C#
Web Server and how we can design app  in C#Web Server and how we can design app  in C#
Web Server and how we can design app in C#
 
Hack ASP.NET website
Hack ASP.NET websiteHack ASP.NET website
Hack ASP.NET website
 

More from TekObserver

Phone companion test
Phone companion testPhone companion test
Phone companion testTekObserver
 
X plat dev - part ii publish
X plat dev - part ii publishX plat dev - part ii publish
X plat dev - part ii publishTekObserver
 
X-Plat Development
X-Plat DevelopmentX-Plat Development
X-Plat DevelopmentTekObserver
 
Voice assistant use cases (in car) & smart kitchen - publish
Voice assistant use cases (in car) & smart kitchen - publishVoice assistant use cases (in car) & smart kitchen - publish
Voice assistant use cases (in car) & smart kitchen - publishTekObserver
 
Voice Assistant Use Cases Analysis
Voice Assistant Use Cases AnalysisVoice Assistant Use Cases Analysis
Voice Assistant Use Cases AnalysisTekObserver
 
X-Device Service Discovery
X-Device Service DiscoveryX-Device Service Discovery
X-Device Service DiscoveryTekObserver
 

More from TekObserver (9)

CHI2021
CHI2021CHI2021
CHI2021
 
Phone companion test
Phone companion testPhone companion test
Phone companion test
 
X plat dev - part ii publish
X plat dev - part ii publishX plat dev - part ii publish
X plat dev - part ii publish
 
X-Plat Development
X-Plat DevelopmentX-Plat Development
X-Plat Development
 
What next
What nextWhat next
What next
 
WWDC 2020
WWDC 2020WWDC 2020
WWDC 2020
 
Voice assistant use cases (in car) & smart kitchen - publish
Voice assistant use cases (in car) & smart kitchen - publishVoice assistant use cases (in car) & smart kitchen - publish
Voice assistant use cases (in car) & smart kitchen - publish
 
Voice Assistant Use Cases Analysis
Voice Assistant Use Cases AnalysisVoice Assistant Use Cases Analysis
Voice Assistant Use Cases Analysis
 
X-Device Service Discovery
X-Device Service DiscoveryX-Device Service Discovery
X-Device Service Discovery
 

Recently uploaded

Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
buds n tech IT solutions
buds n  tech IT                solutionsbuds n  tech IT                solutions
buds n tech IT solutionsmonugehlot87
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsMehedi Hasan Shohan
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
cybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningcybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningVitsRangannavar
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 

Recently uploaded (20)

Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
buds n tech IT solutions
buds n  tech IT                solutionsbuds n  tech IT                solutions
buds n tech IT solutions
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software Solutions
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
 
cybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningcybersecurity notes for mca students for learning
cybersecurity notes for mca students for learning
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 

Fidl analysis

  • 2. Objectives  FIDL overview  Async Event Loop  Connect to server  IPC process  Async call vs Sync call  Fuchsia IPC vs Android IPC
  • 3. FIDL overview  FIDL (Fuchsia Interface Definition Language) is the IPC system for Fuchsia.  Why use FIDL (https://fuchsia.dev/fuchsia-src/concepts/fidl/overview#why_use_fidl) “Fuchsia extensively relies on IPC since it has a microkernel architecture wherein most functionality is implemented in user space outside of the kernel, including privileged components such as device drivers.”  FIDL library  The FIDL library is defined in a separate .fidl file.  Example: //fuchsia/examples/fidl/fuchsia.examples/echo.fidl // Copyright 2020 The Fuchsia Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. library fuchsia.examples; const uint64 MAX_STRING_LENGTH = 32; [Discoverable] protocol Echo { EchoString(string:MAX_STRING_LENGTH value) -> (string:MAX_STRING_LENGTH response); SendString(string:MAX_STRING_LENGTH value); -> OnString(string:MAX_STRING_LENGTH response); } };  Create a GN target for the FIDL library  define a target for the FIDL library that other code can depend on.  Example: //fuchsia/examples/fidl/fuchsia.examples/BUILD.gn # Copyright 2020 The Fuchsia Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # Import the fidl GN template. import("//build/fidl/fidl.gni") # Define a target for our FIDL library by passing it the FIDL source files # that make up the library. fidl("fuchsia.examples") {
  • 4. sources = [ "echo.fidl", "types.fidl", ] }  Compile FIDL $ fx set core.x64 --with //examples/fidl/fuchsia.examples $ fx build examples/fidl/fuchsia.examples After fx build command to build the .fidl file and to check for syntax errors, the real c/c++ interface is generated in the folder: out/default/fidling/gen/examples/fidl/fuchsia.examples/fuchsia/examp les/ … Echo_Proxy::Echo_Proxy(::fidl::internal::ProxyController* controller) : controller_(controller) { (void)controller_; } void Echo_Proxy::EchoString(::std::string value, EchoStringCallback callback) { ::fidl::Encoder _encoder(internal::kEcho_EchoString_Ordinal); controller_->Send(&fuchsia_examples_EchoEchoStringRequestTable, Echo_RequestEncoder::EchoString(&_encoder, &value), Echo_EchoString_ResponseHandler(std::move(callback))); } void Echo_Proxy::SendString(::std::string value) { ::fidl::Encoder _encoder(internal::kEcho_SendString_Ordinal); controller_->Send(&fuchsia_examples_EchoSendStringRequestTable, Echo_RequestEncoder::SendString(&_encoder, &value), nullptr); } Echo_Stub::Echo_Stub(Echo_clazz* impl) : impl_(impl) { (void)impl_; } … zx_status_t Echo_Stub::Dispatch_(::fidl::Message message, ::fidl::internal::PendingResponse response) { bool needs_response; const fidl_type_t* request_type = Echo_RequestDecoder::GetType(message.ordinal(), &needs_response); if (request_type == nullptr) { return ZX_ERR_NOT_SUPPORTED; } if (response.needs_response() != needs_response) { if (needs_response) { FIDL_REPORT_DECODING_ERROR(message, request_type,
  • 5. "Message needing a response with no txid"); } else { FIDL_REPORT_DECODING_ERROR(message, request_type, "Message not needing a response with a txid"); } return ZX_ERR_INVALID_ARGS; } const char* error_msg = nullptr; zx_status_t status = message.Decode(request_type, &error_msg); if (status != ZX_OK) { FIDL_REPORT_DECODING_ERROR(message, request_type, error_msg); return status; } uint64_t ordinal = message.ordinal(); switch (ordinal) { case internal::kEcho_EchoString_Ordinal: { ::fidl::Decoder decoder(std::move(message)); impl_->EchoString(::fidl::DecodeAs<::std::string>(&decoder, 16), Echo_EchoString_Responder(std::move(response))); break; } case internal::kEcho_SendString_Ordinal: { ::fidl::Decoder decoder(std::move(message)); impl_->SendString(::fidl::DecodeAs<::std::string>(&decoder, 16)); break; } default: { status = ZX_ERR_NOT_SUPPORTED; break; } } return status; } ……
  • 6. Async Event Loop  The use of an async loop Both server side and client side need to initialize the async loop and registers it as the default dispatcher for the current thread. After the loop initialization, it should run the loop to wait the signal and data.( https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/hlcpp/multiple_clients/) int main(int argc, const char** argv) { async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread); … return loop.Run(); }  Main Related classes and libraries  loop.c (/zircon/system/ulib/async-loop)  libasync (/zircon/system/ulib/async)  Loop initialization  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread) is used for initializing the loop and registering it as the default dispatcher for the current thread.  invoke async_loop_create(…) in loop.c to initialize the loop and some related lists.  port object is created via zx_port_create(…) in aync_loop_create function.
  • 7.  async_loop_ops supports message loop, irq and vmo.  Loop run  loop.Run() is used for running the loop to wait package data.  invoke async_loop_run(loop,…) in loop.c.  invoke the blocking call zx_port_wait(loop->port, deadline, &packet) to wait signal and packet data.  Once some signal happens, async_loop_dispatch_xxx() is invoked according to the packet type. Different CallHandler() function is invoked in async_loop_dispatch_xxx() function. (xxx can be wait, irq and paged_vmo, etc.) We will take the function async_loop_dispatch_wait() for an example.
  • 8.
  • 9.  Another way to investigate the loop
  • 10. Connect to server  client needs to be connected to the server before sending request.  To demonstrate the process of how the client is connected to the server, fuchsia gives us some examples in the project: Client project: /examples/fidl/hlcpp/multiple_clients/client Server project: /examples/fidl/hlcpp/multiple_clients/server  Client side(/examples/fidl/hlcpp/multiple_clients/client/main.cc) int main(int argc, const char** argv) { async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread); … fuchsia::examples::EchoPtr echo_proxy; auto context = sys::ComponentContext::Create(); context->svc()->Connect(echo_proxy.NewRequest());
  • 11. … loop.Run(); } ● The echo_proxy is actually the InterfacePtr<Echo> type. ● Mechanism beneath the code echo_proxy.NewRequest()invokes zx::channel::create() create a channel between the clientand the server echo_proxy.NewRequest() also invokes Bind() which will call zx_object_wait_async() to designate the port and channel to be used. echo_proxy.NewRequest()will return a InterfaceRequest<Interface> Connect(fidl::InterfaceRequest<Interface> request) sends the InterfaceRequest via kernel.  Server side(/examples/fidl/hlcpp/multiple_clients/server/main.cc) ● To support multiple clients, server has to keep track of multiple fidl::Bindings (one for each client) using a fidl::BindingSet.
  • 12. ● The binding set has a GetHandler method which creates a new Binding and stores it in the vector bindings. // [START main] int main(int argc, const char** argv) { … EchoImpl impl; fidl::BindingSet<fuchsia::examples::Echo> bindings; auto context = sys::ComponentContext::CreateAndServeOutgoingDirectory(); context->outgoing()->AddPublicService(bindings.GetHandler(&impl)); … } // [END main] ● Mechanism beneath the code ● The implementation of GetHandler method is a lambda expression, which means when a new client tries to connect the service, it will invoke AddBinding method. /* https://fuchsia.googlesource.com/fuchsia/+/master/sdk/lib/fidl/cpp/binding_set.h */ InterfaceRequestHandler<Interface> GetHandler(ImplPtr impl, async_dispatcher_t* dispatcher = nullptr) { return [this, impl, dispatcher](InterfaceRequest<Interface> request) { AddBinding(impl, std::move(request), dispatcher); }; } ● The AddBinding method creates a new Binding, and push the new Binding Object into the vector fidl::BindingSet. /* https://fuchsia.googlesource.com/fuchsia/+/master/sdk/lib/fidl/cpp/binding_set.h */ void AddBinding(ImplPtr impl, InterfaceRequest<Interface> request, async_dispatcher_t* dispatcher = nullptr, ErrorHandler handler = nullptr) { bindings_.push_back( std::make_unique<Binding>(std::forward<ImplPtr>(impl), std::move(request), dispatcher)); auto* binding = bindings_.back().get(); … }
  • 13. ● This AddBinding method creates a new Binding object with the Binding constructor. /* https://fuchsia.googlesource.com/fuchsia/+/master/sdk/lib/fidl/cpp/binding.h */ Binding(ImplPtr impl, InterfaceRequest<Interface> request, async_dispatcher_t* dispatcher = nullptr) : Binding(std::forward<ImplPtr>(impl)) { Bind(request.TakeChannel(), dispatcher); } ● In the Binding constructor, it extracts the channel which is created by client via request.TakeChannle() method. ● The Binding constructor finally calls zx_object_wait_async() to designate the port and channel to be used .
  • 14. IPC process ● Server must implement the fidl protocol first.( /examples/fidl/hlcpp/multiple_clients/server/main.cc) /*https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/hlcpp/multiple_clients/server /main.cc */ class EchoImpl : public fuchsia::examples::Echo { public: void EchoString(std::string value, EchoStringCallback callback) override { callback(value); } void SendString(std::string value) override { … } fuchsia::examples::Echo_EventSender* event_sender_; } ● The class EchoImpl subclasses the generated protocol class fuchsia::examples::Echo and implement the virtual methods in the protocol Echo. ● The Implementation for the method EchoString replies with the request value by calling the callback on it.
  • 15. ● The implementation of the method SendString does not have a response. It sends an event using the Echo_EventSender instead. ● In the main function, server needs to initialize the Binding after the loop initialization. /* https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/hlcpp/multiple_clients/server/m ain.cc */ int main(int argc, const char** argv) { async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread); EchoImpl impl; fidl::BindingSet<fuchsia::examples::Echo> bindings; auto context = sys::ComponentContext::CreateAndServeOutgoingDirectory(); context->outgoing()->AddPublicService(bindings.GetHandler(&impl)); … return loop.Run(); }  EchoImpl is ImplPtr<Echo> type  When the InterfaceRequest comes, it will create a new Binding to handle messages on the channel according to the Echo protocol. During the construction of the new Binding, impl_ is EchoImpl actually. /* https://fuchsia.googlesource.com/fuchsia/+/master/sdk/lib/fidl/cpp/binding.h */ explicit Binding(ImplPtr impl) : impl_(std::forward<ImplPtr>(impl)), stub_(&*this->impl()) { controller_.set_stub(&stub_); stub_.set_sender(&controller_); }  Client uses the echo_proxy to send request. /* https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/hlcpp/client/main.cc */ echo_proxy->EchoString("hello", [&](std::string response) { printf("Got response %sn", response.c_str()); …
  • 16. } });  The generated proxy Echo_Proxy(out/default/fidling/gen/examples/fidl/fuchsia.examples /fuchsia/examples/cpp/fidl.cc) uses a callback to handle the response by default for the method EchoString. void Echo_Proxy::EchoString(::std::string value, EchoStringCallback callback) { ::fidl::Encoder _encoder(internal::kEcho_EchoString_Ordinal); controller_->Send(&fuchsia_examples_EchoEchoStringRequestTable, Echo_RequestEncoder::EchoString(&_encoder, &value), Echo_EchoString_ResponseHandler(std::move(callback))); }  controller is actually ProxyController type.  the parameter value is converted into Message type via Echo_RequestEncoder::EchoString method. static ::fidl::Message EchoString(::fidl::Encoder* _encoder, ::fidl::StringPtr* value) { _encoder->Alloc(32 - sizeof(fidl_message_header_t)); ::fidl::Encode(_encoder, value, 16); return _encoder->GetMessage(); }  the callback will be converted into Echo_EchoString_ResponseHandler type which is SingleUseMessageHandler type essentially. ::std::unique_ptr<::fidl::internal::SingleUseMessageHandler> Echo_EchoString_ResponseHandler(Echo::EchoStringCallback callback) { return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>( [callback_ = std::move(callback)](::fidl::Message message) { const char* error_msg = nullptr; zx_status_t status = message.Decode( &fidl_examples_routing_echo_EchoEchoStringResponseTable, &error_msg); … }); }  ProxyController uses message to write the message into the channel via the system call zx_channel_write() which is provided by libzircon.so.
  • 17.
  • 18. Async client vs Sync client /* https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/fuchsia.examples/echo.test.fidl */ [Discoverable] protocol Echo { EchoString(string:MAX_STRING_LENGTH value) -> (string:MAX_STRING_LENGTH response); };  after compiling the fidl library, there are two types of proxy /out/default/fidling/gen/examples/fidl/fuchsia.examples/fuchsia/examples  fuchsia::examples::EchoPtr (by default)  ::fidl::InterfacePtr<Echo> type  Async call or callback  client sends a request to server, but it doesn't block to wait the reply. The reply is returned asynchronously later.  fuchsia::examples::EchoSyncPtr  ::fidl::SynchronousInterfacePtr<Echo> type  Sync call or Blocking call  client sends a request to server and waits for reply from the server side.  Sync call If the client chooses sync call for the method EchoString, it doesn’t need to initialize and run the message loop. /* https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/hlcpp/client_sync/main.cc */ int main(int argc, const char** argv) { fuchsia::examples::EchoSyncPtr echo_proxy; auto context = sys::ComponentContext::Create(); context->svc()->Connect(echo_proxy.NewRequest()); std::string response; ZX_ASSERT(echo_proxy->EchoString("hello", &response) == ZX_OK); printf("Got response: %sn", response.c_str()); …
  • 19. return 0; }  Mechanism beneath the EchoSyncPtr The call to EchoString will block until it receives a reply message from the server. It will return a zx_status_t indicating the result of the method call. zx_status_t Echo_SyncProxy::EchoString(::std::string value,::std::string* out_response) { ::fidl::Encoder _encoder(internal::kEcho_EchoString_Ordinal); ::fidl::MessageBuffer buffer_; ::fidl::Message response_ = buffer_.CreateEmptyMessage(); zx_status_t status_ = proxy_.Call( &fuchsia_examples_EchoEchoStringRequestTable, &fuchsia_examples_EchoEchoStringResponseTable, Echo_RequestEncoder::EchoString(&_encoder, &value), &response_); if (status_ != ZX_OK) return status_; ::fidl::Decoder decoder_(std::move(response_)); *out_response = ::fidl::DecodeAs<::std::string>(&decoder_, 16); return ZX_OK; } /* https://fuchsia.googlesource.com/fuchsia/+/master/sdk/lib/fidl/cpp/internal/synchronous_proxy.c c */ zx_status_t SynchronousProxy::Call(const fidl_type_t* request_type, const fidl_type_t* response_type, Message request, Message* response) { const char* error_msg = nullptr;
  • 20. zx_status_t status = request.Validate(request_type, &error_msg); if (status != ZX_OK) { FIDL_REPORT_ENCODING_ERROR(request, request_type, error_msg); return status; } status = request.Call(channel_.get(), 0, ZX_TIME_INFINITE, response); if (status != ZX_OK) return status; status = response->Decode(response_type, &error_msg); if (status != ZX_OK) { FIDL_REPORT_DECODING_ERROR(*response, response_type, error_msg); return status; } return ZX_OK; } zx_channel_call() is like a combined zx_channel_write(), zx_object_wait_one(), and zx_channel_read(), and it blocks until it reads data from zx_channel_read(). /* https://fuchsia.googlesource.com/fuchsia/+/master/zircon/system/ulib/fidl/message.cc */ zx_status_t Message::Call(zx_handle_t channel, uint32_t flags, zx_time_t deadline, Message* response) { zx_channel_call_args_t args; args.wr_bytes = bytes_.data(); args.wr_handles = handles_.data(); args.rd_bytes = response->bytes_.data(); args.rd_handles = response->handles_.data(); args.wr_num_bytes = bytes_.actual(); args.wr_num_handles = handles_.actual(); args.rd_num_bytes = response->bytes_.capacity(); args.rd_num_handles = response->handles_.capacity(); uint32_t actual_bytes = 0u; uint32_t actual_handles = 0u; zx_status_t status = zx_channel_call(channel, flags, deadline, &args, &actual_bytes, &actual_handles); ClearHandlesUnsafe(); if (status == ZX_OK) { response->bytes_.set_actual(actual_bytes); response->handles_.set_actual(actual_handles); } return status; }
  • 21. Fuchsia IPC vs Android IPC  Interface  AIDL interface IMyAidlInterface { void test1(int p1); void test2(int p1, int p2); }  FIDL /* https://fuchsia.googlesource.com/fuchsia/+/master/examples/fidl/fuchsia.examples/echo.test.fidl */ [Discoverable] protocol Echo { EchoString(string:MAX_STRING_LENGTH value) -> (string:MAX_STRING_LENGTH response); SendString(string:MAX_STRING_LENGTH value); -> OnString(string:MAX_STRING_LENGTH response); };  IPC (Client)  Android The transact method is blocking call. The IBinder object mRemote sends the Parcel object data and the code Stub.TRANSACTION_test1 into Binder Driver and wait until the Parcel object reply returns. @Override public void test1(int p1) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(p1); boolean _status = mRemote.transact(Stub.TRANSACTION_test1, _data, _reply, 0); … _reply.readException(); }… }  Fuchsia
  • 22. By default, it’s an async call. The ProxyController controller will send the code kEcho_SendString_Ordinal and message into channel, and then returns. The callback will return the response. void Echo_Proxy::EchoString(::fidl::StringPtr value, EchoStringCallback callback) { ::fidl::Encoder _encoder(internal::kEcho_EchoString_GenOrdinal); controller_->Send(&fidl_examples_routing_echo_EchoEchoStringRequestTable, Echo_RequestEncoder::EchoString(&_encoder, &value), Echo_EchoString_ResponseHandler(std::move(callback))); }  IPC (Server)  Android @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {… switch (code) { case TRANSACTION_test1: { … this.test1(_arg0); reply.writeNoException(); return true; } case TRANSACTION_test2: { … this.test2(_arg0, _arg1); reply.writeNoException(); return true; }  Fuchsia zx_status_t Echo_Stub::Dispatch_(::fidl::Message message, ::fidl::internal::PendingResponse response) { … uint64_t ordinal = message.ordinal(); switch (ordinal) { case internal::kEcho_EchoString_Ordinal: { ::fidl::Decoder decoder(std::move(message)); impl_->EchoString(::fidl::DecodeAs<::std::string>(&decoder, 16), Echo_EchoString_Responder(std::move(response))); break; } case internal::kEcho_SendString_Ordinal: {
  • 23. ::fidl::Decoder decoder(std::move(message)); impl_->SendString(::fidl::DecodeAs<::std::string>(&decoder, 16)); break; }… }  Message(Fuchsia) vs Parcel(Android)  Message [Discoverable] protocol EchoTest { EchoString(string:MAX_STRING_LENGTH value1,uint8 value2,string:MAX_STRING_LENGTH value3) ; }; After fx build command, Fuchsia automatically generates EchoString method which converts the input values into message. The method id or ordinal number internal::kEchoTest_EchoString_Ordinal is encapsulated into the structure fidl_message_header_t which takes up 16 bytes. static ::fidl::Message EchoString(::fidl::Encoder* _encoder, ::std::string* value1, uint8_t* value2, ::std::string* value3) { _encoder->Alloc(56 - sizeof(fidl_message_header_t)); ::fidl::Encode(_encoder, value1, 16); ::fidl::Encode(_encoder, value2, 32); ::fidl::Encode(_encoder, value3, 40); return _encoder->GetMessage(); } Main related classes : /sdk/lib/fidl/cpp/encoder.cc /sdk/lib/fidl/cpp/encoder.h Message mainly has two parts: the method id and the basic data type are put into the vector bytes_ , and the channel info is put into the vector handles_. std::vector<uint8_t> bytes_;
  • 24. std::vector<zx_handle_t> handles_; When encoding some handles, it needs to invoke EncodeHandle method to save the handle’s value into the vector handles_.  Parcel /frameworks/native/libs/binder/Parcel.cpp /frameworks/native/libs/binder/Parcel.h @Override public void test1(int p1) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(p1); boolean _status = mRemote.transact(Stub.TRANSACTION_test1, _data, _reply, 0); … _reply.readException(); }… }
  • 25. The method id is not included in mData which is like bytes_ in fuchsia. When binder object or FileDescriptor needs to be parcelled, it needs the vector mObjects to store offset of each flat_binder_object.  Conclusion Fuchsia Android Interface Similar concept. It provides method interface(s) to client. Server needs to implement the method interface(s). FIDL AIDL defines virtual methods in Protocol defines virtual methods in Interface Error Callback Client needs to register error callback via set_error_handler method, error message is not straightforward for client. Client doesn’t need to register error callback, there is couples of callback functions. public void onServiceConnected(ComponentName className,IBinder service) { } public void onServiceDisconnected(ComponentN ame arg0) { } IPC call Both Fuchsia and Android adopt proxy/stub pattern. Proxy sends the method id and parameter value to the stub. Stub invoke the method implementation according to the method id. Data is encapsulated during the transmission.
  • 26. There are two types of call for client to choose: 1.async call(by default), which means client only needs to write the message to the channel and then return. 2.sync call, which means client proxy will wait until the server gives back the response. sync call(by default), which means client proxy will wait until the server gives back the response. IPC data encapsulation Both Fuchsia and Android need to capsulate data in the proxy side and decapsulate data in the stub side. Encapsulation process is similar to each other. Message Parcel Method id is encapsulted into message. Method id is in fidl_message_header_t. Method id is not encapsulated into parcel data. Method id is taken by binder itself. It first writes fidl_message_header_t which is not InterfaceToken It writes an InterfaceToken in the head It allocates some fixed length space in the head according to the type of parameters. Some parameter value (e.g., string) is allocated after the fixed length space. Parameter value is allocated one by one. InterfaceToken->param1->param2->… It puts the value of handle(s) into the vector handles_ It puts the offset of flat_binder_object into the array mObjects media Channel + port Binder Language supported c/c++/Rust/Dart/Go Java/Kotlin