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);