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