• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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