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 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "WifiDisplaySource"
     19 #include <utils/Log.h>
     20 
     21 #include "WifiDisplaySource.h"
     22 #include "PlaybackSession.h"
     23 #include "Parameters.h"
     24 #include "rtp/RTPSender.h"
     25 
     26 #include <binder/IServiceManager.h>
     27 #include <gui/IGraphicBufferProducer.h>
     28 #include <media/IHDCP.h>
     29 #include <media/IMediaPlayerService.h>
     30 #include <media/IRemoteDisplayClient.h>
     31 #include <media/stagefright/foundation/ABuffer.h>
     32 #include <media/stagefright/foundation/ADebug.h>
     33 #include <media/stagefright/foundation/AMessage.h>
     34 #include <media/stagefright/foundation/ParsedMessage.h>
     35 #include <media/stagefright/MediaErrors.h>
     36 #include <media/stagefright/Utils.h>
     37 
     38 #include <arpa/inet.h>
     39 #include <cutils/properties.h>
     40 
     41 #include <ctype.h>
     42 
     43 namespace android {
     44 
     45 // static
     46 const int64_t WifiDisplaySource::kReaperIntervalUs;
     47 const int64_t WifiDisplaySource::kTeardownTriggerTimeouSecs;
     48 const int64_t WifiDisplaySource::kPlaybackSessionTimeoutSecs;
     49 const int64_t WifiDisplaySource::kPlaybackSessionTimeoutUs;
     50 const AString WifiDisplaySource::sUserAgent = MakeUserAgent();
     51 
     52 WifiDisplaySource::WifiDisplaySource(
     53         const String16 &opPackageName,
     54         const sp<ANetworkSession> &netSession,
     55         const sp<IRemoteDisplayClient> &client,
     56         const char *path)
     57     : mOpPackageName(opPackageName),
     58       mState(INITIALIZED),
     59       mNetSession(netSession),
     60       mClient(client),
     61       mSessionID(0),
     62       mStopReplyID(NULL),
     63       mChosenRTPPort(-1),
     64       mUsingPCMAudio(false),
     65       mClientSessionID(0),
     66       mReaperPending(false),
     67       mNextCSeq(1),
     68       mUsingHDCP(false),
     69       mIsHDCP2_0(false),
     70       mHDCPPort(0),
     71       mHDCPInitializationComplete(false),
     72       mSetupTriggerDeferred(false),
     73       mPlaybackSessionEstablished(false) {
     74     if (path != NULL) {
     75         mMediaPath.setTo(path);
     76     }
     77 
     78     mSupportedSourceVideoFormats.disableAll();
     79 
     80     mSupportedSourceVideoFormats.setNativeResolution(
     81             VideoFormats::RESOLUTION_CEA, 5);  // 1280x720 p30
     82 
     83     // Enable all resolutions up to 1280x720p30
     84     mSupportedSourceVideoFormats.enableResolutionUpto(
     85             VideoFormats::RESOLUTION_CEA, 5,
     86             VideoFormats::PROFILE_CHP,  // Constrained High Profile
     87             VideoFormats::LEVEL_32);    // Level 3.2
     88 }
     89 
     90 WifiDisplaySource::~WifiDisplaySource() {
     91 }
     92 
     93 static status_t PostAndAwaitResponse(
     94         const sp<AMessage> &msg, sp<AMessage> *response) {
     95     status_t err = msg->postAndAwaitResponse(response);
     96 
     97     if (err != OK) {
     98         return err;
     99     }
    100 
    101     if (response == NULL || !(*response)->findInt32("err", &err)) {
    102         err = OK;
    103     }
    104 
    105     return err;
    106 }
    107 
    108 status_t WifiDisplaySource::start(const char *iface) {
    109     CHECK_EQ(mState, INITIALIZED);
    110 
    111     sp<AMessage> msg = new AMessage(kWhatStart, this);
    112     msg->setString("iface", iface);
    113 
    114     sp<AMessage> response;
    115     return PostAndAwaitResponse(msg, &response);
    116 }
    117 
    118 status_t WifiDisplaySource::stop() {
    119     sp<AMessage> msg = new AMessage(kWhatStop, this);
    120 
    121     sp<AMessage> response;
    122     return PostAndAwaitResponse(msg, &response);
    123 }
    124 
    125 status_t WifiDisplaySource::pause() {
    126     sp<AMessage> msg = new AMessage(kWhatPause, this);
    127 
    128     sp<AMessage> response;
    129     return PostAndAwaitResponse(msg, &response);
    130 }
    131 
    132 status_t WifiDisplaySource::resume() {
    133     sp<AMessage> msg = new AMessage(kWhatResume, this);
    134 
    135     sp<AMessage> response;
    136     return PostAndAwaitResponse(msg, &response);
    137 }
    138 
    139 void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
    140     switch (msg->what()) {
    141         case kWhatStart:
    142         {
    143             sp<AReplyToken> replyID;
    144             CHECK(msg->senderAwaitsResponse(&replyID));
    145 
    146             AString iface;
    147             CHECK(msg->findString("iface", &iface));
    148 
    149             status_t err = OK;
    150 
    151             ssize_t colonPos = iface.find(":");
    152 
    153             unsigned long port;
    154 
    155             if (colonPos >= 0) {
    156                 const char *s = iface.c_str() + colonPos + 1;
    157 
    158                 char *end;
    159                 port = strtoul(s, &end, 10);
    160 
    161                 if (end == s || *end != '\0' || port > 65535) {
    162                     err = -EINVAL;
    163                 } else {
    164                     iface.erase(colonPos, iface.size() - colonPos);
    165                 }
    166             } else {
    167                 port = kWifiDisplayDefaultPort;
    168             }
    169 
    170             if (err == OK) {
    171                 if (inet_aton(iface.c_str(), &mInterfaceAddr) != 0) {
    172                     sp<AMessage> notify = new AMessage(kWhatRTSPNotify, this);
    173 
    174                     err = mNetSession->createRTSPServer(
    175                             mInterfaceAddr, port, notify, &mSessionID);
    176                 } else {
    177                     err = -EINVAL;
    178                 }
    179             }
    180 
    181             mState = AWAITING_CLIENT_CONNECTION;
    182 
    183             sp<AMessage> response = new AMessage;
    184             response->setInt32("err", err);
    185             response->postReply(replyID);
    186             break;
    187         }
    188 
    189         case kWhatRTSPNotify:
    190         {
    191             int32_t reason;
    192             CHECK(msg->findInt32("reason", &reason));
    193 
    194             switch (reason) {
    195                 case ANetworkSession::kWhatError:
    196                 {
    197                     int32_t sessionID;
    198                     CHECK(msg->findInt32("sessionID", &sessionID));
    199 
    200                     int32_t err;
    201                     CHECK(msg->findInt32("err", &err));
    202 
    203                     AString detail;
    204                     CHECK(msg->findString("detail", &detail));
    205 
    206                     ALOGE("An error occurred in session %d (%d, '%s/%s').",
    207                           sessionID,
    208                           err,
    209                           detail.c_str(),
    210                           strerror(-err));
    211 
    212                     mNetSession->destroySession(sessionID);
    213 
    214                     if (sessionID == mClientSessionID) {
    215                         mClientSessionID = 0;
    216 
    217                         mClient->onDisplayError(
    218                                 IRemoteDisplayClient::kDisplayErrorUnknown);
    219                     }
    220                     break;
    221                 }
    222 
    223                 case ANetworkSession::kWhatClientConnected:
    224                 {
    225                     int32_t sessionID;
    226                     CHECK(msg->findInt32("sessionID", &sessionID));
    227 
    228                     if (mClientSessionID > 0) {
    229                         ALOGW("A client tried to connect, but we already "
    230                               "have one.");
    231 
    232                         mNetSession->destroySession(sessionID);
    233                         break;
    234                     }
    235 
    236                     CHECK_EQ(mState, AWAITING_CLIENT_CONNECTION);
    237 
    238                     CHECK(msg->findString("client-ip", &mClientInfo.mRemoteIP));
    239                     CHECK(msg->findString("server-ip", &mClientInfo.mLocalIP));
    240 
    241                     if (mClientInfo.mRemoteIP == mClientInfo.mLocalIP) {
    242                         // Disallow connections from the local interface
    243                         // for security reasons.
    244                         mNetSession->destroySession(sessionID);
    245                         break;
    246                     }
    247 
    248                     CHECK(msg->findInt32(
    249                                 "server-port", &mClientInfo.mLocalPort));
    250                     mClientInfo.mPlaybackSessionID = -1;
    251 
    252                     mClientSessionID = sessionID;
    253 
    254                     ALOGI("We now have a client (%d) connected.", sessionID);
    255 
    256                     mState = AWAITING_CLIENT_SETUP;
    257 
    258                     status_t err = sendM1(sessionID);
    259                     CHECK_EQ(err, (status_t)OK);
    260                     break;
    261                 }
    262 
    263                 case ANetworkSession::kWhatData:
    264                 {
    265                     status_t err = onReceiveClientData(msg);
    266 
    267                     if (err != OK) {
    268                         mClient->onDisplayError(
    269                                 IRemoteDisplayClient::kDisplayErrorUnknown);
    270                     }
    271 
    272 #if 0
    273                     // testing only.
    274                     char val[PROPERTY_VALUE_MAX];
    275                     if (property_get("media.wfd.trigger", val, NULL)) {
    276                         if (!strcasecmp(val, "pause") && mState == PLAYING) {
    277                             mState = PLAYING_TO_PAUSED;
    278                             sendTrigger(mClientSessionID, TRIGGER_PAUSE);
    279                         } else if (!strcasecmp(val, "play")
    280                                     && mState == PAUSED) {
    281                             mState = PAUSED_TO_PLAYING;
    282                             sendTrigger(mClientSessionID, TRIGGER_PLAY);
    283                         }
    284                     }
    285 #endif
    286                     break;
    287                 }
    288 
    289                 case ANetworkSession::kWhatNetworkStall:
    290                 {
    291                     break;
    292                 }
    293 
    294                 default:
    295                     TRESPASS();
    296             }
    297             break;
    298         }
    299 
    300         case kWhatStop:
    301         {
    302             CHECK(msg->senderAwaitsResponse(&mStopReplyID));
    303 
    304             CHECK_LT(mState, AWAITING_CLIENT_TEARDOWN);
    305 
    306             if (mState >= AWAITING_CLIENT_PLAY) {
    307                 // We have a session, i.e. a previous SETUP succeeded.
    308 
    309                 status_t err = sendTrigger(
    310                         mClientSessionID, TRIGGER_TEARDOWN);
    311 
    312                 if (err == OK) {
    313                     mState = AWAITING_CLIENT_TEARDOWN;
    314 
    315                     (new AMessage(kWhatTeardownTriggerTimedOut, this))->post(
    316                             kTeardownTriggerTimeouSecs * 1000000ll);
    317 
    318                     break;
    319                 }
    320 
    321                 // fall through.
    322             }
    323 
    324             finishStop();
    325             break;
    326         }
    327 
    328         case kWhatPause:
    329         {
    330             sp<AReplyToken> replyID;
    331             CHECK(msg->senderAwaitsResponse(&replyID));
    332 
    333             status_t err = OK;
    334 
    335             if (mState != PLAYING) {
    336                 err = INVALID_OPERATION;
    337             } else {
    338                 mState = PLAYING_TO_PAUSED;
    339                 sendTrigger(mClientSessionID, TRIGGER_PAUSE);
    340             }
    341 
    342             sp<AMessage> response = new AMessage;
    343             response->setInt32("err", err);
    344             response->postReply(replyID);
    345             break;
    346         }
    347 
    348         case kWhatResume:
    349         {
    350             sp<AReplyToken> replyID;
    351             CHECK(msg->senderAwaitsResponse(&replyID));
    352 
    353             status_t err = OK;
    354 
    355             if (mState != PAUSED) {
    356                 err = INVALID_OPERATION;
    357             } else {
    358                 mState = PAUSED_TO_PLAYING;
    359                 sendTrigger(mClientSessionID, TRIGGER_PLAY);
    360             }
    361 
    362             sp<AMessage> response = new AMessage;
    363             response->setInt32("err", err);
    364             response->postReply(replyID);
    365             break;
    366         }
    367 
    368         case kWhatReapDeadClients:
    369         {
    370             mReaperPending = false;
    371 
    372             if (mClientSessionID == 0
    373                     || mClientInfo.mPlaybackSession == NULL) {
    374                 break;
    375             }
    376 
    377             if (mClientInfo.mPlaybackSession->getLastLifesignUs()
    378                     + kPlaybackSessionTimeoutUs < ALooper::GetNowUs()) {
    379                 ALOGI("playback session timed out, reaping.");
    380 
    381                 mNetSession->destroySession(mClientSessionID);
    382                 mClientSessionID = 0;
    383 
    384                 mClient->onDisplayError(
    385                         IRemoteDisplayClient::kDisplayErrorUnknown);
    386             } else {
    387                 scheduleReaper();
    388             }
    389             break;
    390         }
    391 
    392         case kWhatPlaybackSessionNotify:
    393         {
    394             int32_t playbackSessionID;
    395             CHECK(msg->findInt32("playbackSessionID", &playbackSessionID));
    396 
    397             int32_t what;
    398             CHECK(msg->findInt32("what", &what));
    399 
    400             if (what == PlaybackSession::kWhatSessionDead) {
    401                 ALOGI("playback session wants to quit.");
    402 
    403                 mClient->onDisplayError(
    404                         IRemoteDisplayClient::kDisplayErrorUnknown);
    405             } else if (what == PlaybackSession::kWhatSessionEstablished) {
    406                 mPlaybackSessionEstablished = true;
    407 
    408                 if (mClient != NULL) {
    409                     if (!mSinkSupportsVideo) {
    410                         mClient->onDisplayConnected(
    411                                 NULL,  // SurfaceTexture
    412                                 0, // width,
    413                                 0, // height,
    414                                 mUsingHDCP
    415                                     ? IRemoteDisplayClient::kDisplayFlagSecure
    416                                     : 0,
    417                                 0);
    418                     } else {
    419                         size_t width, height;
    420 
    421                         CHECK(VideoFormats::GetConfiguration(
    422                                     mChosenVideoResolutionType,
    423                                     mChosenVideoResolutionIndex,
    424                                     &width,
    425                                     &height,
    426                                     NULL /* framesPerSecond */,
    427                                     NULL /* interlaced */));
    428 
    429                         mClient->onDisplayConnected(
    430                                 mClientInfo.mPlaybackSession
    431                                     ->getSurfaceTexture(),
    432                                 width,
    433                                 height,
    434                                 mUsingHDCP
    435                                     ? IRemoteDisplayClient::kDisplayFlagSecure
    436                                     : 0,
    437                                 playbackSessionID);
    438                     }
    439                 }
    440 
    441                 finishPlay();
    442 
    443                 if (mState == ABOUT_TO_PLAY) {
    444                     mState = PLAYING;
    445                 }
    446             } else if (what == PlaybackSession::kWhatSessionDestroyed) {
    447                 disconnectClient2();
    448             } else {
    449                 CHECK_EQ(what, PlaybackSession::kWhatBinaryData);
    450 
    451                 int32_t channel;
    452                 CHECK(msg->findInt32("channel", &channel));
    453 
    454                 sp<ABuffer> data;
    455                 CHECK(msg->findBuffer("data", &data));
    456 
    457                 CHECK_LE(channel, 0xffu);
    458                 CHECK_LE(data->size(), 0xffffu);
    459 
    460                 int32_t sessionID;
    461                 CHECK(msg->findInt32("sessionID", &sessionID));
    462 
    463                 char header[4];
    464                 header[0] = '$';
    465                 header[1] = channel;
    466                 header[2] = data->size() >> 8;
    467                 header[3] = data->size() & 0xff;
    468 
    469                 mNetSession->sendRequest(
    470                         sessionID, header, sizeof(header));
    471 
    472                 mNetSession->sendRequest(
    473                         sessionID, data->data(), data->size());
    474             }
    475             break;
    476         }
    477 
    478         case kWhatKeepAlive:
    479         {
    480             int32_t sessionID;
    481             CHECK(msg->findInt32("sessionID", &sessionID));
    482 
    483             if (mClientSessionID != sessionID) {
    484                 // Obsolete event, client is already gone.
    485                 break;
    486             }
    487 
    488             sendM16(sessionID);
    489             break;
    490         }
    491 
    492         case kWhatTeardownTriggerTimedOut:
    493         {
    494             if (mState == AWAITING_CLIENT_TEARDOWN) {
    495                 ALOGI("TEARDOWN trigger timed out, forcing disconnection.");
    496 
    497                 CHECK(mStopReplyID != NULL);
    498                 finishStop();
    499                 break;
    500             }
    501             break;
    502         }
    503 
    504         case kWhatHDCPNotify:
    505         {
    506             int32_t msgCode, ext1, ext2;
    507             CHECK(msg->findInt32("msg", &msgCode));
    508             CHECK(msg->findInt32("ext1", &ext1));
    509             CHECK(msg->findInt32("ext2", &ext2));
    510 
    511             ALOGI("Saw HDCP notification code %d, ext1 %d, ext2 %d",
    512                     msgCode, ext1, ext2);
    513 
    514             switch (msgCode) {
    515                 case HDCPModule::HDCP_INITIALIZATION_COMPLETE:
    516                 {
    517                     mHDCPInitializationComplete = true;
    518 
    519                     if (mSetupTriggerDeferred) {
    520                         mSetupTriggerDeferred = false;
    521 
    522                         sendTrigger(mClientSessionID, TRIGGER_SETUP);
    523                     }
    524                     break;
    525                 }
    526 
    527                 case HDCPModule::HDCP_SHUTDOWN_COMPLETE:
    528                 case HDCPModule::HDCP_SHUTDOWN_FAILED:
    529                 {
    530                     // Ugly hack to make sure that the call to
    531                     // HDCPObserver::notify is completely handled before
    532                     // we clear the HDCP instance and unload the shared
    533                     // library :(
    534                     (new AMessage(kWhatFinishStop2, this))->post(300000ll);
    535                     break;
    536                 }
    537 
    538                 default:
    539                 {
    540                     ALOGE("HDCP failure, shutting down.");
    541 
    542                     mClient->onDisplayError(
    543                             IRemoteDisplayClient::kDisplayErrorUnknown);
    544                     break;
    545                 }
    546             }
    547             break;
    548         }
    549 
    550         case kWhatFinishStop2:
    551         {
    552             finishStop2();
    553             break;
    554         }
    555 
    556         default:
    557             TRESPASS();
    558     }
    559 }
    560 
    561 void WifiDisplaySource::registerResponseHandler(
    562         int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func) {
    563     ResponseID id;
    564     id.mSessionID = sessionID;
    565     id.mCSeq = cseq;
    566     mResponseHandlers.add(id, func);
    567 }
    568 
    569 status_t WifiDisplaySource::sendM1(int32_t sessionID) {
    570     AString request = "OPTIONS * RTSP/1.0\r\n";
    571     AppendCommonResponse(&request, mNextCSeq);
    572 
    573     request.append(
    574             "Require: org.wfa.wfd1.0\r\n"
    575             "\r\n");
    576 
    577     status_t err =
    578         mNetSession->sendRequest(sessionID, request.c_str(), request.size());
    579 
    580     if (err != OK) {
    581         return err;
    582     }
    583 
    584     registerResponseHandler(
    585             sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM1Response);
    586 
    587     ++mNextCSeq;
    588 
    589     return OK;
    590 }
    591 
    592 status_t WifiDisplaySource::sendM3(int32_t sessionID) {
    593     AString body =
    594         "wfd_content_protection\r\n"
    595         "wfd_video_formats\r\n"
    596         "wfd_audio_codecs\r\n"
    597         "wfd_client_rtp_ports\r\n";
    598 
    599     AString request = "GET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
    600     AppendCommonResponse(&request, mNextCSeq);
    601 
    602     request.append("Content-Type: text/parameters\r\n");
    603     request.append(AStringPrintf("Content-Length: %d\r\n", body.size()));
    604     request.append("\r\n");
    605     request.append(body);
    606 
    607     status_t err =
    608         mNetSession->sendRequest(sessionID, request.c_str(), request.size());
    609 
    610     if (err != OK) {
    611         return err;
    612     }
    613 
    614     registerResponseHandler(
    615             sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM3Response);
    616 
    617     ++mNextCSeq;
    618 
    619     return OK;
    620 }
    621 
    622 status_t WifiDisplaySource::sendM4(int32_t sessionID) {
    623     CHECK_EQ(sessionID, mClientSessionID);
    624 
    625     AString body;
    626 
    627     if (mSinkSupportsVideo) {
    628         body.append("wfd_video_formats: ");
    629 
    630         VideoFormats chosenVideoFormat;
    631         chosenVideoFormat.disableAll();
    632         chosenVideoFormat.setNativeResolution(
    633                 mChosenVideoResolutionType, mChosenVideoResolutionIndex);
    634         chosenVideoFormat.setProfileLevel(
    635                 mChosenVideoResolutionType, mChosenVideoResolutionIndex,
    636                 mChosenVideoProfile, mChosenVideoLevel);
    637 
    638         body.append(chosenVideoFormat.getFormatSpec(true /* forM4Message */));
    639         body.append("\r\n");
    640     }
    641 
    642     if (mSinkSupportsAudio) {
    643         body.append(
    644                 AStringPrintf("wfd_audio_codecs: %s\r\n",
    645                              (mUsingPCMAudio
    646                                 ? "LPCM 00000002 00" // 2 ch PCM 48kHz
    647                                 : "AAC 00000001 00")));  // 2 ch AAC 48kHz
    648     }
    649 
    650     body.append(
    651             AStringPrintf(
    652                 "wfd_presentation_URL: rtsp://%s/wfd1.0/streamid=0 none\r\n",
    653                 mClientInfo.mLocalIP.c_str()));
    654 
    655     body.append(
    656             AStringPrintf(
    657                 "wfd_client_rtp_ports: %s\r\n", mWfdClientRtpPorts.c_str()));
    658 
    659     AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
    660     AppendCommonResponse(&request, mNextCSeq);
    661 
    662     request.append("Content-Type: text/parameters\r\n");
    663     request.append(AStringPrintf("Content-Length: %d\r\n", body.size()));
    664     request.append("\r\n");
    665     request.append(body);
    666 
    667     status_t err =
    668         mNetSession->sendRequest(sessionID, request.c_str(), request.size());
    669 
    670     if (err != OK) {
    671         return err;
    672     }
    673 
    674     registerResponseHandler(
    675             sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM4Response);
    676 
    677     ++mNextCSeq;
    678 
    679     return OK;
    680 }
    681 
    682 status_t WifiDisplaySource::sendTrigger(
    683         int32_t sessionID, TriggerType triggerType) {
    684     AString body = "wfd_trigger_method: ";
    685     switch (triggerType) {
    686         case TRIGGER_SETUP:
    687             body.append("SETUP");
    688             break;
    689         case TRIGGER_TEARDOWN:
    690             ALOGI("Sending TEARDOWN trigger.");
    691             body.append("TEARDOWN");
    692             break;
    693         case TRIGGER_PAUSE:
    694             body.append("PAUSE");
    695             break;
    696         case TRIGGER_PLAY:
    697             body.append("PLAY");
    698             break;
    699         default:
    700             TRESPASS();
    701     }
    702 
    703     body.append("\r\n");
    704 
    705     AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
    706     AppendCommonResponse(&request, mNextCSeq);
    707 
    708     request.append("Content-Type: text/parameters\r\n");
    709     request.append(AStringPrintf("Content-Length: %d\r\n", body.size()));
    710     request.append("\r\n");
    711     request.append(body);
    712 
    713     status_t err =
    714         mNetSession->sendRequest(sessionID, request.c_str(), request.size());
    715 
    716     if (err != OK) {
    717         return err;
    718     }
    719 
    720     registerResponseHandler(
    721             sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM5Response);
    722 
    723     ++mNextCSeq;
    724 
    725     return OK;
    726 }
    727 
    728 status_t WifiDisplaySource::sendM16(int32_t sessionID) {
    729     AString request = "GET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
    730     AppendCommonResponse(&request, mNextCSeq);
    731 
    732     CHECK_EQ(sessionID, mClientSessionID);
    733     request.append(
    734             AStringPrintf("Session: %d\r\n", mClientInfo.mPlaybackSessionID));
    735     request.append("\r\n");  // Empty body
    736 
    737     status_t err =
    738         mNetSession->sendRequest(sessionID, request.c_str(), request.size());
    739 
    740     if (err != OK) {
    741         return err;
    742     }
    743 
    744     registerResponseHandler(
    745             sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM16Response);
    746 
    747     ++mNextCSeq;
    748 
    749     scheduleKeepAlive(sessionID);
    750 
    751     return OK;
    752 }
    753 
    754 status_t WifiDisplaySource::onReceiveM1Response(
    755         int32_t /* sessionID */, const sp<ParsedMessage> &msg) {
    756     int32_t statusCode;
    757     if (!msg->getStatusCode(&statusCode)) {
    758         return ERROR_MALFORMED;
    759     }
    760 
    761     if (statusCode != 200) {
    762         return ERROR_UNSUPPORTED;
    763     }
    764 
    765     return OK;
    766 }
    767 
    768 // sink_audio_list := ("LPCM"|"AAC"|"AC3" HEXDIGIT*8 HEXDIGIT*2)
    769 //                       (", " sink_audio_list)*
    770 static void GetAudioModes(const char *s, const char *prefix, uint32_t *modes) {
    771     *modes = 0;
    772 
    773     size_t prefixLen = strlen(prefix);
    774 
    775     while (*s != '0') {
    776         if (!strncmp(s, prefix, prefixLen) && s[prefixLen] == ' ') {
    777             unsigned latency;
    778             if (sscanf(&s[prefixLen + 1], "%08x %02x", modes, &latency) != 2) {
    779                 *modes = 0;
    780             }
    781 
    782             return;
    783         }
    784 
    785         char *commaPos = strchr(s, ',');
    786         if (commaPos != NULL) {
    787             s = commaPos + 1;
    788 
    789             while (isspace(*s)) {
    790                 ++s;
    791             }
    792         } else {
    793             break;
    794         }
    795     }
    796 }
    797 
    798 status_t WifiDisplaySource::onReceiveM3Response(
    799         int32_t sessionID, const sp<ParsedMessage> &msg) {
    800     int32_t statusCode;
    801     if (!msg->getStatusCode(&statusCode)) {
    802         return ERROR_MALFORMED;
    803     }
    804 
    805     if (statusCode != 200) {
    806         return ERROR_UNSUPPORTED;
    807     }
    808 
    809     sp<Parameters> params =
    810         Parameters::Parse(msg->getContent(), strlen(msg->getContent()));
    811 
    812     if (params == NULL) {
    813         return ERROR_MALFORMED;
    814     }
    815 
    816     AString value;
    817     if (!params->findParameter("wfd_client_rtp_ports", &value)) {
    818         ALOGE("Sink doesn't report its choice of wfd_client_rtp_ports.");
    819         return ERROR_MALFORMED;
    820     }
    821 
    822     unsigned port0 = 0, port1 = 0;
    823     if (sscanf(value.c_str(),
    824                "RTP/AVP/UDP;unicast %u %u mode=play",
    825                &port0,
    826                &port1) == 2
    827         || sscanf(value.c_str(),
    828                "RTP/AVP/TCP;unicast %u %u mode=play",
    829                &port0,
    830                &port1) == 2) {
    831             if (port0 == 0 || port0 > 65535 || port1 != 0) {
    832                 ALOGE("Sink chose its wfd_client_rtp_ports poorly (%s)",
    833                       value.c_str());
    834 
    835                 return ERROR_MALFORMED;
    836             }
    837     } else if (strcmp(value.c_str(), "RTP/AVP/TCP;interleaved mode=play")) {
    838         ALOGE("Unsupported value for wfd_client_rtp_ports (%s)",
    839               value.c_str());
    840 
    841         return ERROR_UNSUPPORTED;
    842     }
    843 
    844     mWfdClientRtpPorts = value;
    845     mChosenRTPPort = port0;
    846 
    847     if (!params->findParameter("wfd_video_formats", &value)) {
    848         ALOGE("Sink doesn't report its choice of wfd_video_formats.");
    849         return ERROR_MALFORMED;
    850     }
    851 
    852     mSinkSupportsVideo = false;
    853 
    854     if  (!(value == "none")) {
    855         mSinkSupportsVideo = true;
    856         if (!mSupportedSinkVideoFormats.parseFormatSpec(value.c_str())) {
    857             ALOGE("Failed to parse sink provided wfd_video_formats (%s)",
    858                   value.c_str());
    859 
    860             return ERROR_MALFORMED;
    861         }
    862 
    863         if (!VideoFormats::PickBestFormat(
    864                     mSupportedSinkVideoFormats,
    865                     mSupportedSourceVideoFormats,
    866                     &mChosenVideoResolutionType,
    867                     &mChosenVideoResolutionIndex,
    868                     &mChosenVideoProfile,
    869                     &mChosenVideoLevel)) {
    870             ALOGE("Sink and source share no commonly supported video "
    871                   "formats.");
    872 
    873             return ERROR_UNSUPPORTED;
    874         }
    875 
    876         size_t width, height, framesPerSecond;
    877         bool interlaced;
    878         CHECK(VideoFormats::GetConfiguration(
    879                     mChosenVideoResolutionType,
    880                     mChosenVideoResolutionIndex,
    881                     &width,
    882                     &height,
    883                     &framesPerSecond,
    884                     &interlaced));
    885 
    886         ALOGI("Picked video resolution %zu x %zu %c%zu",
    887               width, height, interlaced ? 'i' : 'p', framesPerSecond);
    888 
    889         ALOGI("Picked AVC profile %d, level %d",
    890               mChosenVideoProfile, mChosenVideoLevel);
    891     } else {
    892         ALOGI("Sink doesn't support video at all.");
    893     }
    894 
    895     if (!params->findParameter("wfd_audio_codecs", &value)) {
    896         ALOGE("Sink doesn't report its choice of wfd_audio_codecs.");
    897         return ERROR_MALFORMED;
    898     }
    899 
    900     mSinkSupportsAudio = false;
    901 
    902     if  (!(value == "none")) {
    903         mSinkSupportsAudio = true;
    904 
    905         uint32_t modes;
    906         GetAudioModes(value.c_str(), "AAC", &modes);
    907 
    908         bool supportsAAC = (modes & 1) != 0;  // AAC 2ch 48kHz
    909 
    910         GetAudioModes(value.c_str(), "LPCM", &modes);
    911 
    912         bool supportsPCM = (modes & 2) != 0;  // LPCM 2ch 48kHz
    913 
    914         char val[PROPERTY_VALUE_MAX];
    915         if (supportsPCM
    916                 && property_get("media.wfd.use-pcm-audio", val, NULL)
    917                 && (!strcasecmp("true", val) || !strcmp("1", val))) {
    918             ALOGI("Using PCM audio.");
    919             mUsingPCMAudio = true;
    920         } else if (supportsAAC) {
    921             ALOGI("Using AAC audio.");
    922             mUsingPCMAudio = false;
    923         } else if (supportsPCM) {
    924             ALOGI("Using PCM audio.");
    925             mUsingPCMAudio = true;
    926         } else {
    927             ALOGI("Sink doesn't support an audio format we do.");
    928             return ERROR_UNSUPPORTED;
    929         }
    930     } else {
    931         ALOGI("Sink doesn't support audio at all.");
    932     }
    933 
    934     if (!mSinkSupportsVideo && !mSinkSupportsAudio) {
    935         ALOGE("Sink supports neither video nor audio...");
    936         return ERROR_UNSUPPORTED;
    937     }
    938 
    939     mUsingHDCP = false;
    940     if (!params->findParameter("wfd_content_protection", &value)) {
    941         ALOGI("Sink doesn't appear to support content protection.");
    942     } else if (value == "none") {
    943         ALOGI("Sink does not support content protection.");
    944     } else {
    945         mUsingHDCP = true;
    946 
    947         bool isHDCP2_0 = false;
    948         if (value.startsWith("HDCP2.0 ")) {
    949             isHDCP2_0 = true;
    950         } else if (!value.startsWith("HDCP2.1 ")) {
    951             ALOGE("malformed wfd_content_protection: '%s'", value.c_str());
    952 
    953             return ERROR_MALFORMED;
    954         }
    955 
    956         int32_t hdcpPort;
    957         if (!ParsedMessage::GetInt32Attribute(
    958                     value.c_str() + 8, "port", &hdcpPort)
    959                 || hdcpPort < 1 || hdcpPort > 65535) {
    960             return ERROR_MALFORMED;
    961         }
    962 
    963         mIsHDCP2_0 = isHDCP2_0;
    964         mHDCPPort = hdcpPort;
    965 
    966         status_t err = makeHDCP();
    967         if (err != OK) {
    968             ALOGE("Unable to instantiate HDCP component. "
    969                   "Not using HDCP after all.");
    970 
    971             mUsingHDCP = false;
    972         }
    973     }
    974 
    975     return sendM4(sessionID);
    976 }
    977 
    978 status_t WifiDisplaySource::onReceiveM4Response(
    979         int32_t sessionID, const sp<ParsedMessage> &msg) {
    980     int32_t statusCode;
    981     if (!msg->getStatusCode(&statusCode)) {
    982         return ERROR_MALFORMED;
    983     }
    984 
    985     if (statusCode != 200) {
    986         return ERROR_UNSUPPORTED;
    987     }
    988 
    989     if (mUsingHDCP && !mHDCPInitializationComplete) {
    990         ALOGI("Deferring SETUP trigger until HDCP initialization completes.");
    991 
    992         mSetupTriggerDeferred = true;
    993         return OK;
    994     }
    995 
    996     return sendTrigger(sessionID, TRIGGER_SETUP);
    997 }
    998 
    999 status_t WifiDisplaySource::onReceiveM5Response(
   1000         int32_t /* sessionID */, const sp<ParsedMessage> &msg) {
   1001     int32_t statusCode;
   1002     if (!msg->getStatusCode(&statusCode)) {
   1003         return ERROR_MALFORMED;
   1004     }
   1005 
   1006     if (statusCode != 200) {
   1007         return ERROR_UNSUPPORTED;
   1008     }
   1009 
   1010     return OK;
   1011 }
   1012 
   1013 status_t WifiDisplaySource::onReceiveM16Response(
   1014         int32_t sessionID, const sp<ParsedMessage> & /* msg */) {
   1015     // If only the response was required to include a "Session:" header...
   1016 
   1017     CHECK_EQ(sessionID, mClientSessionID);
   1018 
   1019     if (mClientInfo.mPlaybackSession != NULL) {
   1020         mClientInfo.mPlaybackSession->updateLiveness();
   1021     }
   1022 
   1023     return OK;
   1024 }
   1025 
   1026 void WifiDisplaySource::scheduleReaper() {
   1027     if (mReaperPending) {
   1028         return;
   1029     }
   1030 
   1031     mReaperPending = true;
   1032     (new AMessage(kWhatReapDeadClients, this))->post(kReaperIntervalUs);
   1033 }
   1034 
   1035 void WifiDisplaySource::scheduleKeepAlive(int32_t sessionID) {
   1036     // We need to send updates at least 5 secs before the timeout is set to
   1037     // expire, make sure the timeout is greater than 5 secs to begin with.
   1038     CHECK_GT(kPlaybackSessionTimeoutUs, 5000000ll);
   1039 
   1040     sp<AMessage> msg = new AMessage(kWhatKeepAlive, this);
   1041     msg->setInt32("sessionID", sessionID);
   1042     msg->post(kPlaybackSessionTimeoutUs - 5000000ll);
   1043 }
   1044 
   1045 status_t WifiDisplaySource::onReceiveClientData(const sp<AMessage> &msg) {
   1046     int32_t sessionID;
   1047     CHECK(msg->findInt32("sessionID", &sessionID));
   1048 
   1049     sp<RefBase> obj;
   1050     CHECK(msg->findObject("data", &obj));
   1051 
   1052     sp<ParsedMessage> data =
   1053         static_cast<ParsedMessage *>(obj.get());
   1054 
   1055     ALOGV("session %d received '%s'",
   1056           sessionID, data->debugString().c_str());
   1057 
   1058     AString method;
   1059     AString uri;
   1060     data->getRequestField(0, &method);
   1061 
   1062     int32_t cseq;
   1063     if (!data->findInt32("cseq", &cseq)) {
   1064         sendErrorResponse(sessionID, "400 Bad Request", -1 /* cseq */);
   1065         return ERROR_MALFORMED;
   1066     }
   1067 
   1068     if (method.startsWith("RTSP/")) {
   1069         // This is a response.
   1070 
   1071         ResponseID id;
   1072         id.mSessionID = sessionID;
   1073         id.mCSeq = cseq;
   1074 
   1075         ssize_t index = mResponseHandlers.indexOfKey(id);
   1076 
   1077         if (index < 0) {
   1078             ALOGW("Received unsolicited server response, cseq %d", cseq);
   1079             return ERROR_MALFORMED;
   1080         }
   1081 
   1082         HandleRTSPResponseFunc func = mResponseHandlers.valueAt(index);
   1083         mResponseHandlers.removeItemsAt(index);
   1084 
   1085         status_t err = (this->*func)(sessionID, data);
   1086 
   1087         if (err != OK) {
   1088             ALOGW("Response handler for session %d, cseq %d returned "
   1089                   "err %d (%s)",
   1090                   sessionID, cseq, err, strerror(-err));
   1091 
   1092             return err;
   1093         }
   1094 
   1095         return OK;
   1096     }
   1097 
   1098     AString version;
   1099     data->getRequestField(2, &version);
   1100     if (!(version == AString("RTSP/1.0"))) {
   1101         sendErrorResponse(sessionID, "505 RTSP Version not supported", cseq);
   1102         return ERROR_UNSUPPORTED;
   1103     }
   1104 
   1105     status_t err;
   1106     if (method == "OPTIONS") {
   1107         err = onOptionsRequest(sessionID, cseq, data);
   1108     } else if (method == "SETUP") {
   1109         err = onSetupRequest(sessionID, cseq, data);
   1110     } else if (method == "PLAY") {
   1111         err = onPlayRequest(sessionID, cseq, data);
   1112     } else if (method == "PAUSE") {
   1113         err = onPauseRequest(sessionID, cseq, data);
   1114     } else if (method == "TEARDOWN") {
   1115         err = onTeardownRequest(sessionID, cseq, data);
   1116     } else if (method == "GET_PARAMETER") {
   1117         err = onGetParameterRequest(sessionID, cseq, data);
   1118     } else if (method == "SET_PARAMETER") {
   1119         err = onSetParameterRequest(sessionID, cseq, data);
   1120     } else {
   1121         sendErrorResponse(sessionID, "405 Method Not Allowed", cseq);
   1122 
   1123         err = ERROR_UNSUPPORTED;
   1124     }
   1125 
   1126     return err;
   1127 }
   1128 
   1129 status_t WifiDisplaySource::onOptionsRequest(
   1130         int32_t sessionID,
   1131         int32_t cseq,
   1132         const sp<ParsedMessage> &data) {
   1133     int32_t playbackSessionID;
   1134     sp<PlaybackSession> playbackSession =
   1135         findPlaybackSession(data, &playbackSessionID);
   1136 
   1137     if (playbackSession != NULL) {
   1138         playbackSession->updateLiveness();
   1139     }
   1140 
   1141     AString response = "RTSP/1.0 200 OK\r\n";
   1142     AppendCommonResponse(&response, cseq);
   1143 
   1144     response.append(
   1145             "Public: org.wfa.wfd1.0, SETUP, TEARDOWN, PLAY, PAUSE, "
   1146             "GET_PARAMETER, SET_PARAMETER\r\n");
   1147 
   1148     response.append("\r\n");
   1149 
   1150     status_t err = mNetSession->sendRequest(sessionID, response.c_str());
   1151 
   1152     if (err == OK) {
   1153         err = sendM3(sessionID);
   1154     }
   1155 
   1156     return err;
   1157 }
   1158 
   1159 status_t WifiDisplaySource::onSetupRequest(
   1160         int32_t sessionID,
   1161         int32_t cseq,
   1162         const sp<ParsedMessage> &data) {
   1163     CHECK_EQ(sessionID, mClientSessionID);
   1164     if (mClientInfo.mPlaybackSessionID != -1) {
   1165         // We only support a single playback session per client.
   1166         // This is due to the reversed keep-alive design in the wfd specs...
   1167         sendErrorResponse(sessionID, "400 Bad Request", cseq);
   1168         return ERROR_MALFORMED;
   1169     }
   1170 
   1171     AString transport;
   1172     if (!data->findString("transport", &transport)) {
   1173         sendErrorResponse(sessionID, "400 Bad Request", cseq);
   1174         return ERROR_MALFORMED;
   1175     }
   1176 
   1177     RTPSender::TransportMode rtpMode = RTPSender::TRANSPORT_UDP;
   1178 
   1179     int clientRtp, clientRtcp;
   1180     if (transport.startsWith("RTP/AVP/TCP;")) {
   1181         AString interleaved;
   1182         if (ParsedMessage::GetAttribute(
   1183                     transport.c_str(), "interleaved", &interleaved)
   1184                 && sscanf(interleaved.c_str(), "%d-%d",
   1185                           &clientRtp, &clientRtcp) == 2) {
   1186             rtpMode = RTPSender::TRANSPORT_TCP_INTERLEAVED;
   1187         } else {
   1188             bool badRequest = false;
   1189 
   1190             AString clientPort;
   1191             if (!ParsedMessage::GetAttribute(
   1192                         transport.c_str(), "client_port", &clientPort)) {
   1193                 badRequest = true;
   1194             } else if (sscanf(clientPort.c_str(), "%d-%d",
   1195                               &clientRtp, &clientRtcp) == 2) {
   1196             } else if (sscanf(clientPort.c_str(), "%d", &clientRtp) == 1) {
   1197                 // No RTCP.
   1198                 clientRtcp = -1;
   1199             } else {
   1200                 badRequest = true;
   1201             }
   1202 
   1203             if (badRequest) {
   1204                 sendErrorResponse(sessionID, "400 Bad Request", cseq);
   1205                 return ERROR_MALFORMED;
   1206             }
   1207 
   1208             rtpMode = RTPSender::TRANSPORT_TCP;
   1209         }
   1210     } else if (transport.startsWith("RTP/AVP;unicast;")
   1211             || transport.startsWith("RTP/AVP/UDP;unicast;")) {
   1212         bool badRequest = false;
   1213 
   1214         AString clientPort;
   1215         if (!ParsedMessage::GetAttribute(
   1216                     transport.c_str(), "client_port", &clientPort)) {
   1217             badRequest = true;
   1218         } else if (sscanf(clientPort.c_str(), "%d-%d",
   1219                           &clientRtp, &clientRtcp) == 2) {
   1220         } else if (sscanf(clientPort.c_str(), "%d", &clientRtp) == 1) {
   1221             // No RTCP.
   1222             clientRtcp = -1;
   1223         } else {
   1224             badRequest = true;
   1225         }
   1226 
   1227         if (badRequest) {
   1228             sendErrorResponse(sessionID, "400 Bad Request", cseq);
   1229             return ERROR_MALFORMED;
   1230         }
   1231 #if 1
   1232     // The older LG dongles doesn't specify client_port=xxx apparently.
   1233     } else if (transport == "RTP/AVP/UDP;unicast") {
   1234         clientRtp = 19000;
   1235         clientRtcp = -1;
   1236 #endif
   1237     } else {
   1238         sendErrorResponse(sessionID, "461 Unsupported Transport", cseq);
   1239         return ERROR_UNSUPPORTED;
   1240     }
   1241 
   1242     int32_t playbackSessionID = makeUniquePlaybackSessionID();
   1243 
   1244     sp<AMessage> notify = new AMessage(kWhatPlaybackSessionNotify, this);
   1245     notify->setInt32("playbackSessionID", playbackSessionID);
   1246     notify->setInt32("sessionID", sessionID);
   1247 
   1248     sp<PlaybackSession> playbackSession =
   1249         new PlaybackSession(
   1250                 mOpPackageName, mNetSession, notify, mInterfaceAddr, mHDCP, mMediaPath.c_str());
   1251 
   1252     looper()->registerHandler(playbackSession);
   1253 
   1254     AString uri;
   1255     data->getRequestField(1, &uri);
   1256 
   1257     if (strncasecmp("rtsp://", uri.c_str(), 7)) {
   1258         sendErrorResponse(sessionID, "400 Bad Request", cseq);
   1259         return ERROR_MALFORMED;
   1260     }
   1261 
   1262     if (!(uri.startsWith("rtsp://") && uri.endsWith("/wfd1.0/streamid=0"))) {
   1263         sendErrorResponse(sessionID, "404 Not found", cseq);
   1264         return ERROR_MALFORMED;
   1265     }
   1266 
   1267     RTPSender::TransportMode rtcpMode = RTPSender::TRANSPORT_UDP;
   1268     if (clientRtcp < 0) {
   1269         rtcpMode = RTPSender::TRANSPORT_NONE;
   1270     }
   1271 
   1272     status_t err = playbackSession->init(
   1273             mClientInfo.mRemoteIP.c_str(),
   1274             clientRtp,
   1275             rtpMode,
   1276             clientRtcp,
   1277             rtcpMode,
   1278             mSinkSupportsAudio,
   1279             mUsingPCMAudio,
   1280             mSinkSupportsVideo,
   1281             mChosenVideoResolutionType,
   1282             mChosenVideoResolutionIndex,
   1283             mChosenVideoProfile,
   1284             mChosenVideoLevel);
   1285 
   1286     if (err != OK) {
   1287         looper()->unregisterHandler(playbackSession->id());
   1288         playbackSession.clear();
   1289     }
   1290 
   1291     switch (err) {
   1292         case OK:
   1293             break;
   1294         case -ENOENT:
   1295             sendErrorResponse(sessionID, "404 Not Found", cseq);
   1296             return err;
   1297         default:
   1298             sendErrorResponse(sessionID, "403 Forbidden", cseq);
   1299             return err;
   1300     }
   1301 
   1302     mClientInfo.mPlaybackSessionID = playbackSessionID;
   1303     mClientInfo.mPlaybackSession = playbackSession;
   1304 
   1305     AString response = "RTSP/1.0 200 OK\r\n";
   1306     AppendCommonResponse(&response, cseq, playbackSessionID);
   1307 
   1308     if (rtpMode == RTPSender::TRANSPORT_TCP_INTERLEAVED) {
   1309         response.append(
   1310                 AStringPrintf(
   1311                     "Transport: RTP/AVP/TCP;interleaved=%d-%d;",
   1312                     clientRtp, clientRtcp));
   1313     } else {
   1314         int32_t serverRtp = playbackSession->getRTPPort();
   1315 
   1316         AString transportString = "UDP";
   1317         if (rtpMode == RTPSender::TRANSPORT_TCP) {
   1318             transportString = "TCP";
   1319         }
   1320 
   1321         if (clientRtcp >= 0) {
   1322             response.append(
   1323                     AStringPrintf(
   1324                         "Transport: RTP/AVP/%s;unicast;client_port=%d-%d;"
   1325                         "server_port=%d-%d\r\n",
   1326                         transportString.c_str(),
   1327                         clientRtp, clientRtcp, serverRtp, serverRtp + 1));
   1328         } else {
   1329             response.append(
   1330                     AStringPrintf(
   1331                         "Transport: RTP/AVP/%s;unicast;client_port=%d;"
   1332                         "server_port=%d\r\n",
   1333                         transportString.c_str(),
   1334                         clientRtp, serverRtp));
   1335         }
   1336     }
   1337 
   1338     response.append("\r\n");
   1339 
   1340     err = mNetSession->sendRequest(sessionID, response.c_str());
   1341 
   1342     if (err != OK) {
   1343         return err;
   1344     }
   1345 
   1346     mState = AWAITING_CLIENT_PLAY;
   1347 
   1348     scheduleReaper();
   1349     scheduleKeepAlive(sessionID);
   1350 
   1351     return OK;
   1352 }
   1353 
   1354 status_t WifiDisplaySource::onPlayRequest(
   1355         int32_t sessionID,
   1356         int32_t cseq,
   1357         const sp<ParsedMessage> &data) {
   1358     int32_t playbackSessionID;
   1359     sp<PlaybackSession> playbackSession =
   1360         findPlaybackSession(data, &playbackSessionID);
   1361 
   1362     if (playbackSession == NULL) {
   1363         sendErrorResponse(sessionID, "454 Session Not Found", cseq);
   1364         return ERROR_MALFORMED;
   1365     }
   1366 
   1367     if (mState != AWAITING_CLIENT_PLAY
   1368      && mState != PAUSED_TO_PLAYING
   1369      && mState != PAUSED) {
   1370         ALOGW("Received PLAY request but we're in state %d", mState);
   1371 
   1372         sendErrorResponse(
   1373                 sessionID, "455 Method Not Valid in This State", cseq);
   1374 
   1375         return INVALID_OPERATION;
   1376     }
   1377 
   1378     ALOGI("Received PLAY request.");
   1379     if (mPlaybackSessionEstablished) {
   1380         finishPlay();
   1381     } else {
   1382         ALOGI("deferring PLAY request until session established.");
   1383     }
   1384 
   1385     AString response = "RTSP/1.0 200 OK\r\n";
   1386     AppendCommonResponse(&response, cseq, playbackSessionID);
   1387     response.append("Range: npt=now-\r\n");
   1388     response.append("\r\n");
   1389 
   1390     status_t err = mNetSession->sendRequest(sessionID, response.c_str());
   1391 
   1392     if (err != OK) {
   1393         return err;
   1394     }
   1395 
   1396     if (mState == PAUSED_TO_PLAYING || mPlaybackSessionEstablished) {
   1397         mState = PLAYING;
   1398         return OK;
   1399     }
   1400 
   1401     CHECK_EQ(mState, AWAITING_CLIENT_PLAY);
   1402     mState = ABOUT_TO_PLAY;
   1403 
   1404     return OK;
   1405 }
   1406 
   1407 void WifiDisplaySource::finishPlay() {
   1408     const sp<PlaybackSession> &playbackSession =
   1409         mClientInfo.mPlaybackSession;
   1410 
   1411     status_t err = playbackSession->play();
   1412     CHECK_EQ(err, (status_t)OK);
   1413 }
   1414 
   1415 status_t WifiDisplaySource::onPauseRequest(
   1416         int32_t sessionID,
   1417         int32_t cseq,
   1418         const sp<ParsedMessage> &data) {
   1419     int32_t playbackSessionID;
   1420     sp<PlaybackSession> playbackSession =
   1421         findPlaybackSession(data, &playbackSessionID);
   1422 
   1423     if (playbackSession == NULL) {
   1424         sendErrorResponse(sessionID, "454 Session Not Found", cseq);
   1425         return ERROR_MALFORMED;
   1426     }
   1427 
   1428     ALOGI("Received PAUSE request.");
   1429 
   1430     if (mState != PLAYING_TO_PAUSED && mState != PLAYING) {
   1431         return INVALID_OPERATION;
   1432     }
   1433 
   1434     status_t err = playbackSession->pause();
   1435     CHECK_EQ(err, (status_t)OK);
   1436 
   1437     AString response = "RTSP/1.0 200 OK\r\n";
   1438     AppendCommonResponse(&response, cseq, playbackSessionID);
   1439     response.append("\r\n");
   1440 
   1441     err = mNetSession->sendRequest(sessionID, response.c_str());
   1442 
   1443     if (err != OK) {
   1444         return err;
   1445     }
   1446 
   1447     mState = PAUSED;
   1448 
   1449     return err;
   1450 }
   1451 
   1452 status_t WifiDisplaySource::onTeardownRequest(
   1453         int32_t sessionID,
   1454         int32_t cseq,
   1455         const sp<ParsedMessage> &data) {
   1456     ALOGI("Received TEARDOWN request.");
   1457 
   1458     int32_t playbackSessionID;
   1459     sp<PlaybackSession> playbackSession =
   1460         findPlaybackSession(data, &playbackSessionID);
   1461 
   1462     if (playbackSession == NULL) {
   1463         sendErrorResponse(sessionID, "454 Session Not Found", cseq);
   1464         return ERROR_MALFORMED;
   1465     }
   1466 
   1467     AString response = "RTSP/1.0 200 OK\r\n";
   1468     AppendCommonResponse(&response, cseq, playbackSessionID);
   1469     response.append("Connection: close\r\n");
   1470     response.append("\r\n");
   1471 
   1472     mNetSession->sendRequest(sessionID, response.c_str());
   1473 
   1474     if (mState == AWAITING_CLIENT_TEARDOWN) {
   1475         CHECK(mStopReplyID != NULL);
   1476         finishStop();
   1477     } else {
   1478         mClient->onDisplayError(IRemoteDisplayClient::kDisplayErrorUnknown);
   1479     }
   1480 
   1481     return OK;
   1482 }
   1483 
   1484 void WifiDisplaySource::finishStop() {
   1485     ALOGV("finishStop");
   1486 
   1487     mState = STOPPING;
   1488 
   1489     disconnectClientAsync();
   1490 }
   1491 
   1492 void WifiDisplaySource::finishStopAfterDisconnectingClient() {
   1493     ALOGV("finishStopAfterDisconnectingClient");
   1494 
   1495     if (mHDCP != NULL) {
   1496         ALOGI("Initiating HDCP shutdown.");
   1497         mHDCP->shutdownAsync();
   1498         return;
   1499     }
   1500 
   1501     finishStop2();
   1502 }
   1503 
   1504 void WifiDisplaySource::finishStop2() {
   1505     ALOGV("finishStop2");
   1506 
   1507     if (mHDCP != NULL) {
   1508         mHDCP->setObserver(NULL);
   1509         mHDCPObserver.clear();
   1510         mHDCP.clear();
   1511     }
   1512 
   1513     if (mSessionID != 0) {
   1514         mNetSession->destroySession(mSessionID);
   1515         mSessionID = 0;
   1516     }
   1517 
   1518     ALOGI("We're stopped.");
   1519     mState = STOPPED;
   1520 
   1521     status_t err = OK;
   1522 
   1523     sp<AMessage> response = new AMessage;
   1524     response->setInt32("err", err);
   1525     response->postReply(mStopReplyID);
   1526 }
   1527 
   1528 status_t WifiDisplaySource::onGetParameterRequest(
   1529         int32_t sessionID,
   1530         int32_t cseq,
   1531         const sp<ParsedMessage> &data) {
   1532     int32_t playbackSessionID;
   1533     sp<PlaybackSession> playbackSession =
   1534         findPlaybackSession(data, &playbackSessionID);
   1535 
   1536     if (playbackSession == NULL) {
   1537         sendErrorResponse(sessionID, "454 Session Not Found", cseq);
   1538         return ERROR_MALFORMED;
   1539     }
   1540 
   1541     playbackSession->updateLiveness();
   1542 
   1543     AString response = "RTSP/1.0 200 OK\r\n";
   1544     AppendCommonResponse(&response, cseq, playbackSessionID);
   1545     response.append("\r\n");
   1546 
   1547     status_t err = mNetSession->sendRequest(sessionID, response.c_str());
   1548     return err;
   1549 }
   1550 
   1551 status_t WifiDisplaySource::onSetParameterRequest(
   1552         int32_t sessionID,
   1553         int32_t cseq,
   1554         const sp<ParsedMessage> &data) {
   1555     int32_t playbackSessionID;
   1556     sp<PlaybackSession> playbackSession =
   1557         findPlaybackSession(data, &playbackSessionID);
   1558 
   1559     if (playbackSession == NULL) {
   1560         sendErrorResponse(sessionID, "454 Session Not Found", cseq);
   1561         return ERROR_MALFORMED;
   1562     }
   1563 
   1564     if (strstr(data->getContent(), "wfd_idr_request\r\n")) {
   1565         playbackSession->requestIDRFrame();
   1566     }
   1567 
   1568     playbackSession->updateLiveness();
   1569 
   1570     AString response = "RTSP/1.0 200 OK\r\n";
   1571     AppendCommonResponse(&response, cseq, playbackSessionID);
   1572     response.append("\r\n");
   1573 
   1574     status_t err = mNetSession->sendRequest(sessionID, response.c_str());
   1575     return err;
   1576 }
   1577 
   1578 // static
   1579 void WifiDisplaySource::AppendCommonResponse(
   1580         AString *response, int32_t cseq, int32_t playbackSessionID) {
   1581     time_t now = time(NULL);
   1582     struct tm *now2 = gmtime(&now);
   1583     char buf[128];
   1584     strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S %z", now2);
   1585 
   1586     response->append("Date: ");
   1587     response->append(buf);
   1588     response->append("\r\n");
   1589 
   1590     response->append(AStringPrintf("Server: %s\r\n", sUserAgent.c_str()));
   1591 
   1592     if (cseq >= 0) {
   1593         response->append(AStringPrintf("CSeq: %d\r\n", cseq));
   1594     }
   1595 
   1596     if (playbackSessionID >= 0ll) {
   1597         response->append(
   1598                 AStringPrintf(
   1599                     "Session: %d;timeout=%lld\r\n",
   1600                     playbackSessionID, kPlaybackSessionTimeoutSecs));
   1601     }
   1602 }
   1603 
   1604 void WifiDisplaySource::sendErrorResponse(
   1605         int32_t sessionID,
   1606         const char *errorDetail,
   1607         int32_t cseq) {
   1608     AString response;
   1609     response.append("RTSP/1.0 ");
   1610     response.append(errorDetail);
   1611     response.append("\r\n");
   1612 
   1613     AppendCommonResponse(&response, cseq);
   1614 
   1615     response.append("\r\n");
   1616 
   1617     mNetSession->sendRequest(sessionID, response.c_str());
   1618 }
   1619 
   1620 int32_t WifiDisplaySource::makeUniquePlaybackSessionID() const {
   1621     return rand();
   1622 }
   1623 
   1624 sp<WifiDisplaySource::PlaybackSession> WifiDisplaySource::findPlaybackSession(
   1625         const sp<ParsedMessage> &data, int32_t *playbackSessionID) const {
   1626     if (!data->findInt32("session", playbackSessionID)) {
   1627         // XXX the older dongles do not always include a "Session:" header.
   1628         *playbackSessionID = mClientInfo.mPlaybackSessionID;
   1629         return mClientInfo.mPlaybackSession;
   1630     }
   1631 
   1632     if (*playbackSessionID != mClientInfo.mPlaybackSessionID) {
   1633         return NULL;
   1634     }
   1635 
   1636     return mClientInfo.mPlaybackSession;
   1637 }
   1638 
   1639 void WifiDisplaySource::disconnectClientAsync() {
   1640     ALOGV("disconnectClient");
   1641 
   1642     if (mClientInfo.mPlaybackSession == NULL) {
   1643         disconnectClient2();
   1644         return;
   1645     }
   1646 
   1647     if (mClientInfo.mPlaybackSession != NULL) {
   1648         ALOGV("Destroying PlaybackSession");
   1649         mClientInfo.mPlaybackSession->destroyAsync();
   1650     }
   1651 }
   1652 
   1653 void WifiDisplaySource::disconnectClient2() {
   1654     ALOGV("disconnectClient2");
   1655 
   1656     if (mClientInfo.mPlaybackSession != NULL) {
   1657         looper()->unregisterHandler(mClientInfo.mPlaybackSession->id());
   1658         mClientInfo.mPlaybackSession.clear();
   1659     }
   1660 
   1661     if (mClientSessionID != 0) {
   1662         mNetSession->destroySession(mClientSessionID);
   1663         mClientSessionID = 0;
   1664     }
   1665 
   1666     mClient->onDisplayDisconnected();
   1667 
   1668     finishStopAfterDisconnectingClient();
   1669 }
   1670 
   1671 struct WifiDisplaySource::HDCPObserver : public BnHDCPObserver {
   1672     HDCPObserver(const sp<AMessage> &notify);
   1673 
   1674     virtual void notify(
   1675             int msg, int ext1, int ext2, const Parcel *obj);
   1676 
   1677 private:
   1678     sp<AMessage> mNotify;
   1679 
   1680     DISALLOW_EVIL_CONSTRUCTORS(HDCPObserver);
   1681 };
   1682 
   1683 WifiDisplaySource::HDCPObserver::HDCPObserver(
   1684         const sp<AMessage> &notify)
   1685     : mNotify(notify) {
   1686 }
   1687 
   1688 void WifiDisplaySource::HDCPObserver::notify(
   1689         int msg, int ext1, int ext2, const Parcel * /* obj */) {
   1690     sp<AMessage> notify = mNotify->dup();
   1691     notify->setInt32("msg", msg);
   1692     notify->setInt32("ext1", ext1);
   1693     notify->setInt32("ext2", ext2);
   1694     notify->post();
   1695 }
   1696 
   1697 status_t WifiDisplaySource::makeHDCP() {
   1698     sp<IServiceManager> sm = defaultServiceManager();
   1699     sp<IBinder> binder = sm->getService(String16("media.player"));
   1700 
   1701     sp<IMediaPlayerService> service =
   1702         interface_cast<IMediaPlayerService>(binder);
   1703 
   1704     CHECK(service != NULL);
   1705 
   1706     mHDCP = service->makeHDCP(true /* createEncryptionModule */);
   1707 
   1708     if (mHDCP == NULL) {
   1709         return ERROR_UNSUPPORTED;
   1710     }
   1711 
   1712     sp<AMessage> notify = new AMessage(kWhatHDCPNotify, this);
   1713     mHDCPObserver = new HDCPObserver(notify);
   1714 
   1715     status_t err = mHDCP->setObserver(mHDCPObserver);
   1716 
   1717     if (err != OK) {
   1718         ALOGE("Failed to set HDCP observer.");
   1719 
   1720         mHDCPObserver.clear();
   1721         mHDCP.clear();
   1722 
   1723         return err;
   1724     }
   1725 
   1726     ALOGI("Initiating HDCP negotiation w/ host %s:%d",
   1727             mClientInfo.mRemoteIP.c_str(), mHDCPPort);
   1728 
   1729     err = mHDCP->initAsync(mClientInfo.mRemoteIP.c_str(), mHDCPPort);
   1730 
   1731     if (err != OK) {
   1732         return err;
   1733     }
   1734 
   1735     return OK;
   1736 }
   1737 
   1738 }  // namespace android
   1739 
   1740