WifiDisplaySource.h revision 6d339f1f764bbd32e3381dae7bfa7c6c575bb493
1/* 2 * Copyright 2012, 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 WIFI_DISPLAY_SOURCE_H_ 18 19#define WIFI_DISPLAY_SOURCE_H_ 20 21#include "VideoFormats.h" 22 23#include <media/stagefright/foundation/AHandler.h> 24#include <media/stagefright/foundation/ANetworkSession.h> 25 26#include <netinet/in.h> 27 28namespace android { 29 30struct AReplyToken; 31struct IHDCP; 32class IRemoteDisplayClient; 33struct ParsedMessage; 34 35// Represents the RTSP server acting as a wifi display source. 36// Manages incoming connections, sets up Playback sessions as necessary. 37struct WifiDisplaySource : public AHandler { 38 static const unsigned kWifiDisplayDefaultPort = 7236; 39 40 WifiDisplaySource( 41 const sp<ANetworkSession> &netSession, 42 const sp<IRemoteDisplayClient> &client, 43 const char *path = NULL); 44 45 status_t start(const char *iface); 46 status_t stop(); 47 48 status_t pause(); 49 status_t resume(); 50 51protected: 52 virtual ~WifiDisplaySource(); 53 virtual void onMessageReceived(const sp<AMessage> &msg); 54 55private: 56 struct PlaybackSession; 57 struct HDCPObserver; 58 59 enum State { 60 INITIALIZED, 61 AWAITING_CLIENT_CONNECTION, 62 AWAITING_CLIENT_SETUP, 63 AWAITING_CLIENT_PLAY, 64 ABOUT_TO_PLAY, 65 PLAYING, 66 PLAYING_TO_PAUSED, 67 PAUSED, 68 PAUSED_TO_PLAYING, 69 AWAITING_CLIENT_TEARDOWN, 70 STOPPING, 71 STOPPED, 72 }; 73 74 enum { 75 kWhatStart, 76 kWhatRTSPNotify, 77 kWhatStop, 78 kWhatPause, 79 kWhatResume, 80 kWhatReapDeadClients, 81 kWhatPlaybackSessionNotify, 82 kWhatKeepAlive, 83 kWhatHDCPNotify, 84 kWhatFinishStop2, 85 kWhatTeardownTriggerTimedOut, 86 }; 87 88 struct ResponseID { 89 int32_t mSessionID; 90 int32_t mCSeq; 91 92 bool operator<(const ResponseID &other) const { 93 return mSessionID < other.mSessionID 94 || (mSessionID == other.mSessionID 95 && mCSeq < other.mCSeq); 96 } 97 }; 98 99 typedef status_t (WifiDisplaySource::*HandleRTSPResponseFunc)( 100 int32_t sessionID, const sp<ParsedMessage> &msg); 101 102 static const int64_t kReaperIntervalUs = 1000000ll; 103 104 // We request that the dongle send us a "TEARDOWN" in order to 105 // perform an orderly shutdown. We're willing to wait up to 2 secs 106 // for this message to arrive, after that we'll force a disconnect 107 // instead. 108 static const int64_t kTeardownTriggerTimeouSecs = 2; 109 110 static const int64_t kPlaybackSessionTimeoutSecs = 30; 111 112 static const int64_t kPlaybackSessionTimeoutUs = 113 kPlaybackSessionTimeoutSecs * 1000000ll; 114 115 static const AString sUserAgent; 116 117 State mState; 118 VideoFormats mSupportedSourceVideoFormats; 119 sp<ANetworkSession> mNetSession; 120 sp<IRemoteDisplayClient> mClient; 121 AString mMediaPath; 122 struct in_addr mInterfaceAddr; 123 int32_t mSessionID; 124 125 sp<AReplyToken> mStopReplyID; 126 127 AString mWfdClientRtpPorts; 128 int32_t mChosenRTPPort; // extracted from "wfd_client_rtp_ports" 129 130 bool mSinkSupportsVideo; 131 VideoFormats mSupportedSinkVideoFormats; 132 133 VideoFormats::ResolutionType mChosenVideoResolutionType; 134 size_t mChosenVideoResolutionIndex; 135 VideoFormats::ProfileType mChosenVideoProfile; 136 VideoFormats::LevelType mChosenVideoLevel; 137 138 bool mSinkSupportsAudio; 139 140 bool mUsingPCMAudio; 141 int32_t mClientSessionID; 142 143 struct ClientInfo { 144 AString mRemoteIP; 145 AString mLocalIP; 146 int32_t mLocalPort; 147 int32_t mPlaybackSessionID; 148 sp<PlaybackSession> mPlaybackSession; 149 }; 150 ClientInfo mClientInfo; 151 152 bool mReaperPending; 153 154 int32_t mNextCSeq; 155 156 KeyedVector<ResponseID, HandleRTSPResponseFunc> mResponseHandlers; 157 158 // HDCP specific section >>>> 159 bool mUsingHDCP; 160 bool mIsHDCP2_0; 161 int32_t mHDCPPort; 162 sp<IHDCP> mHDCP; 163 sp<HDCPObserver> mHDCPObserver; 164 165 bool mHDCPInitializationComplete; 166 bool mSetupTriggerDeferred; 167 168 bool mPlaybackSessionEstablished; 169 170 status_t makeHDCP(); 171 // <<<< HDCP specific section 172 173 status_t sendM1(int32_t sessionID); 174 status_t sendM3(int32_t sessionID); 175 status_t sendM4(int32_t sessionID); 176 177 enum TriggerType { 178 TRIGGER_SETUP, 179 TRIGGER_TEARDOWN, 180 TRIGGER_PAUSE, 181 TRIGGER_PLAY, 182 }; 183 184 // M5 185 status_t sendTrigger(int32_t sessionID, TriggerType triggerType); 186 187 status_t sendM16(int32_t sessionID); 188 189 status_t onReceiveM1Response( 190 int32_t sessionID, const sp<ParsedMessage> &msg); 191 192 status_t onReceiveM3Response( 193 int32_t sessionID, const sp<ParsedMessage> &msg); 194 195 status_t onReceiveM4Response( 196 int32_t sessionID, const sp<ParsedMessage> &msg); 197 198 status_t onReceiveM5Response( 199 int32_t sessionID, const sp<ParsedMessage> &msg); 200 201 status_t onReceiveM16Response( 202 int32_t sessionID, const sp<ParsedMessage> &msg); 203 204 void registerResponseHandler( 205 int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func); 206 207 status_t onReceiveClientData(const sp<AMessage> &msg); 208 209 status_t onOptionsRequest( 210 int32_t sessionID, 211 int32_t cseq, 212 const sp<ParsedMessage> &data); 213 214 status_t onSetupRequest( 215 int32_t sessionID, 216 int32_t cseq, 217 const sp<ParsedMessage> &data); 218 219 status_t onPlayRequest( 220 int32_t sessionID, 221 int32_t cseq, 222 const sp<ParsedMessage> &data); 223 224 status_t onPauseRequest( 225 int32_t sessionID, 226 int32_t cseq, 227 const sp<ParsedMessage> &data); 228 229 status_t onTeardownRequest( 230 int32_t sessionID, 231 int32_t cseq, 232 const sp<ParsedMessage> &data); 233 234 status_t onGetParameterRequest( 235 int32_t sessionID, 236 int32_t cseq, 237 const sp<ParsedMessage> &data); 238 239 status_t onSetParameterRequest( 240 int32_t sessionID, 241 int32_t cseq, 242 const sp<ParsedMessage> &data); 243 244 void sendErrorResponse( 245 int32_t sessionID, 246 const char *errorDetail, 247 int32_t cseq); 248 249 static void AppendCommonResponse( 250 AString *response, int32_t cseq, int32_t playbackSessionID = -1ll); 251 252 void scheduleReaper(); 253 void scheduleKeepAlive(int32_t sessionID); 254 255 int32_t makeUniquePlaybackSessionID() const; 256 257 sp<PlaybackSession> findPlaybackSession( 258 const sp<ParsedMessage> &data, int32_t *playbackSessionID) const; 259 260 void finishStop(); 261 void disconnectClientAsync(); 262 void disconnectClient2(); 263 void finishStopAfterDisconnectingClient(); 264 void finishStop2(); 265 266 void finishPlay(); 267 268 DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySource); 269}; 270 271} // namespace android 272 273#endif // WIFI_DISPLAY_SOURCE_H_ 274