Home | History | Annotate | Download | only in source
      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