1777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine/* Copyright (C) 2010 The Android Open Source Project 2777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine** 3777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine** This software is licensed under the terms of the GNU General Public 4777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine** License version 2, as published by the Free Software Foundation, and 5777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine** may be copied, distributed, and modified under those terms. 6777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine** 7777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine** This program is distributed in the hope that it will be useful, 8777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine** but WITHOUT ANY WARRANTY; without even the implied warranty of 9777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine** GNU General Public License for more details. 11777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine*/ 12777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 13777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine/* 14777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * Contains the UI-side implementation of the "core-ui-control" service that is 15777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * part of the UI control protocol. Here we handle UI control commands received 16777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * from the Core. 17777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine */ 18777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 19b6c168bbb6477145e843bb4a2e56e72e6d47822dDavid 'Digit' Turner#include <unistd.h> 20777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/looper.h" 21777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/async-utils.h" 22777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/sync-utils.h" 23777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/utils/system.h" 24777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/utils/debug.h" 25777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/utils/panic.h" 26e993126c6704029cb1c656922a66a32bd09b6089David 'Digit' Turner#include "android/protocol/core-connection.h" 27777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/protocol/ui-commands-impl.h" 28777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine#include "android/protocol/ui-commands-api.h" 29777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 30777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine/* Enumerates states for the command reader in UICmdImpl instance. */ 31777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinetypedef enum UICmdImplState { 32777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine /* The reader is waiting on command header. */ 33777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine EXPECTS_HEADER, 34777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 35777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine /* The reader is waiting on command parameters. */ 36777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine EXPECTS_PARAMETERS, 37777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine} UICmdImplState; 38777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 39777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine/* Descriptor for the UI-side of the "core-ui-control" service. */ 40777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinetypedef struct UICmdImpl { 41777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine /* Core connection established for this service. */ 42777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine CoreConnection* core_connection; 43777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 44777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine /* Socket descriptor for the UI service. */ 45777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine int sock; 46777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 47b6c168bbb6477145e843bb4a2e56e72e6d47822dDavid 'Digit' Turner /* Custom i/o handler */ 48b6c168bbb6477145e843bb4a2e56e72e6d47822dDavid 'Digit' Turner LoopIo io[1]; 49b6c168bbb6477145e843bb4a2e56e72e6d47822dDavid 'Digit' Turner 50777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine /* Command reader state. */ 51777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine UICmdImplState reader_state; 52777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 53777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine /* Incoming command header. */ 54777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine UICmdHeader cmd_header; 55777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 56777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine /* Reader's buffer. This field can point to the cmd_header field of this 57777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * structure (when we expect a command header), or to a buffer allocated for 58777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * the (when we expect command parameters). */ 59777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uint8_t* reader_buffer; 60777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 61777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine /* Offset in the reader's buffer where to read next chunk of data. */ 62777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine size_t reader_offset; 63777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 64777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine /* Total number of bytes the reader expects to read. */ 65777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine size_t reader_bytes; 66777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine} UICmdImpl; 67777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 68777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine/* Implemented in android/qemulator.c */ 69777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkineextern void android_emulator_set_window_scale(double scale, int is_dpi); 70777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 71777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine/* One and only one UICmdImpl instance. */ 72777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinestatic UICmdImpl _uiCmdImpl; 73777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 74777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine/* Display brightness change callback. */ 75777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinestatic AndroidHwLightBrightnessCallback _brightness_change_callback = NULL; 76777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinestatic void* _brightness_change_callback_param = NULL; 77777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 78777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine/* Handles UI control command received from the core. 79777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * Param: 80777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * uicmd - UICmdImpl instance that received the command. 81777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * header - UI control command header. 82777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * data - Command parameters formatted accordingly to the command type. 83777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine */ 84777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinestatic void 85777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine_uiCmdImpl_handle_command(UICmdImpl* uicmd, 86777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine const UICmdHeader* header, 87777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine const uint8_t* data) 88777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine{ 89777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine switch (header->cmd_type) { 90777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine case AUICMD_SET_WINDOWS_SCALE: 91777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine { 92777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine UICmdSetWindowsScale* cmd = (UICmdSetWindowsScale*)data; 93777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine android_emulator_set_window_scale(cmd->scale, cmd->is_dpi); 94777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine break; 95777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 96777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 97777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine case AUICMD_CHANGE_DISP_BRIGHTNESS: 98777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine { 99777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine UICmdChangeDispBrightness* cmd = (UICmdChangeDispBrightness*)data; 100777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine if (_brightness_change_callback != NULL) { 101777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine _brightness_change_callback(_brightness_change_callback_param, 102777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine cmd->light, cmd->brightness); 103777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 104777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine break; 105777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 106777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 107777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine default: 108777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine derror("Unknown command %d is received from the Core\n", 109777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine header->cmd_type); 110777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine break; 111777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 112777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine} 113777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 114777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine/* Asynchronous I/O callback reading UI control commands. 115777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * Param: 116777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine * opaque - UICmdImpl instance. 117777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine */ 118777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkinestatic void 119b6c168bbb6477145e843bb4a2e56e72e6d47822dDavid 'Digit' Turner_uiCmdImpl_io_callback(void* opaque, int fd, unsigned events) 120777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine{ 121777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine UICmdImpl* uicmd = opaque; 122777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine int status; 123777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 124777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // Read requests while they are immediately available. 125777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine for (;;) { 126777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // Read next chunk of data. 12717ecca637df2f573edc3ecb8246c0e38a5b32465Vladimir Chtchetkine status = socket_recv(uicmd->sock, 12817ecca637df2f573edc3ecb8246c0e38a5b32465Vladimir Chtchetkine uicmd->reader_buffer + uicmd->reader_offset, 12917ecca637df2f573edc3ecb8246c0e38a5b32465Vladimir Chtchetkine uicmd->reader_bytes - uicmd->reader_offset); 130777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine if (status == 0) { 13107db34976ba1dd045a51c4ab2c7f52479cddcc57David 'Digit' Turner /* Disconnection, meaning that the core process got terminated. */ 132777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine fprintf(stderr, "core-ui-control service got disconnected\n"); 13385276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine uiCmdImpl_destroy(); 134777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine return; 135777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 136777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine if (status < 0) { 137777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine if (errno == EINTR) { 138777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine /* loop on EINTR */ 139777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine continue; 140777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } else if (errno == EWOULDBLOCK || errno == EAGAIN) { 141777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // Chunk is not avalable at this point. Come back later. 142777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine return; 143777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 144777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 145777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 146777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_offset += status; 147777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine if (uicmd->reader_offset != uicmd->reader_bytes) { 148777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // There are still some data left in the pipe. 149777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine continue; 150777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 151777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 152777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // All expected data has been read. Time to change the state. 153777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine if (uicmd->reader_state == EXPECTS_HEADER) { 154777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // Header has been read. 155777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine if (uicmd->cmd_header.cmd_param_size) { 156777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // Prepare for the command parameters. 157777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_state = EXPECTS_PARAMETERS; 158777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_offset = 0; 159777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_bytes = uicmd->cmd_header.cmd_param_size; 160777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_buffer = malloc(uicmd->reader_bytes); 161777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine if (uicmd->reader_buffer == NULL) { 162777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine APANIC("Unable to allocate memory for UI command parameters.\n"); 163777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 164777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } else { 165777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // This command doesn't have any parameters. Handle it now. 166777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine _uiCmdImpl_handle_command(uicmd, &uicmd->cmd_header, NULL); 167777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // Prepare for the next command header. 168777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_state = EXPECTS_HEADER; 169777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_offset = 0; 170777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_bytes = sizeof(uicmd->cmd_header); 171777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_buffer = (uint8_t*)&uicmd->cmd_header; 172777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 173777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } else { 174777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // All command data is in. Handle it. 175777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine _uiCmdImpl_handle_command(uicmd, &uicmd->cmd_header, 176777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_buffer); 177777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // Prepare for the next command header. 178777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine free(uicmd->reader_buffer); 179777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_state = EXPECTS_HEADER; 180777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_offset = 0; 181777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_bytes = sizeof(uicmd->cmd_header); 182777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine uicmd->reader_buffer = (uint8_t*)&uicmd->cmd_header; 183777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 184777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 185777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine} 186777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 187777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkineint 188b6c168bbb6477145e843bb4a2e56e72e6d47822dDavid 'Digit' TurneruiCmdImpl_create(SockAddress* console_socket, Looper* looper) 189777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine{ 19021cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner UICmdImpl* uicmd = &_uiCmdImpl; 191777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine char* handshake = NULL; 192777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 193777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // Setup command reader. 19421cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner uicmd->reader_buffer = (uint8_t*)&uicmd->cmd_header; 19521cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner uicmd->reader_state = EXPECTS_HEADER; 19621cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner uicmd->reader_offset = 0; 19721cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner uicmd->reader_bytes = sizeof(UICmdHeader); 198777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 199777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine // Connect to the core-ui-control service. 20021cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner uicmd->core_connection = 201777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine core_connection_create_and_switch(console_socket, "core-ui-control", 202777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine &handshake); 20321cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner if (uicmd->core_connection == NULL) { 204777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine derror("Unable to connect to the core-ui-control service: %s\n", 205777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine errno_str); 206777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine return -1; 207777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 208777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 20907db34976ba1dd045a51c4ab2c7f52479cddcc57David 'Digit' Turner // Initialize UI command reader. 21021cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner uicmd->sock = core_connection_get_socket(uicmd->core_connection); 21121cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner loopIo_init(uicmd->io, looper, uicmd->sock, 212b6c168bbb6477145e843bb4a2e56e72e6d47822dDavid 'Digit' Turner _uiCmdImpl_io_callback, 213b6c168bbb6477145e843bb4a2e56e72e6d47822dDavid 'Digit' Turner &_uiCmdImpl); 21421cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner loopIo_wantRead(uicmd->io); 215777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 216777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine fprintf(stdout, "core-ui-control is now connected to the core at %s.", 217777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine sock_address_to_string(console_socket)); 218777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine if (handshake != NULL) { 219777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine if (handshake[0] != '\0') { 220777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine fprintf(stdout, " Handshake: %s", handshake); 221777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 222777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine free(handshake); 223777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine } 224777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine fprintf(stdout, "\n"); 225777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 226777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine return 0; 227777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine} 228777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine 22985276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkinevoid 23085276806ec6ac969d7befa2496c1de59adaaac74Vladimir ChtchetkineuiCmdImpl_destroy(void) 23185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine{ 23221cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner UICmdImpl* uicmd = &_uiCmdImpl; 23321cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner 23421cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner if (uicmd->core_connection != NULL) { 23585276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine // Disable I/O callbacks. 23621cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner loopIo_done(uicmd->io); 23721cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner core_connection_close(uicmd->core_connection); 23821cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner core_connection_free(uicmd->core_connection); 23921cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner uicmd->core_connection = NULL; 24085276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine } 24185276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine // Properly deallocate the reader buffer. 24221cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner if (uicmd->reader_buffer != NULL && 24321cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner uicmd->reader_buffer != (uint8_t*)&uicmd->cmd_header) { 24421cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner free(uicmd->reader_buffer); 24521cbdd244bfd12e16c034c910e2f667b44143de0David 'Digit' Turner uicmd->reader_buffer = (uint8_t*)&uicmd->cmd_header; 24685276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine } 24785276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine} 24885276806ec6ac969d7befa2496c1de59adaaac74Vladimir Chtchetkine 249777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkineint 250777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkineuicmd_set_brightness_change_callback(AndroidHwLightBrightnessCallback callback, 251777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine void* opaque) 252777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine{ 253777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine _brightness_change_callback = callback; 254777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine _brightness_change_callback_param = opaque; 255777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine return 0; 256777eb68eb60cac18f4b62e2e1b14a906875cbe7aVladimir Chtchetkine} 257