Merge b2ginbound to central, a=merge

This commit is contained in:
Wes Kocher 2015-10-16 12:27:10 -07:00
commit 063fbab54b
45 changed files with 926 additions and 753 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
@ -135,7 +135,7 @@
<project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/>
<project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/>
<project name="kernel/common" path="kernel" revision="b698c5aa4e9393dfd70d0ea7a0bf93b333b54750"/>
<project name="platform/system/core" path="system/core" revision="4776448ebcd3f07d58b91503c478da9b54cb58a0"/>
<project name="platform/system/core" path="system/core" revision="1b888e1ae54c358246f13e4fb915ce43cde00691"/>
<project name="u-boot" path="u-boot" revision="f1502910977ac88f43da7bf9277c3523ad4b0b2f"/>
<project name="vendor/sprd/gps" path="vendor/sprd/gps" revision="7d6e1269be7186b2073fa568958b357826692c4b"/>
<project name="vendor/sprd/open-source" path="vendor/sprd/open-source" revision="295ff253b74353751a99aafd687196a28c84a58e"/>

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="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>

View File

@ -17,7 +17,7 @@
</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="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="4ace9aaee0e048dfda11bb787646c59982a3dc80"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "8999f0ba6326d815c8366e3c1155b7e4e9763b40",
"git_revision": "f75a7e01912cee313fed92ff2089586f507b2ba5",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "983b7ecb17c67b9fb511f400bb5b28b9069eea00",
"revision": "f51f8770b9665f44e57e9e09faee2b967a80abf1",
"repo_path": "integration/gaia-central"
}

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -18,7 +18,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="31a7849fe9a8b743d6f5e5facc212f0ef9d57499"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0c28789b9957913be975eb002a22323f93585d4c"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8999f0ba6326d815c8366e3c1155b7e4e9763b40"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f75a7e01912cee313fed92ff2089586f507b2ba5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7938df689aa87769fad3f2cf9097fb4ecb106a43"/>

View File

@ -35,6 +35,8 @@ namespace {
static BluetoothA2dpInterface* sBtA2dpInterface;
} // namespace
const int BluetoothA2dpManager::MAX_NUM_CLIENTS = 1;
NS_IMETHODIMP
BluetoothA2dpManager::Observe(nsISupports* aSubject,
const char* aTopic,
@ -86,39 +88,51 @@ AvStatusToSinkString(BluetoothA2dpConnectionState aState, nsAString& aString)
}
}
class BluetoothA2dpManager::InitResultHandler final
: public BluetoothA2dpResultHandler
class BluetoothA2dpManager::RegisterModuleResultHandler final
: public BluetoothSetupResultHandler
{
public:
InitResultHandler(BluetoothProfileResultHandler* aRes)
: mRes(aRes)
RegisterModuleResultHandler(BluetoothA2dpInterface* aInterface,
BluetoothProfileResultHandler* aRes)
: mInterface(aInterface)
, mRes(aRes)
{ }
void OnError(BluetoothStatus aStatus) override
{
BT_WARNING("BluetoothA2dpInterface::Init failed: %d",
MOZ_ASSERT(NS_IsMainThread());
BT_WARNING("BluetoothSetupInterface::RegisterModule failed for A2DP: %d",
(int)aStatus);
mInterface->SetNotificationHandler(nullptr);
if (mRes) {
mRes->OnError(NS_ERROR_FAILURE);
}
}
void Init() override
void RegisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
sBtA2dpInterface = mInterface;
if (mRes) {
mRes->Init();
}
}
private:
BluetoothA2dpInterface* mInterface;
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class BluetoothA2dpManager::OnErrorProfileResultHandlerRunnable final
class BluetoothA2dpManager::InitProfileResultHandlerRunnable final
: public nsRunnable
{
public:
OnErrorProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
nsresult aRv)
: mRes(aRes)
, mRv(aRv)
@ -128,7 +142,13 @@ public:
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
if (NS_SUCCEEDED(mRv)) {
mRes->Init();
} else {
mRes->OnError(mRv);
}
return NS_OK;
}
@ -147,32 +167,64 @@ private:
void
BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
{
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
MOZ_ASSERT(NS_IsMainThread());
if (sBtA2dpInterface) {
BT_LOGR("Bluetooth A2DP interface is already initalized.");
nsRefPtr<nsRunnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP Init runnable");
}
return;
}
auto btInf = BluetoothInterface::GetInstance();
if (NS_WARN_IF(!btInf)) {
// If there's no HFP interface, we dispatch a runnable
// If there's no Bluetooth interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
BT_LOGR("Failed to dispatch A2DP OnError runnable");
}
return;
}
sBtA2dpInterface = btInf->GetBluetoothA2dpInterface();
if (NS_WARN_IF(!sBtA2dpInterface)) {
// If there's no HFP interface, we dispatch a runnable
auto setupInterface = btInf->GetBluetoothSetupInterface();
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
BT_LOGR("Failed to dispatch A2DP OnError runnable");
}
return;
}
BluetoothA2dpManager* a2dpManager = BluetoothA2dpManager::Get();
sBtA2dpInterface->Init(a2dpManager, new InitResultHandler(aRes));
auto a2dpInterface = btInf->GetBluetoothA2dpInterface();
if (NS_WARN_IF(!a2dpInterface)) {
// If there's no A2DP interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP OnError runnable");
}
return;
}
// Set notification handler _before_ registering the module. It could
// happen that we receive notifications, before the result handler runs.
a2dpInterface->SetNotificationHandler(BluetoothA2dpManager::Get());
setupInterface->RegisterModule(
SETUP_SERVICE_ID_A2DP, 0, MAX_NUM_CLIENTS,
new RegisterModuleResultHandler(a2dpInterface, aRes));
}
BluetoothA2dpManager::~BluetoothA2dpManager()
@ -227,19 +279,22 @@ BluetoothA2dpManager::Get()
return sBluetoothA2dpManager;
}
class BluetoothA2dpManager::CleanupResultHandler final
: public BluetoothA2dpResultHandler
class BluetoothA2dpManager::UnregisterModuleResultHandler final
: public BluetoothSetupResultHandler
{
public:
CleanupResultHandler(BluetoothProfileResultHandler* aRes)
UnregisterModuleResultHandler(BluetoothProfileResultHandler* aRes)
: mRes(aRes)
{ }
void OnError(BluetoothStatus aStatus) override
{
BT_WARNING("BluetoothA2dpInterface::Cleanup failed: %d",
MOZ_ASSERT(NS_IsMainThread());
BT_WARNING("BluetoothSetupInterface::UnregisterModule failed for A2DP: %d",
(int)aStatus);
sBtA2dpInterface->SetNotificationHandler(nullptr);
sBtA2dpInterface = nullptr;
if (mRes) {
@ -247,8 +302,11 @@ public:
}
}
void Cleanup() override
void UnregisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
sBtA2dpInterface->SetNotificationHandler(nullptr);
sBtA2dpInterface = nullptr;
if (mRes) {
@ -260,26 +318,33 @@ private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class BluetoothA2dpManager::CleanupResultHandlerRunnable final
class BluetoothA2dpManager::DeinitProfileResultHandlerRunnable final
: public nsRunnable
{
public:
CleanupResultHandlerRunnable(BluetoothProfileResultHandler* aRes)
DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
nsresult aRv)
: mRes(aRes)
{ }
, mRv(aRv)
{
MOZ_ASSERT(mRes);
}
NS_IMETHOD Run() override
{
sBtA2dpInterface = nullptr;
MOZ_ASSERT(NS_IsMainThread());
if (mRes) {
if (NS_SUCCEEDED(mRv)) {
mRes->Deinit();
} else {
mRes->OnError(mRv);
}
return NS_OK;
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
nsresult mRv;
};
// static
@ -288,16 +353,45 @@ BluetoothA2dpManager::DeinitA2dpInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (sBtA2dpInterface) {
sBtA2dpInterface->Cleanup(new CleanupResultHandler(aRes));
} else if (aRes) {
// We dispatch a runnable here to make the profile resource handler
// behave as if A2DP was initialized.
nsRefPtr<nsRunnable> r = new CleanupResultHandlerRunnable(aRes);
if (!sBtA2dpInterface) {
BT_LOGR("Bluetooth A2DP interface has not been initalized.");
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch cleanup-result-handler runnable");
BT_LOGR("Failed to dispatch A2DP Deinit runnable");
}
return;
}
auto btInf = BluetoothInterface::GetInstance();
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP OnError runnable");
}
return;
}
auto setupInterface = btInf->GetBluetoothSetupInterface();
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch A2DP OnError runnable");
}
return;
}
setupInterface->UnregisterModule(
SETUP_SERVICE_ID_A2DP,
new UnregisterModuleResultHandler(aRes));
}
void

View File

@ -17,6 +17,8 @@ class BluetoothA2dpManager : public BluetoothProfileManagerBase
, public BluetoothA2dpNotificationHandler
{
public:
static const int MAX_NUM_CLIENTS;
BT_DECL_PROFILE_MGR_BASE
virtual void GetName(nsACString& aName)
{
@ -47,12 +49,12 @@ protected:
virtual ~BluetoothA2dpManager();
private:
class CleanupResultHandler;
class CleanupResultHandlerRunnable;
class ConnectResultHandler;
class DeinitProfileResultHandlerRunnable;
class DisconnectResultHandler;
class InitResultHandler;
class OnErrorProfileResultHandlerRunnable;
class InitProfileResultHandlerRunnable;
class RegisterModuleResultHandler;
class UnregisterModuleResultHandler;
BluetoothA2dpManager();

View File

@ -35,6 +35,8 @@ namespace {
static BluetoothAvrcpInterface* sBtAvrcpInterface;
} // namespace
const int BluetoothAvrcpManager::MAX_NUM_CLIENTS = 1;
/*
* This function maps attribute id and returns corresponding values
*/
@ -118,18 +120,27 @@ BluetoothAvrcpManager::Reset()
mPlayStatus = ControlPlayStatus::PLAYSTATUS_STOPPED;
}
class BluetoothAvrcpManager::InitResultHandler final
: public BluetoothAvrcpResultHandler
class BluetoothAvrcpManager::RegisterModuleResultHandler final
: public BluetoothSetupResultHandler
{
public:
InitResultHandler(BluetoothProfileResultHandler* aRes)
: mRes(aRes)
{ }
RegisterModuleResultHandler(BluetoothAvrcpInterface* aInterface,
BluetoothProfileResultHandler* aRes)
: mInterface(aInterface)
, mRes(aRes)
{
MOZ_ASSERT(mInterface);
}
void OnError(BluetoothStatus aStatus) override
{
BT_WARNING("BluetoothAvrcpInterface::Init failed: %d",
MOZ_ASSERT(NS_IsMainThread());
BT_WARNING("BluetoothSetupInterface::RegisterModule failed for AVRCP: %d",
(int)aStatus);
mInterface->SetNotificationHandler(nullptr);
if (mRes) {
if (aStatus == STATUS_UNSUPPORTED) {
/* Not all versions of Bluedroid support AVRCP. So if the
@ -143,22 +154,27 @@ public:
}
}
void Init() override
void RegisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
sBtAvrcpInterface = mInterface;
if (mRes) {
mRes->Init();
}
}
private:
BluetoothAvrcpInterface* mInterface;
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class BluetoothAvrcpManager::OnErrorProfileResultHandlerRunnable final
class BluetoothAvrcpManager::InitProfileResultHandlerRunnable final
: public nsRunnable
{
public:
OnErrorProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
nsresult aRv)
: mRes(aRes)
, mRv(aRv)
@ -168,7 +184,13 @@ public:
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
if (NS_SUCCEEDED(mRv)) {
mRes->Init();
} else {
mRes->OnError(mRv);
}
return NS_OK;
}
@ -184,32 +206,64 @@ private:
void
BluetoothAvrcpManager::InitAvrcpInterface(BluetoothProfileResultHandler* aRes)
{
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
if (NS_WARN_IF(!btInf)) {
// If there's no HFP interface, we dispatch a runnable
// that calls the profile result handler.
MOZ_ASSERT(NS_IsMainThread());
if (sBtAvrcpInterface) {
BT_LOGR("Bluetooth AVRCP interface is already initalized.");
nsRefPtr<nsRunnable> r =
new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
new InitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
BT_LOGR("Failed to dispatch AVRCP Init runnable");
}
return;
}
sBtAvrcpInterface = btInf->GetBluetoothAvrcpInterface();
if (NS_WARN_IF(!sBtAvrcpInterface)) {
auto btInf = BluetoothInterface::GetInstance();
if (NS_WARN_IF(!btInf)) {
// If there's no Bluetooth interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP OnError runnable");
}
return;
}
auto setupInterface = btInf->GetBluetoothSetupInterface();
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP OnError runnable");
}
return;
}
auto avrcpInterface = btInf->GetBluetoothAvrcpInterface();
if (NS_WARN_IF(!avrcpInterface)) {
// If there's no AVRCP interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
BT_LOGR("Failed to dispatch AVRCP OnError runnable");
}
return;
}
BluetoothAvrcpManager* avrcpManager = BluetoothAvrcpManager::Get();
sBtAvrcpInterface->Init(avrcpManager, new InitResultHandler(aRes));
// Set notification handler _before_ registering the module. It could
// happen that we receive notifications, before the result handler runs.
avrcpInterface->SetNotificationHandler(BluetoothAvrcpManager::Get());
setupInterface->RegisterModule(
SETUP_SERVICE_ID_AVRCP, 0, MAX_NUM_CLIENTS,
new RegisterModuleResultHandler(avrcpInterface, aRes));
}
BluetoothAvrcpManager::~BluetoothAvrcpManager()
@ -245,37 +299,36 @@ BluetoothAvrcpManager::Get()
return sBluetoothAvrcpManager;
}
class BluetoothAvrcpManager::CleanupResultHandler final
: public BluetoothAvrcpResultHandler
class BluetoothAvrcpManager::UnregisterModuleResultHandler final
: public BluetoothSetupResultHandler
{
public:
CleanupResultHandler(BluetoothProfileResultHandler* aRes)
UnregisterModuleResultHandler(BluetoothProfileResultHandler* aRes)
: mRes(aRes)
{ }
void OnError(BluetoothStatus aStatus) override
{
BT_WARNING("BluetoothAvrcpInterface::Cleanup failed: %d",
MOZ_ASSERT(NS_IsMainThread());
BT_WARNING("BluetoothSetupInterface::UnregisterModule failed for AVRCP: %d",
(int)aStatus);
sBtAvrcpInterface->SetNotificationHandler(nullptr);
sBtAvrcpInterface = nullptr;
if (mRes) {
if (aStatus == STATUS_UNSUPPORTED) {
/* Not all versions of Bluedroid support AVRCP. So if the
* cleanup fails with STATUS_UNSUPPORTED, we still signal
* success.
*/
mRes->Deinit();
} else {
mRes->OnError(NS_ERROR_FAILURE);
}
}
}
void Cleanup() override
void UnregisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
sBtAvrcpInterface->SetNotificationHandler(nullptr);
sBtAvrcpInterface = nullptr;
if (mRes) {
mRes->Deinit();
}
@ -285,25 +338,33 @@ private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class BluetoothAvrcpManager::CleanupResultHandlerRunnable final
class BluetoothAvrcpManager::DeinitProfileResultHandlerRunnable final
: public nsRunnable
{
public:
CleanupResultHandlerRunnable(BluetoothProfileResultHandler* aRes)
DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
nsresult aRv)
: mRes(aRes)
, mRv(aRv)
{
MOZ_ASSERT(mRes);
}
NS_IMETHOD Run() override
{
mRes->Deinit();
MOZ_ASSERT(NS_IsMainThread());
if (NS_SUCCEEDED(mRv)) {
mRes->Deinit();
} else {
mRes->OnError(mRv);
}
return NS_OK;
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
nsresult mRv;
};
// static
@ -312,16 +373,45 @@ BluetoothAvrcpManager::DeinitAvrcpInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (sBtAvrcpInterface) {
sBtAvrcpInterface->Cleanup(new CleanupResultHandler(aRes));
} else if (aRes) {
// We dispatch a runnable here to make the profile resource handler
// behave as if AVRCP was initialized.
nsRefPtr<nsRunnable> r = new CleanupResultHandlerRunnable(aRes);
if (!sBtAvrcpInterface) {
BT_LOGR("Bluetooth AVRCP interface has not been initalized.");
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch cleanup-result-handler runnable");
BT_LOGR("Failed to dispatch AVRCP Deinit runnable");
}
return;
}
auto btInf = BluetoothInterface::GetInstance();
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP OnError runnable");
}
return;
}
auto setupInterface = btInf->GetBluetoothSetupInterface();
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch AVRCP OnError runnable");
}
return;
}
setupInterface->UnregisterModule(
SETUP_SERVICE_ID_AVRCP,
new UnregisterModuleResultHandler(aRes));
}
void

View File

@ -17,6 +17,8 @@ class BluetoothAvrcpManager : public BluetoothProfileManagerBase
, public BluetoothAvrcpNotificationHandler
{
public:
static const int MAX_NUM_CLIENTS;
BT_DECL_PROFILE_MGR_BASE
virtual void GetName(nsACString& aName)
{
@ -60,12 +62,12 @@ protected:
virtual ~BluetoothAvrcpManager();
private:
class CleanupResultHandler;
class CleanupResultHandlerRunnable;
class ConnectRunnable;
class DeinitProfileResultHandlerRunnable;
class DisconnectRunnable;
class InitResultHandler;
class OnErrorProfileResultHandlerRunnable;
class InitProfileResultHandlerRunnable;
class RegisterModuleResultHandler;
class UnregisterModuleResultHandler;
BluetoothAvrcpManager();

View File

@ -15,8 +15,6 @@ using namespace mozilla::ipc;
// A2DP module
//
const int BluetoothDaemonA2dpModule::MAX_NUM_CLIENTS = 1;
BluetoothA2dpNotificationHandler*
BluetoothDaemonA2dpModule::sNotificationHandler;
@ -235,109 +233,13 @@ BluetoothDaemonA2dpInterface::BluetoothDaemonA2dpInterface(
BluetoothDaemonA2dpInterface::~BluetoothDaemonA2dpInterface()
{ }
class BluetoothDaemonA2dpInterface::InitResultHandler final
: public BluetoothSetupResultHandler
{
public:
InitResultHandler(BluetoothA2dpResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
void OnError(BluetoothStatus aStatus) override
{
MOZ_ASSERT(NS_IsMainThread());
mRes->OnError(aStatus);
}
void RegisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
mRes->Init();
}
private:
nsRefPtr<BluetoothA2dpResultHandler> mRes;
};
void
BluetoothDaemonA2dpInterface::Init(
BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes)
{
// Set notification handler _before_ registering the module. It could
// happen that we receive notifications, before the result handler runs.
mModule->SetNotificationHandler(aNotificationHandler);
InitResultHandler* res;
if (aRes) {
res = new InitResultHandler(aRes);
} else {
// We don't need a result handler if the caller is not interested.
res = nullptr;
}
nsresult rv = mModule->RegisterModule(BluetoothDaemonA2dpModule::SERVICE_ID,
0x00, BluetoothDaemonA2dpModule::MAX_NUM_CLIENTS, res);
if (NS_FAILED(rv) && aRes) {
DispatchError(aRes, rv);
}
}
class BluetoothDaemonA2dpInterface::CleanupResultHandler final
: public BluetoothSetupResultHandler
{
public:
CleanupResultHandler(BluetoothDaemonA2dpModule* aModule,
BluetoothA2dpResultHandler* aRes)
: mModule(aModule)
, mRes(aRes)
BluetoothDaemonA2dpInterface::SetNotificationHandler(
BluetoothA2dpNotificationHandler* aNotificationHandler)
{
MOZ_ASSERT(mModule);
}
void OnError(BluetoothStatus aStatus) override
{
MOZ_ASSERT(NS_IsMainThread());
if (mRes) {
mRes->OnError(aStatus);
}
}
void UnregisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
// Clear notification handler _after_ module has been
// unregistered. While unregistering the module, we might
// still receive notifications.
mModule->SetNotificationHandler(nullptr);
if (mRes) {
mRes->Cleanup();
}
}
private:
BluetoothDaemonA2dpModule* mModule;
nsRefPtr<BluetoothA2dpResultHandler> mRes;
};
void
BluetoothDaemonA2dpInterface::Cleanup(
BluetoothA2dpResultHandler* aRes)
{
nsresult rv = mModule->UnregisterModule(
BluetoothDaemonA2dpModule::SERVICE_ID,
new CleanupResultHandler(mModule, aRes));
if (NS_FAILED(rv)) {
DispatchError(aRes, rv);
}
mModule->SetNotificationHandler(aNotificationHandler);
}
/* Connect / Disconnect */

View File

@ -30,18 +30,9 @@ public:
OPCODE_DISCONNECT = 0x02
};
static const int MAX_NUM_CLIENTS;
virtual nsresult Send(DaemonSocketPDU* aPDU,
DaemonSocketResultHandler* aRes) = 0;
virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes) = 0;
virtual nsresult UnregisterModule(uint8_t aId,
BluetoothSetupResultHandler* aRes) = 0;
void SetNotificationHandler(
BluetoothA2dpNotificationHandler* aNotificationHandler);
@ -129,17 +120,12 @@ protected:
class BluetoothDaemonA2dpInterface final
: public BluetoothA2dpInterface
{
class CleanupResultHandler;
class InitResultHandler;
public:
BluetoothDaemonA2dpInterface(BluetoothDaemonA2dpModule* aModule);
~BluetoothDaemonA2dpInterface();
void Init(
BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes) override;
void Cleanup(BluetoothA2dpResultHandler* aRes) override;
void SetNotificationHandler(
BluetoothA2dpNotificationHandler* aNotificationHandler) override;
/* Connect / Disconnect */

View File

@ -15,8 +15,6 @@ using namespace mozilla::ipc;
// AVRCP module
//
const int BluetoothDaemonAvrcpModule::MAX_NUM_CLIENTS = 1;
BluetoothAvrcpNotificationHandler*
BluetoothDaemonAvrcpModule::sNotificationHandler;
@ -805,115 +803,13 @@ BluetoothDaemonAvrcpInterface::BluetoothDaemonAvrcpInterface(
BluetoothDaemonAvrcpInterface::~BluetoothDaemonAvrcpInterface()
{ }
class BluetoothDaemonAvrcpInterface::InitResultHandler final
: public BluetoothSetupResultHandler
{
public:
InitResultHandler(BluetoothAvrcpResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
void OnError(BluetoothStatus aStatus) override
{
MOZ_ASSERT(NS_IsMainThread());
mRes->OnError(aStatus);
}
void RegisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
mRes->Init();
}
private:
nsRefPtr<BluetoothAvrcpResultHandler> mRes;
};
void
BluetoothDaemonAvrcpInterface::Init(
BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes)
BluetoothDaemonAvrcpInterface::SetNotificationHandler(
BluetoothAvrcpNotificationHandler* aNotificationHandler)
{
MOZ_ASSERT(mModule);
// Set notification handler _before_ registering the module. It could
// happen that we receive notifications, before the result handler runs.
mModule->SetNotificationHandler(aNotificationHandler);
InitResultHandler* res;
if (aRes) {
res = new InitResultHandler(aRes);
} else {
// We don't need a result handler if the caller is not interested.
res = nullptr;
}
nsresult rv = mModule->RegisterModule(
BluetoothDaemonAvrcpModule::SERVICE_ID,
BluetoothDaemonAvrcpModule::MAX_NUM_CLIENTS, 0x00, res);
if (NS_FAILED(rv) && aRes) {
DispatchError(aRes, rv);
}
}
class BluetoothDaemonAvrcpInterface::CleanupResultHandler final
: public BluetoothSetupResultHandler
{
public:
CleanupResultHandler(BluetoothDaemonAvrcpModule* aModule,
BluetoothAvrcpResultHandler* aRes)
: mModule(aModule)
, mRes(aRes)
{
MOZ_ASSERT(mModule);
}
void OnError(BluetoothStatus aStatus) override
{
MOZ_ASSERT(NS_IsMainThread());
if (mRes) {
mRes->OnError(aStatus);
}
}
void UnregisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
// Clear notification handler _after_ module has been
// unregistered. While unregistering the module, we might
// still receive notifications.
mModule->SetNotificationHandler(nullptr);
if (mRes) {
mRes->Cleanup();
}
}
private:
BluetoothDaemonAvrcpModule* mModule;
nsRefPtr<BluetoothAvrcpResultHandler> mRes;
};
void
BluetoothDaemonAvrcpInterface::Cleanup(
BluetoothAvrcpResultHandler* aRes)
{
MOZ_ASSERT(mModule);
nsresult rv = mModule->UnregisterModule(
BluetoothDaemonAvrcpModule::SERVICE_ID,
new CleanupResultHandler(mModule, aRes));
if (NS_FAILED(rv)) {
DispatchError(aRes, rv);
}
}
void

View File

@ -62,18 +62,9 @@ public:
#endif
};
static const int MAX_NUM_CLIENTS;
virtual nsresult Send(DaemonSocketPDU* aPDU,
DaemonSocketResultHandler* aRes) = 0;
virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes) = 0;
virtual nsresult UnregisterModule(uint8_t aId,
BluetoothSetupResultHandler* aRes) = 0;
void SetNotificationHandler(
BluetoothAvrcpNotificationHandler* aNotificationHandler);
@ -305,10 +296,8 @@ public:
BluetoothDaemonAvrcpInterface(BluetoothDaemonAvrcpModule* aModule);
~BluetoothDaemonAvrcpInterface();
void Init(BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes) override;
void Cleanup(BluetoothAvrcpResultHandler* aRes) override;
void SetNotificationHandler(
BluetoothAvrcpNotificationHandler* aNotificationHandler) override;
void GetPlayStatusRsp(ControlPlayStatus aPlayStatus,
uint32_t aSongLen, uint32_t aSongPos,

View File

@ -15,8 +15,6 @@ using namespace mozilla::ipc;
// GATT module
//
const int BluetoothDaemonGattModule::MAX_NUM_CLIENTS = 1;
BluetoothGattNotificationHandler*
BluetoothDaemonGattModule::sNotificationHandler;
@ -2010,6 +2008,7 @@ BluetoothDaemonGattInterface::BluetoothDaemonGattInterface(
BluetoothDaemonGattInterface::~BluetoothDaemonGattInterface()
{ }
#if 0
class BluetoothDaemonGattInterface::InitResultHandler final
: public BluetoothSetupResultHandler
{
@ -2057,8 +2056,8 @@ BluetoothDaemonGattInterface::Init(
}
nsresult rv = mModule->RegisterModule(
BluetoothDaemonGattModule::SERVICE_ID, 0x00,
BluetoothDaemonGattModule::MAX_NUM_CLIENTS, res);
SETUP_SERVICE_ID_GATT, 0x00, BluetoothDaemonGattModule::MAX_NUM_CLIENTS,
res);
if (NS_FAILED(rv) && aRes) {
DispatchError(aRes, rv);
@ -2110,12 +2109,21 @@ BluetoothDaemonGattInterface::Cleanup(
BluetoothGattResultHandler* aRes)
{
nsresult rv = mModule->UnregisterModule(
BluetoothDaemonGattModule::SERVICE_ID,
new CleanupResultHandler(mModule, aRes));
SETUP_SERVICE_ID_GATT, new CleanupResultHandler(mModule, aRes));
if (NS_FAILED(rv)) {
DispatchError(aRes, rv);
}
}
#endif
void
BluetoothDaemonGattInterface::SetNotificationHandler(
BluetoothGattNotificationHandler* aNotificationHandler)
{
MOZ_ASSERT(mModule);
mModule->SetNotificationHandler(aNotificationHandler);
}
/* Register / Unregister */
void

View File

@ -64,18 +64,9 @@ public:
// TODO: Add L support
};
static const int MAX_NUM_CLIENTS;
virtual nsresult Send(DaemonSocketPDU* aPDU,
DaemonSocketResultHandler* aRes) = 0;
virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes) = 0;
virtual nsresult UnregisterModule(uint8_t aId,
BluetoothSetupResultHandler* aRes) = 0;
void SetNotificationHandler(
BluetoothGattNotificationHandler* aNotificationHandler);
@ -798,9 +789,8 @@ public:
BluetoothDaemonGattInterface(BluetoothDaemonGattModule* aModule);
~BluetoothDaemonGattInterface();
void Init(BluetoothGattNotificationHandler* aNotificationHandler,
BluetoothGattResultHandler* aRes) override;
void Cleanup(BluetoothGattResultHandler* aRes) override;
void SetNotificationHandler(
BluetoothGattNotificationHandler* aNotificationHandler) override;
/* Register / Unregister */
void RegisterClient(const BluetoothUuid& aUuid,

View File

@ -1409,115 +1409,12 @@ BluetoothDaemonHandsfreeInterface::BluetoothDaemonHandsfreeInterface(
BluetoothDaemonHandsfreeInterface::~BluetoothDaemonHandsfreeInterface()
{ }
class BluetoothDaemonHandsfreeInterface::InitResultHandler final
: public BluetoothSetupResultHandler
{
public:
InitResultHandler(BluetoothHandsfreeResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
void OnError(BluetoothStatus aStatus) override
{
MOZ_ASSERT(NS_IsMainThread());
mRes->OnError(aStatus);
}
void RegisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
mRes->Init();
}
private:
nsRefPtr<BluetoothHandsfreeResultHandler> mRes;
};
void
BluetoothDaemonHandsfreeInterface::Init(
BluetoothHandsfreeNotificationHandler* aNotificationHandler,
int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes)
{
// Set notification handler _before_ registering the module. It could
// happen that we receive notifications, before the result handler runs.
mModule->SetNotificationHandler(aNotificationHandler);
InitResultHandler* res;
if (aRes) {
res = new InitResultHandler(aRes);
} else {
// We don't need a result handler if the caller is not interested.
res = nullptr;
}
nsresult rv = mModule->RegisterModule(
BluetoothDaemonHandsfreeModule::SERVICE_ID, MODE_NARROWBAND_SPEECH,
aMaxNumClients, res);
if (NS_FAILED(rv) && aRes) {
DispatchError(aRes, rv);
}
}
class BluetoothDaemonHandsfreeInterface::CleanupResultHandler final
: public BluetoothSetupResultHandler
{
public:
CleanupResultHandler(BluetoothDaemonHandsfreeModule* aModule,
BluetoothHandsfreeResultHandler* aRes)
: mModule(aModule)
, mRes(aRes)
void BluetoothDaemonHandsfreeInterface::SetNotificationHandler(
BluetoothHandsfreeNotificationHandler* aNotificationHandler)
{
MOZ_ASSERT(mModule);
}
void OnError(BluetoothStatus aStatus) override
{
MOZ_ASSERT(NS_IsMainThread());
BT_LOGR("%s:%d", __func__, __LINE__);
if (mRes) {
mRes->OnError(aStatus);
}
}
void UnregisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
BT_LOGR("%s:%d", __func__, __LINE__);
// Clear notification handler _after_ module has been
// unregistered. While unregistering the module, we might
// still receive notifications.
mModule->SetNotificationHandler(nullptr);
if (mRes) {
mRes->Cleanup();
}
}
private:
BluetoothDaemonHandsfreeModule* mModule;
nsRefPtr<BluetoothHandsfreeResultHandler> mRes;
};
void
BluetoothDaemonHandsfreeInterface::Cleanup(
BluetoothHandsfreeResultHandler* aRes)
{
BT_LOGR("%s:%d", __func__, __LINE__);
nsresult rv = mModule->UnregisterModule(
BluetoothDaemonHandsfreeModule::SERVICE_ID,
new CleanupResultHandler(mModule, aRes));
BT_LOGR("%s:%d", __func__, __LINE__);
if (NS_FAILED(rv)) {
DispatchError(aRes, rv);
}
mModule->SetNotificationHandler(aNotificationHandler);
}
/* Connect / Disconnect */

View File

@ -46,13 +46,6 @@ public:
virtual nsresult Send(DaemonSocketPDU* aPDU,
DaemonSocketResultHandler* aRes) = 0;
virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes) = 0;
virtual nsresult UnregisterModule(uint8_t aId,
BluetoothSetupResultHandler* aRes) = 0;
void SetNotificationHandler(
BluetoothHandsfreeNotificationHandler* aNotificationHandler);
@ -400,23 +393,12 @@ protected:
class BluetoothDaemonHandsfreeInterface final
: public BluetoothHandsfreeInterface
{
class CleanupResultHandler;
class InitResultHandler;
enum {
MODE_HEADSET = 0x00,
MODE_NARROWBAND_SPEECH = 0x01,
MODE_NARRAWBAND_WIDEBAND_SPEECH = 0x02
};
public:
BluetoothDaemonHandsfreeInterface(BluetoothDaemonHandsfreeModule* aModule);
~BluetoothDaemonHandsfreeInterface();
void Init(
BluetoothHandsfreeNotificationHandler* aNotificationHandler,
int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) override;
void Cleanup(BluetoothHandsfreeResultHandler* aRes) override;
void SetNotificationHandler(
BluetoothHandsfreeNotificationHandler* aNotificationHandler) override;
/* Connect / Disconnect */

View File

@ -841,6 +841,35 @@ Convert(BluetoothScanMode aIn, int32_t& aOut)
return NS_OK;
}
nsresult
Convert(BluetoothSetupServiceId aIn, uint8_t& aOut)
{
static const uint8_t sServiceId[] = {
[SETUP_SERVICE_ID_SETUP] = 0x00,
[SETUP_SERVICE_ID_CORE] = 0x01,
[SETUP_SERVICE_ID_SOCKET] = 0x02,
[SETUP_SERVICE_ID_HID] = 0x03,
[SETUP_SERVICE_ID_PAN] = 0x04,
[SETUP_SERVICE_ID_HANDSFREE] = 0x05,
[SETUP_SERVICE_ID_A2DP] = 0x06,
[SETUP_SERVICE_ID_HEALTH] = 0x07,
[SETUP_SERVICE_ID_AVRCP] = 0x08,
[SETUP_SERVICE_ID_GATT] = 0x09,
[SETUP_SERVICE_ID_HANDSFREE_CLIENT] = 0x0a,
[SETUP_SERVICE_ID_MAP_CLIENT] = 0x0b,
[SETUP_SERVICE_ID_AVRCP_CONTROLLER] = 0x0c,
[SETUP_SERVICE_ID_A2DP_SINK] = 0x0d
};
if (MOZ_HAL_IPC_CONVERT_WARN_IF(
aIn >= MOZ_ARRAY_LENGTH(sServiceId),
BluetoothServiceSetupId, uint8_t)) {
aOut = 0; // silences compiler warning
return NS_ERROR_ILLEGAL_VALUE;
}
aOut = sServiceId[aIn];
return NS_OK;
}
nsresult
Convert(BluetoothSspVariant aIn, uint8_t& aOut)
{
@ -1267,6 +1296,12 @@ PackPDU(BluetoothScanMode aIn, DaemonSocketPDU& aPDU)
return PackPDU(PackConversion<BluetoothScanMode, int32_t>(aIn), aPDU);
}
nsresult
PackPDU(BluetoothSetupServiceId aIn, DaemonSocketPDU& aPDU)
{
return PackPDU(PackConversion<BluetoothSetupServiceId, uint8_t>(aIn), aPDU);
}
nsresult
PackPDU(const BluetoothServiceName& aIn, DaemonSocketPDU& aPDU)
{

View File

@ -97,12 +97,6 @@ struct BluetoothAvrcpEventParamPair {
const BluetoothAvrcpNotificationParam& mParam;
};
struct BluetoothConfigurationParameter {
uint8_t mType;
uint16_t mLength;
nsAutoArrayPtr<uint8_t> mValue;
};
//
// Conversion
//
@ -236,6 +230,9 @@ Convert(BluetoothPropertyType aIn, uint8_t& aOut);
nsresult
Convert(BluetoothScanMode aIn, uint8_t& aOut);
nsresult
Convert(BluetoothSetupServiceId aIn, uint8_t& aOut);
nsresult
Convert(BluetoothSocketType aIn, uint8_t& aOut);
@ -335,6 +332,9 @@ PackPDU(BluetoothPropertyType aIn, DaemonSocketPDU& aPDU);
nsresult
PackPDU(const BluetoothServiceName& aIn, DaemonSocketPDU& aPDU);
nsresult
PackPDU(BluetoothSetupServiceId aIn, DaemonSocketPDU& aPDU);
nsresult
PackPDU(BluetoothSocketType aIn, DaemonSocketPDU& aPDU);

View File

@ -39,24 +39,14 @@ static const int sRetryInterval = 100; // ms
//
// Each |BluetoothDaemon*Module| class implements an individual
// module of the HAL protocol. Each class contains the abstract
// methods
// method
//
// - |Send|,
// - |RegisterModule|, and
// - |UnregisterModule|.
// - |Send|.
//
// Module classes use |Send| to send out command PDUs. The socket
// in |BluetoothDaemonProtocol| is required for sending. The abstract
// method hides all these internal details from the modules.
//
// |RegisterModule| is required during module initialization, when
// modules must register themselves at the daemon. The register command
// is not part of the module itself, but contained in the Setup module
// (id of 0x00). The abstract method |RegisterModule| allows modules to
// call into the Setup module for generating the register command.
//
// |UnregisterModule| works like |RegisterModule|, but for cleanups.
//
// |BluetoothDaemonProtocol| also handles PDU receiving. It implements
// the method |Handle| from |DaemonSocketIOConsumer|. The socket
// connections of type |DaemonSocket| invoke this method
@ -66,11 +56,9 @@ static const int sRetryInterval = 100; // ms
// |HandleSvc|. Further PDU processing is module-dependent.
//
// To summarize the interface between |BluetoothDaemonProtocol| and
// modules; the former implements the abstract methods
// modules; the former implements the abstract method
//
// - |Send|,
// - |RegisterModule|, and
// - |UnregisterModule|,
//
// which allow modules to send out data. Each module implements the
// method
@ -95,12 +83,6 @@ public:
void SetConnection(DaemonSocket* aConnection);
nsresult RegisterModule(uint8_t aId, uint8_t aMode, uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes) override;
nsresult UnregisterModule(uint8_t aId,
BluetoothSetupResultHandler* aRes) override;
// Outgoing PDUs
//
@ -153,22 +135,6 @@ BluetoothDaemonProtocol::SetConnection(DaemonSocket* aConnection)
mConnection = aConnection;
}
nsresult
BluetoothDaemonProtocol::RegisterModule(uint8_t aId, uint8_t aMode,
uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes)
{
return BluetoothDaemonSetupModule::RegisterModuleCmd(aId, aMode,
aMaxNumClients, aRes);
}
nsresult
BluetoothDaemonProtocol::UnregisterModule(uint8_t aId,
BluetoothSetupResultHandler* aRes)
{
return BluetoothDaemonSetupModule::UnregisterModuleCmd(aId, aRes);
}
nsresult
BluetoothDaemonProtocol::Send(DaemonSocketPDU* aPDU,
DaemonSocketResultHandler* aRes)
@ -422,7 +388,9 @@ public:
if (!mRegisteredSocketModule) {
mRegisteredSocketModule = true;
// Init, step 5: Register Socket module
mInterface->mProtocol->RegisterModuleCmd(0x02, 0x00,
mInterface->mProtocol->RegisterModuleCmd(
SETUP_SERVICE_ID_SOCKET,
0x00,
BluetoothDaemonSocketModule::MAX_NUM_CLIENTS, this);
} else if (mRes) {
// Init, step 6: Signal success to caller
@ -556,7 +524,7 @@ private:
if (!mUnregisteredCoreModule) {
mUnregisteredCoreModule = true;
// Cleanup, step 2: Unregister Core module
mInterface->mProtocol->UnregisterModuleCmd(0x01, this);
mInterface->mProtocol->UnregisterModuleCmd(SETUP_SERVICE_ID_CORE, this);
} else {
// Cleanup, step 3: Close command channel
mInterface->mCmdChannel->Close();
@ -600,7 +568,7 @@ BluetoothDaemonInterface::Cleanup(BluetoothResultHandler* aRes)
// Cleanup, step 1: Unregister Socket module
nsresult rv = mProtocol->UnregisterModuleCmd(
0x02, new CleanupResultHandler(this));
SETUP_SERVICE_ID_SOCKET, new CleanupResultHandler(this));
if (NS_FAILED(rv)) {
DispatchError(aRes, rv);
return;
@ -889,9 +857,21 @@ BluetoothDaemonInterface::DispatchError(BluetoothResultHandler* aRes,
DispatchError(aRes, status);
}
// Profile Interfaces
// Service Interfaces
//
BluetoothSetupInterface*
BluetoothDaemonInterface::GetBluetoothSetupInterface()
{
if (mSetupInterface) {
return mSetupInterface;
}
mSetupInterface = new BluetoothDaemonSetupInterface(mProtocol);
return mSetupInterface;
}
BluetoothSocketInterface*
BluetoothDaemonInterface::GetBluetoothSocketInterface()
{
@ -1002,7 +982,9 @@ BluetoothDaemonInterface::OnConnectSuccess(int aIndex)
// Init, step 4: Register Core module
nsresult rv = mProtocol->RegisterModuleCmd(
0x01, 0x00, BluetoothDaemonCoreModule::MAX_NUM_CLIENTS,
SETUP_SERVICE_ID_CORE,
0x00,
BluetoothDaemonCoreModule::MAX_NUM_CLIENTS,
new InitResultHandler(this, res));
if (NS_FAILED(rv) && res) {
DispatchError(res, STATUS_FAIL);

View File

@ -27,6 +27,7 @@ class BluetoothDaemonAvrcpInterface;
class BluetoothDaemonGattInterface;
class BluetoothDaemonHandsfreeInterface;
class BluetoothDaemonProtocol;
class BluetoothDaemonSetupInterface;
class BluetoothDaemonSocketInterface;
class BluetoothDaemonInterface final
@ -125,8 +126,9 @@ public:
void ReadEnergyInfo(BluetoothResultHandler* aRes) override;
/* Profile Interfaces */
/* Service Interfaces */
BluetoothSetupInterface* GetBluetoothSetupInterface() override;
BluetoothSocketInterface* GetBluetoothSocketInterface() override;
BluetoothHandsfreeInterface* GetBluetoothHandsfreeInterface() override;
BluetoothA2dpInterface* GetBluetoothA2dpInterface() override;
@ -162,6 +164,7 @@ private:
nsTArray<nsRefPtr<BluetoothResultHandler> > mResultHandlerQ;
nsAutoPtr<BluetoothDaemonSetupInterface> mSetupInterface;
nsAutoPtr<BluetoothDaemonSocketInterface> mSocketInterface;
nsAutoPtr<BluetoothDaemonHandsfreeInterface> mHandsfreeInterface;
nsAutoPtr<BluetoothDaemonA2dpInterface> mA2dpInterface;

View File

@ -9,6 +9,8 @@
BEGIN_BLUETOOTH_NAMESPACE
using namespace mozilla::ipc;
//
// Setup module
//
@ -54,7 +56,7 @@ BluetoothDaemonSetupModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
nsresult
BluetoothDaemonSetupModule::RegisterModuleCmd(
uint8_t aId, uint8_t aMode, uint32_t aMaxNumClients,
BluetoothSetupServiceId aId, uint8_t aMode, uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
@ -81,7 +83,7 @@ BluetoothDaemonSetupModule::RegisterModuleCmd(
nsresult
BluetoothDaemonSetupModule::UnregisterModuleCmd(
uint8_t aId, BluetoothSetupResultHandler* aRes)
BluetoothSetupServiceId aId, BluetoothSetupResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
@ -167,4 +169,77 @@ BluetoothDaemonSetupModule::ConfigurationRsp(
UnpackPDUInitOp(aPDU));
}
//
// Setup interface
//
BluetoothDaemonSetupInterface::BluetoothDaemonSetupInterface(
BluetoothDaemonSetupModule* aModule)
: mModule(aModule)
{ }
BluetoothDaemonSetupInterface::~BluetoothDaemonSetupInterface()
{ }
void
BluetoothDaemonSetupInterface::RegisterModule(
BluetoothSetupServiceId aId, uint8_t aMode, uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes)
{
MOZ_ASSERT(mModule);
nsresult rv = mModule->RegisterModuleCmd(aId, aMode, aMaxNumClients, aRes);
if (NS_FAILED(rv)) {
DispatchError(aRes, rv);
}
}
void
BluetoothDaemonSetupInterface::UnregisterModule(
BluetoothSetupServiceId aId,
BluetoothSetupResultHandler* aRes)
{
MOZ_ASSERT(mModule);
nsresult rv = mModule->UnregisterModuleCmd(aId, aRes);
if (NS_FAILED(rv)) {
DispatchError(aRes, rv);
}
}
void
BluetoothDaemonSetupInterface::Configuration(
const BluetoothConfigurationParameter* aParam, uint8_t aLen,
BluetoothSetupResultHandler* aRes)
{
MOZ_ASSERT(mModule);
nsresult rv = mModule->ConfigurationCmd(aParam, aLen, aRes);
if (NS_FAILED(rv)) {
DispatchError(aRes, rv);
}
}
void
BluetoothDaemonSetupInterface::DispatchError(
BluetoothSetupResultHandler* aRes, BluetoothStatus aStatus)
{
DaemonResultRunnable1<BluetoothSetupResultHandler, void,
BluetoothStatus, BluetoothStatus>::Dispatch(
aRes, &BluetoothSetupResultHandler::OnError,
ConstantInitOp1<BluetoothStatus>(aStatus));
}
void
BluetoothDaemonSetupInterface::DispatchError(
BluetoothSetupResultHandler* aRes, nsresult aRv)
{
BluetoothStatus status;
if (NS_WARN_IF(NS_FAILED(Convert(aRv, status)))) {
status = STATUS_FAIL;
}
DispatchError(aRes, status);
}
END_BLUETOOTH_NAMESPACE

View File

@ -37,11 +37,11 @@ public:
// Commands
//
nsresult RegisterModuleCmd(uint8_t aId, uint8_t aMode,
nsresult RegisterModuleCmd(BluetoothSetupServiceId aId, uint8_t aMode,
uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes);
nsresult UnregisterModuleCmd(uint8_t aId,
nsresult UnregisterModuleCmd(BluetoothSetupServiceId aId,
BluetoothSetupResultHandler* aRes);
nsresult ConfigurationCmd(const BluetoothConfigurationParameter* aParam,
@ -86,6 +86,32 @@ private:
BluetoothSetupResultHandler* aRes);
};
class BluetoothDaemonSetupInterface final
: public BluetoothSetupInterface
{
public:
BluetoothDaemonSetupInterface(BluetoothDaemonSetupModule* aModule);
~BluetoothDaemonSetupInterface();
void RegisterModule(BluetoothSetupServiceId aId, uint8_t aMode,
uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes) override;
void UnregisterModule(BluetoothSetupServiceId aId,
BluetoothSetupResultHandler* aRes) override;
void Configuration(const BluetoothConfigurationParameter* aParam,
uint8_t aLen,
BluetoothSetupResultHandler* aRes) override;
private:
void DispatchError(BluetoothSetupResultHandler* aRes,
BluetoothStatus aStatus);
void DispatchError(BluetoothSetupResultHandler* aRes, nsresult aRv);
BluetoothDaemonSetupModule* mModule;
};
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_bluedroid_BluetoothDaemonSetupInterface_h

View File

@ -37,6 +37,8 @@ namespace {
static BluetoothGattInterface* sBluetoothGattInterface;
} // namespace
const int BluetoothGattManager::MAX_NUM_CLIENTS = 1;
bool BluetoothGattManager::mInShutdown = false;
static StaticAutoPtr<nsTArray<nsRefPtr<BluetoothGattClient> > > sClients;
@ -376,52 +378,126 @@ BluetoothGattManager::Get()
return sBluetoothGattManager;
}
class BluetoothGattManager::InitGattResultHandler final
: public BluetoothGattResultHandler
class BluetoothGattManager::RegisterModuleResultHandler final
: public BluetoothSetupResultHandler
{
public:
InitGattResultHandler(BluetoothProfileResultHandler* aRes)
: mRes(aRes)
RegisterModuleResultHandler(BluetoothGattInterface* aInterface,
BluetoothProfileResultHandler* aRes)
: mInterface(aInterface)
, mRes(aRes)
{ }
void OnError(BluetoothStatus aStatus) override
{
BT_WARNING("BluetoothGattInterface::Init failed: %d",
MOZ_ASSERT(NS_IsMainThread());
BT_WARNING("BluetoothSetupInterface::RegisterModule failed for GATT: %d",
(int)aStatus);
mInterface->SetNotificationHandler(nullptr);
if (mRes) {
mRes->OnError(NS_ERROR_FAILURE);
}
}
void Init() override
void RegisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
sBluetoothGattInterface = mInterface;
if (mRes) {
mRes->Init();
}
}
private:
BluetoothGattInterface* mInterface;
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class BluetoothGattManager::InitProfileResultHandlerRunnable final
: public nsRunnable
{
public:
InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
nsresult aRv)
: mRes(aRes)
, mRv(aRv)
{
MOZ_ASSERT(mRes);
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
if (NS_SUCCEEDED(mRv)) {
mRes->Init();
} else {
mRes->OnError(mRv);
}
return NS_OK;
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
nsresult mRv;
};
// static
void
BluetoothGattManager::InitGattInterface(BluetoothProfileResultHandler* aRes)
{
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
if (!btInf) {
BT_LOGR("Error: Bluetooth interface not available");
if (aRes) {
aRes->OnError(NS_ERROR_FAILURE);
MOZ_ASSERT(NS_IsMainThread());
if (sBluetoothGattInterface) {
BT_LOGR("Bluetooth GATT interface is already initalized.");
nsRefPtr<nsRunnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT Init runnable");
}
return;
}
sBluetoothGattInterface = btInf->GetBluetoothGattInterface();
if (!sBluetoothGattInterface) {
BT_LOGR("Error: Bluetooth GATT interface not available");
if (aRes) {
aRes->OnError(NS_ERROR_FAILURE);
auto btInf = BluetoothInterface::GetInstance();
if (NS_WARN_IF(!btInf)) {
// If there's no Bluetooth interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT OnError runnable");
}
return;
}
auto setupInterface = btInf->GetBluetoothSetupInterface();
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT OnError runnable");
}
return;
}
auto gattInterface = btInf->GetBluetoothGattInterface();
if (NS_WARN_IF(!gattInterface)) {
// If there's no GATT interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT OnError runnable");
}
return;
}
@ -434,30 +510,43 @@ BluetoothGattManager::InitGattInterface(BluetoothProfileResultHandler* aRes)
sServers = new nsTArray<nsRefPtr<BluetoothGattServer> >;
}
BluetoothGattManager* gattManager = BluetoothGattManager::Get();
sBluetoothGattInterface->Init(gattManager,
new InitGattResultHandler(aRes));
// Set notification handler _before_ registering the module. It could
// happen that we receive notifications, before the result handler runs.
gattInterface->SetNotificationHandler(BluetoothGattManager::Get());
setupInterface->RegisterModule(
SETUP_SERVICE_ID_GATT, 0, MAX_NUM_CLIENTS,
new RegisterModuleResultHandler(gattInterface, aRes));
}
class BluetoothGattManager::CleanupResultHandler final
: public BluetoothGattResultHandler
class BluetoothGattManager::UnregisterModuleResultHandler final
: public BluetoothSetupResultHandler
{
public:
CleanupResultHandler(BluetoothProfileResultHandler* aRes)
UnregisterModuleResultHandler(BluetoothProfileResultHandler* aRes)
: mRes(aRes)
{ }
void OnError(BluetoothStatus aStatus) override
{
BT_WARNING("BluetoothGattInterface::Cleanup failed: %d",
MOZ_ASSERT(NS_IsMainThread());
BT_WARNING("BluetoothSetupInterface::UnregisterModule failed for GATT: %d",
(int)aStatus);
sBluetoothGattInterface->SetNotificationHandler(nullptr);
sBluetoothGattInterface = nullptr;
if (mRes) {
mRes->OnError(NS_ERROR_FAILURE);
}
}
void Cleanup() override
void UnregisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
sBluetoothGattInterface->SetNotificationHandler(nullptr);
sBluetoothGattInterface = nullptr;
sClients = nullptr;
sServers = nullptr;
@ -471,24 +560,33 @@ private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class BluetoothGattManager::CleanupResultHandlerRunnable final
class BluetoothGattManager::DeinitProfileResultHandlerRunnable final
: public nsRunnable
{
public:
CleanupResultHandlerRunnable(BluetoothProfileResultHandler* aRes)
DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
nsresult aRv)
: mRes(aRes)
, mRv(aRv)
{
MOZ_ASSERT(mRes);
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
if (NS_SUCCEEDED(mRv)) {
mRes->Deinit();
} else {
mRes->OnError(mRv);
}
return NS_OK;
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
nsresult mRv;
};
// static
@ -497,16 +595,45 @@ BluetoothGattManager::DeinitGattInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (sBluetoothGattInterface) {
sBluetoothGattInterface->Cleanup(new CleanupResultHandler(aRes));
} else if (aRes) {
// We dispatch a runnable here to make the profile resource handler
// behave as if GATT was initialized.
nsRefPtr<nsRunnable> r = new CleanupResultHandlerRunnable(aRes);
if (!sBluetoothGattInterface) {
BT_LOGR("Bluetooth GATT interface has not been initalized.");
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch cleanup-result-handler runnable");
BT_LOGR("Failed to dispatch GATT Deinit runnable");
}
return;
}
auto btInf = BluetoothInterface::GetInstance();
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT OnError runnable");
}
return;
}
auto setupInterface = btInf->GetBluetoothSetupInterface();
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch GATT OnError runnable");
}
return;
}
setupInterface->UnregisterModule(
SETUP_SERVICE_ID_GATT,
new UnregisterModuleResultHandler(aRes));
}
class BluetoothGattManager::RegisterClientResultHandler final

View File

@ -20,6 +20,8 @@ class BluetoothGattManager final : public nsIObserver
, public BluetoothGattNotificationHandler
{
public:
static const int MAX_NUM_CLIENTS;
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
@ -165,9 +167,16 @@ public:
private:
~BluetoothGattManager();
#if 0
class CleanupResultHandler;
class CleanupResultHandlerRunnable;
class InitGattResultHandler;
#endif
class DeinitProfileResultHandlerRunnable;
class InitProfileResultHandlerRunnable;
class RegisterModuleResultHandler;
class UnregisterModuleResultHandler;
class RegisterClientResultHandler;
class UnregisterClientResultHandler;
class StartLeScanResultHandler;

View File

@ -276,11 +276,11 @@ BluetoothHfpManager::Init()
return true;
}
class BluetoothHfpManager::CleanupInitResultHandler final
: public BluetoothHandsfreeResultHandler
class BluetoothHfpManager::RegisterModuleResultHandler final
: public BluetoothSetupResultHandler
{
public:
CleanupInitResultHandler(BluetoothHandsfreeInterface* aInterface,
RegisterModuleResultHandler(BluetoothHandsfreeInterface* aInterface,
BluetoothProfileResultHandler* aRes)
: mInterface(aInterface)
, mRes(aRes)
@ -290,67 +290,39 @@ public:
void OnError(BluetoothStatus aStatus) override
{
BT_WARNING("BluetoothHandsfreeInterface::Init failed: %d", (int)aStatus);
MOZ_ASSERT(NS_IsMainThread());
BT_WARNING("BluetoothSetupInterface::RegisterModule failed for HFP: %d",
(int)aStatus);
mInterface->SetNotificationHandler(nullptr);
if (mRes) {
mRes->OnError(NS_ERROR_FAILURE);
}
}
void Init() override
void RegisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
sBluetoothHfpInterface = mInterface;
if (mRes) {
mRes->Init();
}
}
void Cleanup() override
{
sBluetoothHfpInterface = nullptr;
/* During re-initialization, a previouly initialized
* |BluetoothHandsfreeInterface| has now been cleaned
* up, so we start initialization.
*/
RunInit();
}
void RunInit()
{
BluetoothHfpManager* hfpManager = BluetoothHfpManager::Get();
mInterface->Init(hfpManager, BluetoothHfpManager::MAX_NUM_CLIENTS, this);
}
private:
BluetoothHandsfreeInterface* mInterface;
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class BluetoothHfpManager::InitResultHandlerRunnable final
class BluetoothHfpManager::InitProfileResultHandlerRunnable final
: public nsRunnable
{
public:
InitResultHandlerRunnable(CleanupInitResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
NS_IMETHOD Run() override
{
mRes->RunInit();
return NS_OK;
}
private:
nsRefPtr<CleanupInitResultHandler> mRes;
};
class BluetoothHfpManager::OnErrorProfileResultHandlerRunnable final
: public nsRunnable
{
public:
OnErrorProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
InitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
nsresult aRv)
: mRes(aRes)
, mRv(aRv)
@ -360,7 +332,13 @@ public:
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
if (NS_SUCCEEDED(mRv)) {
mRes->Init();
} else {
mRes->OnError(mRv);
}
return NS_OK;
}
@ -373,45 +351,64 @@ private:
void
BluetoothHfpManager::InitHfpInterface(BluetoothProfileResultHandler* aRes)
{
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
MOZ_ASSERT(NS_IsMainThread());
if (sBluetoothHfpInterface) {
BT_LOGR("Bluetooth Handsfree interface is already initalized.");
nsRefPtr<nsRunnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP Init runnable");
}
return;
}
auto btInf = BluetoothInterface::GetInstance();
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
}
return;
}
BluetoothHandsfreeInterface *interface =
btInf->GetBluetoothHandsfreeInterface();
auto setupInterface = btInf->GetBluetoothSetupInterface();
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
}
return;
}
auto interface = btInf->GetBluetoothHandsfreeInterface();
if (NS_WARN_IF(!interface)) {
// If there's no HFP interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new OnErrorProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
new InitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
}
return;
}
nsRefPtr<CleanupInitResultHandler> res =
new CleanupInitResultHandler(interface, aRes);
// Set notification handler _before_ registering the module. It could
// happen that we receive notifications, before the result handler runs.
interface->SetNotificationHandler(BluetoothHfpManager::Get());
if (sBluetoothHfpInterface) {
// Cleanup an initialized HFP before initializing again.
sBluetoothHfpInterface->Cleanup(res);
} else {
// If there's no HFP interface to cleanup first, we dispatch
// a runnable that calls the profile result handler.
nsRefPtr<nsRunnable> r = new InitResultHandlerRunnable(res);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP init runnable");
}
}
setupInterface->RegisterModule(
SETUP_SERVICE_ID_HANDSFREE, MODE_NARROWBAND_SPEECH, MAX_NUM_CLIENTS,
new RegisterModuleResultHandler(interface, aRes));
}
BluetoothHfpManager::~BluetoothHfpManager()
@ -432,18 +429,22 @@ BluetoothHfpManager::~BluetoothHfpManager()
hal::UnregisterBatteryObserver(this);
}
class BluetoothHfpManager::CleanupResultHandler final
: public BluetoothHandsfreeResultHandler
class BluetoothHfpManager::UnregisterModuleResultHandler final
: public BluetoothSetupResultHandler
{
public:
CleanupResultHandler(BluetoothProfileResultHandler* aRes)
UnregisterModuleResultHandler(BluetoothProfileResultHandler* aRes)
: mRes(aRes)
{ }
void OnError(BluetoothStatus aStatus) override
{
BT_WARNING("BluetoothHandsfreeInterface::Cleanup failed: %d", (int)aStatus);
MOZ_ASSERT(NS_IsMainThread());
BT_WARNING("BluetoothSetupInterface::UnregisterModule failed for HFP: %d",
(int)aStatus);
sBluetoothHfpInterface->SetNotificationHandler(nullptr);
sBluetoothHfpInterface = nullptr;
if (mRes) {
@ -451,9 +452,13 @@ public:
}
}
void Cleanup() override
void UnregisterModule() override
{
MOZ_ASSERT(NS_IsMainThread());
sBluetoothHfpInterface->SetNotificationHandler(nullptr);
sBluetoothHfpInterface = nullptr;
if (mRes) {
mRes->Deinit();
}
@ -463,40 +468,80 @@ private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
};
class BluetoothHfpManager::DeinitResultHandlerRunnable final
class BluetoothHfpManager::DeinitProfileResultHandlerRunnable final
: public nsRunnable
{
public:
DeinitResultHandlerRunnable(BluetoothProfileResultHandler* aRes)
DeinitProfileResultHandlerRunnable(BluetoothProfileResultHandler* aRes,
nsresult aRv)
: mRes(aRes)
, mRv(aRv)
{
MOZ_ASSERT(mRes);
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
if (NS_SUCCEEDED(mRv)) {
mRes->Deinit();
} else {
mRes->OnError(mRv);
}
return NS_OK;
}
private:
nsRefPtr<BluetoothProfileResultHandler> mRes;
nsresult mRv;
};
// static
void
BluetoothHfpManager::DeinitHfpInterface(BluetoothProfileResultHandler* aRes)
{
if (sBluetoothHfpInterface) {
sBluetoothHfpInterface->Cleanup(new CleanupResultHandler(aRes));
} else if (aRes) {
// We dispatch a runnable here to make the profile resource handler
// behave as if HFP was initialized.
nsRefPtr<nsRunnable> r = new DeinitResultHandlerRunnable(aRes);
MOZ_ASSERT(NS_IsMainThread());
if (!sBluetoothHfpInterface) {
BT_LOGR("Bluetooth Handsfree interface has not been initialized.");
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_OK);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch cleanup-result-handler runnable");
BT_LOGR("Failed to dispatch HFP Deinit runnable");
}
return;
}
auto btInf = BluetoothInterface::GetInstance();
if (NS_WARN_IF(!btInf)) {
// If there's no backend interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
}
return;
}
auto setupInterface = btInf->GetBluetoothSetupInterface();
if (NS_WARN_IF(!setupInterface)) {
// If there's no Setup interface, we dispatch a runnable
// that calls the profile result handler.
nsRefPtr<nsRunnable> r =
new DeinitProfileResultHandlerRunnable(aRes, NS_ERROR_FAILURE);
if (NS_FAILED(NS_DispatchToMainThread(r))) {
BT_LOGR("Failed to dispatch HFP OnError runnable");
}
return;
}
setupInterface->UnregisterModule(
SETUP_SERVICE_ID_HANDSFREE,
new UnregisterModuleResultHandler(aRes));
}
//static

View File

@ -73,6 +73,12 @@ class BluetoothHfpManager : public BluetoothHfpManagerBase
, public BluetoothHandsfreeNotificationHandler
, public BatteryObserver
{
enum {
MODE_HEADSET = 0x00,
MODE_NARROWBAND_SPEECH = 0x01,
MODE_NARRAWBAND_WIDEBAND_SPEECH = 0x02
};
public:
BT_DECL_HFP_MGR_BASE
@ -151,21 +157,20 @@ private:
class ConnectResultHandler;
class CopsResponseResultHandler;
class ClccResponseResultHandler;
class CleanupInitResultHandler;
class CleanupResultHandler;
class CloseScoRunnable;
class CloseScoTask;
class DeinitResultHandlerRunnable;
class DeinitProfileResultHandlerRunnable;
class DeviceStatusNotificationResultHandler;
class DisconnectAudioResultHandler;
class DisconnectResultHandler;
class FormattedAtResponseResultHandler;
class GetVolumeTask;
class InitResultHandlerRunnable;
class InitProfileResultHandlerRunnable;
class MainThreadTask;
class OnErrorProfileResultHandlerRunnable;
class PhoneStateChangeResultHandler;
class RegisterModuleResultHandler;
class RespondToBLDNTask;
class UnregisterModuleResultHandler;
class VolumeControlResultHandler;
friend class BluetoothHfpManagerObserver;

View File

@ -9,6 +9,7 @@
#include "mozilla/Compiler.h"
#include "mozilla/Observer.h"
#include "nsAutoPtr.h"
#include "nsPrintfCString.h"
#include "nsString.h"
#include "nsTArray.h"
@ -325,6 +326,23 @@ enum BluetoothBondState {
BOND_STATE_BONDED
};
enum BluetoothSetupServiceId {
SETUP_SERVICE_ID_SETUP,
SETUP_SERVICE_ID_CORE,
SETUP_SERVICE_ID_SOCKET,
SETUP_SERVICE_ID_HID,
SETUP_SERVICE_ID_PAN,
SETUP_SERVICE_ID_HANDSFREE,
SETUP_SERVICE_ID_A2DP,
SETUP_SERVICE_ID_HEALTH,
SETUP_SERVICE_ID_AVRCP,
SETUP_SERVICE_ID_GATT,
SETUP_SERVICE_ID_HANDSFREE_CLIENT,
SETUP_SERVICE_ID_MAP_CLIENT,
SETUP_SERVICE_ID_AVRCP_CONTROLLER,
SETUP_SERVICE_ID_A2DP_SINK
};
/* Physical transport for GATT connections to remote dual-mode devices */
enum BluetoothTransport {
TRANSPORT_AUTO, /* No preference of physical transport */
@ -480,6 +498,12 @@ struct BluetoothAddress {
};
struct BluetoothConfigurationParameter {
uint8_t mType;
uint16_t mLength;
nsAutoArrayPtr<uint8_t> mValue;
};
struct BluetoothUuid {
uint8_t mUuid[16];

View File

@ -39,6 +39,12 @@ void
BluetoothSetupResultHandler::Configuration()
{ }
// Interface
//
BluetoothSetupInterface::~BluetoothSetupInterface()
{ }
//
// Socket Interface
//
@ -181,14 +187,6 @@ BluetoothHandsfreeResultHandler::OnError(BluetoothStatus aStatus)
BT_WARNING("Received error code %d", (int)aStatus);
}
void
BluetoothHandsfreeResultHandler::Init()
{ }
void
BluetoothHandsfreeResultHandler::Cleanup()
{ }
void
BluetoothHandsfreeResultHandler::Connect()
{ }
@ -295,14 +293,6 @@ BluetoothA2dpResultHandler::OnError(BluetoothStatus aStatus)
BT_WARNING("Received error code %d", (int)aStatus);
}
void
BluetoothA2dpResultHandler::Init()
{ }
void
BluetoothA2dpResultHandler::Cleanup()
{ }
void
BluetoothA2dpResultHandler::Connect()
{ }
@ -400,14 +390,6 @@ BluetoothAvrcpResultHandler::OnError(BluetoothStatus aStatus)
BT_WARNING("Received error code %d", (int)aStatus);
}
void
BluetoothAvrcpResultHandler::Init()
{ }
void
BluetoothAvrcpResultHandler::Cleanup()
{ }
void
BluetoothAvrcpResultHandler::GetPlayStatusRsp()
{ }
@ -679,14 +661,6 @@ BluetoothGattResultHandler::OnError(BluetoothStatus aStatus)
BT_WARNING("Received error code %d", (int)aStatus);
}
void
BluetoothGattResultHandler::Init()
{ }
void
BluetoothGattResultHandler::Cleanup()
{ }
void
BluetoothGattResultHandler::RegisterClient()
{ }

View File

@ -30,6 +30,25 @@ protected:
virtual ~BluetoothSetupResultHandler() { }
};
class BluetoothSetupInterface
{
public:
virtual void RegisterModule(BluetoothSetupServiceId aId,
uint8_t aMode,
uint32_t aMaxNumClients,
BluetoothSetupResultHandler* aRes) = 0;
virtual void UnregisterModule(BluetoothSetupServiceId aId,
BluetoothSetupResultHandler* aRes) = 0;
virtual void Configuration(const BluetoothConfigurationParameter* aParam,
uint8_t aLen,
BluetoothSetupResultHandler* aRes) = 0;
protected:
virtual ~BluetoothSetupInterface();
};
//
// Socket Interface
//
@ -155,9 +174,6 @@ class BluetoothHandsfreeResultHandler
public:
virtual void OnError(BluetoothStatus aStatus);
virtual void Init();
virtual void Cleanup();
virtual void Connect();
virtual void Disconnect();
virtual void ConnectAudio();
@ -186,10 +202,8 @@ protected:
class BluetoothHandsfreeInterface
{
public:
virtual void Init(
BluetoothHandsfreeNotificationHandler* aNotificationHandler,
int aMaxNumClients, BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void Cleanup(BluetoothHandsfreeResultHandler* aRes) = 0;
virtual void SetNotificationHandler(
BluetoothHandsfreeNotificationHandler* aNotificationHandler) = 0;
/* Connect / Disconnect */
@ -295,8 +309,6 @@ class BluetoothA2dpResultHandler
public:
virtual void OnError(BluetoothStatus aStatus);
virtual void Init();
virtual void Cleanup();
virtual void Connect();
virtual void Disconnect();
@ -307,9 +319,8 @@ protected:
class BluetoothA2dpInterface
{
public:
virtual void Init(BluetoothA2dpNotificationHandler* aNotificationHandler,
BluetoothA2dpResultHandler* aRes) = 0;
virtual void Cleanup(BluetoothA2dpResultHandler* aRes) = 0;
virtual void SetNotificationHandler(
BluetoothA2dpNotificationHandler* aNotificationHandler) = 0;
virtual void Connect(const BluetoothAddress& aBdAddr,
BluetoothA2dpResultHandler* aRes) = 0;
@ -382,9 +393,6 @@ class BluetoothAvrcpResultHandler
public:
virtual void OnError(BluetoothStatus aStatus);
virtual void Init();
virtual void Cleanup();
virtual void GetPlayStatusRsp();
virtual void ListPlayerAppAttrRsp();
@ -409,9 +417,8 @@ protected:
class BluetoothAvrcpInterface
{
public:
virtual void Init(BluetoothAvrcpNotificationHandler* aNotificationHandler,
BluetoothAvrcpResultHandler* aRes) = 0;
virtual void Cleanup(BluetoothAvrcpResultHandler* aRes) = 0;
virtual void SetNotificationHandler(
BluetoothAvrcpNotificationHandler* aNotificationHandler) = 0;
virtual void GetPlayStatusRsp(ControlPlayStatus aPlayStatus,
uint32_t aSongLen, uint32_t aSongPos,
@ -663,9 +670,6 @@ class BluetoothGattResultHandler
public:
virtual void OnError(BluetoothStatus aStatus);
virtual void Init();
virtual void Cleanup();
virtual void RegisterClient();
virtual void UnregisterClient();
@ -723,9 +727,8 @@ protected:
class BluetoothGattInterface
{
public:
virtual void Init(BluetoothGattNotificationHandler* aNotificationHandler,
BluetoothGattResultHandler* aRes) = 0;
virtual void Cleanup(BluetoothGattResultHandler* aRes) = 0;
virtual void SetNotificationHandler(
BluetoothGattNotificationHandler* aNotificationHandler) = 0;
/* Register / Unregister */
virtual void RegisterClient(const BluetoothUuid& aUuid,
@ -1111,6 +1114,7 @@ public:
/* Profile Interfaces */
virtual BluetoothSetupInterface* GetBluetoothSetupInterface() = 0;
virtual BluetoothSocketInterface* GetBluetoothSocketInterface() = 0;
virtual BluetoothHandsfreeInterface* GetBluetoothHandsfreeInterface() = 0;
virtual BluetoothA2dpInterface* GetBluetoothA2dpInterface() = 0;

View File

@ -998,7 +998,7 @@ BrowserElementParent.prototype = {
try {
let nfcContentHelper =
Cc["@mozilla.org/nfc/content-helper;1"].getService(Ci.nsINfcBrowserAPI);
nfcContentHelper.setFocusApp(tabId, isFocus);
nfcContentHelper.setFocusTab(tabId, isFocus);
} catch(e) {
// Not all platforms support NFC
}

View File

@ -97,8 +97,8 @@ NfcContentHelper.prototype = {
return cpmm.sendSyncMessage("NFC:QueryInfo")[0].rfState;
},
setFocusApp: function setFocusApp(tabId, isFocus) {
cpmm.sendAsyncMessage("NFC:SetFocusApp", {
setFocusTab: function setFocusTab(tabId, isFocus) {
cpmm.sendAsyncMessage("NFC:SetFocusTab", {
tabId: tabId,
isFocus: isFocus
});

View File

@ -79,7 +79,7 @@ const NFC_IPC_MSG_ENTRIES = [
"NFC:NotifyUserAcceptedP2P",
"NFC:NotifySendFileStatus",
"NFC:ChangeRFState",
"NFC:SetFocusApp"] }
"NFC:SetFocusTab"] }
];
// Should be consistent with NfcRequestType defined in NfcOptions.webidl.
@ -148,7 +148,7 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
eventListeners: {},
focusApp: NFC.SYSTEM_APP_ID,
focusId: NFC.SYSTEM_APP_ID,
init: function init(nfc) {
this.nfc = nfc;
@ -214,7 +214,7 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
});
},
notifyFocusApp: function notifyFocusApp(options) {
notifyFocusTab: function notifyFocusTab(options) {
let tabId = this.getFocusTabId();
options.tabId = tabId;
@ -231,29 +231,29 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
},
getFocusTabId: function getFocusTabId() {
return this.eventListeners[this.focusApp] ? this.focusApp
return this.eventListeners[this.focusId] ? this.focusId
: NFC.SYSTEM_APP_ID;
},
setFocusApp: function setFocusApp(id, isFocus) {
setFocusTab: function setFocusTab(id, isFocus) {
// if calling setNFCFocus(true) on the browser-element which is already
// focused, or calling setNFCFocus(false) on the browser-element which has
// lost focus already, ignore.
if (isFocus == (id == this.focusApp)) {
if (isFocus == (id == this.focusId)) {
return;
}
if (this.focusApp != NFC.SYSTEM_APP_ID) {
this.onFocusChanged(this.focusApp, false);
if (this.focusId != NFC.SYSTEM_APP_ID) {
this.onFocusChanged(this.focusId, false);
}
if (isFocus) {
// Now we only support one focus app.
this.focusApp = id;
this.onFocusChanged(this.focusApp, true);
} else if (this.focusApp == id){
// Set focusApp to SystemApp means currently there is no foreground app.
this.focusApp = NFC.SYSTEM_APP_ID;
this.focusId = id;
this.onFocusChanged(this.focusId, true);
} else if (this.focusId == id){
// Set focusId to SystemApp means currently there is no foreground app.
this.focusId = NFC.SYSTEM_APP_ID;
}
},
@ -325,17 +325,17 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
onTagFound: function onTagFound(message) {
message.event = NFC.TAG_EVENT_FOUND;
this.notifyFocusApp(message);
this.notifyFocusTab(message);
delete message.event;
},
onTagLost: function onTagLost(sessionToken) {
this.notifyFocusApp({ event: NFC.TAG_EVENT_LOST,
this.notifyFocusTab({ event: NFC.TAG_EVENT_LOST,
sessionToken: sessionToken });
},
onPeerEvent: function onPeerEvent(eventType, sessionToken) {
this.notifyFocusApp({ event: eventType,
this.notifyFocusTab({ event: eventType,
sessionToken: sessionToken });
},
@ -348,13 +348,13 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
}
},
onFocusChanged: function onFocusChanged(focusApp, focus) {
let target = this.eventListeners[focusApp];
onFocusChanged: function onFocusChanged(focusId, focus) {
let target = this.eventListeners[focusId];
if (!target) {
return;
}
this.notifyDOMEvent(target, { tabId: this.focusApp,
this.notifyDOMEvent(target, { tabId: this.focusId,
event: NFC.FOCUS_CHANGED,
focus: focus });
},
@ -386,8 +386,8 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
}
switch (message.name) {
case "NFC:SetFocusApp":
this.setFocusApp(message.data.tabId, message.data.isFocus);
case "NFC:SetFocusTab":
this.setFocusTab(message.data.tabId, message.data.isFocus);
return null;
case "NFC:AddEventListener":
this.addEventListener(message.target, message.data.tabId);

View File

@ -115,12 +115,12 @@ interface nsINfcRequestCallback : nsISupports
void notifyError(in DOMString errorMsg);
};
[scriptable, uuid(2dbc73d4-ba16-4c89-bce5-3c22cee6b50a)]
[scriptable, uuid(9f86c799-6959-4ad2-bdd6-6fbf49b52d1c)]
interface nsINfcBrowserAPI : nsISupports
{
const int32_t SYSTEM_APP_ID = 0;
void setFocusApp(in uint64_t tabId,
void setFocusTab(in uint64_t tabId,
in boolean isFocus);
};

View File

@ -732,7 +732,7 @@ nsHttpHandler::InitUserAgentComponents()
#endif
#if defined(ANDROID) || defined(FXOS_SIMULATOR)
#ifdef ANDROID
nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1");
MOZ_ASSERT(infoService, "Could not find a system info service");
nsresult rv;
@ -753,15 +753,35 @@ nsHttpHandler::InitUserAgentComponents()
}
}
#endif
// Add the `Mobile` or `Tablet` token when running on device or in the
// b2g desktop simulator.
// Add the `Mobile` or `Tablet` or `TV` token when running on device.
bool isTablet;
rv = infoService->GetPropertyAsBool(NS_LITERAL_STRING("tablet"), &isTablet);
if (NS_SUCCEEDED(rv) && isTablet)
if (NS_SUCCEEDED(rv) && isTablet) {
mCompatDevice.AssignLiteral("Tablet");
else
} else {
bool isTV;
rv = infoService->GetPropertyAsBool(NS_LITERAL_STRING("tv"), &isTV);
if (NS_SUCCEEDED(rv) && isTV) {
mCompatDevice.AssignLiteral("TV");
} else {
mCompatDevice.AssignLiteral("Mobile");
#endif
}
}
#endif // ANDROID
#ifdef FXOS_SIMULATOR
{
// Add the `Mobile` or `Tablet` or `TV` token when running in the b2g
// desktop simulator via preference.
nsCString deviceType;
nsresult rv = Preferences::GetCString("devtools.useragent.device_type", &deviceType);
if (NS_SUCCEEDED(rv)) {
mCompatDevice.Assign(deviceType);
} else {
mCompatDevice.AssignLiteral("Mobile");
}
}
#endif // FXOS_SIMULATOR
#if defined(MOZ_WIDGET_GONK)
// Device model identifier should be a simple token, which can be composed

View File

@ -186,6 +186,8 @@ tests:
allowed_build_tasks:
tasks/builds/b2g_emulator_ics_opt.yml:
task: tasks/tests/b2g_emulator_crashtest.yml
tasks/builds/b2g_emulator_x86_kk_opt.yml:
task: tasks/tests/b2g_emulator_crashtest.yml
gaia-build:
allowed_build_tasks:
tasks/builds/b2g_desktop_opt.yml:

View File

@ -32,7 +32,9 @@ task:
extra:
chunks:
total: 5
treeherderEnv:
- production
- staging
treeherder:
groupName: Reftest
groupSymbol: tc-R

View File

@ -743,6 +743,8 @@ nsSystemInfo::Init()
if (__system_property_get("ro.build.characteristics", characteristics)) {
if (!strcmp(characteristics, "tablet")) {
SetPropertyAsBool(NS_LITERAL_STRING("tablet"), true);
} else if (!strcmp(characteristics, "tv")) {
SetPropertyAsBool(NS_LITERAL_STRING("tv"), true);
}
}