1 // Copyright 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #pragma once
15 
16 #include "android_pipe_common.h"
17 
18 #include "aemu/base/c_header.h"
19 #include "aemu/base/utils/stream.h"
20 
21 #include <stdbool.h>
22 #include <stdint.h>
23 
24 ANDROID_BEGIN_HEADER
25 
26 // The set of methods implemented by an AndroidPipe instance.
27 // All these methods are called at runtime by the virtual device
28 // implementation. Note that transfers are always initiated by the virtual
29 // device through the sendBuffers() and recvBuffers() callbacks.
30 //
31 // More specifically:
32 //
33 // - When a pipe has data for the guest, it should signal it by calling
34 //   'android_pipe_host_signal_wake(pipe, PIPE_WAKE_READ)'. The guest kernel
35 //   will be signaled and will later initiate a recvBuffers() call.
36 //
37 // - When a pipe is ready to accept data from the guest, it should signal
38 //   it by calling 'android_pipe_host_signal_wake(pipe, PIPE_WAKE_WRITE)'. The
39 //   guest kernel will be signaled, and will later initiate a sendBuffers()
40 //   call when the guest client writes data to the pipe.
41 //
42 // - Finally, the guest kernel can signal whether it wants to be signaled
43 //   on read or write events by calling the wakeOn() callback.
44 //
45 // - When the emulator wants to close a pipe, it shall call
46 //   android_pipe_host_close(). This signals the guest kernel which will later
47 //   initiate a close() call.
48 //
49 typedef struct AndroidPipeFuncs {
50     // Call to open a new pipe instance. |hwpipe| is a device-side view of the
51     // pipe that must be passed to android_pipe_host_signal_wake() and
52     // android_pipe_host_close()
53     // functions. |serviceOpaque| is the parameter passed to
54     // android_pipe_add_type(), and |args| is either NULL
55     // or parameters passed to the service when opening the connection.
56     // Return a new service pipe instance, or NULL on error.
57     void* (*init)(void* hwpipe, void* serviceOpaque, const char* args);
58 
59     // Called when the guest kernel has finally closed a pipe connection.
60     // This is the only place one should release/free the instance, but never
61     // call this directly, use android_pipe_host_close() instead. |pipe| is a
62     // client
63     // instance returned by init() or load().
64     void (*close)(void* service_pipe);
65 
66     // Called when the guest wants to write data to the |pipe| client instance,
67     // |buffers| points to an array of |numBuffers| descriptors that describe
68     // where to copy the data from. Return the number of bytes that were
69     // actually transferred, 0 for EOF status, or a negative error value
70     // otherwise, including PIPE_ERROR_AGAIN to indicate that the emulator
71     // is not ready yet to receive data.
72     int (*sendBuffers)(void* service_pipe,
73                        const AndroidPipeBuffer* buffers,
74                        int numBuffers);
75 
76     // Called when the guest wants to read data from the |pipe| client,
77     // |buffers| points to an array of |numBuffers| descriptors that describe
78     // where to copy the data to. Return the number of bytes that were
79     // actually transferred, 0 for EOF status, or a negative error value
80     // otherwise, including PIPE_ERROR_AGAIN to indicate that the emulator
81     // doesn't have data for the guest yet.
82     int (*recvBuffers)(void* service_pipe,
83                        AndroidPipeBuffer* buffers,
84                        int numBuffers);
85 
86     // Called when guest wants to poll the read/write status for the |pipe|
87     // client. Should return a combination of PIPE_POLL_XXX flags.
88     unsigned (*poll)(void* service_pipe);
89 
90     // Called to signal that the guest wants to be woken when the set of
91     // PIPE_WAKE_XXX bit-flags in |flags| occur. When the condition occurs,
92     // then the |service_pipe| client shall call
93     // android_pipe_host_signal_wake().
94     void (*wakeOn)(void* service_pipe, int flags);
95 
96     // Called to save the |service_pipe| client's state to a Stream, i.e. when
97     // saving snapshots.
98     void (*save)(void* service_pipe, Stream* file);
99 
100     // Called to load the sate of a pipe client from a Stream. This will always
101     // correspond to the state of the client as saved by a previous call to
102     // the 'save' method. Can be NULL to indicate that the pipe state cannot
103     // be loaded. In this case, the emulator will automatically force-close
104     // it. Parameters are similar to init(), with the addition of |file|
105     // which is the input stream.
106     void* (*load)(void* hwpipe, void* serviceOpaque, const char* args,
107                   Stream* file);
108 
109 } AndroidPipeFuncs;
110 
111 /* Register a new pipe service type. |serviceOpaque| is passed directly
112  * to 'init() when a new pipe is connected to.
113  */
114 extern void  android_pipe_add_type(const char* serviceName,
115                                    void* serviceOpaque,
116                                    const AndroidPipeFuncs* pipeFuncs);
117 
118 // The following functions are only used during unit-testing.
119 
120 // Reset the list of services registered through android_pipe_add_type().
121 // Useful at the start and end of a unit-test.
122 extern void android_pipe_reset_services(void);
123 
124 /* This tells the guest system that we want to close the pipe and that
125  * further attempts to read or write to it will fail. This will not
126  * necessarily destroys the |hwpipe| immediately. The latter will call
127  * android_pipe_guest_close() at destruction time though.
128  *
129  * This will also wake-up any blocked guest threads waiting for i/o.
130  * NOTE: This function can be called from any thread.
131  */
132 extern void android_pipe_host_close(void* hwpipe);
133 
134 /* Signal that the pipe can be woken up. 'flags' must be a combination of
135  * PIPE_WAKE_READ and PIPE_WAKE_WRITE.
136  * NOTE: This function can be called from any thread.
137  */
138 extern void android_pipe_host_signal_wake(void* hwpipe, unsigned flags);
139 
140 ANDROID_END_HEADER
141