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