1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 18 #ifndef CTSAUDIO_REMOTEAUDIO_H 19 #define CTSAUDIO_REMOTEAUDIO_H 20 21 #include <map> 22 23 #include <utils/Looper.h> 24 #include <utils/String8.h> 25 #include <utils/StrongPointer.h> 26 #include <utils/threads.h> 27 28 #include "audio/Buffer.h" 29 #include "AudioProtocol.h" 30 #include "ClientSocket.h" 31 #include "Semaphore.h" 32 33 class CommandHandler; 34 /** 35 * Tcp communication runs in a separate thread, 36 * and client can communicate using public APIs 37 * Assumption: only one command at a time. No other command can come 38 * while a command is pending. 39 */ 40 class RemoteAudio: public android::Thread { 41 public: 42 43 explicit RemoteAudio(ClientSocket& socket); 44 virtual ~RemoteAudio(); 45 46 /** launch a thread, and connect to host */ 47 bool init(int port); 48 bool downloadData(const android::String8& name, android::sp<Buffer>& buffer, int& id); 49 // <0 : not found 50 int getDataId(const android::String8& name); 51 bool startPlayback(bool stereo, int samplingF, int mode, int volume, 52 int id, int numberRepetition); 53 void stopPlayback(); 54 bool waitForPlaybackCompletion(); 55 // buffer.getSize() determines number of samples 56 bool startRecording(bool stereo, int samplingF, int mode, int volume, 57 android::sp<Buffer>& buffer); 58 bool waitForRecordingCompletion(); 59 void stopRecording(); 60 61 bool getDeviceInfo(android::String8& data); 62 /** should be called before RemoteAudio is destroyed */ 63 void release(); 64 65 private: 66 RemoteAudio(const RemoteAudio&); 67 68 bool threadLoop(); 69 void wakeClient(bool result); 70 void cleanup(bool notifyClient); 71 72 bool handlePacket(); 73 static int socketRxCallback(int fd, int events, void* data); 74 75 class CommandHandler; 76 void sendCommand(android::sp<android::MessageHandler>& command); 77 78 // this is just semaphore wait without any addition 79 bool waitForCompletion(android::sp<android::MessageHandler>& command, int timeInMSec); 80 // common code for waitForXXXCompletion 81 bool waitForPlaybackOrRecordingCompletion( 82 android::sp<android::MessageHandler>& commandHandler); 83 // common code for stopXXX 84 void doStop(android::sp<android::MessageHandler>& commandHandler, AudioProtocol::CommandId id); 85 toCommandHandler(android::sp<android::MessageHandler> & command)86 CommandHandler* toCommandHandler(android::sp<android::MessageHandler>& command) { 87 return reinterpret_cast<CommandHandler*>(command.get()); 88 }; 89 90 private: 91 bool mExitRequested; 92 bool mInitResult; 93 // used only for notifying successful init 94 Semaphore mInitWait; 95 96 97 enum EventId { 98 EIdSocket = 1, 99 }; 100 static const int CLIENT_WAIT_TIMEOUT_MSEC = 2000; 101 int mPort; 102 ClientSocket& mSocket; 103 104 105 android::sp<android::Looper> mLooper; 106 107 friend class CommandHandler; 108 109 class CommandHandler: public android::MessageHandler { 110 public: 111 enum ClientCommands { 112 EExit = 1, 113 }; CommandHandler(RemoteAudio & thread,int command)114 CommandHandler(RemoteAudio& thread, int command) 115 : mThread(thread), 116 mMessage(command), 117 mNotifyOnReply(false), 118 mActive(false) {}; ~CommandHandler()119 virtual ~CommandHandler() {}; 120 void handleMessage(const android::Message& message); timedWait(int timeInMSec)121 bool timedWait(int timeInMSec) { 122 return mClientWait.timedWait(timeInMSec); 123 }; getParam()124 AudioParam& getParam() { 125 return mParam; 126 }; getMessage()127 android::Message& getMessage() { 128 return mMessage; 129 }; 130 131 private: 132 RemoteAudio& mThread; 133 AudioParam mParam; 134 Semaphore mClientWait; 135 android::Mutex mStateLock; 136 android::Message mMessage; 137 bool mResult; 138 bool mNotifyOnReply; 139 bool mActive; 140 friend class RemoteAudio; 141 }; 142 android::sp<android::MessageHandler> mDownloadHandler; 143 android::sp<android::MessageHandler> mPlaybackHandler; 144 android::sp<android::MessageHandler> mRecordingHandler; 145 android::sp<android::MessageHandler> mDeviceInfoHandler; 146 147 AudioProtocol* mCmds[AudioProtocol::ECmdLast - AudioProtocol::ECmdStart]; 148 int mDownloadId; 149 std::map<int, android::sp<Buffer> > mBufferList; 150 std::map<android::String8, int> mIdMap; 151 }; 152 153 154 155 #endif // CTSAUDIO_REMOTEAUDIO_H 156