diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index e228377e23b..984adac9fdf 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index dbc87ec981c..052693d89d6 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 2c1db7a7a85..76e22577314 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index e228377e23b..984adac9fdf 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 26189a28d23..2d1dc6629fe 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 45fb4a46803..4b8e53b74bb 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "c2a75dc08b6c97aa2fb7cdf547f7231d96381106", + "revision": "849cd3df00bea01e00f9d19a272c8e88c9571830", "repo_path": "/integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 18e97fdc8ac..310ccaea1a5 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 92a62ef8caf..4ed068c715a 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index d66c3efaaf3..92669660177 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 53bb617b060..43e7bea6eee 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/content/media/omx/RtspOmxDecoder.cpp b/content/media/omx/RtspOmxDecoder.cpp index 058a17bf344..cf70be21e8b 100644 --- a/content/media/omx/RtspOmxDecoder.cpp +++ b/content/media/omx/RtspOmxDecoder.cpp @@ -23,5 +23,25 @@ MediaDecoderStateMachine* RtspOmxDecoder::CreateStateMachine() mResource->IsRealTime()); } +void RtspOmxDecoder::ApplyStateToStateMachine(PlayState aState) +{ + MOZ_ASSERT(NS_IsMainThread()); + + MediaDecoder::ApplyStateToStateMachine(aState); + + // Notify RTSP controller if the play state is ended. + // This is necessary for RTSP controller to transit its own state. + if (aState == PLAY_STATE_ENDED) { + nsRefPtr resource = mResource->GetRtspPointer(); + if (resource) { + nsIStreamingProtocolController* controller = + resource->GetMediaStreamController(); + if (controller) { + controller->PlaybackEnded(); + } + } + } +} + } // namespace mozilla diff --git a/content/media/omx/RtspOmxDecoder.h b/content/media/omx/RtspOmxDecoder.h index 20b757469c6..4221ff9131d 100644 --- a/content/media/omx/RtspOmxDecoder.h +++ b/content/media/omx/RtspOmxDecoder.h @@ -30,8 +30,10 @@ public: MOZ_COUNT_DTOR(RtspOmxDecoder); } - virtual MediaDecoder* Clone() MOZ_OVERRIDE; - virtual MediaDecoderStateMachine* CreateStateMachine() MOZ_OVERRIDE; + virtual MediaDecoder* Clone() MOZ_OVERRIDE MOZ_FINAL; + virtual MediaDecoderStateMachine* CreateStateMachine() MOZ_OVERRIDE MOZ_FINAL; + virtual void ApplyStateToStateMachine(PlayState aState) + MOZ_OVERRIDE MOZ_FINAL; }; } // namespace mozilla diff --git a/dom/mobileconnection/interfaces/moz.build b/dom/mobileconnection/interfaces/moz.build index 1a7f3c79d0e..16d3ce5b834 100644 --- a/dom/mobileconnection/interfaces/moz.build +++ b/dom/mobileconnection/interfaces/moz.build @@ -9,6 +9,7 @@ XPIDL_SOURCES += [ 'nsIMobileConnectionInfo.idl', 'nsIMobileConnectionProvider.idl', 'nsIMobileNetworkInfo.idl', + 'nsINeighboringCellInfo.idl', ] XPIDL_MODULE = 'dom_mobileconnection' diff --git a/dom/mobileconnection/interfaces/nsINeighboringCellInfo.idl b/dom/mobileconnection/interfaces/nsINeighboringCellInfo.idl new file mode 100644 index 00000000000..01a31594725 --- /dev/null +++ b/dom/mobileconnection/interfaces/nsINeighboringCellInfo.idl @@ -0,0 +1,64 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +[scriptable, uuid(909f5972-c74e-44dd-b72a-7ddb62aae617)] +interface nsINeighboringCellIdsCallback : nsISupports +{ + /** + * result is an array of nsINeighboringCellInfo. + */ + void notifyGetNeighboringCellIds(in jsval result); + + /** + * Callback function with error message. + */ + void notifyGetNeighboringCellIdsFailed(in DOMString error); +}; + +[scriptable, uuid(87dc222e-abb3-4342-95bf-626aa19fa20e)] +interface nsINeighboringCellInfo: nsISupports +{ + /** + * Type of radio technology. + * + * Possible values: 'gsm', 'gprs', 'edge', 'umts', 'hsdpa', 'hsupa', 'hspa', + * 'hspa+' or null (unknown). + */ + readonly attribute DOMString networkType; + + /** + * Mobile Location Area Code (LAC) for GSM networks. + * + * Possible ranges from 0x0000 to 0xffff. + * -1 if the LAC is unknown. + */ + readonly attribute long gsmLocationAreaCode; + + /** + * Mobile Cell ID for GSM networks. + * + * Possible ranges from 0x00000000 to 0xffffffff. + * -1 if the cell id is unknown. + */ + readonly attribute long long gsmCellId; + + /** + * Primary Scrambling Code (PSC) for WCDMA networks. + * + * Possible ranges from 0x0000 to 0x01ff. + * -1 if the psc is unknown. + */ + readonly attribute long wcdmaPsc; + + /** + * For GSM networks, signalStrength is the received rssi, ranging from 0 to 31. + * For WCDMA networks, signalStrength is the CPICH Received Signal Code Power, + * ranging from -120 to -25. + * + * 99 if signalStrength is unknown. + */ + readonly attribute long signalStrength; +}; \ No newline at end of file diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js index c2d95acaa9e..a88bda2a1e8 100644 --- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -54,6 +54,8 @@ const GSMICCINFO_CID = Components.ID("{d90c4261-a99d-47bc-8b05-b057bb7e8f8a}"); const CDMAICCINFO_CID = Components.ID("{39ba3c08-aacc-46d0-8c04-9b619c387061}"); +const NEIGHBORINGCELLINFO_CID = + Components.ID("{f9dfe26a-851e-4a8b-a769-cbb1baae7ded}"); const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown"; const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed"; @@ -1055,6 +1057,25 @@ CdmaIccInfo.prototype = { prlVersion: 0 }; +function NeighboringCellInfo() {} +NeighboringCellInfo.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsINeighboringCellInfo]), + classID: NEIGHBORINGCELLINFO_CID, + classInfo: XPCOMUtils.generateCI({ + classID: NEIGHBORINGCELLINFO_CID, + classDescription: "NeighboringCellInfo", + interfaces: [Ci.nsINeighboringCellInfo] + }), + + // nsINeighboringCellInfo + + networkType: null, + gsmLocationAreaCode: -1, + gsmCellId: -1, + wcdmaPsc: -1, + signalStrength: 99 +}; + function DataConnectionHandler(clientId, radioInterface) { // Initial owning attributes. this.clientId = clientId; @@ -4352,6 +4373,28 @@ RadioInterface.prototype = { } else { this.workerMessenger.send(rilMessageType, message); } + }, + + getNeighboringCellIds: function(callback) { + this.workerMessenger.send("getNeighboringCellIds", + null, + function(response) { + if (response.errorMsg) { + callback.notifyGetNeighboringCellIdsFailed(response.errorMsg); + return; + } + + let neighboringCellIds = []; + let count = response.result.length; + for (let i = 0; i < count; i++) { + let srcCellInfo = response.result[i]; + let cellInfo = new NeighboringCellInfo(); + this.updateInfo(srcCellInfo, cellInfo); + neighboringCellIds.push(cellInfo); + } + callback.notifyGetNeighboringCellIds(neighboringCellIds); + + }.bind(this)); } }; diff --git a/dom/system/gonk/nsIRadioInterfaceLayer.idl b/dom/system/gonk/nsIRadioInterfaceLayer.idl index 98823174f7f..e247607de0b 100644 --- a/dom/system/gonk/nsIRadioInterfaceLayer.idl +++ b/dom/system/gonk/nsIRadioInterfaceLayer.idl @@ -8,6 +8,7 @@ interface nsIDOMMozIccInfo; interface nsIMobileConnectionInfo; interface nsIMobileMessageCallback; +interface nsINeighboringCellIdsCallback; [scriptable, uuid(6e0f45b8-410e-11e3-8c8e-b715b2cd0128)] interface nsIRilNetworkInterface : nsINetworkInterface @@ -55,7 +56,7 @@ interface nsIRilSendWorkerMessageCallback : nsISupports boolean handleResponse(in jsval response); }; -[scriptable, uuid(181d460e-220e-4274-8ba4-43f122eb518d)] +[scriptable, uuid(31ba65b6-05c7-4bc8-abdc-f1a219811fb4)] interface nsIRadioInterface : nsISupports { readonly attribute nsIRilContext rilContext; @@ -85,6 +86,11 @@ interface nsIRadioInterface : nsISupports [optional] in nsIRilSendWorkerMessageCallback callback); void getSmscAddress(in nsIMobileMessageCallback request); + + /** + * Cell Info functionality. + */ + void getNeighboringCellIds(in nsINeighboringCellIdsCallback callback); }; [scriptable, uuid(d035c32e-b491-11e3-9f9d-c716fab88bd6)] diff --git a/dom/system/gonk/ril_worker.js b/dom/system/gonk/ril_worker.js index 8486188c745..40998f4353c 100644 --- a/dom/system/gonk/ril_worker.js +++ b/dom/system/gonk/ril_worker.js @@ -1300,6 +1300,13 @@ RilObject.prototype = { this.context.Buf.simpleRequest(REQUEST_GET_PREFERRED_NETWORK_TYPE, options); }, + /** + * Request neighboring cell ids in GSM network. + */ + getNeighboringCellIds: function(options) { + this.context.Buf.simpleRequest(REQUEST_GET_NEIGHBORING_CELL_IDS, options); + }, + /** * Request various states about the network. */ @@ -6381,7 +6388,68 @@ RilObject.prototype[REQUEST_GET_PREFERRED_NETWORK_TYPE] = function REQUEST_GET_P options.type = RIL_PREFERRED_NETWORK_TYPE_TO_GECKO[networkType]; this.sendChromeMessage(options); }; -RilObject.prototype[REQUEST_GET_NEIGHBORING_CELL_IDS] = null; +RilObject.prototype[REQUEST_GET_NEIGHBORING_CELL_IDS] = function REQUEST_GET_NEIGHBORING_CELL_IDS(length, options) { + if (options.rilRequestError) { + options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError]; + this.sendChromeMessage(options); + return; + } + + let radioTech = this.voiceRegistrationState.radioTech; + if (radioTech == undefined || radioTech == NETWORK_CREG_TECH_UNKNOWN) { + options.errorMsg = "RadioTechUnavailable"; + this.sendChromeMessage(options); + return; + } + if (!this._isGsmTechGroup(radioTech) || radioTech == NETWORK_CREG_TECH_LTE) { + options.errorMsg = "UnsupportedRadioTech"; + this.sendChromeMessage(options); + return; + } + + let Buf = this.context.Buf; + let neighboringCellIds = []; + let num = Buf.readInt32(); + + for (let i = 0; i < num; i++) { + let cellId = {}; + cellId.networkType = GECKO_RADIO_TECH[radioTech]; + cellId.signalStrength = Buf.readInt32(); + + let cid = Buf.readString(); + // pad cid string with leading "0" + let length = cid.length; + if (length > 8) { + continue; + } + if (length < 8) { + for (let j = 0; j < (8-length); j++) { + cid = "0" + cid; + } + } + + switch (radioTech) { + case NETWORK_CREG_TECH_GPRS: + case NETWORK_CREG_TECH_EDGE: + case NETWORK_CREG_TECH_GSM: + cellId.gsmCellId = this.parseInt(cid.substring(4), -1, 16); + cellId.gsmLocationAreaCode = this.parseInt(cid.substring(0, 4), -1, 16); + break; + case NETWORK_CREG_TECH_UMTS: + case NETWORK_CREG_TECH_HSDPA: + case NETWORK_CREG_TECH_HSUPA: + case NETWORK_CREG_TECH_HSPA: + case NETWORK_CREG_TECH_HSPAP: + cellId.wcdmaPsc = this.parseInt(cid, -1, 16); + break; + } + + neighboringCellIds.push(cellId); + } + + options.result = neighboringCellIds; + this.sendChromeMessage(options); +}; RilObject.prototype[REQUEST_SET_LOCATION_UPDATES] = null; RilObject.prototype[REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE] = null; RilObject.prototype[REQUEST_CDMA_SET_ROAMING_PREFERENCE] = function REQUEST_CDMA_SET_ROAMING_PREFERENCE(length, options) { diff --git a/dom/system/gonk/tests/marionette/manifest.ini b/dom/system/gonk/tests/marionette/manifest.ini index 624c052a39b..52331d5ae13 100644 --- a/dom/system/gonk/tests/marionette/manifest.ini +++ b/dom/system/gonk/tests/marionette/manifest.ini @@ -12,3 +12,4 @@ disabled = Bug 808783 [test_data_connection.js] [test_network_active_changed.js] [test_multiple_data_connection.js] +[test_neighboring_cell_ids.js] diff --git a/dom/system/gonk/tests/marionette/test_neighboring_cell_ids.js b/dom/system/gonk/tests/marionette/test_neighboring_cell_ids.js new file mode 100644 index 00000000000..349300816cd --- /dev/null +++ b/dom/system/gonk/tests/marionette/test_neighboring_cell_ids.js @@ -0,0 +1,33 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 30000; +MARIONETTE_HEAD_JS = "head.js"; + +function testGetNeighboringCellIds() { + log("Test getting neighboring cell ids"); + let deferred = Promise.defer(); + + radioInterface.getNeighboringCellIds({ + notifyGetNeighboringCellIds: function(aResult) { + deferred.resolve(aResult); + }, + notifyGetNeighboringCellIdsFailed: function(aError) { + deferred.reject(aError); + } + }); + return deferred.promise; +} + +// Start tests +startTestBase(function() { + // TODO: Bug 1028837 - B2G Emulator: support neighboring cell ids. + // Currently, emulator does not support RIL_REQUEST_NEIGHBORING_CELL_IDS, + // so we expect to get a 'RequestNotSupported' error here. + return testGetNeighboringCellIds() + .then(function resolve(aResult) { + ok(false, "getNeighboringCellIds should not success"); + }, function reject(aError) { + is(aError, "RequestNotSupported", "failed to getNeighboringCellIds"); + }); +}); diff --git a/dom/telephony/gonk/TelephonyService.js b/dom/telephony/gonk/TelephonyService.js index 2a212bd8309..a10c4340b9c 100644 --- a/dom/telephony/gonk/TelephonyService.js +++ b/dom/telephony/gonk/TelephonyService.js @@ -439,10 +439,10 @@ TelephonyService.prototype = { return; } - function onCdmaDialSuccess() { + function onCdmaDialSuccess(aCallIndex) { let indexes = Object.keys(this._currentCalls[aClientId]); - if (indexes.length != 1 ) { - aTelephonyCallback.notifyDialSuccess(); + if (indexes.length == 0) { + aTelephonyCallback.notifyDialSuccess(aCallIndex); return; } @@ -458,7 +458,7 @@ TelephonyService.prototype = { isMergeable: true, parentId: indexes[0] }; - aTelephonyCallback.notifyDialSuccess(); + aTelephonyCallback.notifyDialSuccess(CDMA_SECOND_CALL_INDEX); // Manual update call state according to the request response. this.notifyCallStateChanged(aClientId, childCall); @@ -486,7 +486,7 @@ TelephonyService.prototype = { } if (response.isCdma) { - onCdmaDialSuccess.call(this); + onCdmaDialSuccess.call(this, response.callIndex); } else { aTelephonyCallback.notifyDialSuccess(response.callIndex); } diff --git a/netwerk/base/public/nsIStreamingProtocolController.idl b/netwerk/base/public/nsIStreamingProtocolController.idl index 072f643de0c..571672271cc 100644 --- a/netwerk/base/public/nsIStreamingProtocolController.idl +++ b/netwerk/base/public/nsIStreamingProtocolController.idl @@ -115,7 +115,7 @@ interface nsIStreamingProtocolListener : nsISupports /** * Media stream controller API: control and retrieve meta data from media stream. */ -[uuid(a9bdd4b0-8559-11e2-9e96-0800200c9a66)] +[uuid(4ce040f0-c50d-461f-94e2-af5a77fe13a5)] interface nsIStreamingProtocolController : nsISupports { /** @@ -173,6 +173,12 @@ interface nsIStreamingProtocolController : nsISupports */ void stop(); + /* + * Notify the streaming controller that the playback has ended. + * The controller might have to perform certain internal state transition. + */ + void playbackEnded(); + /** * Total number of audio/video tracks. */ diff --git a/netwerk/ipc/PRtspController.ipdl b/netwerk/ipc/PRtspController.ipdl index 27124cdbcc7..de74461779f 100644 --- a/netwerk/ipc/PRtspController.ipdl +++ b/netwerk/ipc/PRtspController.ipdl @@ -44,6 +44,7 @@ parent: Suspend(); Seek(uint64_t offset); Stop(); + PlaybackEnded(); __delete__(); child: diff --git a/netwerk/protocol/rtsp/controller/RtspController.cpp b/netwerk/protocol/rtsp/controller/RtspController.cpp index aa2eb591382..b6aa25424be 100644 --- a/netwerk/protocol/rtsp/controller/RtspController.cpp +++ b/netwerk/protocol/rtsp/controller/RtspController.cpp @@ -369,5 +369,18 @@ RtspController::Init(nsIURI *aURI) return NS_OK; } +NS_IMETHODIMP +RtspController::PlaybackEnded() +{ + LOG(("RtspController::PlaybackEnded()")); + if (!mRtspSource.get()) { + MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!"); + return NS_ERROR_NOT_INITIALIZED; + } + + mRtspSource->playbackEnded(); + return NS_OK; +} + } // namespace mozilla::net } // namespace mozilla diff --git a/netwerk/protocol/rtsp/controller/RtspControllerChild.cpp b/netwerk/protocol/rtsp/controller/RtspControllerChild.cpp index 40667d7a88f..471a33688c4 100644 --- a/netwerk/protocol/rtsp/controller/RtspControllerChild.cpp +++ b/netwerk/protocol/rtsp/controller/RtspControllerChild.cpp @@ -237,7 +237,8 @@ enum IPCEvent SendSeekEvent, SendResumeEvent, SendSuspendEvent, - SendStopEvent + SendStopEvent, + SendPlaybackEndedEvent }; class SendIPCEvent : public nsRunnable @@ -281,6 +282,8 @@ public: rv = mController->SendSuspend(); } else if (mEvent == SendStopEvent) { rv = mController->SendStop(); + } else if (mEvent == SendPlaybackEndedEvent) { + rv = mController->SendPlaybackEnded(); } else { LOG(("RtspControllerChild::SendIPCEvent")); } @@ -424,6 +427,24 @@ RtspControllerChild::GetTotalTracks(uint8_t *aTracks) return NS_OK; } +NS_IMETHODIMP +RtspControllerChild::PlaybackEnded() +{ + LOG(("RtspControllerChild::PlaybackEnded")); + + if (NS_IsMainThread()) { + if (!OKToSendIPC() || !SendPlaybackEnded()) { + return NS_ERROR_FAILURE; + } + } else { + nsresult rv = NS_DispatchToMainThread( + new SendIPCEvent(this, SendPlaybackEndedEvent)); + NS_ENSURE_SUCCESS(rv, rv); + } + + return NS_OK; +} + //----------------------------------------------------------------------------- // RtspControllerChild::nsIStreamingProtocolListener //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/rtsp/controller/RtspControllerParent.cpp b/netwerk/protocol/rtsp/controller/RtspControllerParent.cpp index c7b8a266751..0c8d7ed5869 100644 --- a/netwerk/protocol/rtsp/controller/RtspControllerParent.cpp +++ b/netwerk/protocol/rtsp/controller/RtspControllerParent.cpp @@ -167,6 +167,17 @@ RtspControllerParent::RecvStop() return true; } +bool +RtspControllerParent::RecvPlaybackEnded() +{ + LOG(("RtspControllerParent::RecvPlaybackEnded()")); + NS_ENSURE_TRUE(mController, true); + + nsresult rv = mController->PlaybackEnded(); + SEND_DISCONNECT_IF_ERROR(rv) + return true; +} + NS_IMETHODIMP RtspControllerParent::OnMediaDataAvailable(uint8_t index, const nsACString & data, diff --git a/netwerk/protocol/rtsp/controller/RtspControllerParent.h b/netwerk/protocol/rtsp/controller/RtspControllerParent.h index b8a3c9bd3d5..c96678b07ed 100644 --- a/netwerk/protocol/rtsp/controller/RtspControllerParent.h +++ b/netwerk/protocol/rtsp/controller/RtspControllerParent.h @@ -37,6 +37,7 @@ class RtspControllerParent : public PRtspControllerParent bool RecvSuspend(); bool RecvSeek(const uint64_t& offset); bool RecvStop(); + bool RecvPlaybackEnded(); private: bool mIPCOpen; diff --git a/netwerk/protocol/rtsp/rtsp/RTSPSource.cpp b/netwerk/protocol/rtsp/rtsp/RTSPSource.cpp index 98a331c94ac..bf515ff5333 100644 --- a/netwerk/protocol/rtsp/rtsp/RTSPSource.cpp +++ b/netwerk/protocol/rtsp/rtsp/RTSPSource.cpp @@ -132,6 +132,13 @@ void RTSPSource::seek(uint64_t timeUs) seekTo(timeUs); } +void RTSPSource::playbackEnded() +{ + LOGI("RTSPSource::playbackEnded()"); + sp msg = new AMessage(kWhatPerformPlaybackEnded, mReflector->id()); + msg->post(); +} + status_t RTSPSource::feedMoreTSData() { return mFinalResult; } @@ -246,6 +253,15 @@ void RTSPSource::performSuspend() { // TODO, Bug 895753. } +void RTSPSource::performPlaybackEnded() { + // Transition from PLAYING to CONNECTED state so that we are ready to + // perform an another play operation. + if (mState != PLAYING) { + return; + } + mState = CONNECTED; +} + void RTSPSource::performSeek(int64_t seekTimeUs) { if (mState != CONNECTED && mState != PLAYING && mState != PAUSING) { return; @@ -310,6 +326,9 @@ void RTSPSource::onMessageReceived(const sp &msg) { } else if (msg->what() == kWhatPerformSuspend) { performSuspend(); return; + } else if (msg->what() == kWhatPerformPlaybackEnded) { + performPlaybackEnded(); + return; } CHECK_EQ(msg->what(), (uint32_t)kWhatNotify); @@ -675,7 +694,6 @@ void RTSPSource::onTrackDataAvailable(size_t trackIndex) void RTSPSource::onTrackEndOfStream(size_t trackIndex) { - mState = CONNECTED; if (!mListener) { return; } diff --git a/netwerk/protocol/rtsp/rtsp/RTSPSource.h b/netwerk/protocol/rtsp/rtsp/RTSPSource.h index 73008546be9..f33cc940455 100644 --- a/netwerk/protocol/rtsp/rtsp/RTSPSource.h +++ b/netwerk/protocol/rtsp/rtsp/RTSPSource.h @@ -54,6 +54,7 @@ public: void seek(uint64_t timeUs); void resume(); void suspend(); + void playbackEnded(); status_t feedMoreTSData(); @@ -71,13 +72,14 @@ protected: private: enum { - kWhatNotify = 'noti', - kWhatDisconnect = 'disc', - kWhatPerformSeek = 'seek', - kWhatPerformPlay = 'play', - kWhatPerformPause = 'paus', - kWhatPerformResume = 'resu', - kWhatPerformSuspend = 'susp', + kWhatNotify = 'noti', + kWhatDisconnect = 'disc', + kWhatPerformSeek = 'seek', + kWhatPerformPlay = 'play', + kWhatPerformPause = 'paus', + kWhatPerformResume = 'resu', + kWhatPerformSuspend = 'susp', + kWhatPerformPlaybackEnded = 'ende', }; enum State { @@ -140,6 +142,8 @@ private: void performSuspend(); + void performPlaybackEnded(); + void onTrackDataAvailable(size_t trackIndex); void onTrackEndOfStream(size_t trackIndex);