185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine/* Copyright (C) 2010 The Android Open Source Project 285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine** 385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine** This software is licensed under the terms of the GNU General Public 485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine** License version 2, as published by the Free Software Foundation, and 585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine** may be copied, distributed, and modified under those terms. 685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine** 785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine** This program is distributed in the hope that it will be useful, 885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine** but WITHOUT ANY WARRANTY; without even the implied warranty of 985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine** GNU General Public License for more details. 1185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine*/ 1285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 1385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine/* 1485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine * Contains the Core-side implementation of the "attach-ui" service that is 1585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine * used to establish connection between the UI and the Core. 1685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine */ 1785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 1885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine#include "android/android.h" 1985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine#include "android/globals.h" 2085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine#include "android/looper.h" 2185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine#include "android/async-utils.h" 2285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine#include "android/sync-utils.h" 2385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine#include "android/utils/debug.h" 2485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine#include "android/protocol/core-commands.h" 2585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine#include "android/protocol/core-commands-impl.h" 2685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 2785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine/* Descriptor for the UI attach-ui proxy. */ 2885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkinetypedef struct AttachUIProxy { 2985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine /* Reader to detect UI disconnection. */ 3085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine AsyncReader async_reader; 3185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 3285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine /* I/O associated with this descriptor. */ 3385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine LoopIo io; 3485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 3585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine /* Looper used to communicate with the UI. */ 3685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine Looper* looper; 3785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 3885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine /* Socket descriptor for this service. */ 3985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine int sock; 4085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine} AttachUIProxy; 4185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 4285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine/* One and only one AttachUIProxy instance. */ 4385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkinestatic AttachUIProxy _attachUiProxy; 4485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 4585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine/* Implemented in android/console.c */ 4685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkineextern void destroy_attach_ui_client(void); 4785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 4885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine/* Asynchronous I/O callback for AttachUIProxy instance. 4985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine * We expect this callback to be called only on UI detachment condition. In this 5085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine * case the event should be LOOP_IO_READ, and read should fail with errno set 5185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine * to ECONNRESET. 5285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine * Param: 5385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine * opaque - AttachUIProxy instance. 5485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine */ 5585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkinestatic void 5685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine_attachUiProxy_io_func(void* opaque, int fd, unsigned events) 5785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine{ 5885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine AttachUIProxy* uicmd = (AttachUIProxy*)opaque; 5985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine AsyncReader reader; 6085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine AsyncStatus status; 6185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine uint8_t read_buf[1]; 6285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 6385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine if (events & LOOP_IO_WRITE) { 6485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine derror("Unexpected LOOP_IO_WRITE in _attachUiProxy_io_func.\n"); 6585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine return; 6685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine } 6785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 6885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine // Try to read 6985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine asyncReader_init(&reader, read_buf, sizeof(read_buf), &uicmd->io); 70f9e333ade2529f257ced6bcff8e5824cb07eacf9David 'Digit' Turner status = asyncReader_read(&reader); 7185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine // We expect only error status here. 7285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine if (status != ASYNC_ERROR) { 7385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine derror("Unexpected read status %d in _attachUiProxy_io_func\n", status); 7485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine return; 7585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine } 7685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine // We expect only socket disconnection error here. 7785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine if (errno != ECONNRESET) { 7885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine derror("Unexpected read error %d (%s) in _attachUiProxy_io_func.\n", 7985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine errno, errno_str); 8085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine return; 8185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine } 8285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 8385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine // Client got disconnectted. 8485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine destroy_attach_ui_client(); 8585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine} 8685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 8785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkineint 8885276806ec6ac969d7befa2496c1de59adaaac74Vladimir ChtchetkineattachUiProxy_create(int fd) 8985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine{ 9085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine // Initialize the only AttachUIProxy instance. 9185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine _attachUiProxy.sock = fd; 9285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine _attachUiProxy.looper = looper_newCore(); 9385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine loopIo_init(&_attachUiProxy.io, _attachUiProxy.looper, _attachUiProxy.sock, 9485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine _attachUiProxy_io_func, &_attachUiProxy); 9585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine loopIo_wantRead(&_attachUiProxy.io); 9685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 9785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine return 0; 9885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine} 9985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 10085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkinevoid 10185276806ec6ac969d7befa2496c1de59adaaac74Vladimir ChtchetkineattachUiProxy_destroy(void) 10285276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine{ 10385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine if (_attachUiProxy.looper != NULL) { 10485276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine // Stop all I/O that may still be going on. 10585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine loopIo_done(&_attachUiProxy.io); 10685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine looper_free(_attachUiProxy.looper); 10785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine _attachUiProxy.looper = NULL; 10885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine } 10985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine _attachUiProxy.sock = -1; 11085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine} 111