You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
8.1 KiB
188 lines
8.1 KiB
// Copyright 2020 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.
|
|
#pragma once
|
|
|
|
#include "base/Stream.h"
|
|
#include "base/export.h"
|
|
#include "android_pipe_common.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#define ANDROID_PIPE_DEVICE_EXPORT extern AEMU_EXPORT
|
|
|
|
// TECHNICAL NOTE:
|
|
//
|
|
// An Android pipe is a very fast communication channel between the guest
|
|
// system and the emulator program.
|
|
//
|
|
// To open a new pipe to the emulator, a guest client will do the following:
|
|
//
|
|
// fd = open("/dev/qemu_pipe", O_RDWR);
|
|
// ret = write(fd, pipeServiceName, strlen(pipeServiceName) + 1);
|
|
// if (ret < 0) {
|
|
// // something bad happened, see errno
|
|
// }
|
|
//
|
|
// Where 'pipeServiceName' is a string that looke like "pipe:<service>"
|
|
// or "pipe:<service>:<args>", terminated by a zero.
|
|
//
|
|
// now read()/write() to communicate with <pipeServiceName> service in the
|
|
// emulator. select() and non-blocking i/o will also work properly.
|
|
//
|
|
|
|
// The Goldfish pipe virtual device is in charge of communicating with the
|
|
// kernel to manage pipe operations.
|
|
//
|
|
// Each pipe connection corresponds to two objects:
|
|
//
|
|
// - A hardware-side opaque object (implemented by the virtual pipe device)
|
|
// identified here as a |hwpipe| value.
|
|
//
|
|
// - A host-specific opaque object, identified here either as |host-pipe|.
|
|
//
|
|
// (virtual device) |hwpipe| <-----> |host-pipe| (emulator)
|
|
//
|
|
// Expected usage is the following:
|
|
//
|
|
// 1/ During setup, the virtual device should call android_pipe_set_hw_funcs()
|
|
// to point to callbacks it provides to implement a few functions called
|
|
// from the host, later at runtime.
|
|
//
|
|
// 2/ During setup, the emulator should register host pipe service instances,
|
|
// each one identified by a name, before the VM starts.
|
|
//
|
|
// 3/ At runtime, when a guest opens /dev/goldfish_pipe, this ends up creating
|
|
// a new |hwpipe| object in the virtual device, which will then call
|
|
// android_pipe_guest_open() to create a corresponding |host-pipe|
|
|
// object.
|
|
//
|
|
// Note that at this point, the |host-pipe| corresponds to a special
|
|
// host-side pipe state that waits for the name of the pipe service to
|
|
// connect to, and potential arguments. This is called a |connect-pipe|
|
|
// here:
|
|
//
|
|
// android_pipe_guest_open()
|
|
// |hwpipe| <---------------------------> |connect-pipe|
|
|
//
|
|
// 4/ When the pipe service name is fully written, the |connect-pipe| finds a
|
|
// service registered for it, and calls its ::init() callback to create
|
|
// a new |service-pipe| instance.
|
|
//
|
|
// |hwpipe| <---------------------------> |connect-pipe|
|
|
//
|
|
// |service-pipe|
|
|
//
|
|
// 5/ It then calls the AndroidPipeHwFuncs::resetPipe() callback provided
|
|
// by the virtual device to reattach the |hwpipe| to the |service-pipe|
|
|
// then later delete the now-useless |connect-pipe|.
|
|
//
|
|
// |hwpipe| <------------+ |connect-pipe|
|
|
// |
|
|
// +---------------->|service-pipe|
|
|
//
|
|
// VERY IMPORTANT NOTE:
|
|
//
|
|
// All operations should happen on the thread that currently holds the
|
|
// global VM state lock (see host-common/VmLock.h). It's up to
|
|
// the host implementation to ensure that this is always the case.
|
|
//
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// The following functions are called from the virtual device only and are
|
|
// implemented by AndroidEmu. They will always be called from the device thread
|
|
// context as well.
|
|
|
|
// Open a new Android pipe. |hwpipe| is a unique pointer value identifying the
|
|
// hardware-side view of the pipe, and will be passed to the 'init' callback
|
|
// from AndroidPipeHwFuncs. This returns a new |internal-pipe| value that is
|
|
// only used by the virtual device to call android_pipe_xxx() functions below.
|
|
ANDROID_PIPE_DEVICE_EXPORT void* android_pipe_guest_open(
|
|
void* hwpipe);
|
|
|
|
// Similar to android_pipe_guest_open(), but has a flags parameter that is used
|
|
// to communicate unique transport properties about the pipe.
|
|
ANDROID_PIPE_DEVICE_EXPORT void* android_pipe_guest_open_with_flags(
|
|
void* hwpipe, uint32_t flags);
|
|
|
|
// Close and free an Android pipe. |pipe| must be the result of a previous
|
|
// android_pipe_guest_open() call or the second parameter to
|
|
// android_pipe_reset().
|
|
// This must *not* be called from the host side, see android_pipe_host_close()
|
|
// instead.
|
|
ANDROID_PIPE_DEVICE_EXPORT void android_pipe_guest_close(
|
|
void* internal_pipe, PipeCloseReason reason);
|
|
|
|
// Hooks for a start/end of save/load operations, called once per each snapshot.
|
|
ANDROID_PIPE_DEVICE_EXPORT void android_pipe_guest_pre_load(android::base::Stream* file);
|
|
ANDROID_PIPE_DEVICE_EXPORT void android_pipe_guest_post_load(android::base::Stream* file);
|
|
ANDROID_PIPE_DEVICE_EXPORT void android_pipe_guest_pre_save(android::base::Stream* file);
|
|
ANDROID_PIPE_DEVICE_EXPORT void android_pipe_guest_post_save(android::base::Stream* file);
|
|
|
|
// Save the state of an Android pipe to a stream. |internal_pipe| is the pipe
|
|
// instance from android_pipe_guest_open() or android_pipe_guest_load(), and
|
|
// |file| is the
|
|
// output stream.
|
|
ANDROID_PIPE_DEVICE_EXPORT void android_pipe_guest_save(
|
|
void* internal_pipe, android::base::Stream* file);
|
|
|
|
// Load the state of an Android pipe from a stream. |file| is the input stream,
|
|
// |hwpipe| is the hardware-side pipe descriptor. On success, return a new
|
|
// internal pipe instance (similar to one returned by
|
|
// android_pipe_guest_open()), and
|
|
// sets |*force_close| to 1 to indicate that the pipe must be force-closed
|
|
// just after its load/creation (only useful for certain services that can't
|
|
// preserve state into streams). Return NULL on faillure.
|
|
ANDROID_PIPE_DEVICE_EXPORT void* android_pipe_guest_load(
|
|
android::base::Stream* file, void* hwpipe, char* force_close);
|
|
|
|
// Similar to android_pipe_guest_load(), but this function is only called from
|
|
// the
|
|
// QEMU1 virtual pipe device, to support legacy snapshot formats. It can be
|
|
// ignored by the QEMU2 virtual device implementation.
|
|
//
|
|
// The difference is that this must also read the hardware-specific state
|
|
// fields, and store them into |*channel|, |*wakes| and |*closed| on
|
|
// success.
|
|
ANDROID_PIPE_DEVICE_EXPORT void* android_pipe_guest_load_legacy(
|
|
android::base::Stream* file, void* hwpipe, uint64_t* channel,
|
|
unsigned char* wakes, unsigned char* closed, char* force_close);
|
|
|
|
// Call the poll() callback of the client associated with |pipe|.
|
|
ANDROID_PIPE_DEVICE_EXPORT unsigned android_pipe_guest_poll(void* internal_pipe);
|
|
|
|
// Call the recvBuffers() callback of the client associated with |pipe|.
|
|
ANDROID_PIPE_DEVICE_EXPORT int android_pipe_guest_recv(
|
|
void* internal_pipe, AndroidPipeBuffer* buffers, int numBuffers);
|
|
|
|
// Call the sendBuffers() callback of the client associated with |pipe|.
|
|
ANDROID_PIPE_DEVICE_EXPORT int android_pipe_guest_send(
|
|
void** internal_pipe, const AndroidPipeBuffer* buffer, int numBuffer);
|
|
|
|
// Call the wakeOn() callback of the client associated with |pipe|.
|
|
ANDROID_PIPE_DEVICE_EXPORT void android_pipe_guest_wake_on(
|
|
void* internal_pipe, unsigned wakes);
|
|
|
|
// Utility functions to look up pipe instances and ids.
|
|
ANDROID_PIPE_DEVICE_EXPORT int android_pipe_get_id(void* internal_pipe);
|
|
ANDROID_PIPE_DEVICE_EXPORT void* android_pipe_lookup_by_id(int id);
|
|
|
|
// Each pipe type should regiter its callback to lookup instances by it.
|
|
// |android_pipe_lookup_by_id| will go through the list of callbacks and
|
|
// will check if no more than one value is returned, it will crash otherwise.
|
|
// The |tag| argiment will be used in the crash message.
|
|
ANDROID_PIPE_DEVICE_EXPORT void android_pipe_append_lookup_by_id_callback(
|
|
void*(*callback)(int), const char* tag);
|