/* Copyright (C) 2010 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/

/*
 * Contains the Core-side implementation of the "core-ui-control" service that is
 * part of the UI control protocol. Here we send UI control commands to the UI.
 */

#include "android/android.h"
#include "android/hw-control.h"
#include "android/looper.h"
#include "android/async-utils.h"
#include "android/sync-utils.h"
#include "android/utils/debug.h"
#include "android/protocol/ui-commands.h"
#include "android/protocol/ui-commands-proxy.h"
#include "android/protocol/ui-commands-api.h"

/* Descriptor for the UI commands proxy. */
typedef struct UICmdProxy {
    /* I/O associated with this descriptor. */
    LoopIo          io;

    /* Looper associated with this descriptor. */
    Looper*         looper;

    /* Writer to send UI commands. */
    SyncSocket*     sync_writer;

    /* Socket descriptor for this service. */
    int             sock;
} UICmdProxy;

/* One and only one UICmdProxy instance. */
static UICmdProxy    _uiCmdProxy;

/* Implemented in android/console.c */
extern void destroy_uicmd_client(void);

/* Calculates timeout for transferring the given number of bytes via socket.
 * Return:
 *  Number of milliseconds during which the entire number of bytes is expected
 *  to be transferred via socket.
 */
static int
_uiCmdProxy_get_timeout(size_t data_size)
{
    // Min 2 seconds + 10 millisec for each transferring byte.
    // TODO: Come up with a better arithmetics here.
    return 2000 + data_size * 10;
}

/* Sends request to the UI client of this service.
 * Param:
 *  cmd_type, cmd_param, cmd_param_size - Define the command to send.
 * Return:
 *  0 on success, or < 0 on failure.
 */
static int
_uiCmdProxy_send_command(uint8_t cmd_type,
                         void* cmd_param,
                         uint32_t cmd_param_size)
{
    UICmdHeader header;
    int status = syncsocket_start_write(_uiCmdProxy.sync_writer);
    if (!status) {
        // Initialize and send the header.
        header.cmd_type = cmd_type;
        header.cmd_param_size = cmd_param_size;
        status = syncsocket_write(_uiCmdProxy.sync_writer, &header, sizeof(header),
                                  _uiCmdProxy_get_timeout(sizeof(header)));
        // If there are command parameters, send them too.
        if (status > 0 && cmd_param != NULL && cmd_param_size > 0) {
            status = syncsocket_write(_uiCmdProxy.sync_writer, cmd_param,
                                      cmd_param_size,
                                      _uiCmdProxy_get_timeout(cmd_param_size));
        }
        status = syncsocket_result(status);
        syncsocket_stop_write(_uiCmdProxy.sync_writer);
    }
    if (status < 0) {
        derror("Send UI command %d (%u bytes) has failed: %s\n",
               cmd_type, cmd_param_size, errno_str);
    }
    return status;
}

/* Asynchronous I/O callback for UICmdProxy instance.
 * We expect this callback to be called only on UI detachment condition. In this
 * case the event should be LOOP_IO_READ, and read should fail with errno set
 * to ECONNRESET.
 * Param:
 *  opaque - UICmdProxy instance.
 */
static void
_uiCmdProxy_io_func(void* opaque, int fd, unsigned events)
{
    UICmdProxy* uicmd = (UICmdProxy*)opaque;
    AsyncReader reader;
    AsyncStatus status;
    uint8_t read_buf[1];

    if (events & LOOP_IO_WRITE) {
        derror("Unexpected LOOP_IO_WRITE in _uiCmdProxy_io_func.\n");
        return;
    }

    // Try to read
    asyncReader_init(&reader, read_buf, sizeof(read_buf), &uicmd->io);
    status = asyncReader_read(&reader);
    // We expect only error status here.
    if (status != ASYNC_ERROR) {
        derror("Unexpected read status %d in _uiCmdProxy_io_func\n", status);
        return;
    }
    // We expect only socket disconnection error here.
    if (errno != ECONNRESET) {
        derror("Unexpected read error %d (%s) in _uiCmdProxy_io_func.\n",
               errno, errno_str);
        return;
    }

    // Client got disconnectted.
    destroy_uicmd_client();
}
/* a callback function called when the system wants to change the brightness
 * of a given light. 'light' is a string which can be one of:
 * 'lcd_backlight', 'button_backlight' or 'Keyboard_backlight'
 *
 * brightness is an integer (acceptable range are 0..255), however the
 * default is around 105, and we probably don't want to dim the emulator's
 * output at that level.
 */
static void
_uiCmdProxy_brightness_change_callback(void* opaque,
                                       const char* light,
                                       int brightness)
{
    // Calculate size of the command parameters.
    const size_t cmd_size = sizeof(UICmdChangeDispBrightness) + strlen(light) + 1;
    // Allocate and initialize parameters.
    UICmdChangeDispBrightness* cmd =
        (UICmdChangeDispBrightness*)g_malloc(cmd_size);
    cmd->brightness = brightness;
    strcpy(cmd->light, light);
    // Send the command.
    _uiCmdProxy_send_command(AUICMD_CHANGE_DISP_BRIGHTNESS, cmd, cmd_size);
    g_free(cmd);
}

int
uiCmdProxy_create(int fd)
{
    // Initialize the only UICmdProxy instance.
    _uiCmdProxy.sock = fd;
    _uiCmdProxy.looper = looper_newCore();
    loopIo_init(&_uiCmdProxy.io, _uiCmdProxy.looper, _uiCmdProxy.sock,
                _uiCmdProxy_io_func, &_uiCmdProxy);
    loopIo_wantRead(&_uiCmdProxy.io);
    _uiCmdProxy.sync_writer = syncsocket_init(fd);
    if (_uiCmdProxy.sync_writer == NULL) {
        derror("Unable to initialize UICmdProxy writer: %s\n", errno_str);
        uiCmdProxy_destroy();
        return -1;
    }
    {
        // Set brighness change callback, so we can notify
        // the UI about the event.
        AndroidHwControlFuncs  funcs;
        funcs.light_brightness = _uiCmdProxy_brightness_change_callback;
        android_hw_control_set(&_uiCmdProxy, &funcs);
    }
    return 0;
}

void
uiCmdProxy_destroy()
{
    // Destroy the sync writer.
    if (_uiCmdProxy.sync_writer != NULL) {
        syncsocket_close(_uiCmdProxy.sync_writer);
        syncsocket_free(_uiCmdProxy.sync_writer);
    }
    if (_uiCmdProxy.looper != NULL) {
        // Stop all I/O that may still be going on.
        loopIo_done(&_uiCmdProxy.io);
        looper_free(_uiCmdProxy.looper);
        _uiCmdProxy.looper = NULL;
    }
    _uiCmdProxy.sock = -1;
}

int
uicmd_set_window_scale(double scale, int is_dpi)
{
    UICmdSetWindowsScale cmd;
    cmd.scale = scale;
    cmd.is_dpi = is_dpi;
    return _uiCmdProxy_send_command(AUICMD_SET_WINDOWS_SCALE, &cmd, sizeof(cmd));
}
