summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/wifi-display
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2012-10-01 11:26:30 -0700
committerAndreas Huber <andih@google.com>2012-10-01 11:26:30 -0700
commitad0d97c7cf620e96a0b088dd9461645a3f8900b7 (patch)
tree83c354a2a43102ce1e58a191c1abc41b19b4dd69 /media/libstagefright/wifi-display
parent0e1d71641624c641a0a1abe4098943f5a42c6f94 (diff)
downloadframeworks_av-ad0d97c7cf620e96a0b088dd9461645a3f8900b7.zip
frameworks_av-ad0d97c7cf620e96a0b088dd9461645a3f8900b7.tar.gz
frameworks_av-ad0d97c7cf620e96a0b088dd9461645a3f8900b7.tar.bz2
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
Diffstat (limited to 'media/libstagefright/wifi-display')
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.cpp4
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp54
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.h20
3 files changed, 71 insertions, 7 deletions
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index c8b9afd..9c065b2 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -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();
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index d5ffc65..adb1549 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -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;
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index ade623a..8c043cd 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -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;