aboutsummaryrefslogtreecommitdiffstats
path: root/android/android-device.h
diff options
context:
space:
mode:
Diffstat (limited to 'android/android-device.h')
-rw-r--r--android/android-device.h239
1 files changed, 239 insertions, 0 deletions
diff --git a/android/android-device.h b/android/android-device.h
new file mode 100644
index 0000000..9fde906
--- /dev/null
+++ b/android/android-device.h
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_ANDROID_DEVICE_H_
+#define ANDROID_ANDROID_DEVICE_H_
+
+/*
+ * Encapsulates an exchange protocol between the emulator, and an Android device
+ * that is connected to the host via USB. The communication is established over
+ * a TCP port forwarding, enabled by ADB (always use 'adb -d forward ...' variant
+ * of this command, so ADB will know to enable port forwarding on the connected
+ * device, and not on the emulator's guest system).
+ *
+ * Exchange protocol contains two channel:
+ *
+ * - Query channel.
+ * - Event channel.
+ *
+ * Both channels are implemented on top of TCP sockets that are connected to the
+ * same port.
+ *
+ * I QUERY CHANNEL.
+ * Query channel is intended to send queries to and receive responses from the
+ * connected device. It is implemented on top of iolooper_xxx API (see iolooper.h)
+ * because it must work outside of the main event loop. This is required to enable
+ * proper initialization of components (such as sensors) that must be set up
+ * before emulator enters the main loop.
+ *
+ * II EVENT CHANNEL.
+ * Event channel is intended to listen on events sent from the device, and
+ * asynchronously report them back to the client of this API by invoking an event
+ * callback that was registered by the client. Event channel is implemented on
+ * top of asyncXxx API (see android/async-utils.*). Note that using of asyncXxx
+ * API limits the use of event channel to the time after the emulator has entered
+ * its main event loop. The only exception is if event channel is connected from
+ * android_device_connect_sync API, in which case iolooper_xxx API is used to
+ * establish the connection. However, even in this case listening for events will
+ * not be available until after the emulator enters its event loop, since event
+ * listening always uses asyncXxx API.
+ *
+ * III. ESTABLISHING CONNECTION.
+ * ADB port forwarding requires that the server socket is to be run on the device,
+ * while emulator must use a client socket for communication. Thus, it's the
+ * emulator that initiates the connection.
+ *
+ * There are two ways how emulator can initiate the connection:
+ *
+ * - Synchronous connection.
+ * - Asynchronous connection.
+ *
+ * III.I SYNCHROUNOUS CONNECTION.
+ * Synchronous connection is initiated via android_device_connect_sync API, and
+ * completes synchronously.
+ *
+ * This API should be used when connection with the device is required at the time
+ * of the call. For instance, when initializing sensor emulation, connection with
+ * the device is required to properly set up the emulator before the guest system
+ * starts, and before emulator enters its main event loop.
+ *
+ * III.II ASYNCHRONOUS CONNECTION.
+ * Asynchronous connection is initiated via android_device_connect_async API. The
+ * main difference with the synchronous connection is that this API will not fail
+ * if connection is not immediately available. If connection is not available at
+ * the time of the call, the API will schedule a retry (based on a timer), and
+ * will continue reprying untill connection becomes available, or until an error
+ * occurs that prevent further retries.
+ *
+ * This API should be used when ... Well, whenever appropriate. For instance,
+ * sensor emulation will use this API to restore lost connection with the device.
+ *
+ * NOTE: Asynchronous connection will complete no sooner than the emulator enters
+ * its main loop.
+ *
+ * IV EXCHANGE PROTOCOL.
+ * Obviously, there must be some application running on the device, that implements
+ * a socket server listening on the forwarded TCP port, and accepting the clients.
+ *
+ * IV.I Query vs. event channel.
+ * The exchange protocol assumes, that when a channel is connected, it will
+ * identify itself by sending a string containing channel type. Only after such
+ * identification has been made the channel becomes available for use.
+ *
+ * IV.II Message format.
+ * All data that is transferred in both directions over both channels are zero-
+ * terminated strings.
+ */
+
+#include "qemu-common.h"
+#include "android/async-utils.h"
+#include "android/utils/debug.h"
+
+/* TCP port reserved for sensor emulation. */
+#define AD_SENSOR_PORT 1968
+
+/* Definis infinite timeout. */
+#define AD_INFINITE_WAIT -1
+
+/* Android device descriptor. */
+typedef struct AndroidDevice AndroidDevice;
+
+/********************************************************************************
+ * Callback declarations
+ *******************************************************************************/
+
+/* Callback routine that is invoked when android device is connected, or failed
+ * to connect. As discussed above, this callback is called when both, query and
+ * event channels have been connected. This callback is used only for asynchronous
+ * connections.
+ * Param:
+ * opaque - Opaque pointer that was passed to android_device_init API.
+ * ad - Androd device descriptor for the connection.
+ * failure - Zero indicates that connection with the device has been successfuly
+ * established. Non-zero vaule passed in this parameter indicates a failure,
+ * and contains 'errno'-reason for failure.
+ */
+typedef void (*device_connected_cb)(void* opaque, AndroidDevice* ad, int failure);
+
+/* Callback routine that is invoked on an event received in the event channel.
+ * NOTE: It's important to check 'errno' in this callback. If 'errno' is set to
+ * ENOMEM, this signals that buffer passed to android_device_listen was too small
+ * to contain the entire event message.
+ * Param:
+ * opaque - Opaque pointer that was passed to android_device_init API.
+ * ad - Androd device descriptor for the connection.
+ * msg - Event message (a zero-terminated string) received from the device.
+ * msgsize - Event message size (including zero-terminator).
+ */
+typedef void (*event_cb)(void* opaque, AndroidDevice* ad, char* msg, int msgsize);
+
+/* Callback routine that is invoked when an I/O failure occurs on a channel.
+ * Note that this callback will not be invoked on connection failures.
+ * Param:
+ * opaque - Opaque pointer that was passed to android_device_init API.
+ * ad - Android device instance
+ * failure - Contains 'errno' indicating the reason for failure.
+ */
+typedef void (*io_failure_cb)(void* opaque, AndroidDevice* ad, int failure);
+
+/********************************************************************************
+ * Android Device API.
+ *******************************************************************************/
+
+/* Initializes android device descriptor.
+ * Param:
+ * opaque - An opaque pointer to associate with the descriptor. This pointer
+ * will be passed to all callbacks (see above) that were invoked by the
+ * initializing android device instance.
+ * port - TCP port to use for connection.
+ * on_io_failure - Callback to invoke when an I/O failure occurs on a channel
+ * used by the initializing android device instance. Can be NULL.
+ * Return:
+ * Initialized android device descriptor on success, or NULL on failure.
+ */
+extern AndroidDevice* android_device_init(void* opaque,
+ int port,
+ io_failure_cb on_io_failure);
+
+/* Disconnects and destroys android device descriptor.
+ * Param:
+ * ad - Android device descriptor, returned from android_device_init API.
+ * Note that memory allocated for this descriptor will be freed in this
+ * routine.
+ */
+extern void android_device_destroy(AndroidDevice* ad);
+
+/* Synchronously connects to the device. See notes above for more details.
+ * Param:
+ * ad - Android device descriptor, returned from android_device_init API.
+ * to - Milliseconds to wait for connection to be established.
+ * Return:
+ * Zero on success, or non-zero value on failure with 'errno' properly set.
+ */
+extern int android_device_connect_sync(AndroidDevice* ad, int to);
+
+/* Asynchronously connects to the device. See notes above for more details.
+ * Param:
+ * ad - Android device descriptor, returned from android_device_init API.
+ * on_connected - Callback to invoke when connection is completed (i,e, both,
+ * event, and query channels have been connected). This parameter can be
+ * NULL. Note that connection errors will be also reported through this
+ * callback. Also note that this callback will be invoked even if this
+ * routine returns with a failure.
+ * Return:
+ * Zero on success, or non-zero value on failure with 'errno' properly set.
+ */
+extern int android_device_connect_async(AndroidDevice* ad,
+ device_connected_cb on_connected);
+
+/* Disconnects from the android device.
+ * Param:
+ * ad - Android device descriptor, returned from android_device_init API.
+ */
+extern void android_device_disconnect(AndroidDevice* ad);
+
+/* Queries the device via query channel.
+ * Param:
+ * ad - Android device descriptor, returned from android_device_init API.
+ * query - Zero-terminated query string.
+ * buff, buffsize - Buffer where to receive the response to the query.
+ * to - Milliseconds to wait for the entire query to complete.
+ * Return:
+ * Zero on success, or non-zero value on failure with 'errno' properly set:
+ * - 0 Indicates that the server has failed the query.
+ * - Anything else indicates an I/O error.
+ */
+extern int android_device_query(AndroidDevice* ad,
+ const char* query,
+ char* buff,
+ size_t buffsize,
+ int to);
+
+/* Start listening on the event channel.
+ * Param:
+ * ad - Android device descriptor, returned from android_device_init API.
+ * buff, buffsize - Buffer where to receive the event message.
+ * on_event - Callback to invoke on event. Note that this callback will be
+ * invoked even if this routine returns with a failure.
+ * Return:
+ * Zero on success, or non-zero value on failure with 'errno' properly set.
+ */
+extern int android_device_listen(AndroidDevice* ad,
+ char* buff,
+ int buffsize,
+ event_cb on_event);
+
+#endif /* ANDROID_ANDROID_DEVICE_H_ */