From 89e2dcf83fa3901090893e98c17708e279dea47f Mon Sep 17 00:00:00 2001 From: Tom Marshall Date: Mon, 24 Nov 2014 15:11:41 -0800 Subject: recovery: Initial dialog implementation Implement two types of dialogs: info and error. Info dialogs are intended to show that an operation is in progress and cannot be interrupted. Error dialogs are intended to show that an error occurred. The user must respond by dismissing the dialog with any input (a swipe or keypress). Dialogs may be initiated internally within the UI code or externally via a named local socket. Dialogs created via socket are presumed to be info and may not be dismissed. When the client socket is closed, the dialog automatically dismisses. Initial implementation shows dialogs for adb backup and restore. Future work will show dialogs for all errors and lengthy operations. Change-Id: Icefea12ec0fd70fb487d54aa2eb1cae9dd451355 --- messagesocket.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 messagesocket.cpp (limited to 'messagesocket.cpp') diff --git a/messagesocket.cpp b/messagesocket.cpp new file mode 100644 index 0000000..355a667 --- /dev/null +++ b/messagesocket.cpp @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "messagesocket.h" + +static const char * const SOCKET_PATH = "/tmp/.dialog_sock"; + +bool MessageSocket::ServerInit() +{ + int fd, rc; + unlink(SOCKET_PATH); + fd = ::socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + return false; + } + struct sockaddr_un sa; + socklen_t salen; + memset(&sa, 0, sizeof(sa)); + sa.sun_family = AF_UNIX; + strcpy(sa.sun_path, SOCKET_PATH); + rc = ::bind(fd, (struct sockaddr *)&sa, sizeof(sa)); + if (rc != 0) { + ::close(fd); + return false; + } + rc = ::listen(fd, 5); + if (rc != 0) { + ::close(fd); + return false; + } + _sock = fd; + return true; +} + +MessageSocket* MessageSocket::Accept() +{ + int clientfd; + struct sockaddr_un sa; + socklen_t salen; + memset(&sa, 0, sizeof(sa)); + salen = sizeof(sa); + clientfd = ::accept(_sock, (struct sockaddr*)&sa, &salen); + if (clientfd < 0) { + return NULL; + } + return new MessageSocket(clientfd); +} + +ssize_t MessageSocket::Read(void* buf, size_t len) +{ + //XXX: use fdopen/getline + ssize_t nread = ::read(_sock, buf, len); + if (nread > 0) { + char* p = (char*)memchr(buf, '\n', nread); + if (p) { + *p = '\0'; + } + } + return nread; +} + +bool MessageSocket::ClientInit() +{ + int fd, rc; + fd = ::socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + return false; + } + struct sockaddr_un sa; + socklen_t salen; + memset(&sa, 0, sizeof(sa)); + sa.sun_family = AF_UNIX; + strcpy(sa.sun_path, SOCKET_PATH); + rc = ::connect(fd, (struct sockaddr*)&sa, sizeof(sa)); + if (rc != 0) { + ::close(fd); + return false; + } + _sock = fd; + return true; +} + +bool MessageSocket::Show(const char* message) +{ + char buf[256]; + sprintf(buf, "show %s", message); + return send_command(buf); +} + +bool MessageSocket::Dismiss() +{ + return send_command("dismiss"); +} + +void MessageSocket::Close() +{ + if (_sock != -1) { + ::close(_sock); + _sock = -1; + } +} + +bool MessageSocket::send_command(const char* command) +{ + char buf[256]; + int len; + ssize_t written; + len = sprintf(buf, "dialog %s\n", command); + written = ::write(_sock, buf, len); + return (written == len); +} -- cgit v1.1