• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
toCommandHandler(android::sp<android::MessageHandler> & command)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         };
CommandHandler(RemoteAudio & thread,int command)111         CommandHandler(RemoteAudio& thread, int command)
112             : mThread(thread),
113               mMessage(command),
114               mNotifyOnReply(false),
115               mActive(false) {};
~CommandHandler()116         virtual ~CommandHandler() {};
117         void handleMessage(const android::Message& message);
timedWait(int timeInMSec)118         bool timedWait(int timeInMSec) {
119             return mClientWait.timedWait(timeInMSec);
120         };
getParam()121         AudioParam& getParam() {
122             return mParam;
123         };
getMessage()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