socket_client.h revision f972651484105181854f604e4709e32c8bf30375
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef CHRE_HOST_SOCKET_CLIENT_H_ 18#define CHRE_HOST_SOCKET_CLIENT_H_ 19 20#include <atomic> 21#include <condition_variable> 22#include <mutex> 23#include <thread> 24 25#include <cutils/sockets.h> 26#include <utils/RefBase.h> 27#include <utils/StrongPointer.h> 28 29namespace android { 30namespace chre { 31 32class SocketClient { 33 public: 34 SocketClient(); 35 ~SocketClient(); 36 37 /** 38 * Represents the callback interface used for handling events that occur on 39 * the receive thread. Note that it is *not* safe to call connect() or 40 * disconnect() from the context of these callbacks. 41 */ 42 class ICallbacks : public VirtualLightRefBase { 43 public: 44 /** 45 * Invoked from within the context of the read thread when a message is 46 * received on the socket. 47 * 48 * @param data Buffer containing received message data 49 * @param length Size of the message in bytes 50 */ 51 virtual void onMessageReceived(const void *data, size_t length) = 0; 52 53 /** 54 * Invoked when the remote side disconnects the socket. It is not safe to 55 * call connect() or disconnect() from the context of this callback. 56 */ 57 virtual void onSocketDisconnectedByRemote() {}; 58 59 /** 60 * Invoked if reconnectAutomatically was true in connect() and we've 61 * successfully reconnected the socket. 62 */ 63 virtual void onSocketReconnected() {}; 64 65 /** 66 * Invoked if reconnectAutomatically was true in connect(), and we've tried 67 * to reconnect the socket too many times and are giving up. After this, the 68 */ 69 virtual void onReconnectAborted() {}; 70 }; 71 72 /** 73 * Connects to the Android reserved namespace socket with the given name, 74 * and starts a receive thread to handle messages received on the socket. 75 * Returns 76 * 77 * @param socketName 78 * @param reconnectAutomatically If true, automatically attempt to re-connect 79 * to the socket if disconnected by the remote end. This does not 80 * influence the initial connection attempt, which happens 81 * synchronously within this function call. 82 * @param callbacks 83 * 84 * @return true if the connection was successful 85 */ 86 bool connect(const char *socketName, bool reconnectAutomatically, 87 ::android::sp<ICallbacks> callbacks); 88 89 /** 90 * Performs graceful teardown of the socket. After this function returns, this 91 * object will no longer invoke any callbacks or hold a reference to the 92 * callbacks object provided to connect(). 93 */ 94 void disconnect(); 95 96 /** 97 * Send a message on the connected socket. Safe to call from any thread. 98 * 99 * @param data Buffer containing message data 100 * @param length Size of the message to send in bytes 101 * 102 * @return true if the message was successfully sent 103 */ 104 bool sendMessage(const void *data, size_t length); 105 106 private: 107 static constexpr size_t kMaxSocketNameLen = 64; 108 char mSocketName[kMaxSocketNameLen]; 109 bool mReconnectAutomatically; 110 sp<ICallbacks> mCallbacks; 111 112 std::atomic<int> mSockFd; 113 std::thread mRxThread; 114 115 //! Set to true when we initiate the graceful socket shutdown procedure, so we 116 //! know not to invoke onSocketDisconnectedByRemote() 117 std::atomic<bool> mGracefulShutdown; 118 119 //! Condition variable used as the method to wake the RX thread when we want 120 //! to disconnect, but it's trying to reconnect automatically 121 std::condition_variable mShutdownCond; 122 std::mutex mShutdownMutex; 123 124 bool inReceiveThread() const; 125 void receiveThread(); 126 bool receiveThreadRunning() const; 127 bool reconnect(); 128 bool tryConnect(); 129}; 130 131} // namespace chre 132} // namespace android 133 134#endif // CHRE_HOST_SOCKET_CLIENT_H_ 135