Merge b2ginbound to central, a=merge

This commit is contained in:
Wes Kocher 2015-07-14 15:25:44 -07:00
commit 521aacc980
24 changed files with 2021 additions and 274 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="66638d0e65bf58b7f640bcc7bed4a0b23d1356c6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="42b31cf3248acf7acd1fd30c7491871c50305fa8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="66638d0e65bf58b7f640bcc7bed4a0b23d1356c6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="42b31cf3248acf7acd1fd30c7491871c50305fa8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="66638d0e65bf58b7f640bcc7bed4a0b23d1356c6"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="66638d0e65bf58b7f640bcc7bed4a0b23d1356c6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="42b31cf3248acf7acd1fd30c7491871c50305fa8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="66638d0e65bf58b7f640bcc7bed4a0b23d1356c6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="42b31cf3248acf7acd1fd30c7491871c50305fa8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="66638d0e65bf58b7f640bcc7bed4a0b23d1356c6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="42b31cf3248acf7acd1fd30c7491871c50305fa8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="66638d0e65bf58b7f640bcc7bed4a0b23d1356c6"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="66638d0e65bf58b7f640bcc7bed4a0b23d1356c6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="42b31cf3248acf7acd1fd30c7491871c50305fa8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "66638d0e65bf58b7f640bcc7bed4a0b23d1356c6",
"git_revision": "803d04e3829fd4fe9261211aa0ddca6b79d4e328",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "f99acf8fe79c200c9456000e8651e48be96a8bc0",
"revision": "ad35f158cbd79823e9449f30df5d693613eef17f",
"repo_path": "integration/gaia-central"
}

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="66638d0e65bf58b7f640bcc7bed4a0b23d1356c6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="657894b4a1dc0a926117f4812e0940229f9f676f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="42b31cf3248acf7acd1fd30c7491871c50305fa8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="66638d0e65bf58b7f640bcc7bed4a0b23d1356c6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="803d04e3829fd4fe9261211aa0ddca6b79d4e328"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="c490ae41c67f892232599f4ef049467a922b613e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="42b31cf3248acf7acd1fd30c7491871c50305fa8"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="cfa80d0c1c13a13a64b049173ea3a1d605f2cffd"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

View File

@ -1749,8 +1749,29 @@ BluetoothServiceBluedroid::IsConnected(const nsAString& aRemoteBdAddr)
// Bluetooth notifications
//
class BluetoothServiceBluedroid::CleanupResultHandler final
: public BluetoothResultHandler
{
public:
void Cleanup() override
{
MOZ_ASSERT(NS_IsMainThread());
BluetoothService::AcknowledgeToggleBt(false);
}
void OnError(BluetoothStatus aStatus) override
{
MOZ_ASSERT(NS_IsMainThread());
BT_LOGR("BluetoothInterface::Cleanup failed: %d", aStatus);
BluetoothService::AcknowledgeToggleBt(false);
}
};
/* |ProfileDeinitResultHandler| collects the results of all profile
* result handlers and calls |Proceed| after all results handlers
* result handlers and cleans up the Bluedroid driver after all handlers
* have been run.
*/
class BluetoothServiceBluedroid::ProfileDeinitResultHandler final
@ -1781,7 +1802,7 @@ private:
void Proceed() const
{
if (!sIsRestart) {
sBtInterface->Cleanup(nullptr);
sBtInterface->Cleanup(new CleanupResultHandler());
} else {
BT_LOGR("ProfileDeinitResultHandler::Proceed cancel cleanup() ");
}
@ -1849,7 +1870,8 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
NS_LITERAL_STRING(KEY_ADAPTER),
BluetoothValue(props));
// Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
// Cleanup Bluetooth interfaces after state becomes BT_STATE_OFF. This
// will also stop the Bluetooth daemon and disable the adapter.
nsRefPtr<ProfileDeinitResultHandler> res =
new ProfileDeinitResultHandler(MOZ_ARRAY_LENGTH(sDeinitManager));
@ -1858,9 +1880,14 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
}
}
BluetoothService::AcknowledgeToggleBt(sAdapterEnabled);
if (sAdapterEnabled) {
// We enable the Bluetooth adapter here. Disabling is implemented
// in |CleanupResultHandler|, which runs at the end of the shutdown
// procedure. We cannot disable the adapter immediately, because re-
// enabling it might interfere with the shutdown procedure.
BluetoothService::AcknowledgeToggleBt(true);
// Bluetooth just enabled, clear profile controllers and runnable arrays.
sControllerArray.Clear();
sChangeDiscoveryRunnableArray.Clear();

View File

@ -17,6 +17,7 @@ class BluetoothServiceBluedroid : public BluetoothService
, public BluetoothNotificationHandler
{
class CancelDiscoveryResultHandler;
class CleanupResultHandler;
class CreateBondResultHandler;
class DisableResultHandler;
class EnableResultHandler;

View File

@ -3,7 +3,9 @@ b2g = true
browser = false
qemu = false
disabled = Bug 1175389
# Hint: "disabled = xxxxx" statement should be added *below* the test that
# we want to disable.
[test_dom_BluetoothManager_API2.js]
disabled = Bug 1175389
[test_dom_BluetoothAdapter_enable_API2.js]
@ -15,3 +17,4 @@ disabled = Bug 1175389
[test_dom_BluetoothDevice_API2.js]
disabled = Bug 1175389
[test_dom_BluetoothAdapter_pair_API2.js]
disabled = Bug 1175389

File diff suppressed because it is too large Load Diff

View File

@ -1056,18 +1056,23 @@ AutoMounter::UpdateState()
LOG("UpdateState: Volume %s is %s", vol->NameStr(), vol->StateStr());
if (vol->IsFormatting() && !vol->IsFormatRequested()) {
vol->SetFormatRequested(false);
LOG("UpdateState: Mounting %s", vol->NameStr());
vol->StartMount(mResponseCallback);
break;
if (!(tryToShare && vol->IsSharingEnabled()) && volState == nsIVolume::STATE_IDLE) {
LOG("UpdateState: Mounting %s", vol->NameStr());
vol->StartMount(mResponseCallback);
break;
}
}
if (tryToShare && vol->IsSharingEnabled() && volState == nsIVolume::STATE_IDLE) {
// Volume is unmounted. We can go ahead and share.
LOG("UpdateState: Sharing %s", vol->NameStr());
vol->StartShare(mResponseCallback);
} else if (vol->IsFormatRequested()){
// If there are format and share requests in the same time,
// we should do format first then share.
if (vol->IsFormatRequested()) {
// Volume is unmounted. We can go ahead and format.
LOG("UpdateState: Formatting %s", vol->NameStr());
vol->StartFormat(mResponseCallback);
} else if (tryToShare && vol->IsSharingEnabled() && volState == nsIVolume::STATE_IDLE) {
// Volume is unmounted. We can go ahead and share.
LOG("UpdateState: Sharing %s", vol->NameStr());
vol->StartShare(mResponseCallback);
}
return; // UpdateState will be called again when the Share/Format command completes
}

View File

@ -119,7 +119,7 @@ SystemWorkerManager::Shutdown()
ShutdownAutoMounter();
#ifdef MOZ_B2G_RIL
RilConsumer::Shutdown();
RilWorker::Shutdown();
#endif
nsCOMPtr<nsIWifi> wifi(do_QueryInterface(mWifiWorker));
@ -201,7 +201,7 @@ SystemWorkerManager::RegisterRilWorker(unsigned int aClientId,
return NS_ERROR_FAILURE;
}
return RilConsumer::Register(aClientId, wctd);
return RilWorker::Register(aClientId, wctd);
#endif // MOZ_B2G_RIL
}

View File

@ -5,13 +5,22 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ipc/Ril.h"
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h> // For gethostbyname.
#include "jsfriendapi.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/workers/Workers.h"
#include "mozilla/ipc/RilSocket.h"
#include "mozilla/ipc/RilSocketConsumer.h"
#include "nsThreadUtils.h" // For NS_IsMainThread.
#include "RilConnector.h"
#ifdef CHROMIUM_LOG
#undef CHROMIUM_LOG
#endif
#if defined(MOZ_WIDGET_GONK)
#include <android/log.h>
#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
@ -19,189 +28,95 @@
#define CHROMIUM_LOG(args...) printf(args);
#endif
#include "jsfriendapi.h"
#include "mozilla/ArrayUtils.h"
#include "nsTArray.h"
#include "nsThreadUtils.h" // For NS_IsMainThread.
#include "RilConnector.h"
namespace mozilla {
namespace ipc {
USING_WORKERS_NAMESPACE
using namespace mozilla::ipc;
USING_WORKERS_NAMESPACE;
using namespace JS;
namespace {
class RilConsumer;
static const char RIL_SOCKET_NAME[] = "/dev/socket/rilproxy";
static nsTArray<nsAutoPtr<mozilla::ipc::RilConsumer>> sRilConsumers;
static nsTArray<nsAutoPtr<RilConsumer>> sRilConsumers;
class ConnectWorkerToRIL final : public WorkerTask
//
// RilConsumer
//
class RilConsumer final : public RilSocketConsumer
{
public:
bool RunTask(JSContext* aCx) override;
};
RilConsumer();
class SendRilSocketDataTask final : public nsRunnable
{
public:
SendRilSocketDataTask(unsigned long aClientId,
UnixSocketRawData* aRawData)
: mRawData(aRawData)
, mClientId(aClientId)
{ }
nsresult ConnectWorkerToRIL(JSContext* aCx);
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
nsresult Register(unsigned long aClientId,
WorkerCrossThreadDispatcher* aDispatcher);
void Unregister();
if (sRilConsumers.Length() <= mClientId || !sRilConsumers[mClientId]) {
// Probably shutting down.
delete mRawData;
return NS_OK;
}
// Methods for |RilSocketConsumer|
//
sRilConsumers[mClientId]->Send(mRawData);
return NS_OK;
}
void ReceiveSocketData(JSContext* aCx,
int aIndex,
nsAutoPtr<UnixSocketBuffer>& aBuffer) override;
void OnConnectSuccess(int aIndex) override;
void OnConnectError(int aIndex) override;
void OnDisconnect(int aIndex) override;
protected:
static bool PostRILMessage(JSContext* aCx, unsigned aArgc, Value* aVp);
nsresult Send(JSContext* aCx, const CallArgs& aArgs);
nsresult Receive(JSContext* aCx,
uint32_t aClientId,
const UnixSocketBuffer* aBuffer);
void Close();
private:
UnixSocketRawData* mRawData;
unsigned long mClientId;
nsRefPtr<RilSocket> mSocket;
nsCString mAddress;
bool mShutdown;
};
static bool
PostToRIL(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
{
JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
RilConsumer::RilConsumer()
: mShutdown(false)
{ }
if (args.length() != 2) {
JS_ReportError(aCx, "Expecting two arguments with the RIL message");
return false;
}
int clientId = args[0].toInt32();
JS::Value v = args[1];
UnixSocketRawData* raw = nullptr;
if (v.isString()) {
JSAutoByteString abs;
JS::Rooted<JSString*> str(aCx, v.toString());
if (!abs.encodeUtf8(aCx, str)) {
return false;
}
raw = new UnixSocketRawData(abs.ptr(), abs.length());
} else if (!v.isPrimitive()) {
JSObject* obj = v.toObjectOrNull();
if (!JS_IsTypedArrayObject(obj)) {
JS_ReportError(aCx, "Object passed in wasn't a typed array");
return false;
}
uint32_t type = JS_GetArrayBufferViewType(obj);
if (type != js::Scalar::Int8 &&
type != js::Scalar::Uint8 &&
type != js::Scalar::Uint8Clamped) {
JS_ReportError(aCx, "Typed array data is not octets");
return false;
}
JS::AutoCheckCannotGC nogc;
size_t size = JS_GetTypedArrayByteLength(obj);
void* data = JS_GetArrayBufferViewData(obj, nogc);
raw = new UnixSocketRawData(data, size);
} else {
JS_ReportError(
aCx, "Incorrect argument. Expecting a string or a typed array");
return false;
}
if (!raw) {
JS_ReportError(aCx, "Unable to post to RIL");
return false;
}
nsRefPtr<SendRilSocketDataTask> task = new SendRilSocketDataTask(clientId,
raw);
NS_DispatchToMainThread(task);
return true;
}
bool
ConnectWorkerToRIL::RunTask(JSContext* aCx)
nsresult
RilConsumer::ConnectWorkerToRIL(JSContext* aCx)
{
// Set up the postRILMessage on the function for worker -> RIL thread
// communication.
NS_ASSERTION(!NS_IsMainThread(), "Expecting to be on the worker thread");
NS_ASSERTION(!JS_IsRunning(aCx), "Are we being called somehow?");
JS::Rooted<JSObject*> workerGlobal(aCx, JS::CurrentGlobalOrNull(aCx));
Rooted<JSObject*> workerGlobal(aCx, CurrentGlobalOrNull(aCx));
// Check whether |postRILMessage| has been defined. No one but this class
// should ever define |postRILMessage| in a RIL worker.
JS::Rooted<JS::Value> val(aCx);
Rooted<Value> val(aCx);
if (!JS_GetProperty(aCx, workerGlobal, "postRILMessage", &val)) {
JS_ReportPendingException(aCx);
return false;
return NS_ERROR_FAILURE;
}
// Make sure that |postRILMessage| is a function.
if (JSTYPE_FUNCTION == JS_TypeOfValue(aCx, val)) {
return true;
return NS_OK;
}
return !!JS_DefineFunction(aCx, workerGlobal, "postRILMessage",
PostToRIL, 2, 0);
JSFunction* postRILMessage = JS_DefineFunction(aCx, workerGlobal,
"postRILMessage",
PostRILMessage, 2, 0);
if (NS_WARN_IF(!postRILMessage)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
class DispatchRILEvent final : public WorkerTask
{
public:
DispatchRILEvent(unsigned long aClient, UnixSocketBuffer* aBuffer)
: mClientId(aClient)
, mBuffer(aBuffer)
{ }
bool RunTask(JSContext* aCx) override;
private:
unsigned long mClientId;
nsAutoPtr<UnixSocketBuffer> mBuffer;
};
bool
DispatchRILEvent::RunTask(JSContext* aCx)
{
JS::Rooted<JSObject*> obj(aCx, JS::CurrentGlobalOrNull(aCx));
JS::Rooted<JSObject*> array(aCx,
JS_NewUint8Array(aCx, mBuffer->GetSize()));
if (!array) {
return false;
}
{
JS::AutoCheckCannotGC nogc;
memcpy(JS_GetArrayBufferViewData(array, nogc),
mBuffer->GetData(), mBuffer->GetSize());
}
JS::AutoValueArray<2> args(aCx);
args[0].setNumber((uint32_t)mClientId);
args[1].setObject(*array);
JS::Rooted<JS::Value> rval(aCx);
return JS_CallFunctionName(aCx, obj, "onRILMessage", args, &rval);
}
} // namespace
namespace mozilla {
namespace ipc {
RilConsumer::RilConsumer(unsigned long aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
: mDispatcher(aDispatcher)
, mShutdown(false)
nsresult
RilConsumer::Register(unsigned long aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
{
// Only append client id after RIL_SOCKET_NAME when it's not connected to
// the first(0) rilproxy for compatibility.
@ -214,60 +129,131 @@ RilConsumer::RilConsumer(unsigned long aClientId,
mAddress = addr_un.sun_path;
}
mSocket = new StreamSocket(this, aClientId);
mSocket->Connect(new RilConnector(mAddress, aClientId));
}
mSocket = new RilSocket(aDispatcher, this, aClientId);
nsresult
RilConsumer::Register(unsigned int aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
{
MOZ_ASSERT(NS_IsMainThread());
sRilConsumers.EnsureLengthAtLeast(aClientId + 1);
if (sRilConsumers[aClientId]) {
NS_WARNING("RilConsumer already registered");
return NS_ERROR_FAILURE;
nsresult rv = mSocket->Connect(new RilConnector(mAddress, aClientId));
if (NS_FAILED(rv)) {
return rv;
}
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
if (!aDispatcher->PostTask(connection)) {
NS_WARNING("Failed to connect worker to ril");
return NS_ERROR_UNEXPECTED;
}
// Now that we're set up, connect ourselves to the RIL thread.
sRilConsumers[aClientId] = new RilConsumer(aClientId, aDispatcher);
return NS_OK;
}
void
RilConsumer::Shutdown()
RilConsumer::Unregister()
{
MOZ_ASSERT(NS_IsMainThread());
for (unsigned long i = 0; i < sRilConsumers.Length(); i++) {
nsAutoPtr<RilConsumer> instance(sRilConsumers[i]);
if (!instance) {
continue;
}
instance->mShutdown = true;
instance->Close();
instance = nullptr;
}
mShutdown = true;
Close();
}
void
RilConsumer::Send(UnixSocketRawData* aRawData)
bool
RilConsumer::PostRILMessage(JSContext* aCx, unsigned aArgc, Value* aVp)
{
if (!mSocket || mSocket->GetConnectionStatus() != SOCKET_CONNECTED) {
// Probably shutting down.
delete aRawData;
return;
CallArgs args = CallArgsFromVp(aArgc, aVp);
if (args.length() != 2) {
JS_ReportError(aCx, "Expecting two arguments with the RIL message");
return false;
}
mSocket->SendSocketData(aRawData);
int clientId = args[0].toInt32();
if ((ssize_t)sRilConsumers.Length() <= clientId || !sRilConsumers[clientId]) {
// Probably shutting down.
return true;
}
nsresult rv = sRilConsumers[clientId]->Send(aCx, args);
if (NS_FAILED(rv)) {
return false;
}
return true;
}
nsresult
RilConsumer::Send(JSContext* aCx, const CallArgs& aArgs)
{
if (NS_WARN_IF(!mSocket) ||
NS_WARN_IF(mSocket->GetConnectionStatus() != SOCKET_CONNECTED)) {
// Probably shutting down.
return NS_OK;
}
nsAutoPtr<UnixSocketRawData> raw;
Value v = aArgs[1];
if (v.isString()) {
JSAutoByteString abs;
Rooted<JSString*> str(aCx, v.toString());
if (!abs.encodeUtf8(aCx, str)) {
return NS_ERROR_FAILURE;
}
raw = new UnixSocketRawData(abs.ptr(), abs.length());
} else if (!v.isPrimitive()) {
JSObject* obj = v.toObjectOrNull();
if (!JS_IsTypedArrayObject(obj)) {
JS_ReportError(aCx, "Object passed in wasn't a typed array");
return NS_ERROR_FAILURE;
}
uint32_t type = JS_GetArrayBufferViewType(obj);
if (type != js::Scalar::Int8 &&
type != js::Scalar::Uint8 &&
type != js::Scalar::Uint8Clamped) {
JS_ReportError(aCx, "Typed array data is not octets");
return NS_ERROR_FAILURE;
}
AutoCheckCannotGC nogc;
size_t size = JS_GetTypedArrayByteLength(obj);
void* data = JS_GetArrayBufferViewData(obj, nogc);
raw = new UnixSocketRawData(data, size);
} else {
JS_ReportError(
aCx, "Incorrect argument. Expecting a string or a typed array");
return NS_ERROR_FAILURE;
}
if (!raw) {
JS_ReportError(aCx, "Unable to post to RIL");
return NS_ERROR_FAILURE;
}
mSocket->SendSocketData(raw.forget());
return NS_OK;
}
nsresult
RilConsumer::Receive(JSContext* aCx,
uint32_t aClientId,
const UnixSocketBuffer* aBuffer)
{
MOZ_ASSERT(aBuffer);
Rooted<JSObject*> obj(aCx, CurrentGlobalOrNull(aCx));
Rooted<JSObject*> array(aCx, JS_NewUint8Array(aCx, aBuffer->GetSize()));
if (NS_WARN_IF(!array)) {
return NS_ERROR_FAILURE;
}
{
AutoCheckCannotGC nogc;
memcpy(JS_GetArrayBufferViewData(array, nogc),
aBuffer->GetData(), aBuffer->GetSize());
}
AutoValueArray<2> args(aCx);
args[0].setNumber(aClientId);
args[1].setObject(*array);
Rooted<Value> rval(aCx);
JS_CallFunctionName(aCx, obj, "onRILMessage", args, &rval);
return NS_OK;
}
void
@ -279,16 +265,14 @@ RilConsumer::Close()
}
}
// |StreamSocketConnector|
// |RilSocketConnector|
void
RilConsumer::ReceiveSocketData(int aIndex,
RilConsumer::ReceiveSocketData(JSContext* aCx,
int aIndex,
nsAutoPtr<UnixSocketBuffer>& aBuffer)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<DispatchRILEvent> dre(new DispatchRILEvent(aIndex, aBuffer.forget()));
mDispatcher->PostTask(dre);
Receive(aCx, (uint32_t)aIndex, aBuffer);
}
void
@ -316,5 +300,140 @@ RilConsumer::OnDisconnect(int aIndex)
mSocket->GetSuggestedConnectDelayMs());
}
//
// RilWorker
//
nsTArray<nsAutoPtr<RilWorker>> RilWorker::sRilWorkers;
nsresult
RilWorker::Register(unsigned int aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
{
MOZ_ASSERT(NS_IsMainThread());
sRilWorkers.EnsureLengthAtLeast(aClientId + 1);
if (sRilWorkers[aClientId]) {
NS_WARNING("RilWorkers already registered");
return NS_ERROR_FAILURE;
}
// Now that we're set up, connect ourselves to the RIL thread.
sRilWorkers[aClientId] = new RilWorker(aDispatcher);
nsresult rv = sRilWorkers[aClientId]->RegisterConsumer(aClientId);
if (NS_FAILED(rv)) {
return rv;
}
return NS_OK;
}
void
RilWorker::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
for (size_t i = 0; i < sRilWorkers.Length(); ++i) {
if (!sRilWorkers[i]) {
continue;
}
sRilWorkers[i]->UnregisterConsumer(i);
sRilWorkers[i] = nullptr;
}
}
RilWorker::RilWorker(WorkerCrossThreadDispatcher* aDispatcher)
: mDispatcher(aDispatcher)
{
MOZ_ASSERT(mDispatcher);
}
class RilWorker::RegisterConsumerTask : public WorkerTask
{
public:
RegisterConsumerTask(unsigned int aClientId,
WorkerCrossThreadDispatcher* aDispatcher)
: mClientId(aClientId)
, mDispatcher(aDispatcher)
{
MOZ_ASSERT(mDispatcher);
}
bool RunTask(JSContext* aCx) override
{
sRilConsumers.EnsureLengthAtLeast(mClientId + 1);
MOZ_ASSERT(!sRilConsumers[mClientId]);
nsAutoPtr<RilConsumer> rilConsumer(new RilConsumer());
nsresult rv = rilConsumer->ConnectWorkerToRIL(aCx);
if (NS_FAILED(rv)) {
return false;
}
rv = rilConsumer->Register(mClientId, mDispatcher);
if (NS_FAILED(rv)) {
return false;
}
sRilConsumers[mClientId] = rilConsumer;
return true;
}
private:
unsigned int mClientId;
nsRefPtr<WorkerCrossThreadDispatcher> mDispatcher;
};
nsresult
RilWorker::RegisterConsumer(unsigned int aClientId)
{
nsRefPtr<RegisterConsumerTask> task = new RegisterConsumerTask(aClientId,
mDispatcher);
if (!mDispatcher->PostTask(task)) {
NS_WARNING("Failed to post register-consumer task.");
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
class RilWorker::UnregisterConsumerTask : public WorkerTask
{
public:
UnregisterConsumerTask(unsigned int aClientId)
: mClientId(aClientId)
{ }
bool RunTask(JSContext* aCx) override
{
MOZ_ASSERT(mClientId < sRilConsumers.Length());
MOZ_ASSERT(sRilConsumers[mClientId]);
sRilConsumers[mClientId]->Unregister();
sRilConsumers[mClientId] = nullptr;
return true;
}
private:
unsigned int mClientId;
};
void
RilWorker::UnregisterConsumer(unsigned int aClientId)
{
nsRefPtr<UnregisterConsumerTask> task =
new UnregisterConsumerTask(aClientId);
if (!mDispatcher->PostTask(task)) {
NS_WARNING("Failed to post unregister-consumer task.");
return;
}
}
} // namespace ipc
} // namespace mozilla

View File

@ -7,42 +7,45 @@
#ifndef mozilla_ipc_Ril_h
#define mozilla_ipc_Ril_h 1
#include <mozilla/dom/workers/Workers.h>
#include <mozilla/ipc/StreamSocket.h>
#include <mozilla/ipc/StreamSocketConsumer.h>
#include "nsAutoPtr.h"
#include "nsError.h"
#include "nsTArray.h"
namespace mozilla {
namespace dom {
namespace workers {
class WorkerCrossThreadDispatcher;
} // namespace workers
} // namespace dom
namespace ipc {
class RilConsumer final : public StreamSocketConsumer
class RilConsumer;
class RilWorker final
{
public:
static nsresult Register(
unsigned int aClientId,
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
static void Shutdown();
void Send(UnixSocketRawData* aRawData);
private:
RilConsumer(unsigned long aClientId,
mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
class RegisterConsumerTask;
class UnregisterConsumerTask;
void Close();
RilWorker(mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher);
// Methods for |StreamSocketConsumer|
//
nsresult RegisterConsumer(unsigned int aClientId);
void UnregisterConsumer(unsigned int aClientId);
void ReceiveSocketData(int aIndex,
nsAutoPtr<UnixSocketBuffer>& aBuffer) override;
void OnConnectSuccess(int aIndex) override;
void OnConnectError(int aIndex) override;
void OnDisconnect(int aIndex) override;
static nsTArray<nsAutoPtr<RilWorker>> sRilWorkers;
nsRefPtr<StreamSocket> mSocket;
nsRefPtr<mozilla::dom::workers::WorkerCrossThreadDispatcher> mDispatcher;
nsCString mAddress;
bool mShutdown;
};
} // namespace ipc

433
ipc/ril/RilSocket.cpp Normal file
View File

@ -0,0 +1,433 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "RilSocket.h"
#include <fcntl.h>
#include "mozilla/dom/workers/Workers.h"
#include "mozilla/ipc/UnixSocketConnector.h"
#include "mozilla/RefPtr.h"
#include "nsXULAppAPI.h"
#include "RilSocketConsumer.h"
static const size_t MAX_READ_SIZE = 1 << 16;
namespace mozilla {
namespace ipc {
USING_WORKERS_NAMESPACE
//
// RilSocketIO
//
class RilSocketIO final : public ConnectionOrientedSocketIO
{
public:
class ConnectTask;
class DelayedConnectTask;
class ReceiveTask;
RilSocketIO(WorkerCrossThreadDispatcher* aDispatcher,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
RilSocket* aRilSocket,
UnixSocketConnector* aConnector);
~RilSocketIO();
RilSocket* GetRilSocket();
DataSocket* GetDataSocket();
// Delayed-task handling
//
void SetDelayedConnectTask(CancelableTask* aTask);
void ClearDelayedConnectTask();
void CancelDelayedConnectTask();
// Methods for |DataSocket|
//
nsresult QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) override;
void ConsumeBuffer() override;
void DiscardBuffer() override;
// Methods for |SocketIOBase|
//
SocketBase* GetSocketBase() override;
bool IsShutdownOnConsumerThread() const override;
bool IsShutdownOnIOThread() const override;
void ShutdownOnConsumerThread() override;
void ShutdownOnIOThread() override;
private:
/**
* Cross-thread dispatcher for the RIL worker
*/
nsRefPtr<WorkerCrossThreadDispatcher> mDispatcher;
/**
* Consumer pointer. Non-thread safe RefPtr, so should only be manipulated
* directly from consumer thread. All non-consumer-thread accesses should
* happen with mIO as container.
*/
RefPtr<RilSocket> mRilSocket;
/**
* If true, do not requeue whatever task we're running
*/
bool mShuttingDownOnIOThread;
/**
* Task member for delayed connect task. Should only be access on consumer
* thread.
*/
CancelableTask* mDelayedConnectTask;
/**
* I/O buffer for received data
*/
nsAutoPtr<UnixSocketRawData> mBuffer;
};
RilSocketIO::RilSocketIO(WorkerCrossThreadDispatcher* aDispatcher,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
RilSocket* aRilSocket,
UnixSocketConnector* aConnector)
: ConnectionOrientedSocketIO(aConsumerLoop, aIOLoop, aConnector)
, mDispatcher(aDispatcher)
, mRilSocket(aRilSocket)
, mShuttingDownOnIOThread(false)
, mDelayedConnectTask(nullptr)
{
MOZ_ASSERT(mDispatcher);
MOZ_ASSERT(mRilSocket);
}
RilSocketIO::~RilSocketIO()
{
MOZ_ASSERT(IsConsumerThread());
MOZ_ASSERT(IsShutdownOnConsumerThread());
}
RilSocket*
RilSocketIO::GetRilSocket()
{
return mRilSocket.get();
}
DataSocket*
RilSocketIO::GetDataSocket()
{
return mRilSocket.get();
}
void
RilSocketIO::SetDelayedConnectTask(CancelableTask* aTask)
{
MOZ_ASSERT(IsConsumerThread());
mDelayedConnectTask = aTask;
}
void
RilSocketIO::ClearDelayedConnectTask()
{
MOZ_ASSERT(IsConsumerThread());
mDelayedConnectTask = nullptr;
}
void
RilSocketIO::CancelDelayedConnectTask()
{
MOZ_ASSERT(IsConsumerThread());
if (!mDelayedConnectTask) {
return;
}
mDelayedConnectTask->Cancel();
ClearDelayedConnectTask();
}
// |DataSocketIO|
nsresult
RilSocketIO::QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer)
{
MOZ_ASSERT(aBuffer);
if (!mBuffer) {
mBuffer = new UnixSocketRawData(MAX_READ_SIZE);
}
*aBuffer = mBuffer.get();
return NS_OK;
}
/**
* |ReceiveTask| transfers data received on the I/O thread
* to an instance of |RilSocket| on the consumer thread.
*/
class RilSocketIO::ReceiveTask final : public WorkerTask
{
public:
ReceiveTask(RilSocketIO* aIO, UnixSocketBuffer* aBuffer)
: mIO(aIO)
, mBuffer(aBuffer)
{
MOZ_ASSERT(mIO);
}
bool RunTask(JSContext* aCx) override
{
// Dispatched via WCTD, but still needs to run on the consumer thread
MOZ_ASSERT(mIO->IsConsumerThread());
if (NS_WARN_IF(mIO->IsShutdownOnConsumerThread())) {
// Since we've already explicitly closed and the close
// happened before this, this isn't really an error.
return true;
}
RilSocket* rilSocket = mIO->GetRilSocket();
MOZ_ASSERT(rilSocket);
rilSocket->ReceiveSocketData(aCx, mBuffer);
return true;
}
private:
RilSocketIO* mIO;
nsAutoPtr<UnixSocketBuffer> mBuffer;
};
void
RilSocketIO::ConsumeBuffer()
{
nsRefPtr<ReceiveTask> task = new ReceiveTask(this, mBuffer.forget());
NS_WARN_IF(!mDispatcher->PostTask(task));
}
void
RilSocketIO::DiscardBuffer()
{
// Nothing to do.
}
// |SocketIOBase|
SocketBase*
RilSocketIO::GetSocketBase()
{
return GetDataSocket();
}
bool
RilSocketIO::IsShutdownOnConsumerThread() const
{
MOZ_ASSERT(IsConsumerThread());
return mRilSocket == nullptr;
}
bool
RilSocketIO::IsShutdownOnIOThread() const
{
return mShuttingDownOnIOThread;
}
void
RilSocketIO::ShutdownOnConsumerThread()
{
MOZ_ASSERT(IsConsumerThread());
MOZ_ASSERT(!IsShutdownOnConsumerThread());
mRilSocket = nullptr;
}
void
RilSocketIO::ShutdownOnIOThread()
{
MOZ_ASSERT(!IsConsumerThread());
MOZ_ASSERT(!mShuttingDownOnIOThread);
Close(); // will also remove fd from I/O loop
mShuttingDownOnIOThread = true;
}
//
// Socket tasks
//
class RilSocketIO::ConnectTask final
: public SocketIOTask<RilSocketIO>
{
public:
ConnectTask(RilSocketIO* aIO)
: SocketIOTask<RilSocketIO>(aIO)
{ }
void Run() override
{
MOZ_ASSERT(!GetIO()->IsConsumerThread());
MOZ_ASSERT(!IsCanceled());
GetIO()->Connect();
}
};
class RilSocketIO::DelayedConnectTask final
: public SocketIOTask<RilSocketIO>
{
public:
DelayedConnectTask(RilSocketIO* aIO)
: SocketIOTask<RilSocketIO>(aIO)
{ }
void Run() override
{
MOZ_ASSERT(GetIO()->IsConsumerThread());
if (IsCanceled()) {
return;
}
RilSocketIO* io = GetIO();
if (io->IsShutdownOnConsumerThread()) {
return;
}
io->ClearDelayedConnectTask();
io->GetIOLoop()->PostTask(FROM_HERE, new ConnectTask(io));
}
};
//
// RilSocket
//
RilSocket::RilSocket(WorkerCrossThreadDispatcher* aDispatcher,
RilSocketConsumer* aConsumer, int aIndex)
: mIO(nullptr)
, mDispatcher(aDispatcher)
, mConsumer(aConsumer)
, mIndex(aIndex)
{
MOZ_ASSERT(mDispatcher);
MOZ_ASSERT(mConsumer);
}
RilSocket::~RilSocket()
{
MOZ_ASSERT(!mIO);
}
void
RilSocket::ReceiveSocketData(JSContext* aCx,
nsAutoPtr<UnixSocketBuffer>& aBuffer)
{
mConsumer->ReceiveSocketData(aCx, mIndex, aBuffer);
}
nsresult
RilSocket::Connect(UnixSocketConnector* aConnector, int aDelayMs,
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop)
{
MOZ_ASSERT(!mIO);
mIO = new RilSocketIO(mDispatcher, aConsumerLoop, aIOLoop, this, aConnector);
SetConnectionStatus(SOCKET_CONNECTING);
if (aDelayMs > 0) {
RilSocketIO::DelayedConnectTask* connectTask =
new RilSocketIO::DelayedConnectTask(mIO);
mIO->SetDelayedConnectTask(connectTask);
MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
} else {
aIOLoop->PostTask(FROM_HERE, new RilSocketIO::ConnectTask(mIO));
}
return NS_OK;
}
nsresult
RilSocket::Connect(UnixSocketConnector* aConnector, int aDelayMs)
{
return Connect(aConnector, aDelayMs,
MessageLoop::current(), XRE_GetIOMessageLoop());
}
// |ConnectionOrientedSocket|
nsresult
RilSocket::PrepareAccept(UnixSocketConnector* aConnector,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
ConnectionOrientedSocketIO*& aIO)
{
MOZ_CRASH("|RilSocket| does not support accepting connections.");
}
// |DataSocket|
void
RilSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
{
MOZ_ASSERT(mIO);
MOZ_ASSERT(mIO->IsConsumerThread());
MOZ_ASSERT(!mIO->IsShutdownOnConsumerThread());
mIO->GetIOLoop()->PostTask(
FROM_HERE,
new SocketIOSendTask<RilSocketIO, UnixSocketIOBuffer>(mIO, aBuffer));
}
// |SocketBase|
void
RilSocket::Close()
{
MOZ_ASSERT(mIO);
MOZ_ASSERT(mIO->IsConsumerThread());
mIO->CancelDelayedConnectTask();
// From this point on, we consider |mIO| as being deleted. We sever
// the relationship here so any future calls to |Connect| will create
// a new I/O object.
mIO->ShutdownOnConsumerThread();
mIO->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO));
mIO = nullptr;
NotifyDisconnect();
}
void
RilSocket::OnConnectSuccess()
{
mConsumer->OnConnectSuccess(mIndex);
}
void
RilSocket::OnConnectError()
{
mConsumer->OnConnectError(mIndex);
}
void
RilSocket::OnDisconnect()
{
mConsumer->OnDisconnect(mIndex);
}
} // namespace ipc
} // namespace mozilla

110
ipc/ril/RilSocket.h Normal file
View File

@ -0,0 +1,110 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_ipc_RilSocket_h
#define mozilla_ipc_RilSocket_h
#include "mozilla/ipc/ConnectionOrientedSocket.h"
class JSContext;
class MessageLoop;
namespace mozilla {
namespace dom {
namespace workers {
class WorkerCrossThreadDispatcher;
} // namespace workers
} // namespace dom
} // namespace mozilla
namespace mozilla {
namespace ipc {
class RilSocketConsumer;
class RilSocketIO;
class UnixSocketConnector;
class RilSocket final : public ConnectionOrientedSocket
{
public:
/**
* Constructs an instance of |RilSocket|.
*
* @param aDispatcher The dispatcher class for the received messages.
* @param aConsumer The consumer for the socket.
* @param aIndex An arbitrary index.
*/
RilSocket(mozilla::dom::workers::WorkerCrossThreadDispatcher* aDispatcher,
RilSocketConsumer* aConsumer, int aIndex);
/**
* Method to be called whenever data is received. RIL-worker only.
*
* @param aCx The RIL worker's JS context.
* @param aBuffer Data received from the socket.
*/
void ReceiveSocketData(JSContext* aCx, nsAutoPtr<UnixSocketBuffer>& aBuffer);
/**
* Starts a task on the socket that will try to connect to a socket in a
* non-blocking manner.
*
* @param aConnector Connector object for socket type specific functions
* @param aDelayMs Time delay in milliseconds.
* @param aConsumerLoop The socket's consumer thread.
* @param aIOLoop The socket's I/O thread.
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
nsresult Connect(UnixSocketConnector* aConnector, int aDelayMs,
MessageLoop* aConsumerLoop, MessageLoop* aIOLoop);
/**
* Starts a task on the socket that will try to connect to a socket in a
* non-blocking manner.
*
* @param aConnector Connector object for socket type specific functions
* @param aDelayMs Time delay in milliseconds.
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
nsresult Connect(UnixSocketConnector* aConnector, int aDelayMs = 0);
// Methods for |ConnectionOrientedSocket|
//
nsresult PrepareAccept(UnixSocketConnector* aConnector,
MessageLoop* aConsumerLoop,
MessageLoop* aIOLoop,
ConnectionOrientedSocketIO*& aIO) override;
// Methods for |DataSocket|
//
void SendSocketData(UnixSocketIOBuffer* aBuffer) override;
// Methods for |SocketBase|
//
void Close() override;
void OnConnectSuccess() override;
void OnConnectError() override;
void OnDisconnect() override;
protected:
virtual ~RilSocket();
private:
RilSocketIO* mIO;
nsRefPtr<mozilla::dom::workers::WorkerCrossThreadDispatcher> mDispatcher;
RilSocketConsumer* mConsumer;
int mIndex;
};
} // namespace ipc
} // namepsace mozilla
#endif // mozilla_ipc_RilSocket_h

View File

@ -0,0 +1,20 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "RilSocketConsumer.h"
namespace mozilla {
namespace ipc {
//
// RilSocketConsumer
//
RilSocketConsumer::~RilSocketConsumer()
{ }
}
}

View File

@ -0,0 +1,64 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_ipc_RilSocketConsumer_h
#define mozilla_ipc_RilSocketConsumer_h
#include "nsAutoPtr.h"
class JSContext;
namespace mozilla {
namespace ipc {
class UnixSocketBuffer;
/**
* |RilSocketConsumer| handles socket events and received data.
*/
class RilSocketConsumer
{
public:
/**
* Method to be called whenever data is received. RIL-worker only.
*
* @param aCx The RIL worker's JS context.
* @param aIndex The index that has been given to the stream socket.
* @param aBuffer Data received from the socket.
*/
virtual void ReceiveSocketData(JSContext* aCx,
int aIndex,
nsAutoPtr<UnixSocketBuffer>& aBuffer) = 0;
/**
* Callback for socket success. Consumer-thread only.
*
* @param aIndex The index that has been given to the stream socket.
*/
virtual void OnConnectSuccess(int aIndex) = 0;
/**
* Callback for socket errors. Consumer-thread only.
*
* @param aIndex The index that has been given to the stream socket.
*/
virtual void OnConnectError(int aIndex) = 0;
/**
* Callback for socket disconnect. Consumer-thread only.
*
* @param aIndex The index that has been given to the stream socket.
*/
virtual void OnDisconnect(int aIndex) = 0;
protected:
virtual ~RilSocketConsumer();
};
}
}
#endif

View File

@ -6,11 +6,15 @@
EXPORTS.mozilla.ipc += [
'Ril.h',
'RilSocket.h',
'RilSocketConsumer.h'
]
SOURCES += [
'Ril.cpp',
'RilConnector.cpp'
'RilConnector.cpp',
'RilSocket.cpp',
'RilSocketConsumer.cpp'
]
include('/ipc/chromium/chromium-config.mozbuild')