summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/wifi-display
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2012-09-27 14:31:04 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-09-27 14:31:05 -0700
commitecc8db5ee83d648532be1392f53277aa3a25284e (patch)
tree9cb266a15854ea7fc2af8c4e1e8e38613b84107d /media/libstagefright/wifi-display
parent5cfd237fd70572796b86f977ff4fdfe29cab888d (diff)
parentef7d3793fa9bbfb25253626ede9a020ee9280a17 (diff)
downloadframeworks_av-ecc8db5ee83d648532be1392f53277aa3a25284e.zip
frameworks_av-ecc8db5ee83d648532be1392f53277aa3a25284e.tar.gz
frameworks_av-ecc8db5ee83d648532be1392f53277aa3a25284e.tar.bz2
Merge "Cleaner Wifi Display shutdown process, avoid crashing HDCP on exit." into jb-mr1-dev
Diffstat (limited to 'media/libstagefright/wifi-display')
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.cpp41
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.h3
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp92
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.h7
4 files changed, 89 insertions, 54 deletions
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index 28fe0ec..0facafe 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -153,6 +153,8 @@ void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t i
}
status_t WifiDisplaySource::PlaybackSession::Track::start() {
+ ALOGV("Track::start isAudio=%d", mIsAudio);
+
if (mStarted) {
return INVALID_OPERATION;
}
@@ -171,6 +173,8 @@ status_t WifiDisplaySource::PlaybackSession::Track::start() {
}
status_t WifiDisplaySource::PlaybackSession::Track::stop() {
+ ALOGV("Track::stop isAudio=%d", mIsAudio);
+
if (!mStarted) {
return INVALID_OPERATION;
}
@@ -217,6 +221,7 @@ WifiDisplaySource::PlaybackSession::PlaybackSession(
mNotify(notify),
mInterfaceAddr(interfaceAddr),
mHDCP(hdcp),
+ mWeAreDead(false),
mLastLifesignUs(),
mVideoTrackIndex(-1),
mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)),
@@ -531,6 +536,10 @@ status_t WifiDisplaySource::PlaybackSession::destroy() {
void WifiDisplaySource::PlaybackSession::onMessageReceived(
const sp<AMessage> &msg) {
+ if (mWeAreDead) {
+ return;
+ }
+
switch (msg->what()) {
case kWhatRTPNotify:
case kWhatRTCPNotify:
@@ -590,10 +599,7 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
}
#endif
- // Inform WifiDisplaySource of our premature death (wish).
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatSessionDead);
- notify->post();
+ notifySessionDead();
break;
}
@@ -714,12 +720,7 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
status_t err = packetizeQueuedAccessUnits();
if (err != OK) {
- // Inform WifiDisplaySource of our premature death
- // (wish).
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatSessionDead);
- notify->post();
-
+ notifySessionDead();
break;
}
}
@@ -736,11 +737,7 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
status_t err = packetizeAccessUnit(trackIndex, accessUnit);
if (err != OK) {
- // Inform WifiDisplaySource of our premature death
- // (wish).
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatSessionDead);
- notify->post();
+ notifySessionDead();
}
break;
} else if (what == Converter::kWhatEOS) {
@@ -768,10 +765,7 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
ALOGE("converter signaled error %d", err);
- // Inform WifiDisplaySource of our premature death (wish).
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatSessionDead);
- notify->post();
+ notifySessionDead();
}
break;
}
@@ -1482,5 +1476,14 @@ status_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() {
return OK;
}
+void WifiDisplaySource::PlaybackSession::notifySessionDead() {
+ // Inform WifiDisplaySource of our premature death (wish).
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatSessionDead);
+ notify->post();
+
+ mWeAreDead = true;
+}
+
} // namespace android
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h
index b4aaa4d..342fc85 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.h
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.h
@@ -107,6 +107,7 @@ private:
sp<AMessage> mNotify;
in_addr mInterfaceAddr;
sp<IHDCP> mHDCP;
+ bool mWeAreDead;
int64_t mLastLifesignUs;
@@ -205,6 +206,8 @@ private:
status_t packetizeQueuedAccessUnits();
+ void notifySessionDead();
+
DISALLOW_EVIL_CONSTRUCTORS(PlaybackSession);
};
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index b9139c9..286adfa 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -169,9 +169,10 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
mNetSession->destroySession(sessionID);
if (sessionID == mClientSessionID) {
- mClientSessionID = -1;
+ mClientSessionID = 0;
- disconnectClient(UNKNOWN_ERROR);
+ mClient->onDisplayError(
+ IRemoteDisplayClient::kDisplayErrorUnknown);
}
break;
}
@@ -217,7 +218,8 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
status_t err = onReceiveClientData(msg);
if (err != OK) {
- disconnectClient(err);
+ mClient->onDisplayError(
+ IRemoteDisplayClient::kDisplayErrorUnknown);
}
break;
}
@@ -232,7 +234,8 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
{
CHECK(msg->senderAwaitsResponse(&mStopReplyID));
- if (mSessionID != 0 && mClientSessionID != 0) {
+ if (mClientSessionID != 0
+ && mClientInfo.mPlaybackSessionID != -1) {
status_t err = sendM5(
mClientSessionID, true /* requestShutdown */);
@@ -258,7 +261,11 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
+ kPlaybackSessionTimeoutUs < ALooper::GetNowUs()) {
ALOGI("playback session timed out, reaping.");
- disconnectClient(-ETIMEDOUT);
+ mNetSession->destroySession(mClientSessionID);
+ mClientSessionID = 0;
+
+ mClient->onDisplayError(
+ IRemoteDisplayClient::kDisplayErrorUnknown);
} else {
scheduleReaper();
}
@@ -276,7 +283,8 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
if (what == PlaybackSession::kWhatSessionDead) {
ALOGI("playback session wants to quit.");
- disconnectClient(UNKNOWN_ERROR);
+ mClient->onDisplayError(
+ IRemoteDisplayClient::kDisplayErrorUnknown);
} else if (what == PlaybackSession::kWhatSessionEstablished) {
if (mClient != NULL) {
mClient->onDisplayConnected(
@@ -354,8 +362,13 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
}
case HDCPModule::HDCP_SHUTDOWN_COMPLETE:
+ case HDCPModule::HDCP_SHUTDOWN_FAILED:
{
- finishStop2();
+ // Ugly hack to make sure that the call to
+ // HDCPObserver::notify is completely handled before
+ // we clear the HDCP instance and unload the shared
+ // library :(
+ (new AMessage(kWhatFinishStop2, id()))->post(300000ll);
break;
}
@@ -363,12 +376,19 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
{
ALOGE("HDCP failure, shutting down.");
- disconnectClient(-EACCES);
+ mClient->onDisplayError(
+ IRemoteDisplayClient::kDisplayErrorUnknown);
break;
}
}
break;
}
+
+ case kWhatFinishStop2:
+ {
+ finishStop2();
+ break;
+ }
#endif
default:
@@ -508,6 +528,7 @@ status_t WifiDisplaySource::sendM4(int32_t sessionID) {
status_t WifiDisplaySource::sendM5(int32_t sessionID, bool requestShutdown) {
AString body = "wfd_trigger_method: ";
if (requestShutdown) {
+ ALOGI("Sending TEARDOWN trigger.");
body.append("TEARDOWN");
} else {
body.append("SETUP");
@@ -1017,6 +1038,8 @@ status_t WifiDisplaySource::onPlayRequest(
return ERROR_MALFORMED;
}
+ ALOGI("Received PLAY request.");
+
status_t err = playbackSession->play();
CHECK_EQ(err, (status_t)OK);
@@ -1065,6 +1088,8 @@ status_t WifiDisplaySource::onTeardownRequest(
int32_t sessionID,
int32_t cseq,
const sp<ParsedMessage> &data) {
+ ALOGI("Received TEARDOWN request.");
+
int32_t playbackSessionID;
sp<PlaybackSession> playbackSession =
findPlaybackSession(data, &playbackSessionID);
@@ -1079,26 +1104,23 @@ status_t WifiDisplaySource::onTeardownRequest(
response.append("Connection: close\r\n");
response.append("\r\n");
- status_t err = mNetSession->sendRequest(sessionID, response.c_str());
-
- if (err != OK) {
- return err;
- }
+ mNetSession->sendRequest(sessionID, response.c_str());
if (mStopReplyID != 0) {
finishStop();
} else {
- disconnectClient(UNKNOWN_ERROR);
+ mClient->onDisplayError(IRemoteDisplayClient::kDisplayErrorUnknown);
}
return OK;
}
void WifiDisplaySource::finishStop() {
- disconnectClient(OK);
+ ALOGV("finishStop");
#if REQUIRE_HDCP
if (mHDCP != NULL) {
+ ALOGI("Initiating HDCP shutdown.");
mHDCP->shutdownAsync();
return;
}
@@ -1108,10 +1130,23 @@ void WifiDisplaySource::finishStop() {
}
void WifiDisplaySource::finishStop2() {
+ ALOGV("finishStop2");
+
#if REQUIRE_HDCP
+ mHDCP->setObserver(NULL);
+ mHDCPObserver.clear();
mHDCP.clear();
#endif
+ disconnectClient();
+
+ if (mSessionID != 0) {
+ mNetSession->destroySession(mSessionID);
+ mSessionID = 0;
+ }
+
+ ALOGV("finishStop2 completed.");
+
status_t err = OK;
sp<AMessage> response = new AMessage;
@@ -1230,27 +1265,22 @@ sp<WifiDisplaySource::PlaybackSession> WifiDisplaySource::findPlaybackSession(
return mClientInfo.mPlaybackSession;
}
-void WifiDisplaySource::disconnectClient(status_t err) {
- if (mClientSessionID != 0) {
- if (mClientInfo.mPlaybackSession != NULL) {
- sp<PlaybackSession> playbackSession = mClientInfo.mPlaybackSession;
- mClientInfo.mPlaybackSession.clear();
+void WifiDisplaySource::disconnectClient() {
+ if (mClientInfo.mPlaybackSession != NULL) {
+ sp<PlaybackSession> playbackSession = mClientInfo.mPlaybackSession;
+ mClientInfo.mPlaybackSession.clear();
- playbackSession->destroy();
- looper()->unregisterHandler(playbackSession->id());
- }
+ ALOGI("Destroying PlaybackSession");
+ playbackSession->destroy();
+ looper()->unregisterHandler(playbackSession->id());
+ }
+ if (mClientSessionID != 0) {
mNetSession->destroySession(mClientSessionID);
mClientSessionID = 0;
}
- if (mClient != NULL) {
- if (err != OK) {
- mClient->onDisplayError(IRemoteDisplayClient::kDisplayErrorUnknown);
- } else {
- mClient->onDisplayDisconnected();
- }
- }
+ mClient->onDisplayDisconnected();
}
#if REQUIRE_HDCP
@@ -1306,7 +1336,7 @@ status_t WifiDisplaySource::makeHDCP() {
return err;
}
- ALOGI("initiating HDCP negotiation w/ host %s:%d",
+ ALOGI("Initiating HDCP negotiation w/ host %s:%d",
mClientInfo.mRemoteIP.c_str(), mHDCPPort);
err = mHDCP->initAsync(mClientInfo.mRemoteIP.c_str(), mHDCPPort);
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index fb4f53d..77b15f8 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -63,6 +63,7 @@ private:
kWhatPlaybackSessionNotify,
kWhatKeepAlive,
kWhatHDCPNotify,
+ kWhatFinishStop2,
};
struct ResponseID {
@@ -200,10 +201,8 @@ private:
const sp<ParsedMessage> &data, int32_t *playbackSessionID) const;
// Disconnects the current client and shuts down its playback session
- // (if any). The reason for the disconnection is OK for orderly shutdown
- // or a nonzero error code.
- // A listener is notified accordingly.
- void disconnectClient(status_t err);
+ // (if any).
+ void disconnectClient();
void finishStop();
void finishStop2();