Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32ca2bfb authored by Andreas Huber's avatar Andreas Huber Committed by The Android Automerger
Browse files

Perform an orderly shutdown if possible, force disconnect if necessary

wait for up to 2 secs for the dongle to send us a "TEARDOWN", after that
forcibly shutdown the connection.

Change-Id: Ie049857cd468b7af6986d6305f725c54571b2276
related-to-bug: 7258622
parent 27f706e4
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -173,13 +173,11 @@ status_t WifiDisplaySource::PlaybackSession::Track::start() {
void WifiDisplaySource::PlaybackSession::Track::stopAsync() {
    ALOGV("Track::stopAsync isAudio=%d", mIsAudio);

    CHECK(mStarted);

    mConverter->shutdownAsync();

    sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());

    if (mMediaPuller != NULL) {
    if (mStarted && mMediaPuller != NULL) {
        mMediaPuller->stopAsync(msg);
    } else {
        msg->post();
+50 −4
Original line number Diff line number Diff line
@@ -41,7 +41,8 @@ namespace android {
WifiDisplaySource::WifiDisplaySource(
        const sp<ANetworkSession> &netSession,
        const sp<IRemoteDisplayClient> &client)
    : mNetSession(netSession),
    : mState(INITIALIZED),
      mNetSession(netSession),
      mClient(client),
      mSessionID(0),
      mStopReplyID(0),
@@ -61,6 +62,8 @@ WifiDisplaySource::~WifiDisplaySource() {
}

status_t WifiDisplaySource::start(const char *iface) {
    CHECK_EQ(mState, INITIALIZED);

    sp<AMessage> msg = new AMessage(kWhatStart, id());
    msg->setString("iface", iface);

@@ -137,6 +140,10 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
                }
            }

            if (err == OK) {
                mState = AWAITING_CLIENT_CONNECTION;
            }

            sp<AMessage> response = new AMessage;
            response->setInt32("err", err);
            response->postReply(replyID);
@@ -190,6 +197,8 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
                        break;
                    }

                    CHECK_EQ(mState, AWAITING_CLIENT_CONNECTION);

                    CHECK(msg->findString("client-ip", &mClientInfo.mRemoteIP));
                    CHECK(msg->findString("server-ip", &mClientInfo.mLocalIP));

@@ -208,6 +217,8 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {

                    ALOGI("We now have a client (%d) connected.", sessionID);

                    mState = AWAITING_CLIENT_SETUP;

                    status_t err = sendM1(sessionID);
                    CHECK_EQ(err, (status_t)OK);
                    break;
@@ -234,14 +245,24 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
        {
            CHECK(msg->senderAwaitsResponse(&mStopReplyID));

            if (mClientSessionID != 0
                    && mClientInfo.mPlaybackSessionID != -1) {
            CHECK_LT(mState, AWAITING_CLIENT_TEARDOWN);

            if (mState >= AWAITING_CLIENT_PLAY) {
                // We have a session, i.e. a previous SETUP succeeded.

                status_t err = sendM5(
                        mClientSessionID, true /* requestShutdown */);

                if (err == OK) {
                    mState = AWAITING_CLIENT_TEARDOWN;

                    (new AMessage(kWhatTeardownTriggerTimedOut, id()))->post(
                            kTeardownTriggerTimeouSecs * 1000000ll);

                    break;
                }

                // fall through.
            }

            finishStop();
@@ -293,6 +314,10 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
                            mClientInfo.mPlaybackSession->height(),
                            0 /* flags */);
                }

                if (mState == ABOUT_TO_PLAY) {
                    mState = PLAYING;
                }
            } else if (what == PlaybackSession::kWhatSessionDestroyed) {
                disconnectClient2();
            } else {
@@ -339,6 +364,18 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
            break;
        }

        case kWhatTeardownTriggerTimedOut:
        {
            if (mState == AWAITING_CLIENT_TEARDOWN) {
                ALOGI("TEARDOWN trigger timed out, forcing disconnection.");

                CHECK_NE(mStopReplyID, 0);
                finishStop();
                break;
            }
            break;
        }

#if REQUIRE_HDCP
        case kWhatHDCPNotify:
        {
@@ -1020,6 +1057,8 @@ status_t WifiDisplaySource::onSetupRequest(
        return err;
    }

    mState = AWAITING_CLIENT_PLAY;

    scheduleReaper();
    scheduleKeepAlive(sessionID);

@@ -1057,6 +1096,9 @@ status_t WifiDisplaySource::onPlayRequest(

    playbackSession->finishPlay();

    CHECK_EQ(mState, AWAITING_CLIENT_PLAY);
    mState = ABOUT_TO_PLAY;

    return OK;
}

@@ -1107,7 +1149,8 @@ status_t WifiDisplaySource::onTeardownRequest(

    mNetSession->sendRequest(sessionID, response.c_str());

    if (mStopReplyID != 0) {
    if (mState == AWAITING_CLIENT_TEARDOWN) {
        CHECK_NE(mStopReplyID, 0);
        finishStop();
    } else {
        mClient->onDisplayError(IRemoteDisplayClient::kDisplayErrorUnknown);
@@ -1119,6 +1162,8 @@ status_t WifiDisplaySource::onTeardownRequest(
void WifiDisplaySource::finishStop() {
    ALOGV("finishStop");

    mState = STOPPING;

    disconnectClientAsync();
}

@@ -1153,6 +1198,7 @@ void WifiDisplaySource::finishStop2() {
    }

    ALOGI("We're stopped.");
    mState = STOPPED;

    status_t err = OK;

+20 −0
Original line number Diff line number Diff line
@@ -55,6 +55,18 @@ private:
    struct HDCPObserver;
#endif

    enum State {
        INITIALIZED,
        AWAITING_CLIENT_CONNECTION,
        AWAITING_CLIENT_SETUP,
        AWAITING_CLIENT_PLAY,
        ABOUT_TO_PLAY,
        PLAYING,
        AWAITING_CLIENT_TEARDOWN,
        STOPPING,
        STOPPED,
    };

    enum {
        kWhatStart,
        kWhatRTSPNotify,
@@ -64,6 +76,7 @@ private:
        kWhatKeepAlive,
        kWhatHDCPNotify,
        kWhatFinishStop2,
        kWhatTeardownTriggerTimedOut,
    };

    struct ResponseID {
@@ -82,11 +95,18 @@ private:

    static const int64_t kReaperIntervalUs = 1000000ll;

    // We request that the dongle send us a "TEARDOWN" in order to
    // perform an orderly shutdown. We're willing to wait up to 2 secs
    // for this message to arrive, after that we'll force a disconnect
    // instead.
    static const int64_t kTeardownTriggerTimeouSecs = 2;

    static const int64_t kPlaybackSessionTimeoutSecs = 30;

    static const int64_t kPlaybackSessionTimeoutUs =
        kPlaybackSessionTimeoutSecs * 1000000ll;

    State mState;
    sp<ANetworkSession> mNetSession;
    sp<IRemoteDisplayClient> mClient;
    struct in_addr mInterfaceAddr;