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