Merge b2ginbound to central, a=merge

--HG--
extra : commitid : L79NffLqBZA
This commit is contained in:
Wes Kocher 2016-01-21 17:10:26 -08:00
Родитель fe7ebe9593 4aa79eb7c1
Коммит fa57d28546
47 изменённых файлов: 875 добавлений и 306 удалений

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee",
"git_revision": "89602d6ae53ecf4129b35a84e49d25b9fd37bc39",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "d74e738cd626558fb9dc289500ad28ae29deab03",
"revision": "ea9b9cc69315e86bf7198ec0d57a267e64345b32",
"repo_path": "integration/gaia-central"
}

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -21,7 +21,7 @@
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="619766a1ce78d50fb8a3b5a9e0821c335a0ed7ee"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="89602d6ae53ecf4129b35a84e49d25b9fd37bc39"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="35dccb3127db8f39f20b985ad312d2cd44780669"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>

Просмотреть файл

@ -228,6 +228,10 @@ BluetoothA2dpManager::InitA2dpInterface(BluetoothProfileResultHandler* aRes)
}
BluetoothA2dpManager::~BluetoothA2dpManager()
{ }
void
BluetoothA2dpManager::Uninit()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE_VOID(obs);
@ -273,9 +277,9 @@ BluetoothA2dpManager::Get()
// If we're in shutdown, don't create a new instance
NS_ENSURE_FALSE(sInShutdown, nullptr);
// Create a new instance, register, and return
BluetoothA2dpManager* manager = new BluetoothA2dpManager();
sBluetoothA2dpManager = manager;
// Create a new instance and return
sBluetoothA2dpManager = new BluetoothA2dpManager();
return sBluetoothA2dpManager;
}
@ -297,6 +301,9 @@ public:
sBtA2dpInterface->SetNotificationHandler(nullptr);
sBtA2dpInterface = nullptr;
sBluetoothA2dpManager->Uninit();
sBluetoothA2dpManager = nullptr;
if (mRes) {
mRes->OnError(NS_ERROR_FAILURE);
}
@ -309,6 +316,9 @@ public:
sBtA2dpInterface->SetNotificationHandler(nullptr);
sBtA2dpInterface = nullptr;
sBluetoothA2dpManager->Uninit();
sBluetoothA2dpManager = nullptr;
if (mRes) {
mRes->Deinit();
}

Просмотреть файл

@ -58,6 +58,7 @@ private:
BluetoothA2dpManager();
void Uninit();
void HandleShutdown();
void NotifyConnectionStatusChanged();

Просмотреть файл

@ -268,6 +268,10 @@ BluetoothAvrcpManager::InitAvrcpInterface(BluetoothProfileResultHandler* aRes)
}
BluetoothAvrcpManager::~BluetoothAvrcpManager()
{ }
void
BluetoothAvrcpManager::Uninit()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE_VOID(obs);
@ -294,9 +298,9 @@ BluetoothAvrcpManager::Get()
// If we're in shutdown, don't create a new instance
NS_ENSURE_FALSE(sInShutdown, nullptr);
// Create a new instance, register, and return
BluetoothAvrcpManager* manager = new BluetoothAvrcpManager();
sBluetoothAvrcpManager = manager;
// Create a new instance and return
sBluetoothAvrcpManager = new BluetoothAvrcpManager();
return sBluetoothAvrcpManager;
}
@ -318,6 +322,9 @@ public:
sBtAvrcpInterface->SetNotificationHandler(nullptr);
sBtAvrcpInterface = nullptr;
sBluetoothAvrcpManager->Uninit();
sBluetoothAvrcpManager = nullptr;
if (mRes) {
mRes->OnError(NS_ERROR_FAILURE);
}
@ -330,6 +337,9 @@ public:
sBtAvrcpInterface->SetNotificationHandler(nullptr);
sBtAvrcpInterface = nullptr;
sBluetoothAvrcpManager->Uninit();
sBluetoothAvrcpManager = nullptr;
if (mRes) {
mRes->Deinit();
}

Просмотреть файл

@ -71,6 +71,7 @@ private:
BluetoothAvrcpManager();
void Uninit();
void HandleShutdown();
void NotifyConnectionStatusChanged();

Просмотреть файл

@ -389,26 +389,39 @@ BluetoothGattManager::Get()
NS_ENSURE_FALSE(mInShutdown, nullptr);
// Create a new instance, register, and return
BluetoothGattManager* manager = new BluetoothGattManager();
NS_ENSURE_TRUE(manager->Init(), nullptr);
RefPtr<BluetoothGattManager> manager = new BluetoothGattManager();
NS_ENSURE_SUCCESS(manager->Init(), nullptr);
sBluetoothGattManager = manager;
return sBluetoothGattManager;
}
bool
nsresult
BluetoothGattManager::Init()
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE(obs, false);
NS_ENSURE_TRUE(obs, NS_ERROR_NOT_AVAILABLE);
if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
if (NS_FAILED(rv)) {
BT_WARNING("Failed to add observers!");
return false;
return rv;
}
return true;
return NS_OK;
}
void
BluetoothGattManager::Uninit()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE_VOID(obs);
if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
BT_WARNING("Failed to remove shutdown observer!");
}
}
class BluetoothGattManager::RegisterModuleResultHandler final
@ -569,6 +582,11 @@ public:
sBluetoothGattInterface->SetNotificationHandler(nullptr);
sBluetoothGattInterface = nullptr;
sClients = nullptr;
sServers = nullptr;
sBluetoothGattManager->Uninit();
sBluetoothGattManager = nullptr;
if (mRes) {
mRes->OnError(NS_ERROR_FAILURE);
@ -584,6 +602,9 @@ public:
sClients = nullptr;
sServers = nullptr;
sBluetoothGattManager->Uninit();
sBluetoothGattManager = nullptr;
if (mRes) {
mRes->Deinit();
}
@ -4090,13 +4111,7 @@ BluetoothGattManager::BluetoothGattManager()
{ }
BluetoothGattManager::~BluetoothGattManager()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE_VOID(obs);
if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
BT_WARNING("Failed to remove shutdown observer!");
}
}
{ }
NS_IMETHODIMP
BluetoothGattManager::Observe(nsISupports* aSubject,

Просмотреть файл

@ -216,8 +216,9 @@ private:
class ServerSendIndicationResultHandler;
BluetoothGattManager();
bool Init();
nsresult Init();
void Uninit();
void HandleShutdown();
void RegisterClientNotification(BluetoothGattStatus aStatus,

Просмотреть файл

@ -84,6 +84,8 @@ BluetoothMapSmsManager::HandleShutdown()
sInShutdown = true;
Disconnect(nullptr);
Uninit();
sMapSmsManager = nullptr;
}
@ -98,27 +100,19 @@ BluetoothMapSmsManager::BluetoothMapSmsManager()
}
BluetoothMapSmsManager::~BluetoothMapSmsManager()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return;
}
{ }
NS_WARN_IF(NS_FAILED(
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)));
}
bool
nsresult
BluetoothMapSmsManager::Init()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return false;
return NS_ERROR_NOT_AVAILABLE;
}
if (NS_WARN_IF(NS_FAILED(
obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false)))) {
return false;
auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
/**
@ -130,7 +124,64 @@ BluetoothMapSmsManager::Init()
* absence of read events when device boots up.
*/
return true;
return NS_OK;
}
void
BluetoothMapSmsManager::Uninit()
{
if (mMasServerSocket) {
mMasServerSocket->SetObserver(nullptr);
if (mMasServerSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mMasServerSocket->Close();
}
mMasServerSocket = nullptr;
}
if (mMasSocket) {
mMasSocket->SetObserver(nullptr);
if (mMasSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mMasSocket->Close();
}
mMasSocket = nullptr;
}
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return;
}
NS_WARN_IF(NS_FAILED(
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)));
}
// static
void
BluetoothMapSmsManager::InitMapSmsInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (aRes) {
aRes->Init();
}
}
// static
void
BluetoothMapSmsManager::DeinitMapSmsInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (sMapSmsManager) {
sMapSmsManager->Uninit();
sMapSmsManager = nullptr;
}
if (aRes) {
aRes->Deinit();
}
}
//static
@ -150,8 +201,8 @@ BluetoothMapSmsManager::Get()
}
// Create a new instance, register, and return
BluetoothMapSmsManager *manager = new BluetoothMapSmsManager();
if (NS_WARN_IF(!manager->Init())) {
RefPtr<BluetoothMapSmsManager> manager = new BluetoothMapSmsManager();
if (NS_WARN_IF(NS_FAILED(manager->Init()))) {
return nullptr;
}
@ -175,10 +226,11 @@ BluetoothMapSmsManager::Listen()
* BT stops; otherwise no more read events would be received even if
* BT restarts.
*/
if (mMasServerSocket) {
if (mMasServerSocket &&
mMasServerSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mMasServerSocket->Close();
mMasServerSocket = nullptr;
}
mMasServerSocket = nullptr;
mMasServerSocket = new BluetoothSocket(this);
@ -1510,7 +1562,17 @@ BluetoothMapSmsManager::OnSocketConnectError(BluetoothSocket* aSocket)
}
// MAS socket connection error
if (mMasServerSocket &&
mMasServerSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mMasServerSocket->Close();
}
mMasServerSocket = nullptr;
if (mMasSocket &&
mMasSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mMasSocket->Close();
}
mMasSocket = nullptr;
}
@ -1541,6 +1603,7 @@ BluetoothMapSmsManager::OnSocketDisconnect(BluetoothSocket* aSocket)
// MAS socket is disconnected
AfterMapSmsDisconnected();
mDeviceAddress.Clear();
mMasSocket = nullptr;
Listen();

Просмотреть файл

@ -86,7 +86,10 @@ public:
// By defualt SMS/MMS is default supported
static const int SDP_SMS_MMS_INSTANCE_ID = 0;
static void InitMapSmsInterface(BluetoothProfileResultHandler* aRes);
static void DeinitMapSmsInterface(BluetoothProfileResultHandler* aRes);
static BluetoothMapSmsManager* Get();
bool Listen();
/**
@ -194,7 +197,9 @@ protected:
private:
BluetoothMapSmsManager();
bool Init();
nsresult Init();
void Uninit();
void HandleShutdown();
void ReplyToConnect();

Просмотреть файл

@ -214,31 +214,24 @@ BluetoothOppManager::BluetoothOppManager() : mConnected(false)
{ }
BluetoothOppManager::~BluetoothOppManager()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE_VOID(obs);
if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
BT_WARNING("Failed to remove shutdown observer!");
}
{ }
if (NS_FAILED(obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED))) {
BT_WARNING("Failed to remove volume observer!");
}
}
bool
nsresult
BluetoothOppManager::Init()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE(obs, false);
if (NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
NS_ENSURE_TRUE(obs, NS_ERROR_NOT_AVAILABLE);
auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
if (NS_FAILED(rv)) {
BT_WARNING("Failed to add shutdown observer!");
return false;
return rv;
}
if (NS_FAILED(obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, false))) {
rv = obs->AddObserver(this, NS_VOLUME_STATE_CHANGED, false);
if (NS_FAILED(rv)) {
BT_WARNING("Failed to add ns volume observer!");
return false;
return rv;
}
/**
@ -250,7 +243,67 @@ BluetoothOppManager::Init()
* absence of read events when device boots up.
*/
return true;
return NS_OK;
}
void
BluetoothOppManager::Uninit()
{
if (mServerSocket) {
mServerSocket->SetObserver(nullptr);
if (mServerSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mServerSocket->Close();
}
mServerSocket = nullptr;
}
if (mSocket) {
mSocket->SetObserver(nullptr);
if (mSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mSocket->Close();
}
mSocket = nullptr;
}
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
NS_ENSURE_TRUE_VOID(obs);
if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID))) {
BT_WARNING("Failed to remove shutdown observer!");
}
if (NS_FAILED(obs->RemoveObserver(this, NS_VOLUME_STATE_CHANGED))) {
BT_WARNING("Failed to remove volume observer!");
}
}
// static
void
BluetoothOppManager::InitOppInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (aRes) {
aRes->Init();
}
}
// static
void
BluetoothOppManager::DeinitOppInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (sBluetoothOppManager) {
sBluetoothOppManager->Uninit();
sBluetoothOppManager = nullptr;
}
if (aRes) {
aRes->Deinit();
}
}
//static
@ -268,10 +321,11 @@ BluetoothOppManager::Get()
NS_ENSURE_FALSE(sInShutdown, nullptr);
// Create a new instance, register, and return
BluetoothOppManager *manager = new BluetoothOppManager();
NS_ENSURE_TRUE(manager->Init(), nullptr);
RefPtr<BluetoothOppManager> manager = new BluetoothOppManager();
NS_ENSURE_SUCCESS(manager->Init(), nullptr);
sBluetoothOppManager = manager;
return sBluetoothOppManager;
}
@ -281,10 +335,11 @@ BluetoothOppManager::ConnectInternal(const BluetoothAddress& aDeviceAddress)
MOZ_ASSERT(NS_IsMainThread());
// Stop listening because currently we only support one connection at a time.
if (mServerSocket) {
if (mServerSocket &&
mServerSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mServerSocket->Close();
mServerSocket = nullptr;
}
mServerSocket = nullptr;
mIsServer = false;
@ -310,6 +365,8 @@ BluetoothOppManager::HandleShutdown()
MOZ_ASSERT(NS_IsMainThread());
sInShutdown = true;
Disconnect(nullptr);
Uninit();
sBluetoothOppManager = nullptr;
}
@ -356,10 +413,11 @@ BluetoothOppManager::Listen()
* BT stops; otherwise no more read events would be received even if
* BT restarts.
*/
if (mServerSocket) {
if (mServerSocket &&
mServerSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mServerSocket->Close();
mServerSocket = nullptr;
}
mServerSocket = nullptr;
mServerSocket = new BluetoothSocket(this);
@ -1526,7 +1584,16 @@ BluetoothOppManager::OnSocketConnectError(BluetoothSocket* aSocket)
{
BT_LOGR("[%s]", (mIsServer)? "server" : "client");
if (mServerSocket &&
mServerSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mServerSocket->Close();
}
mServerSocket = nullptr;
if (mSocket &&
mSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mSocket->Close();
}
mSocket = nullptr;
if (!mIsServer) {
@ -1576,7 +1643,8 @@ BluetoothOppManager::OnSocketDisconnect(BluetoothSocket* aSocket)
mDeviceAddress.Clear();
mSuccessFlag = false;
mSocket = nullptr;
mSocket = nullptr; // should already be closed
// Listen as a server if there's no more batch to process
if (!ProcessNextBatch()) {
Listen();

Просмотреть файл

@ -40,6 +40,7 @@ class BluetoothOppManager : public BluetoothSocketObserver
class SendSocketDataTask;
public:
BT_DECL_PROFILE_MGR_BASE
BT_DECL_SOCKET_OBSERVER
virtual void GetName(nsACString& aName)
@ -49,7 +50,10 @@ public:
static const int MAX_PACKET_LENGTH = 0xFFFE;
static void InitOppInterface(BluetoothProfileResultHandler* aRes);
static void DeinitOppInterface(BluetoothProfileResultHandler* aRes);
static BluetoothOppManager* Get();
void ClientDataHandler(mozilla::ipc::UnixSocketBuffer* aMessage);
void ServerDataHandler(mozilla::ipc::UnixSocketBuffer* aMessage);
@ -75,7 +79,8 @@ protected:
private:
BluetoothOppManager();
bool Init();
nsresult Init();
void Uninit();
void HandleShutdown();
void HandleVolumeStateChanged(nsISupports* aSubject);

Просмотреть файл

@ -94,6 +94,8 @@ BluetoothPbapManager::HandleShutdown()
sInShutdown = true;
Disconnect(nullptr);
Uninit();
sPbapManager = nullptr;
}
@ -105,27 +107,19 @@ BluetoothPbapManager::BluetoothPbapManager() : mPhonebookSizeRequired(false)
}
BluetoothPbapManager::~BluetoothPbapManager()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return;
}
{ }
NS_WARN_IF(NS_FAILED(
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)));
}
bool
nsresult
BluetoothPbapManager::Init()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return false;
return NS_ERROR_NOT_AVAILABLE;
}
if (NS_WARN_IF(NS_FAILED(
obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false)))) {
return false;
auto rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
/**
@ -137,7 +131,64 @@ BluetoothPbapManager::Init()
* absence of read events when device boots up.
*/
return true;
return NS_OK;
}
void
BluetoothPbapManager::Uninit()
{
if (mServerSocket) {
mServerSocket->SetObserver(nullptr);
if (mServerSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mServerSocket->Close();
}
mServerSocket = nullptr;
}
if (mSocket) {
mSocket->SetObserver(nullptr);
if (mSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mSocket->Close();
}
mSocket = nullptr;
}
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return;
}
NS_WARN_IF(NS_FAILED(
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)));
}
// static
void
BluetoothPbapManager::InitPbapInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (aRes) {
aRes->Init();
}
}
// static
void
BluetoothPbapManager::DeinitPbapInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (sPbapManager) {
sPbapManager->Uninit();
sPbapManager = nullptr;
}
if (aRes) {
aRes->Deinit();
}
}
//static
@ -157,8 +208,8 @@ BluetoothPbapManager::Get()
}
// Create a new instance, register, and return
BluetoothPbapManager *manager = new BluetoothPbapManager();
if (NS_WARN_IF(!manager->Init())) {
RefPtr<BluetoothPbapManager> manager = new BluetoothPbapManager();
if (NS_WARN_IF(NS_FAILED(manager->Init()))) {
return nullptr;
}
@ -181,10 +232,11 @@ BluetoothPbapManager::Listen()
* BT stops; otherwise no more read events would be received even if
* BT restarts.
*/
if (mServerSocket) {
if (mServerSocket &&
mServerSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mServerSocket->Close();
mServerSocket = nullptr;
}
mServerSocket = nullptr;
mServerSocket = new BluetoothSocket(this);
@ -1131,7 +1183,16 @@ BluetoothPbapManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
void
BluetoothPbapManager::OnSocketConnectError(BluetoothSocket* aSocket)
{
if (mServerSocket &&
mServerSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mServerSocket->Close();
}
mServerSocket = nullptr;
if (mSocket &&
mSocket->GetConnectionStatus() != SOCKET_DISCONNECTED) {
mSocket->Close();
}
mSocket = nullptr;
}
@ -1147,7 +1208,8 @@ BluetoothPbapManager::OnSocketDisconnect(BluetoothSocket* aSocket)
AfterPbapDisconnected();
mDeviceAddress.Clear();
mSocket = nullptr;
mSocket = nullptr; // should already be closed
Listen();
}

Просмотреть файл

@ -67,7 +67,10 @@ public:
static const int MAX_PACKET_LENGTH = 0xFFFE;
static const int DIGEST_LENGTH = 16;
static void InitPbapInterface(BluetoothProfileResultHandler* aRes);
static void DeinitPbapInterface(BluetoothProfileResultHandler* aRes);
static BluetoothPbapManager* Get();
bool Listen();
/**
@ -146,7 +149,9 @@ protected:
private:
BluetoothPbapManager();
bool Init();
nsresult Init();
void Uninit();
void HandleShutdown();
void ReplyToConnect(const nsAString& aPassword = EmptyString());

Просмотреть файл

@ -138,6 +138,10 @@ public:
void Init() override
{
static void (* const sInitManager[])(BluetoothProfileResultHandler*) = {
BluetoothMapSmsManager::InitMapSmsInterface,
BluetoothOppManager::InitOppInterface,
BluetoothPbapManager::InitPbapInterface,
BluetoothHidManager::InitHidInterface,
BluetoothHfpManager::InitHfpInterface,
BluetoothA2dpManager::InitA2dpInterface,
BluetoothAvrcpManager::InitAvrcpInterface,
@ -280,14 +284,15 @@ BluetoothServiceBluedroid::StopInternal(BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
static BluetoothProfileManagerBase* sProfiles[] = {
BluetoothHfpManager::Get(),
BluetoothProfileManagerBase* sProfiles[] = {
// BluetoothGattManager not handled here
BluetoothAvrcpManager::Get(),
BluetoothA2dpManager::Get(),
BluetoothOppManager::Get(),
BluetoothHfpManager::Get(),
BluetoothHidManager::Get(),
BluetoothPbapManager::Get(),
BluetoothMapSmsManager::Get(),
BluetoothHidManager::Get()
BluetoothOppManager::Get(),
BluetoothMapSmsManager::Get()
};
// Disconnect all connected profiles
@ -2037,7 +2042,11 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
BluetoothGattManager::DeinitGattInterface,
BluetoothAvrcpManager::DeinitAvrcpInterface,
BluetoothA2dpManager::DeinitA2dpInterface,
BluetoothHfpManager::DeinitHfpInterface
BluetoothHfpManager::DeinitHfpInterface,
BluetoothHidManager::DeinitHidInterface,
BluetoothPbapManager::DeinitPbapInterface,
BluetoothOppManager::DeinitOppInterface,
BluetoothMapSmsManager::DeinitMapSmsInterface
};
// Return error if BluetoothService is unavailable

Просмотреть файл

@ -20,24 +20,6 @@ using namespace mozilla::ipc;
USING_BLUETOOTH_NAMESPACE
static const size_t MAX_READ_SIZE = 1 << 16;
static BluetoothSocketInterface* sBluetoothSocketInterface;
// helper functions
static bool
EnsureBluetoothSocketHalLoad()
{
if (sBluetoothSocketInterface) {
return true;
}
BluetoothInterface* btInf = BluetoothInterface::GetInstance();
NS_ENSURE_TRUE(btInf, false);
sBluetoothSocketInterface = btInf->GetBluetoothSocketInterface();
NS_ENSURE_TRUE(sBluetoothSocketInterface, false);
return true;
}
class mozilla::dom::bluetooth::DroidSocketImpl
: public mozilla::ipc::UnixFdWatcher
@ -429,24 +411,20 @@ private:
class InvokeAcceptTask final : public SocketTask<DroidSocketImpl>
{
public:
InvokeAcceptTask(DroidSocketImpl* aImpl, int aFd)
InvokeAcceptTask(DroidSocketImpl* aImpl, int aListenFd)
: SocketTask<DroidSocketImpl>(aImpl)
, mFd(aFd)
, mListenFd(aListenFd)
{ }
void Run() override
{
MOZ_ASSERT(GetIO()->IsConsumerThread());
MOZ_ASSERT(sBluetoothSocketInterface);
BluetoothSocketResultHandler* res = new AcceptResultHandler(GetIO());
GetIO()->mConsumer->SetCurrentResultHandler(res);
sBluetoothSocketInterface->Accept(mFd, res);
GetIO()->mConsumer->Accept(mListenFd, new AcceptResultHandler(GetIO()));
}
private:
int mFd;
int mListenFd;
};
void
@ -581,22 +559,27 @@ DroidSocketImpl::DiscardBuffer()
//
BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver)
: mObserver(aObserver)
: mSocketInterface(nullptr)
, mObserver(aObserver)
, mCurrentRes(nullptr)
, mImpl(nullptr)
{
MOZ_ASSERT(aObserver);
MOZ_COUNT_CTOR_INHERITED(BluetoothSocket, DataSocket);
EnsureBluetoothSocketHalLoad();
}
BluetoothSocket::~BluetoothSocket()
{
MOZ_ASSERT(!mImpl); // Socket is closed
MOZ_COUNT_DTOR_INHERITED(BluetoothSocket, DataSocket);
}
void
BluetoothSocket::SetObserver(BluetoothSocketObserver* aObserver)
{
mObserver = aObserver;
}
class ConnectSocketResultHandler final : public BluetoothSocketResultHandler
{
public:
@ -655,6 +638,11 @@ BluetoothSocket::Connect(const BluetoothAddress& aDeviceAddress,
{
MOZ_ASSERT(!mImpl);
auto rv = LoadSocketInterface();
if (NS_FAILED(rv)) {
return rv;
}
SetConnectionStatus(SOCKET_CONNECTING);
mImpl = new DroidSocketImpl(aConsumerLoop, aIOLoop, this);
@ -662,7 +650,7 @@ BluetoothSocket::Connect(const BluetoothAddress& aDeviceAddress,
BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
SetCurrentResultHandler(res);
sBluetoothSocketInterface->Connect(
mSocketInterface->Connect(
aDeviceAddress, aType,
aServiceUuid, aChannel,
aEncrypt, aAuth, res);
@ -719,8 +707,13 @@ BluetoothSocket::Listen(const nsAString& aServiceName,
{
MOZ_ASSERT(!mImpl);
auto rv = LoadSocketInterface();
if (NS_FAILED(rv)) {
return rv;
}
BluetoothServiceName serviceName;
nsresult rv = StringToServiceName(aServiceName, serviceName);
rv = StringToServiceName(aServiceName, serviceName);
if (NS_FAILED(rv)) {
return rv;
}
@ -732,7 +725,7 @@ BluetoothSocket::Listen(const nsAString& aServiceName,
BluetoothSocketResultHandler* res = new ListenResultHandler(mImpl);
SetCurrentResultHandler(res);
sBluetoothSocketInterface->Listen(
mSocketInterface->Listen(
aType,
serviceName, aServiceUuid, aChannel,
aEncrypt, aAuth, res);
@ -751,12 +744,26 @@ BluetoothSocket::Listen(const nsAString& aServiceName,
MessageLoop::current(), XRE_GetIOMessageLoop());
}
nsresult
BluetoothSocket::Accept(int aListenFd, BluetoothSocketResultHandler* aRes)
{
auto rv = LoadSocketInterface();
if (NS_FAILED(rv)) {
return rv;
}
SetCurrentResultHandler(aRes);
mSocketInterface->Accept(aListenFd, aRes);
return NS_OK;
}
void
BluetoothSocket::ReceiveSocketData(nsAutoPtr<UnixSocketBuffer>& aBuffer)
{
MOZ_ASSERT(mObserver);
mObserver->ReceiveSocketData(this, aBuffer);
if (mObserver) {
mObserver->ReceiveSocketData(this, aBuffer);
}
}
// |DataSocket|
@ -778,50 +785,86 @@ BluetoothSocket::SendSocketData(UnixSocketIOBuffer* aBuffer)
void
BluetoothSocket::Close()
{
MOZ_ASSERT(sBluetoothSocketInterface);
if (!mImpl) {
return;
}
MOZ_ASSERT(mImpl->IsConsumerThread());
// Stop any watching |SocketMessageWatcher|
if (mCurrentRes) {
sBluetoothSocketInterface->Close(mCurrentRes);
}
// From this point on, we consider mImpl as being deleted.
// We sever the relationship here so any future calls to listen or connect
// will create a new implementation.
mImpl->ShutdownOnConsumerThread();
mImpl->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mImpl));
mImpl = nullptr;
NotifyDisconnect();
}
void
BluetoothSocket::OnConnectSuccess()
{
MOZ_ASSERT(mObserver);
SetCurrentResultHandler(nullptr);
mObserver->OnSocketConnectSuccess(this);
if (mObserver) {
mObserver->OnSocketConnectSuccess(this);
}
}
void
BluetoothSocket::OnConnectError()
{
MOZ_ASSERT(mObserver);
auto observer = mObserver;
SetCurrentResultHandler(nullptr);
mObserver->OnSocketConnectError(this);
Cleanup();
if (observer) {
observer->OnSocketConnectError(this);
}
}
void
BluetoothSocket::OnDisconnect()
{
MOZ_ASSERT(mObserver);
mObserver->OnSocketDisconnect(this);
auto observer = mObserver;
Cleanup();
if (observer) {
observer->OnSocketDisconnect(this);
}
}
nsresult
BluetoothSocket::LoadSocketInterface()
{
if (mSocketInterface) {
return NS_OK;
}
auto interface = BluetoothInterface::GetInstance();
NS_ENSURE_TRUE(!!interface, NS_ERROR_FAILURE);
auto socketInterface = interface->GetBluetoothSocketInterface();
NS_ENSURE_TRUE(!!socketInterface, NS_ERROR_FAILURE);
mSocketInterface = socketInterface;
return NS_OK;
}
void
BluetoothSocket::Cleanup()
{
MOZ_ASSERT(mSocketInterface);
MOZ_ASSERT(mImpl);
MOZ_ASSERT(mImpl->IsConsumerThread());
// Stop any watching |SocketMessageWatcher|
if (mCurrentRes) {
mSocketInterface->Close(mCurrentRes);
}
// From this point on, we consider mImpl as being deleted. We
// sever the relationship here so any future calls to listen
// or connect will create a new implementation.
mImpl->ShutdownOnConsumerThread();
mImpl->GetIOLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mImpl));
mImpl = nullptr;
mSocketInterface = nullptr;
mObserver = nullptr;
mCurrentRes = nullptr;
mDeviceAddress.Clear();
}

Просмотреть файл

@ -14,6 +14,7 @@ class MessageLoop;
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothSocketInterface;
class BluetoothSocketObserver;
class BluetoothSocketResultHandler;
class DroidSocketImpl;
@ -24,6 +25,8 @@ public:
BluetoothSocket(BluetoothSocketObserver* aObserver);
~BluetoothSocket();
void SetObserver(BluetoothSocketObserver* aObserver);
nsresult Connect(const BluetoothAddress& aDeviceAddress,
const BluetoothUuid& aServiceUuid,
BluetoothSocketType aType,
@ -52,6 +55,8 @@ public:
int aChannel,
bool aAuth, bool aEncrypt);
nsresult Accept(int aListenFd, BluetoothSocketResultHandler* aRes);
/**
* Method to be called whenever data is received. This is only called on the
* consumer thread.
@ -70,11 +75,6 @@ public:
mDeviceAddress = aDeviceAddress;
}
inline void SetCurrentResultHandler(BluetoothSocketResultHandler* aRes)
{
mCurrentRes = aRes;
}
// Methods for |DataSocket|
//
@ -90,6 +90,15 @@ public:
void OnDisconnect() override;
private:
nsresult LoadSocketInterface();
void Cleanup();
inline void SetCurrentResultHandler(BluetoothSocketResultHandler* aRes)
{
mCurrentRes = aRes;
}
BluetoothSocketInterface* mSocketInterface;
BluetoothSocketObserver* mObserver;
BluetoothSocketResultHandler* mCurrentRes;
DroidSocketImpl* mImpl;

Просмотреть файл

@ -176,6 +176,8 @@ BluetoothHfpManager::DeinitHfpInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
sBluetoothHfpManager = nullptr;
/**
* TODO:
* Implement DeinitHfpInterface() for applications that want to create SCO

Просмотреть файл

@ -446,6 +446,7 @@ public:
sBluetoothHfpInterface->SetNotificationHandler(nullptr);
sBluetoothHfpInterface = nullptr;
sBluetoothHfpManager = nullptr;
if (mRes) {
mRes->OnError(NS_ERROR_FAILURE);
@ -458,6 +459,7 @@ public:
sBluetoothHfpInterface->SetNotificationHandler(nullptr);
sBluetoothHfpInterface = nullptr;
sBluetoothHfpManager = nullptr;
if (mRes) {
mRes->Deinit();

Просмотреть файл

@ -78,6 +78,30 @@ BluetoothHidManager::~BluetoothHidManager()
}
}
// static
void
BluetoothHidManager::InitHidInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
if (aRes) {
aRes->Init();
}
}
// static
void
BluetoothHidManager::DeinitHidInterface(BluetoothProfileResultHandler* aRes)
{
MOZ_ASSERT(NS_IsMainThread());
sBluetoothHidManager = nullptr;
if (aRes) {
aRes->Deinit();
}
}
//static
BluetoothHidManager*
BluetoothHidManager::Get()

Просмотреть файл

@ -22,6 +22,8 @@ public:
aName.AssignLiteral("HID");
}
static void InitHidInterface(BluetoothProfileResultHandler* aRes);
static void DeinitHidInterface(BluetoothProfileResultHandler* aRes);
static BluetoothHidManager* Get();
// HID-specific functions

Просмотреть файл

@ -36,7 +36,6 @@ const kSmsDeletedObserverTopic = "sms-deleted";
const NS_XPCOM_SHUTDOWN_OBSERVER_ID = "xpcom-shutdown";
const kNetworkConnStateChangedTopic = "network-connection-state-changed";
const kPrefRilRadioDisabled = "ril.radio.disabled";
const kPrefMmsDebuggingEnabled = "mms.debugging.enabled";
// HTTP status codes:
@ -194,18 +193,12 @@ function getDefaultServiceId() {
}
/**
* Return Radio disabled state.
* Return radio disabled state.
*/
function getRadioDisabledState() {
let state;
try {
state = Services.prefs.getBoolPref(kPrefRilRadioDisabled);
} catch (e) {
if (DEBUG) debug("Getting preference 'ril.radio.disabled' fails.");
state = false;
}
return state;
function isRadioOff(aServiceId) {
let connection = gMobileConnectionService.getItemByServiceId(aServiceId);
return connection.radioState
!== Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED;
}
/**
@ -422,7 +415,7 @@ MmsConnection.prototype = {
this.pendingCallbacks.push(callback);
let errorStatus;
if (getRadioDisabledState()) {
if (isRadioOff(this.serviceId)) {
if (DEBUG) debug("Error! Radio is disabled when sending MMS.");
errorStatus = _HTTP_STATUS_RADIO_DISABLED;
} else if (this.getCardState() != Ci.nsIIcc.CARD_STATE_READY) {
@ -993,7 +986,8 @@ function CancellableTransaction(cancellableId, serviceId) {
this.isCancelled = false;
}
CancellableTransaction.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsIMobileConnectionListener]),
// The timer for retrying sending or retrieving process.
timer: null,
@ -1010,8 +1004,9 @@ CancellableTransaction.prototype = {
if (!this.isObserversAdded) {
Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
Services.obs.addObserver(this, kSmsDeletedObserverTopic, false);
Services.prefs.addObserver(kPrefRilRadioDisabled, this, false);
Services.prefs.addObserver(kPrefDefaultServiceId, this, false);
gMobileConnectionService
.getItemByServiceId(this.serviceId).registerListener(this);
this.isObserversAdded = true;
}
@ -1023,8 +1018,9 @@ CancellableTransaction.prototype = {
if (this.isObserversAdded) {
Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
Services.obs.removeObserver(this, kSmsDeletedObserverTopic);
Services.prefs.removeObserver(kPrefRilRadioDisabled, this);
Services.prefs.removeObserver(kPrefDefaultServiceId, this);
gMobileConnectionService
.getItemByServiceId(this.serviceId).unregisterListener(this);
this.isObserversAdded = false;
}
},
@ -1080,18 +1076,35 @@ CancellableTransaction.prototype = {
break;
}
case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID: {
if (data == kPrefRilRadioDisabled) {
if (getRadioDisabledState()) {
this.cancelRunning(_MMS_ERROR_RADIO_DISABLED);
}
} else if (data === kPrefDefaultServiceId &&
if (data === kPrefDefaultServiceId &&
this.serviceId != getDefaultServiceId()) {
this.cancelRunning(_MMS_ERROR_SIM_CARD_CHANGED);
}
break;
}
}
}
},
// nsIMobileConnectionListener
notifyVoiceChanged: function() {},
notifyDataChanged: function() {},
notifyDataError: function(message) {},
notifyCFStateChanged: function(action, reason, number, timeSeconds, serviceClass) {},
notifyEmergencyCbModeChanged: function(active, timeoutMs) {},
notifyOtaStatusChanged: function(status) {},
notifyRadioStateChanged: function() {
if (isRadioOff(this.serviceId)) {
this.cancelRunning(_MMS_ERROR_RADIO_DISABLED);
}
},
notifyClirModeChanged: function(mode) {},
notifyLastKnownNetworkChanged: function() {},
notifyLastKnownHomeNetworkChanged: function() {},
notifyNetworkSelectionModeChanged: function() {},
notifyDeviceIdentitiesChanged: function() {}
};
/**
@ -2388,7 +2401,7 @@ MmsService.prototype = {
}
// Check radio state in prior to default service Id.
if (getRadioDisabledState()) {
if (isRadioOff(aServiceId)) {
if (DEBUG) debug("Error! Radio is disabled when sending MMS.");
sendTransactionCb(mmsMessage,
Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR,
@ -2502,7 +2515,13 @@ MmsService.prototype = {
// Hence, for manual retrieving, instead of checking radio state later
// in MmsConnection.acquire(), We have to check radio state in prior to
// iccId to return the error correctly.
if (getRadioDisabledState()) {
let numRadioInterfaces = gMobileConnectionService.numItems;
let isAllRadioOff = true;
for (let serviceId = 0; serviceId < numRadioInterfaces; serviceId++) {
isAllRadioOff &= isRadioOff(serviceId);
}
if (isAllRadioOff) {
if (DEBUG) debug("Error! Radio is disabled when retrieving MMS.");
aRequest.notifyGetMessageFailed(
Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR);

Просмотреть файл

@ -663,3 +663,60 @@ function runIfMultiSIM(aTest) {
return Promise.resolve();
}
}
/**
* Helper to enable/disable connection radio state.
*
* @param aConnection
* connection to enable / disable
* @param aEnabled
* True to enable the radio.
* @return a Promise object.
*/
function setRadioEnabled(aConnection, aEnabled) {
log("setRadioEnabled to " + aEnabled);
let deferred = Promise.defer();
let finalState = (aEnabled) ? "enabled" : "disabled";
if (aConnection.radioState == finalState) {
return deferred.resolve(aConnection);
}
aConnection.onradiostatechange = function() {
log("Received 'radiostatechange', radioState: " + aConnection.radioState);
if (aConnection.radioState == finalState) {
deferred.resolve(aConnection);
aConnection.onradiostatechange = null;
}
};
let req = aConnection.setRadioEnabled(aEnabled);
req.onsuccess = function() {
log("setRadioEnabled success");
};
req.onerror = function() {
ok(false, "setRadioEnabled should not fail");
deferred.reject();
};
return deferred.promise;
}
/**
* Helper to enable/disable all connections radio state.
*
* @param aEnabled
* True to enable the radio.
* @return a Promise object.
*/
function setAllRadioEnabled(aEnabled) {
let promises = []
for (let i = 0; i < window.navigator.mozMobileConnections.length; ++i) {
promises.push(ensureMobileConnection(i)
.then((connection) => setRadioEnabled(connection, aEnabled)));
}
return Promise.all(promises);
}

Просмотреть файл

@ -2,6 +2,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
// We apply "chrome" context to be more flexible to
// specify the content of M-Notification.ind such as iccId
// for different kinds of testing.
@ -17,11 +18,17 @@ var gMobileMessageDatabaseService =
.getService(Ci.nsIGonkMobileMessageDatabaseService);
var gUuidGenerator =
Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator);
Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
var gMmsService = Cc["@mozilla.org/mms/gonkmmsservice;1"]
.getService(Ci.nsIMmsService);
var gMmsService =
Cc["@mozilla.org/mms/gonkmmsservice;1"].getService(Ci.nsIMmsService);
var gMobileConnectionService =
Cc["@mozilla.org/mobileconnection/mobileconnectionservice;1"]
.getService(Ci.nsIMobileConnectionService);
var gIccService =
Cc["@mozilla.org/icc/gonkiccservice;1"].getService(Ci.nsIIccService);
function saveMmsNotification() {
log("saveMmsNotification()");
@ -101,23 +108,111 @@ function retrieveMmsWithFailure(aId) {
return deferred.promise;
}
function testRetrieve(aCause, aInit, aCleanup) {
function testRetrieve(aCause) {
log("testRetrieve: aCause = " + aCause);
return Promise.resolve()
.then(() => { if (aInit) aInit(); })
.then(saveMmsNotification)
.then((message) => retrieveMmsWithFailure(message.id))
.then((response) => verifyErrorCause(response, aCause))
.then(() => { if (aCleanup) aCleanup(); });
.then((response) => verifyErrorCause(response, aCause));
}
var setRadioDisabled = function(aDisabled) {
log("set ril.radio.disabled to " + aDisabled);
Services.prefs.setBoolPref("ril.radio.disabled", aDisabled);
};
function setRadioEnabled(aConnection, aEnabled) {
let deferred = Promise.defer();
let finalState = (aEnabled) ?
Ci.nsIMobileConnection.MOBILE_RADIO_STATE_ENABLED :
Ci.nsIMobileConnection.MOBILE_RADIO_STATE_DISABLED;
testRetrieve(Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR,
setRadioDisabled.bind(null, true),
setRadioDisabled.bind(null, false))
if (aConnection.radioState == finalState) {
return deferred.resolve(aConnection);
}
let listener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileConnectionListener]),
notifyVoiceChanged: function() {},
notifyDataChanged: function() {},
notifyDataError: function(message) {},
notifyCFStateChanged: function(action, reason, number, timeSeconds, serviceClass) {},
notifyEmergencyCbModeChanged: function(active, timeoutMs) {},
notifyOtaStatusChanged: function(status) {},
notifyRadioStateChanged: function() {
log("setRadioEnabled state changed to " + aConnection.radioState);
if (aConnection.radioState == finalState) {
aConnection.unregisterListener(listener);
deferred.resolve(aConnection);
}
},
notifyClirModeChanged: function(mode) {},
notifyLastKnownNetworkChanged: function() {},
notifyLastKnownHomeNetworkChanged: function() {},
notifyNetworkSelectionModeChanged: function() {},
notifyDeviceIdentitiesChanged: function() {}
};
let callback = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileConnectionCallback]),
notifySuccess() {},
notifySuccessWithBoolean(result) {},
notifyGetNetworksSuccess(count, networks) {},
notifyGetCallForwardingSuccess(count, results) {},
notifyGetCallBarringSuccess(program, enabled, serviceClass) {},
notifyGetCallWaitingSuccess(serviceClass) {},
notifyGetClirStatusSuccess(n, m) {},
notifyGetPreferredNetworkTypeSuccess(type) {},
notifyGetRoamingPreferenceSuccess(mode) {},
notifyError(name) {
log("setRadioEnabled reject");
aConnection.unregisterListener(listener);
deferred.reject();
}
};
aConnection.registerListener(listener);
aConnection.setRadioEnabled(aEnabled, callback);
return deferred.promise;
}
function setAllRadioEnabled(aEnabled) {
log("setAllRadioEnabled connection number = " +
gMobileConnectionService.numItems);
let promises = [];
for (let i = 0; i < gMobileConnectionService.numItems; ++i) {
promises.push(setRadioEnabled(
gMobileConnectionService.getItemByServiceId(i), aEnabled));
}
return Promise.all(promises);
}
function waitIccReady(aIcc) {
let deferred = Promise.defer();
if (aIcc.cardState == Ci.nsIIcc.CARD_STATE_READY) {
return deferred.resolve(aIcc);
}
let listener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIIccListener]),
notifyStkCommand(aStkProactiveCmd) {},
notifyStkSessionEnd() {},
notifyCardStateChanged() {
if (aIcc.cardState == Ci.nsIIcc.CARD_STATE_READY) {
aIcc.unregisterListener(listener);
deferred.resolve(aIcc);
}
},
notifyIccInfoChanged() {}
};
aIcc.registerListener(listener);
return deferred.promise;
}
function waitAllIccReady() {
let promises = [];
for (let i = 0; i < gMobileConnectionService.numItems; ++i) {
let icc = gIccService.getIccByServiceId(i);
promises.push(waitIccReady(icc));
}
return Promise.all(promises);
}
setAllRadioEnabled(false)
.then(() => testRetrieve(Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR))
.then(() => setAllRadioEnabled(true))
.then(() => waitAllIccReady())
.then(() => testRetrieve(Ci.nsIMobileMessageCallback.SIM_NOT_MATCHED_ERROR))
.then(finish);

Просмотреть файл

@ -4,8 +4,6 @@
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const kPrefRilRadioDisabled = "ril.radio.disabled";
function testSendFailed(aCause, aServiceId) {
log("testSendFailed, aCause: " + aCause + ", aServiceId: " + aServiceId);
let sendParameters;
@ -44,13 +42,9 @@ function testSendFailed(aCause, aServiceId) {
startTestCommon(function testCaseMain() {
return Promise.resolve()
.then(() => {
SpecialPowers.setBoolPref(kPrefRilRadioDisabled, true);
})
.then(() => testSendFailed("RadioDisabledError"))
.then(() => {
SpecialPowers.setBoolPref(kPrefRilRadioDisabled, false);
})
.then(() => setAllRadioEnabled(false))
.then(() => testSendFailed("RadioDisabledError"), 0)
.then(() => setAllRadioEnabled(true))
.then(() => runIfMultiSIM(
() => testSendFailed("NonActiveSimCardError", 1)));
});

Просмотреть файл

@ -4,79 +4,6 @@
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const kPrefRilRadioDisabled = "ril.radio.disabled";
var connection;
function ensureMobileConnection() {
let deferred = Promise.defer();
let permissions = [{
"type": "mobileconnection",
"allow": true,
"context": document,
}];
SpecialPowers.pushPermissions(permissions, function() {
ok(true, "permissions pushed: " + JSON.stringify(permissions));
connection = window.navigator.mozMobileConnections[0];
if (connection) {
log("navigator.mozMobileConnections[0] is instance of " + connection.constructor);
} else {
log("navigator.mozMobileConnections[0] is undefined.");
}
if (connection instanceof MozMobileConnection) {
deferred.resolve(connection);
} else {
deferred.reject();
}
});
return deferred.promise;
}
function waitRadioState(state) {
let deferred = Promise.defer();
waitFor(function() {
deferred.resolve();
}, function() {
return connection.radioState == state;
});
return deferred.promise;
}
function setRadioEnabled(enabled) {
log("setRadioEnabled to " + enabled);
let deferred = Promise.defer();
let finalState = (enabled) ? "enabled" : "disabled";
connection.onradiostatechange = function() {
let state = connection.radioState;
log("Received 'radiostatechange' event, radioState: " + state);
if (state == finalState) {
deferred.resolve();
connection.onradiostatechange = null;
}
};
let req = connection.setRadioEnabled(enabled);
req.onsuccess = function() {
log("setRadioEnabled success");
};
req.onerror = function() {
ok(false, "setRadioEnabled should not fail");
deferred.reject();
};
return deferred.promise;
}
function testSendFailed(aCause) {
log("testSendFailed, aCause: " + aCause);
@ -98,8 +25,7 @@ function testSendFailed(aCause) {
startTestCommon(function testCaseMain() {
return ensureMobileConnection()
.then(() => waitRadioState("enabled"))
.then(() => setRadioEnabled(false))
.then(() => setRadioEnabled(mobileConnection, false))
.then(() => testSendFailed("RadioDisabledError"))
.then(() => setRadioEnabled(true));
.then(() => setRadioEnabled(mobileConnection, true));
});

Просмотреть файл

@ -5,6 +5,9 @@ MAINTAINER Jonas Finnemann Jensen <jopsen@gmail.com>
COPY sources.list /etc/apt/sources.list
RUN useradd -d /home/worker -s /bin/bash -m worker
# allow the worker user to access video devices
RUN usermod -a -G video worker
RUN apt-get update && apt-get install -y --force-yes \
alsa-base \
alsa-utils \
@ -111,6 +114,7 @@ RUN apt-get update && apt-get install -y --force-yes \
vim \
wget \
x11-xserver-utils \
x11-utils \
xvfb \
yasm \
zip

Просмотреть файл

@ -1 +1 @@
0.1.2
0.1.3

Просмотреть файл

@ -1,4 +1,4 @@
FROM taskcluster/base-test:0.1.2
FROM taskcluster/base-test:0.1.3
MAINTAINER Jonas Finnemann Jensen <jopsen@gmail.com>
# Add utilities and configuration

Просмотреть файл

@ -1 +1 @@
0.4.5
0.4.6

Просмотреть файл

@ -0,0 +1,31 @@
#! /bin/bash -vex
set -x -e
: GECKO_HEAD_REPOSITORY ${GECKO_HEAD_REPOSITORY:=https://hg.mozilla.org/mozilla-central}
: GECKO_HEAD_REV ${GECKO_HEAD_REV:=default}
: WORKSPACE ${WORKSPACE:=/home/worker/workspace}
# TODO: when bug 1093833 is solved and tasks can run as non-root, reduce this
# to a simple fail-if-root check
if [ $(id -u) = 0 ]; then
chown -R worker:worker /home/worker
# drop privileges by re-running this script
exec sudo -E -u worker bash /home/worker/bin/test.sh "${@}"
fi
####
# Now get the test-linux.sh script from the given Gecko tree and run it with
# the same arguments.
####
[ -d $WORKSPACE ] || mkdir -p $WORKSPACE
cd $WORKSPACE
script=testing/taskcluster/scripts/tester/test-mulet.sh
url=${GECKO_HEAD_REPOSITORY}/raw-file/${GECKO_HEAD_REV}/${script}
curl --fail -o ./test-mulet.sh --retry 10 $url
chmod +x ./test-mulet.sh
exec ./test-mulet.sh "${@}"

Просмотреть файл

@ -0,0 +1,99 @@
#! /bin/bash -xe
set -x -e
echo "running as" $(id)
####
# Taskcluster friendly wrapper for performing fx desktop tests via mozharness.
####
# Inputs, with defaults
: MOZHARNESS_URL ${MOZHARNESS_URL}
: MOZHARNESS_SCRIPT ${MOZHARNESS_SCRIPT}
: MOZHARNESS_CONFIG ${MOZHARNESS_CONFIG}
: NEED_XVFB ${NEED_XVFB:=true}
: NEED_PULSEAUDIO ${NEED_PULSEAUDIO:=false}
: SKIP_MOZHARNESS_RUN ${SKIP_MOZHARNESS_RUN:=false}
: WORKSPACE ${WORKSPACE:=/home/worker/workspace}
: mozharness args "${@}"
set -v
cd $WORKSPACE
# test required parameters are supplied
if [[ -z ${MOZHARNESS_URL} ]]; then exit 1; fi
if [[ -z ${MOZHARNESS_SCRIPT} ]]; then exit 1; fi
if [[ -z ${MOZHARNESS_CONFIG} ]]; then exit 1; fi
mkdir -p ~/artifacts/public
cleanup() {
if [ -n "$xvfb_pid" ]; then
kill $xvfb_pid || true
fi
}
trap cleanup EXIT INT
# Unzip the mozharness ZIP file created by the build task
curl --fail -o mozharness.zip --retry 10 -L $MOZHARNESS_URL
rm -rf mozharness
unzip -q mozharness.zip
rm mozharness.zip
if ! [ -d mozharness ]; then
echo "mozharness zip did not contain mozharness/"
exit 1
fi
# start up the pulseaudio daemon. Note that it's important this occur
# before the Xvfb startup.
if $NEED_PULSEAUDIO; then
pulseaudio --fail --daemonize --start
pactl load-module module-null-sink
fi
# run XVfb in the background, if necessary
if $NEED_XVFB; then
Xvfb :0 -nolisten tcp -screen 0 1600x1200x24 \
> ~/artifacts/public/xvfb.log 2>&1 &
export DISPLAY=:0
xvfb_pid=$!
# Only error code 255 matters, because it signifies that no
# display could be opened. As long as we can open the display
# tests should work. We'll retry a few times with a sleep before
# failing.
retry_count=0
max_retries=2
xvfb_test=0
until [ $retry_count -gt $max_retries ]; do
xvinfo || xvfb_test=$?
if [ $xvfb_test != 255 ]; then
retry_count=$(($max_retries + 1))
else
retry_count=$(($retry_count + 1))
echo "Failed to start Xvfb, retry: $retry_count"
sleep 2
fi done
if [ $xvfb_test == 255 ]; then exit 255; fi
fi
# support multiple, space delimited, config files
config_cmds=""
for cfg in $MOZHARNESS_CONFIG; do
config_cmds="${config_cmds} --config-file ${cfg}"
done
if [ ${SKIP_MOZHARNESS_RUN} == true ]; then
# Skipping Mozharness is to allow the developer start the window manager
# properly and letting them change the execution of Mozharness without
# exiting the container
echo "We skipped running Mozharness."
echo "Make sure you export DISPLAY=:0 before calling Mozharness."
echo "Don't forget to call it with 'sudo -E -u worker'."
else
# run the given mozharness script and configs, but pass the rest of the
# arguments in from our own invocation
python2.7 $WORKSPACE/${MOZHARNESS_SCRIPT} ${config_cmds} "${@}"
fi

Просмотреть файл

@ -53,7 +53,7 @@ tasks:
# Note: This task is built server side without the context or tooling that
# exist in tree so we must hard code the version
image: 'quay.io/mozilla/builder:0.3.0'
image: 'taskcluster/builder:0.5.11'
# Virtually no network or other potentially risky operations happen as part
# of the task timeout aside from the initial clone. We intentionally have
@ -65,12 +65,13 @@ tasks:
- /bin/bash
- -cx
- >
source ./bin/decision.sh &&
mkdir -p /home/worker/artifacts &&
checkout-gecko workspace &&
cd workspace/gecko &&
./mach taskcluster-graph
--pushlog-id='{{pushlog_id}}'
--message='{{comment}}'
--project='{{project}}'
--message='{{comment}}'
--owner='{{owner}}'
--level='{{level}}'
--revision-hash='{{revision_hash}}'

Просмотреть файл

@ -59,7 +59,7 @@ tasks:
# Note: This task is built server side without the context or tooling that
# exist in tree so we must hard code the version
image: 'quay.io/mozilla/builder:0.5.0'
image: 'taskcluster/builder:0.5.11'
# Virtually no network or other potentially risky operations happen as part
# of the task timeout aside from the initial clone. We intentionally have

Просмотреть файл

@ -33,7 +33,11 @@ task:
extra:
chunks:
total: 20
treeherderEnv:
- production
- staging
treeherder:
groupName: XPCShell
symbol: X{{chunk}}
productName: b2g
tier: 2

Просмотреть файл

@ -11,7 +11,7 @@ task:
- 'docker-worker:capability:device:loopbackVideo'
- 'docker-worker:capability:device:loopbackAudio'
payload:
image: '{{#docker_image}}desktop-test{{/docker_image}}'
image: '{{#docker_image}}tester{{/docker_image}}'
cache:
# So pip installs are cached...
level-{{level}}-{{project}}-dotcache: /home/worker/.cache
@ -21,6 +21,8 @@ task:
loopbackVideo: true
loopbackAudio: true
env:
GECKO_HEAD_REPOSITORY: '{{{head_repository}}}'
GECKO_HEAD_REV: '{{{head_rev}}}'
NEED_XVFB: true
NEED_PULSEAUDIO: true
MOZHARNESS_SCRIPT: 'mozharness/scripts/desktop_unittest.py'