Merge m-c to fx-team, a=merge

This commit is contained in:
Wes Kocher 2015-06-01 12:32:44 -07:00
commit 1eac30fc7c
25 changed files with 499 additions and 316 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="85e6fcef45c0cb2c017739df42b68b96cf5bb9c3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="85e6fcef45c0cb2c017739df42b68b96cf5bb9c3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<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="85e6fcef45c0cb2c017739df42b68b96cf5bb9c3"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>

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="85e6fcef45c0cb2c017739df42b68b96cf5bb9c3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4a697ec692aa762eb8cdb7812f5a051c5870020f"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="85e6fcef45c0cb2c017739df42b68b96cf5bb9c3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="85e6fcef45c0cb2c017739df42b68b96cf5bb9c3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<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="85e6fcef45c0cb2c017739df42b68b96cf5bb9c3"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="85e6fcef45c0cb2c017739df42b68b96cf5bb9c3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "85e6fcef45c0cb2c017739df42b68b96cf5bb9c3",
"git_revision": "6d477a7884273886605049b20f60af5c1583a150",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "a4d81914887c6dac8e96e149a573d22fa313444f",
"revision": "c7beef2b034d2308a85e8c866395c78245bc554f",
"repo_path": "integration/gaia-central"
}

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="85e6fcef45c0cb2c017739df42b68b96cf5bb9c3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="4a697ec692aa762eb8cdb7812f5a051c5870020f"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="85e6fcef45c0cb2c017739df42b68b96cf5bb9c3"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="6d477a7884273886605049b20f60af5c1583a150"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -294,9 +294,10 @@ BluetoothOppManager::ConnectInternal(const nsAString& aDeviceAddress)
return;
}
mSocket =
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, false, true);
mSocket->ConnectSocket(aDeviceAddress, kObexObjectPush, -1);
mSocket = new BluetoothSocket(this);
mSocket->Connect(aDeviceAddress, kObexObjectPush,
BluetoothSocketType::RFCOMM, -1,
false, true);
}
void
@ -356,12 +357,14 @@ BluetoothOppManager::Listen()
mServerSocket = nullptr;
}
mServerSocket =
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, false, true);
mServerSocket = new BluetoothSocket(this);
if (!mServerSocket->ListenSocket(NS_LITERAL_STRING("OBEX Object Push"),
kObexObjectPush,
BluetoothReservedChannels::CHANNEL_OPUSH)) {
nsresult rv = mServerSocket->Listen(NS_LITERAL_STRING("OBEX Object Push"),
kObexObjectPush,
BluetoothSocketType::RFCOMM,
BluetoothReservedChannels::CHANNEL_OPUSH,
false, true);
if (NS_FAILED(rv)) {
BT_WARNING("[OPP] Can't listen on RFCOMM socket!");
mServerSocket = nullptr;
return false;

View File

@ -161,13 +161,15 @@ BluetoothPbapManager::Listen()
mServerSocket = nullptr;
}
mServerSocket =
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, false, true);
mServerSocket = new BluetoothSocket(this);
if (NS_WARN_IF(!mServerSocket->ListenSocket(
NS_LITERAL_STRING("OBEX Phonebook Access Server"),
kPbapPSE,
BluetoothReservedChannels::CHANNEL_PBAP_PSE))) {
nsresult rv = mServerSocket->Listen(
NS_LITERAL_STRING("OBEX Phonebook Access Server"),
kPbapPSE,
BluetoothSocketType::RFCOMM,
BluetoothReservedChannels::CHANNEL_PBAP_PSE, false, true);
if (NS_FAILED(rv)) {
mServerSocket = nullptr;
return false;
}

View File

@ -579,15 +579,10 @@ DroidSocketImpl::DiscardBuffer()
// |BluetoothSocket|
//
BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
BluetoothSocketType aType,
bool aAuth,
bool aEncrypt)
BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver)
: mObserver(aObserver)
, mCurrentRes(nullptr)
, mImpl(nullptr)
, mAuth(aAuth)
, mEncrypt(aEncrypt)
{
MOZ_ASSERT(aObserver);
@ -642,13 +637,15 @@ private:
DroidSocketImpl* mImpl;
};
bool
BluetoothSocket::ConnectSocket(const nsAString& aDeviceAddress,
const BluetoothUuid& aServiceUuid,
int aChannel)
nsresult
BluetoothSocket::Connect(const nsAString& aDeviceAddress,
const BluetoothUuid& aServiceUuid,
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_FALSE(mImpl, false);
MOZ_ASSERT(!mImpl);
SetConnectionStatus(SOCKET_CONNECTING);
@ -658,12 +655,11 @@ BluetoothSocket::ConnectSocket(const nsAString& aDeviceAddress,
SetCurrentResultHandler(res);
sBluetoothSocketInterface->Connect(
aDeviceAddress,
BluetoothSocketType::RFCOMM,
aDeviceAddress, aType,
aServiceUuid.mUuid, aChannel,
mEncrypt, mAuth, res);
aEncrypt, aAuth, res);
return true;
return NS_OK;
}
class ListenResultHandler final : public BluetoothSocketResultHandler
@ -694,13 +690,15 @@ private:
DroidSocketImpl* mImpl;
};
bool
BluetoothSocket::ListenSocket(const nsAString& aServiceName,
const BluetoothUuid& aServiceUuid,
int aChannel)
nsresult
BluetoothSocket::Listen(const nsAString& aServiceName,
const BluetoothUuid& aServiceUuid,
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_FALSE(mImpl, false);
MOZ_ASSERT(!mImpl);
SetConnectionStatus(SOCKET_LISTENING);
@ -710,11 +708,11 @@ BluetoothSocket::ListenSocket(const nsAString& aServiceName,
SetCurrentResultHandler(res);
sBluetoothSocketInterface->Listen(
BluetoothSocketType::RFCOMM,
aType,
aServiceName, aServiceUuid.mUuid, aChannel,
mEncrypt, mAuth, res);
aEncrypt, aAuth, res);
return true;
return NS_OK;
}
void

View File

@ -19,18 +19,19 @@ class DroidSocketImpl;
class BluetoothSocket final : public mozilla::ipc::DataSocket
{
public:
BluetoothSocket(BluetoothSocketObserver* aObserver,
BluetoothSocket(BluetoothSocketObserver* aObserver);
nsresult Connect(const nsAString& aDeviceAddress,
const BluetoothUuid& aServiceUuid,
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt);
nsresult Listen(const nsAString& aServiceName,
const BluetoothUuid& aServiceUuid,
BluetoothSocketType aType,
bool aAuth,
bool aEncrypt);
bool ConnectSocket(const nsAString& aDeviceAddress,
const BluetoothUuid& aServiceUuid,
int aChannel);
bool ListenSocket(const nsAString& aServiceName,
const BluetoothUuid& aServiceUuid,
int aChannel);
int aChannel,
bool aAuth, bool aEncrypt);
/**
* Method to be called whenever data is received. This is only called on the
@ -74,8 +75,6 @@ private:
BluetoothSocketResultHandler* mCurrentRes;
DroidSocketImpl* mImpl;
nsString mDeviceAddress;
bool mAuth;
bool mEncrypt;
};
END_BLUETOOTH_NAMESPACE

View File

@ -483,10 +483,7 @@ BluetoothHfpManager::Init()
Listen();
mScoSocket = new BluetoothSocket(this,
BluetoothSocketType::SCO,
true,
false);
mScoSocket = new BluetoothSocket(this);
mScoSocketStatus = mScoSocket->GetConnectionStatus();
ListenSco();
return true;
@ -1150,18 +1147,17 @@ BluetoothHfpManager::Connect(const nsAString& aDeviceAddress,
// Stop listening because currently we only support one connection at a time.
if (mHandsfreeSocket) {
mHandsfreeSocket->Disconnect();
mHandsfreeSocket->Close();
mHandsfreeSocket = nullptr;
}
if (mHeadsetSocket) {
mHeadsetSocket->Disconnect();
mHeadsetSocket->Close();
mHeadsetSocket = nullptr;
}
mController = aController;
mSocket =
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
mSocket = new BluetoothSocket(this);
}
bool
@ -1180,13 +1176,16 @@ BluetoothHfpManager::Listen()
}
if (!mHandsfreeSocket) {
mHandsfreeSocket =
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
mHandsfreeSocket = new BluetoothSocket(this);
if (!mHandsfreeSocket->Listen(
NS_LITERAL_STRING("Handsfree Audio Gateway"),
kHandsfreeAG,
BluetoothReservedChannels::CHANNEL_HANDSFREE_AG)) {
nsresult rv = mHandsfreeSocket->Listen(
NS_LITERAL_STRING("Handsfree Audio Gateway"),
kHandsfreeAG,
BluetoothSocketType::RFCOMM,
BluetoothReservedChannels::CHANNEL_HANDSFREE_AG,
true, true);
if (NS_FAILED(rv)) {
BT_WARNING("[HFP] Can't listen on RFCOMM socket!");
mHandsfreeSocket = nullptr;
return false;
@ -1194,15 +1193,18 @@ BluetoothHfpManager::Listen()
}
if (!mHeadsetSocket) {
mHeadsetSocket =
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
mHeadsetSocket = new BluetoothSocket(this);
if (!mHeadsetSocket->Listen(
NS_LITERAL_STRING("Headset Audio Gateway"),
kHeadsetAG,
BluetoothReservedChannels::CHANNEL_HEADSET_AG)) {
nsresult rv = mHeadsetSocket->Listen(
NS_LITERAL_STRING("Headset Audio Gateway"),
kHeadsetAG,
BluetoothSocketType::RFCOMM,
BluetoothReservedChannels::CHANNEL_HEADSET_AG,
true, true);
if (NS_FAILED(rv)) {
BT_WARNING("[HSP] Can't listen on RFCOMM socket!");
mHandsfreeSocket->Disconnect();
mHandsfreeSocket->Close();
mHandsfreeSocket = nullptr;
mHeadsetSocket = nullptr;
return false;
@ -1227,7 +1229,7 @@ BluetoothHfpManager::Disconnect(BluetoothProfileController* aController)
MOZ_ASSERT(!mController);
mController = aController;
mSocket->Disconnect();
mSocket->Close();
}
#ifdef MOZ_B2G_RIL
@ -1796,14 +1798,14 @@ BluetoothHfpManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
mIsHsp = false;
mHandsfreeSocket.swap(mSocket);
mHeadsetSocket->Disconnect();
mHeadsetSocket->Close();
mHeadsetSocket = nullptr;
} else if (aSocket == mHeadsetSocket) {
MOZ_ASSERT(!mSocket);
mIsHsp = true;
mHeadsetSocket.swap(mSocket);
mHandsfreeSocket->Disconnect();
mHandsfreeSocket->Close();
mHandsfreeSocket = nullptr;
}
@ -1904,9 +1906,12 @@ BluetoothHfpManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
MOZ_ASSERT(mSocket);
if (!mSocket->Connect(aDeviceAddress,
mIsHsp? kHeadsetAG : kHandsfreeAG,
aChannel)) {
nsresult rv = mSocket->Connect(aDeviceAddress,
mIsHsp? kHeadsetAG : kHandsfreeAG,
BluetoothSocketType::RFCOMM,
aChannel,
true, true);
if (NS_FAILED(rv)) {
OnConnect(NS_LITERAL_STRING(ERR_CONNECTION_FAILED));
}
}
@ -1990,9 +1995,11 @@ BluetoothHfpManager::ConnectSco(BluetoothReplyRunnable* aRunnable)
}
// Stop listening
mScoSocket->Disconnect();
mScoSocket->Close();
mScoSocket->Connect(mDeviceAddress, kUnknownService, -1);
mScoSocket->Connect(mDeviceAddress, kUnknownService,
BluetoothSocketType::SCO,
-1, true, false);
mScoSocketStatus = mScoSocket->GetConnectionStatus();
mScoRunnable = aRunnable;
@ -2007,7 +2014,7 @@ BluetoothHfpManager::DisconnectSco()
return false;
}
mScoSocket->Disconnect();
mScoSocket->Close();
return true;
}
@ -2027,10 +2034,15 @@ BluetoothHfpManager::ListenSco()
return false;
}
mScoSocket->Disconnect();
mScoSocket->Close();
if (!mScoSocket->Listen(NS_LITERAL_STRING("Handsfree Audio Gateway SCO"),
kUnknownService, -1)) {
nsresult rv = mScoSocket->Listen(
NS_LITERAL_STRING("Handsfree Audio Gateway SCO"),
kUnknownService,
BluetoothSocketType::SCO,
-1, true, false);
if (NS_FAILED(rv)) {
BT_WARNING("Can't listen on SCO socket!");
return false;
}

View File

@ -185,7 +185,7 @@ public:
if (mSocket->GetConnectionStatus() ==
SocketConnectionStatus::SOCKET_CONNECTED) {
mSocket->Disconnect();
mSocket->Close();
}
}
@ -193,25 +193,27 @@ private:
nsRefPtr<BluetoothSocket> mSocket;
};
BluetoothOppManager::BluetoothOppManager() : mConnected(false)
, mRemoteObexVersion(0)
, mRemoteConnectionFlags(0)
, mRemoteMaxPacketLength(0)
, mLastCommand(0)
, mPacketLength(0)
, mPutPacketReceivedLength(0)
, mBodySegmentLength(0)
, mAbortFlag(false)
, mNewFileFlag(false)
, mPutFinalFlag(false)
, mSendTransferCompleteFlag(false)
, mSuccessFlag(false)
, mIsServer(true)
, mWaitingForConfirmationFlag(false)
, mFileLength(0)
, mSentFileLength(0)
, mWaitingToSendPutFinal(false)
, mCurrentBlobIndex(-1)
BluetoothOppManager::BluetoothOppManager()
: mConnected(false)
, mRemoteObexVersion(0)
, mRemoteConnectionFlags(0)
, mRemoteMaxPacketLength(0)
, mLastCommand(0)
, mPacketLength(0)
, mPutPacketReceivedLength(0)
, mBodySegmentLength(0)
, mAbortFlag(false)
, mNewFileFlag(false)
, mPutFinalFlag(false)
, mSendTransferCompleteFlag(false)
, mSuccessFlag(false)
, mIsServer(true)
, mWaitingForConfirmationFlag(false)
, mFileLength(0)
, mSentFileLength(0)
, mWaitingToSendPutFinal(false)
, mCurrentBlobIndex(-1)
, mSocketType(static_cast<BluetoothSocketType>(0))
{
mConnectedDeviceAddress.AssignLiteral(BLUETOOTH_ADDRESS_NONE);
}
@ -269,12 +271,12 @@ BluetoothOppManager::ConnectInternal(const nsAString& aDeviceAddress)
// Stop listening because currently we only support one connection at a time.
if (mRfcommSocket) {
mRfcommSocket->Disconnect();
mRfcommSocket->Close();
mRfcommSocket = nullptr;
}
if (mL2capSocket) {
mL2capSocket->Disconnect();
mL2capSocket->Close();
mL2capSocket = nullptr;
}
@ -296,8 +298,8 @@ BluetoothOppManager::ConnectInternal(const nsAString& aDeviceAddress)
return;
}
mSocket =
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
mSocket = new BluetoothSocket(this);
mSocketType = BluetoothSocketType::RFCOMM;
}
void
@ -320,12 +322,16 @@ BluetoothOppManager::Listen()
}
if (!mRfcommSocket) {
mRfcommSocket =
new BluetoothSocket(this, BluetoothSocketType::RFCOMM, true, true);
mRfcommSocket = new BluetoothSocket(this);
if (!mRfcommSocket->Listen(NS_LITERAL_STRING("OBEX Object Push"),
kObexObjectPush,
BluetoothReservedChannels::CHANNEL_OPUSH)) {
nsresult rv = mRfcommSocket->Listen(
NS_LITERAL_STRING("OBEX Object Push"),
kObexObjectPush,
BluetoothSocketType::RFCOMM,
BluetoothReservedChannels::CHANNEL_OPUSH,
true, true);
if (NS_FAILED(rv)) {
BT_WARNING("[OPP] Can't listen on RFCOMM socket!");
mRfcommSocket = nullptr;
return false;
@ -333,14 +339,18 @@ BluetoothOppManager::Listen()
}
if (!mL2capSocket) {
mL2capSocket =
new BluetoothSocket(this, BluetoothSocketType::EL2CAP, true, true);
mL2capSocket = new BluetoothSocket(this);
if (!mL2capSocket->Listen(NS_LITERAL_STRING("OBEX Object Push"),
kObexObjectPush,
BluetoothReservedChannels::CHANNEL_OPUSH_L2CAP)) {
nsresult rv = mL2capSocket->Listen(
NS_LITERAL_STRING("OBEX Object Push"),
kObexObjectPush,
BluetoothSocketType::EL2CAP,
BluetoothReservedChannels::CHANNEL_OPUSH_L2CAP,
true, true);
if (NS_FAILED(rv)) {
BT_WARNING("[OPP] Can't listen on L2CAP socket!");
mRfcommSocket->Disconnect();
mRfcommSocket->Close();
mRfcommSocket = nullptr;
mL2capSocket = nullptr;
return false;
@ -1532,14 +1542,16 @@ BluetoothOppManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
if (aSocket == mRfcommSocket) {
MOZ_ASSERT(!mSocket);
mRfcommSocket.swap(mSocket);
mSocketType = BluetoothSocketType::RFCOMM;
mL2capSocket->Disconnect();
mL2capSocket->Close();
mL2capSocket = nullptr;
} else if (aSocket == mL2capSocket) {
MOZ_ASSERT(!mSocket);
mL2capSocket.swap(mSocket);
mSocketType = BluetoothSocketType::EL2CAP;
mRfcommSocket->Disconnect();
mRfcommSocket->Close();
mRfcommSocket = nullptr;
}
@ -1561,6 +1573,7 @@ BluetoothOppManager::OnSocketConnectError(BluetoothSocket* aSocket)
mRfcommSocket = nullptr;
mL2capSocket = nullptr;
mSocket = nullptr;
mSocketType = static_cast<BluetoothSocketType>(0);
if (!mIsServer) {
// Inform gaia of remaining blobs' sending failure
@ -1608,6 +1621,8 @@ BluetoothOppManager::OnSocketDisconnect(BluetoothSocket* aSocket)
mSuccessFlag = false;
mSocket = nullptr;
mSocketType = static_cast<BluetoothSocketType>(0);
// Listen as a server if there's no more batch to process
if (!ProcessNextBatch()) {
Listen();
@ -1618,7 +1633,7 @@ void
BluetoothOppManager::Disconnect(BluetoothProfileController* aController)
{
if (mSocket) {
mSocket->Disconnect();
mSocket->Close();
} else {
BT_WARNING("%s: No ongoing file transfer to stop", __FUNCTION__);
}
@ -1654,7 +1669,9 @@ BluetoothOppManager::OnGetServiceChannel(const nsAString& aDeviceAddress,
return;
}
if (!mSocket->Connect(aDeviceAddress, kObexObjectPush, aChannel)) {
nsresult rv = mSocket->Connect(aDeviceAddress, kObexObjectPush,
mSocketType, aChannel, true, true);
if (NS_FAILED(rv)) {
OnSocketConnectError(mSocket);
}
}

View File

@ -219,6 +219,8 @@ private:
nsRefPtr<BluetoothSocket> mRfcommSocket;
nsRefPtr<BluetoothSocket> mL2capSocket;
BluetoothSocketType mSocketType;
// This holds the time when OPP manager fail to get service channel and
// prepare to refresh SDP records.
mozilla::TimeStamp mLastServiceChannelCheck;

View File

@ -557,14 +557,8 @@ public:
// BluetoothSocket
//
BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
BluetoothSocketType aType,
bool aAuth,
bool aEncrypt)
BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver)
: mObserver(aObserver)
, mType(aType)
, mAuth(aAuth)
, mEncrypt(aEncrypt)
, mIO(nullptr)
{
MOZ_ASSERT(aObserver);
@ -575,50 +569,57 @@ BluetoothSocket::~BluetoothSocket()
MOZ_ASSERT(!mIO);
}
bool
nsresult
BluetoothSocket::Connect(const nsAString& aDeviceAddress,
const BluetoothUuid& aServiceUuid,
int aChannel)
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
nsAutoPtr<BluetoothUnixSocketConnector> c(
nsAutoPtr<BluetoothUnixSocketConnector> connector(
new BluetoothUnixSocketConnector(NS_ConvertUTF16toUTF8(aDeviceAddress),
mType, aChannel, mAuth, mEncrypt));
aType, aChannel, aAuth, aEncrypt));
if (!ConnectSocket(c.forget(),
NS_ConvertUTF16toUTF8(aDeviceAddress).BeginReading())) {
nsresult rv = Connect(connector);
if (NS_FAILED(rv)) {
nsAutoString addr;
GetAddress(addr);
BT_LOGD("%s failed. Current connected device address: %s",
__FUNCTION__, NS_ConvertUTF16toUTF8(addr).get());
return false;
return rv;
}
connector.forget();
return true;
return NS_OK;
}
bool
nsresult
BluetoothSocket::Listen(const nsAString& aServiceName,
const BluetoothUuid& aServiceUuid,
int aChannel)
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt)
{
MOZ_ASSERT(NS_IsMainThread());
nsAutoPtr<BluetoothUnixSocketConnector> c(
nsAutoPtr<BluetoothUnixSocketConnector> connector(
new BluetoothUnixSocketConnector(NS_LITERAL_CSTRING(BLUETOOTH_ADDRESS_NONE),
mType, aChannel, mAuth, mEncrypt));
aType, aChannel, aAuth, aEncrypt));
if (!ListenSocket(c.forget())) {
nsresult rv = Listen(connector);
if (NS_FAILED(rv)) {
nsAutoString addr;
GetAddress(addr);
BT_LOGD("%s failed. Current connected device address: %s",
__FUNCTION__, NS_ConvertUTF16toUTF8(addr).get());
return false;
return rv;
}
connector.forget();
return true;
return NS_OK;
}
void
@ -642,34 +643,16 @@ BluetoothSocket::SendSocketData(const nsACString& aStr)
return true;
}
void
BluetoothSocket::GetSocketAddr(nsAString& aAddrStr)
nsresult
BluetoothSocket::Connect(BluetoothUnixSocketConnector* aConnector,
int aDelayMs)
{
aAddrStr.Truncate();
if (!mIO || GetConnectionStatus() != SOCKET_CONNECTED) {
NS_WARNING("No socket currently open!");
return;
}
mIO->GetSocketAddr(aAddrStr);
}
bool
BluetoothSocket::ConnectSocket(BluetoothUnixSocketConnector* aConnector,
const char* aAddress,
int aDelayMs)
{
MOZ_ASSERT(aConnector);
MOZ_ASSERT(NS_IsMainThread());
nsAutoPtr<UnixSocketConnector> connector(aConnector);
if (mIO) {
NS_WARNING("Socket already connecting/connected!");
return false;
}
MOZ_ASSERT(aConnector);
MOZ_ASSERT(!mIO);
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
mIO = new BluetoothSocketIO(ioLoop, this, connector.forget());
mIO = new BluetoothSocketIO(ioLoop, this, aConnector);
SetConnectionStatus(SOCKET_CONNECTING);
if (aDelayMs > 0) {
DelayedConnectTask* connectTask = new DelayedConnectTask(mIO);
@ -678,29 +661,34 @@ BluetoothSocket::ConnectSocket(BluetoothUnixSocketConnector* aConnector,
} else {
ioLoop->PostTask(FROM_HERE, new ConnectTask(mIO));
}
return true;
return NS_OK;
}
bool
BluetoothSocket::ListenSocket(BluetoothUnixSocketConnector* aConnector)
nsresult
BluetoothSocket::Listen(BluetoothUnixSocketConnector* aConnector)
{
MOZ_ASSERT(aConnector);
MOZ_ASSERT(NS_IsMainThread());
nsAutoPtr<UnixSocketConnector> connector(aConnector);
if (mIO) {
NS_WARNING("Socket already connecting/connected!");
return false;
}
MOZ_ASSERT(aConnector);
MOZ_ASSERT(!mIO);
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
mIO = new BluetoothSocketIO(ioLoop, this, connector.forget());
mIO = new BluetoothSocketIO(ioLoop, this, aConnector);
SetConnectionStatus(SOCKET_LISTENING);
ioLoop->PostTask(FROM_HERE, new ListenTask(mIO));
return true;
return NS_OK;
}
void
BluetoothSocket::GetAddress(nsAString& aAddrStr)
{
aAddrStr.Truncate();
if (!mIO || GetConnectionStatus() != SOCKET_CONNECTED) {
NS_WARNING("No socket currently open!");
return;
}
mIO->GetSocketAddr(aAddrStr);
}
// |DataSocket|

View File

@ -24,27 +24,20 @@ class BluetoothUnixSocketConnector;
class BluetoothSocket final : public mozilla::ipc::DataSocket
{
public:
BluetoothSocket(BluetoothSocketObserver* aObserver,
BluetoothSocketType aType,
bool aAuth,
bool aEncrypt);
BluetoothSocket(BluetoothSocketObserver* aObserver);
~BluetoothSocket();
bool Connect(const nsAString& aDeviceAddress,
const BluetoothUuid& aServiceUuid,
int aChannel);
bool Listen(const nsAString& aServiceName,
const BluetoothUuid& aServiceUuid,
int aChannel);
inline void Disconnect()
{
Close();
}
nsresult Connect(const nsAString& aDeviceAddress,
const BluetoothUuid& aServiceUuid,
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt);
inline void GetAddress(nsAString& aDeviceAddress)
{
GetSocketAddr(aDeviceAddress);
}
nsresult Listen(const nsAString& aServiceName,
const BluetoothUuid& aServiceUuid,
BluetoothSocketType aType,
int aChannel,
bool aAuth, bool aEncrypt);
/**
* Method to be called whenever data is received. This is only called on the
@ -70,29 +63,27 @@ public:
* non-blocking manner.
*
* @param aConnector Connector object for socket type specific functions
* @param aAddress Address to connect to.
* @param aDelayMs Time delay in milli-seconds.
*
* @return true on connect task started, false otherwise.
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
bool ConnectSocket(BluetoothUnixSocketConnector* aConnector,
const char* aAddress,
int aDelayMs = 0);
nsresult Connect(BluetoothUnixSocketConnector* aConnector,
int aDelayMs = 0);
/**
* Starts a task on the socket that will try to accept a new connection in a
* non-blocking manner.
*
* @param aConnector Connector object for socket type specific functions
*
* @return true on listen started, false otherwise
* @return NS_OK on success, or an XPCOM error code otherwise.
*/
bool ListenSocket(BluetoothUnixSocketConnector* aConnector);
nsresult Listen(BluetoothUnixSocketConnector* aConnector);
/**
* Get the current sockaddr for the socket
* Get the current socket address.
*
* @param[out] aDeviceAddress Returns the address string.
*/
void GetSocketAddr(nsAString& aAddrStr);
void GetAddress(nsAString& aDeviceAddress);
// Methods for |DataSocket|
//
@ -115,9 +106,6 @@ private:
class ListenTask;
BluetoothSocketObserver* mObserver;
BluetoothSocketType mType;
bool mAuth;
bool mEncrypt;
BluetoothSocketIO* mIO;
};

View File

@ -78,9 +78,13 @@ BluetoothUnixSocketConnector::CreateSocket(int& aFd) const
MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sType));
MOZ_ASSERT(mType < MOZ_ARRAY_LENGTH(sProtocol));
BT_LOGR("mType=%d, sType=%d sProtocol=%d",
static_cast<int>(mType), sType[mType], sProtocol[mType]);
aFd = socket(AF_BLUETOOTH, sType[mType], sProtocol[mType]);
if (aFd < 0) {
BT_LOGR("Could not open Bluetooth socket!");
BT_LOGR("Could not open Bluetooth socket: %d(%s)",
errno, strerror(errno));
return NS_ERROR_FAILURE;
}
@ -320,6 +324,9 @@ BluetoothUnixSocketConnector::ConvertAddressToString(
b = l2->l2_bdaddr.b;
}
break;
default:
BT_LOGR("Unknown socket type %d", static_cast<int>(mType));
return NS_ERROR_ILLEGAL_VALUE;
}
char str[32];

View File

@ -5,9 +5,27 @@ MARIONETTE_TIMEOUT = 90000;
MARIONETTE_HEAD_JS = "head.js";
let TEST_ADD_DATA = [{
name: ["add"],
// a contact without email and anr.
name: ["add1"],
tel: [{value: "0912345678"}],
email:[]
}, {
// a contact over 20 digits.
name: ["add2"],
tel: [{value: "012345678901234567890123456789"}],
}, {
// a contact with email but without anr.
name: ["add3"],
tel: [{value: "01234567890123456789"}],
email:[{value: "test@mozilla.com"}],
}, {
// a contact with anr but without email.
name: ["add4"],
tel: [{value: "01234567890123456789"}, {value: "123456"}, {value: "123"}],
}, {
// a contact with email and anr.
name: ["add5"],
tel: [{value: "01234567890123456789"}, {value: "123456"}, {value: "123"}],
email:[{value: "test@mozilla.com"}],
}];
function testAddContact(aIcc, aType, aMozContact, aPin2) {
@ -17,7 +35,11 @@ function testAddContact(aIcc, aType, aMozContact, aPin2) {
return aIcc.updateContact(aType, contact, aPin2)
.then((aResult) => {
is(aResult.name[0], aMozContact.name[0]);
is(aResult.tel[0].value, aMozContact.tel[0].value);
// Maximum digits of the Dialling Number is 20.
is(aResult.tel[0].value, aMozContact.tel[0].value.substring(0, 20));
// We only support SIM in emulator, so we don't have anr and email field.
ok(aResult.tel.length == 1);
ok(!aResult.email);
// Get ICC contact for checking new contact
return aIcc.readContacts(aType)
@ -25,7 +47,8 @@ function testAddContact(aIcc, aType, aMozContact, aPin2) {
let contact = aResult[aResult.length - 1];
is(contact.name[0], aMozContact.name[0]);
is(contact.tel[0].value, aMozContact.tel[0].value);
// Maximum digits of the Dialling Number is 20.
is(contact.tel[0].value, aMozContact.tel[0].value.substring(0, 20));
is(contact.id, aIcc.iccInfo.iccid + aResult.length);
return contact.id;

View File

@ -797,10 +797,11 @@ RilObject.prototype = {
* @param requestId Request id from RadioInterfaceLayer.
*/
updateICCContact: function(options) {
let onsuccess = function onsuccess() {
let onsuccess = function onsuccess(updatedContact) {
let recordIndex =
contact.pbrIndex * ICC_MAX_LINEAR_FIXED_RECORDS + contact.recordId;
contact.contactId = this.iccInfo.iccid + recordIndex;
updatedContact.pbrIndex * ICC_MAX_LINEAR_FIXED_RECORDS + updatedContact.recordId;
updatedContact.contactId = this.iccInfo.iccid + recordIndex;
options.contact = updatedContact;
// Reuse 'options' to get 'requestId' and 'contactType'.
this.sendChromeMessage(options);
}.bind(this);
@ -9358,6 +9359,8 @@ ICCPDUHelperObject.prototype = {
* @param numOctets Number of total octets to be writen, including trailing
* 0xff.
* @param str String to be written. Could be null.
*
* @return The string has been written into Buf.
*/
writeStringTo8BitUnpacked: function(numOctets, str) {
const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
@ -9396,6 +9399,8 @@ ICCPDUHelperObject.prototype = {
while (j++ < numOctets) {
GsmPDUHelper.writeHexOctet(0xff);
}
return (str) ? str.substring(0, i) : null;
},
/**
@ -9409,6 +9414,7 @@ ICCPDUHelperObject.prototype = {
* @param str
* String to be written.
*
* @return The string has been written into Buf.
*/
writeICCUCS2String: function(numOctets, str) {
let GsmPDUHelper = this.context.GsmPDUHelper;
@ -9468,7 +9474,7 @@ ICCPDUHelperObject.prototype = {
for (let i = str.length * 2; i < numOctets; i++) {
GsmPDUHelper.writeHexOctet(0xff);
}
return;
return str;
}
/**
* +------+-----+--------------+-----+-----+-----+--------+------+
@ -9541,6 +9547,7 @@ ICCPDUHelperObject.prototype = {
GsmPDUHelper.writeHexOctet(0xff);
}
}
return str;
},
/**
@ -9675,6 +9682,9 @@ ICCPDUHelperObject.prototype = {
* @param recordSize The size of linear fixed record.
* @param alphaId Alpha Identifier to be written.
* @param number Dialling Number to be written.
*
* @return An object contains the alphaId and number
* that have been written into Buf.
*/
writeAlphaIdDiallingNumber: function(recordSize, alphaId, number) {
let Buf = this.context.Buf;
@ -9685,13 +9695,16 @@ ICCPDUHelperObject.prototype = {
Buf.writeInt32(strLen);
let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
this.writeAlphaIdentifier(alphaLen, alphaId);
this.writeNumberWithLength(number);
let writtenAlphaId = this.writeAlphaIdentifier(alphaLen, alphaId);
let writtenNumber = this.writeNumberWithLength(number);
// Write unused octets 0xff, CCP and EXT1.
GsmPDUHelper.writeHexOctet(0xff);
GsmPDUHelper.writeHexOctet(0xff);
Buf.writeStringDelimiter(strLen);
return {alphaId: writtenAlphaId,
number: writtenNumber};
},
/**
@ -9736,18 +9749,20 @@ ICCPDUHelperObject.prototype = {
* @param alphaId
* Alpha Identifier to be written.
*
* @return The Alpha Identifier has been written into Buf.
*
* Unused octets will be written as 0xff.
*/
writeAlphaIdentifier: function(numOctets, alphaId) {
if (numOctets === 0) {
return;
return null;
}
// If alphaId is empty or it's of GSM 8 bit.
if (!alphaId || this.context.ICCUtilsHelper.isGsm8BitAlphabet(alphaId)) {
this.writeStringTo8BitUnpacked(numOctets, alphaId);
return this.writeStringTo8BitUnpacked(numOctets, alphaId);
} else {
this.writeICCUCS2String(numOctets, alphaId);
return this.writeICCUCS2String(numOctets, alphaId);
}
},
@ -9834,37 +9849,45 @@ ICCPDUHelperObject.prototype = {
return number;
},
/**
* Write Number with Length
*
* @param number The value to be written.
*
* @return The number has been written into Buf.
*/
writeNumberWithLength: function(number) {
let GsmPDUHelper = this.context.GsmPDUHelper;
if (number) {
let numStart = number[0] == "+" ? 1 : 0;
number = number.substring(0, numStart) +
number.substring(numStart)
.replace(/[^0-9*#,]/g, "")
.replace(/\*/g, "a")
.replace(/\#/g, "b")
.replace(/\,/g, "c");
let writtenNumber = number.substring(0, numStart) +
number.substring(numStart)
.replace(/[^0-9*#,]/g, "");
let numDigits = number.length - numStart;
let numDigits = writtenNumber.length - numStart;
if (numDigits > ADN_MAX_NUMBER_DIGITS) {
number = number.substring(0, ADN_MAX_NUMBER_DIGITS + numStart);
numDigits = number.length - numStart;
writtenNumber = writtenNumber.substring(0, ADN_MAX_NUMBER_DIGITS + numStart);
numDigits = writtenNumber.length - numStart;
}
// +1 for TON/NPI
let numLen = Math.ceil(numDigits / 2) + 1;
GsmPDUHelper.writeHexOctet(numLen);
this.writeDiallingNumber(number);
this.writeDiallingNumber(writtenNumber.replace(/\*/g, "a")
.replace(/\#/g, "b")
.replace(/\,/g, "c"));
// Write trailing 0xff of Dialling Number.
for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES - numLen; i++) {
GsmPDUHelper.writeHexOctet(0xff);
}
return writtenNumber;
} else {
// +1 for numLen
for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES + 1; i++) {
GsmPDUHelper.writeHexOctet(0xff);
}
return null;
}
}
};
@ -12268,15 +12291,16 @@ ICCRecordHelperObject.prototype = {
* @param onerror Callback to be called when error.
*/
updateADNLike: function(fileId, contact, pin2, onsuccess, onerror) {
let updatedContact;
function dataWriter(recordSize) {
this.context.ICCPDUHelper.writeAlphaIdDiallingNumber(recordSize,
contact.alphaId,
contact.number);
updatedContact = this.context.ICCPDUHelper.writeAlphaIdDiallingNumber(recordSize,
contact.alphaId,
contact.number);
}
function callback(options) {
if (onsuccess) {
onsuccess();
onsuccess(updatedContact);
}
}
@ -12511,6 +12535,7 @@ ICCRecordHelperObject.prototype = {
updateEmail: function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
let fileId = pbr[USIM_PBR_EMAIL].fileId;
let fileType = pbr[USIM_PBR_EMAIL].fileType;
let writtenEmail;
let dataWriter = function dataWriter(recordSize) {
let Buf = this.context.Buf;
let GsmPDUHelper = this.context.GsmPDUHelper;
@ -12521,9 +12546,9 @@ ICCRecordHelperObject.prototype = {
Buf.writeInt32(strLen);
if (fileType == ICC_USIM_TYPE1_TAG) {
ICCPDUHelper.writeStringTo8BitUnpacked(recordSize, email);
writtenEmail = ICCPDUHelper.writeStringTo8BitUnpacked(recordSize, email);
} else {
ICCPDUHelper.writeStringTo8BitUnpacked(recordSize - 2, email);
writtenEmail = ICCPDUHelper.writeStringTo8BitUnpacked(recordSize - 2, email);
GsmPDUHelper.writeHexOctet(pbr.adn.sfi || 0xff);
GsmPDUHelper.writeHexOctet(adnRecordId);
}
@ -12531,11 +12556,17 @@ ICCRecordHelperObject.prototype = {
Buf.writeStringDelimiter(strLen);
}.bind(this);
let callback = (options) => {
if (onsuccess) {
onsuccess(writtenEmail);
}
}
this.context.ICCIOHelper.updateLinearFixedEF({
fileId: fileId,
recordNumber: recordNumber,
dataWriter: dataWriter,
callback: onsuccess,
callback: callback,
onerror: onerror
});
},
@ -12608,6 +12639,7 @@ ICCRecordHelperObject.prototype = {
updateANR: function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
let fileId = pbr[USIM_PBR_ANR0].fileId;
let fileType = pbr[USIM_PBR_ANR0].fileType;
let writtenNumber;
let dataWriter = function dataWriter(recordSize) {
let Buf = this.context.Buf;
let GsmPDUHelper = this.context.GsmPDUHelper;
@ -12619,7 +12651,7 @@ ICCRecordHelperObject.prototype = {
// EF_AAS record Id. Unused for now.
GsmPDUHelper.writeHexOctet(0xff);
this.context.ICCPDUHelper.writeNumberWithLength(number);
writtenNumber = this.context.ICCPDUHelper.writeNumberWithLength(number);
// Write unused octets 0xff, CCP and EXT1.
GsmPDUHelper.writeHexOctet(0xff);
@ -12634,11 +12666,17 @@ ICCRecordHelperObject.prototype = {
Buf.writeStringDelimiter(strLen);
}.bind(this);
let callback = (options) => {
if (onsuccess) {
onsuccess(writtenNumber);
}
}
this.context.ICCIOHelper.updateLinearFixedEF({
fileId: fileId,
recordNumber: recordNumber,
dataWriter: dataWriter,
callback: onsuccess,
callback: callback,
onerror: onerror
});
},
@ -14760,12 +14798,18 @@ ICCContactHelperObject.prototype = {
let ICCRecordHelper = this.context.ICCRecordHelper;
let ICCUtilsHelper = this.context.ICCUtilsHelper;
let updateContactCb = (updatedContact) => {
updatedContact.pbrIndex = contact.pbrIndex;
updatedContact.recordId = contact.recordId;
onsuccess(updatedContact);
}
switch (contactType) {
case GECKO_CARDCONTACT_TYPE_ADN:
if (!this.hasDfPhoneBook(appType)) {
ICCRecordHelper.updateADNLike(ICC_EF_ADN, contact, null, onsuccess, onerror);
ICCRecordHelper.updateADNLike(ICC_EF_ADN, contact, null, updateContactCb, onerror);
} else {
this.updateUSimContact(contact, onsuccess, onerror);
this.updateUSimContact(contact, updateContactCb, onerror);
}
break;
case GECKO_CARDCONTACT_TYPE_FDN:
@ -14777,7 +14821,7 @@ ICCContactHelperObject.prototype = {
onerror(CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED);
break;
}
ICCRecordHelper.updateADNLike(ICC_EF_FDN, contact, pin2, onsuccess, onerror);
ICCRecordHelper.updateADNLike(ICC_EF_FDN, contact, pin2, updateContactCb, onerror);
break;
default:
if (DEBUG) {
@ -15037,8 +15081,10 @@ ICCContactHelperObject.prototype = {
* @param onerror Callback to be called when error.
*/
updatePhonebookSet: function(pbr, contact, onsuccess, onerror) {
let updateAdnCb = function() {
this.updateSupportedPBRFields(pbr, contact, onsuccess, onerror);
let updateAdnCb = function(updatedContact) {
this.updateSupportedPBRFields(pbr, contact, (updatedContactField) => {
onsuccess(Object.assign(updatedContact, updatedContactField));
}, onerror);
}.bind(this);
this.context.ICCRecordHelper.updateADNLike(pbr.adn.fileId, contact, null,
@ -15055,12 +15101,15 @@ ICCContactHelperObject.prototype = {
*/
updateSupportedPBRFields: function(pbr, contact, onsuccess, onerror) {
let fieldIndex = 0;
let contactField = {};
(function updateField() {
let field = USIM_PBR_FIELDS[fieldIndex];
fieldIndex += 1;
if (!field) {
if (onsuccess) {
onsuccess();
onsuccess(contactField);
}
return;
}
@ -15071,7 +15120,10 @@ ICCContactHelperObject.prototype = {
return;
}
this.updateContactField(pbr, contact, field, updateField.bind(this), onerror);
this.updateContactField(pbr, contact, field, (fieldEntry) => {
contactField = Object.assign(contactField, fieldEntry);
updateField.call(this);
}, onerror);
}).call(this);
},
@ -15110,10 +15162,18 @@ ICCContactHelperObject.prototype = {
let ICCRecordHelper = this.context.ICCRecordHelper;
if (field === USIM_PBR_EMAIL) {
ICCRecordHelper.updateEmail(pbr, contact.recordId, contact.email, null, onsuccess, onerror);
ICCRecordHelper.updateEmail(pbr, contact.recordId, contact.email, null,
(updatedEmail) => {
onsuccess({email: updatedEmail});
}, onerror);
} else if (field === USIM_PBR_ANR0) {
let anr = Array.isArray(contact.anr) ? contact.anr[0] : null;
ICCRecordHelper.updateANR(pbr, contact.recordId, anr, null, onsuccess, onerror);
ICCRecordHelper.updateANR(pbr, contact.recordId, anr, null,
(updatedANR) => {
// ANR could have multiple files. If we support more than one anr,
// we will save it as anr0, anr1,...etc.
onsuccess((updatedANR) ? {anr: [updatedANR]} : null);
}, onerror);
} else {
if (DEBUG) {
this.context.debug("Unsupported field :" + field);
@ -15164,10 +15224,18 @@ ICCContactHelperObject.prototype = {
// Case 2.
if (field === USIM_PBR_EMAIL) {
ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId, onsuccess, onerror);
ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId,
(updatedEmail) => {
onsuccess({email: updatedEmail});
}, onerror);
} else if (field === USIM_PBR_ANR0) {
let anr = Array.isArray(contact.anr) ? contact.anr[0] : null;
ICCRecordHelper.updateANR(pbr, recordId, anr, contact.recordId, onsuccess, onerror);
ICCRecordHelper.updateANR(pbr, recordId, anr, contact.recordId,
(updatedANR) => {
// ANR could have multiple files. If we support more than one anr,
// we will save it as anr0, anr1,...etc.
onsuccess((updatedANR) ? {anr: [updatedANR]} : null);
}, onerror);
} else {
if (DEBUG) {
this.context.debug("Unsupported field :" + field);
@ -15191,16 +15259,26 @@ ICCContactHelperObject.prototype = {
*/
addContactFieldType2: function(pbr, contact, field, onsuccess, onerror) {
let ICCRecordHelper = this.context.ICCRecordHelper;
let successCb = function successCb(recordId) {
let updateCb = function updateCb() {
this.updateContactFieldIndexInIAP(pbr, contact.recordId, field, recordId, onsuccess, onerror);
let updateCb = function updateCb(contactField) {
this.updateContactFieldIndexInIAP(pbr, contact.recordId, field, recordId, () => {
onsuccess(contactField);
}, onerror);
}.bind(this);
if (field === USIM_PBR_EMAIL) {
ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId, updateCb, onerror);
ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId,
(updatedEmail) => {
updateCb({email: updatedEmail});
}, onerror);
} else if (field === USIM_PBR_ANR0) {
ICCRecordHelper.updateANR(pbr, recordId, contact.anr[0], contact.recordId, updateCb, onerror);
ICCRecordHelper.updateANR(pbr, recordId, contact.anr[0], contact.recordId,
(updatedANR) => {
// ANR could have multiple files. If we support more than one anr,
// we will save it as anr0, anr1,...etc.
updateCb((updatedANR) ? {anr: [updatedANR]} : null);
}, onerror);
}
}.bind(this);

View File

@ -447,7 +447,8 @@ add_test(function test_update_icc_contact() {
equal(pin2, aPin2);
equal(contact.alphaId, aContact.alphaId);
equal(contact.number, aContact.number);
onsuccess();
onsuccess({alphaId: contact.alphaId,
number: contact.number});
};
recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) {
@ -471,7 +472,7 @@ add_test(function test_update_icc_contact() {
equal(recordNumber, EMAIL_RECORD_ID);
}
equal(email, aContact.email);
onsuccess();
onsuccess(email);
};
recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
@ -484,7 +485,7 @@ add_test(function test_update_icc_contact() {
if (Array.isArray(aContact.anr)) {
equal(number, aContact.anr[0]);
}
onsuccess();
onsuccess(number);
};
recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) {
@ -498,7 +499,23 @@ add_test(function test_update_icc_contact() {
};
let isSuccess = false;
let onsuccess = function onsuccess() {
let onsuccess = function onsuccess(updatedContact) {
equal(ADN_RECORD_ID, updatedContact.recordId);
equal(aContact.alphaId, updatedContact.alphaId);
if ((aSimType == CARD_APPTYPE_USIM || aSimType == CARD_APPTYPE_RUIM) &&
(aFileType == ICC_USIM_TYPE1_TAG || aFileType == ICC_USIM_TYPE2_TAG)) {
if (aContact.hasOwnProperty('email')) {
equal(aContact.email, updatedContact.email);
}
if (aContact.hasOwnProperty('anr')) {
equal(aContact.anr[0], updatedContact.anr[0]);
}
} else {
equal(updatedContact.email, null);
equal(updatedContact.anr, null);
}
do_print("updateICCContact success");
isSuccess = true;
};
@ -606,7 +623,8 @@ add_test(function test_update_icc_contact_with_remove_type1_attr() {
let contactHelper = context.ICCContactHelper;
recordHelper.updateADNLike = function(fileId, contact, pin2, onsuccess, onerror) {
onsuccess();
onsuccess({alphaId: contact.alphaId,
number: contact.number});
};
let contact = {
@ -622,12 +640,12 @@ add_test(function test_update_icc_contact_with_remove_type1_attr() {
recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
ok(email == null);
onsuccess();
onsuccess(email);
};
recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
ok(number == null);
onsuccess();
onsuccess(number);
};
function do_test(type) {
@ -652,7 +670,9 @@ add_test(function test_update_icc_contact_with_remove_type1_attr() {
}
};
let successCb = function() {
let successCb = function(updatedContact) {
equal(updatedContact.email, null);
equal(updatedContact.anr, null);
ok(true);
};

View File

@ -93,11 +93,36 @@ add_test(function test_write_icc_ucs2_string() {
for (let i = 0; i < test_data.length; i++) {
let test = test_data[i];
iccHelper.writeICCUCS2String(alphaLen, test.data);
let writtenStr = iccHelper.writeICCUCS2String(alphaLen, test.data);
equal(writtenStr, test.data);
equal(helper.readHexOctet(), test.encode);
equal(iccHelper.readICCUCS2String(test.encode, alphaLen - 1), test.data);
}
// This string use 0x80 encoded and the maximum capacity is 17 octets.
// Each alphabet takes 2 octets, thus the first 8 alphabets can be written.
let str = "Mozilla \u82b3\u8233 On Fire";
let writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
equal(writtenStr, str.substring(0, 8));
equal(helper.readHexOctet(), 0x80);
equal(iccHelper.readICCUCS2String(0x80, alphaLen - 1), str.substring(0, 8));
// This string use 0x81 encoded and the maximum capacity is 15 octets.
// Each alphabet takes 1 octets, thus the first 15 alphabets can be written.
str = "Mozilla \u6901\u697f On Fire";
writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
equal(writtenStr, str.substring(0, 15));
equal(helper.readHexOctet(), 0x81);
equal(iccHelper.readICCUCS2String(0x81, alphaLen - 1), str.substring(0, 15));
// This string use 0x82 encoded and the maximum capacity is 14 octets.
// Each alphabet takes 1 octets, thus the first 14 alphabets can be written.
str = "Mozilla \u0514\u0593 On Fire";
writtenStr = iccHelper.writeICCUCS2String(alphaLen, str);
equal(writtenStr, str.substring(0, 14));
equal(helper.readHexOctet(), 0x82);
equal(iccHelper.readICCUCS2String(0x82, alphaLen - 1), str.substring(0, 14));
run_next_test();
});
/**
@ -207,7 +232,8 @@ add_test(function test_write_string_to_8bit_unpacked() {
let str;
// Test 1, write GSM alphabets.
iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable);
let writtenStr = iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable);
equal(writtenStr, langTable);
for (let i = 0; i < langTable.length; i++) {
equal(helper.readHexOctet(), i);
@ -219,8 +245,8 @@ add_test(function test_write_string_to_8bit_unpacked() {
// Test 2, write GSM extended alphabets.
str = "\u000c\u20ac";
iccHelper.writeStringTo8BitUnpacked(4, str);
writtenStr = iccHelper.writeStringTo8BitUnpacked(4, str);
equal(writtenStr, str);
equal(iccHelper.read8BitUnpackedToString(4), str);
// Test 3, write GSM and GSM extended alphabets.
@ -232,8 +258,8 @@ add_test(function test_write_string_to_8bit_unpacked() {
// 1 octet for 1 gsm alphabet,
// 2 octes for trailing 0xff.
// "Totally 7 octets are to be written."
iccHelper.writeStringTo8BitUnpacked(7, str);
writtenStr = iccHelper.writeStringTo8BitUnpacked(7, str);
equal(writtenStr, str);
equal(iccHelper.read8BitUnpackedToString(7), str);
run_next_test();
@ -252,7 +278,8 @@ add_test(function test_write_string_to_8bit_unpacked_with_max_octets_written() {
// The maximum of the number of octets that can be written is 3.
// Only 3 characters shall be written even the length of the string is 4.
iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4));
let writtenStr = iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4));
equal(writtenStr, langTable.substring(0, 3));
helper.writeHexOctet(0xff); // dummy octet.
for (let i = 0; i < 3; i++) {
equal(helper.readHexOctet(), i);
@ -262,18 +289,21 @@ add_test(function test_write_string_to_8bit_unpacked_with_max_octets_written() {
// \u000c is GSM extended alphabet, 2 octets.
// \u00a3 is GSM alphabet, 1 octet.
let str = "\u000c\u00a3";
iccHelper.writeStringTo8BitUnpacked(3, str);
writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
equal(writtenStr, str.substring(0, 2));
equal(iccHelper.read8BitUnpackedToString(3), str);
str = "\u00a3\u000c";
iccHelper.writeStringTo8BitUnpacked(3, str);
writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
equal(writtenStr, str.substring(0, 2));
equal(iccHelper.read8BitUnpackedToString(3), str);
// 2 GSM extended alphabets cost 4 octets, but maximum is 3, so only the 1st
// alphabet can be written.
str = "\u000c\u000c";
iccHelper.writeStringTo8BitUnpacked(3, str);
writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str);
helper.writeHexOctet(0xff); // dummy octet.
equal(writtenStr, str.substring(0, 1));
equal(iccHelper.read8BitUnpackedToString(4), str.substring(0, 1));
run_next_test();
@ -336,36 +366,42 @@ add_test(function test_write_alpha_identifier() {
let ffLen = 2;
// Removal
iccHelper.writeAlphaIdentifier(10, null);
let writenAlphaId = iccHelper.writeAlphaIdentifier(10, null);
equal(writenAlphaId, null);
equal(iccHelper.readAlphaIdentifier(10), "");
// GSM 8 bit
let str = "Mozilla";
iccHelper.writeAlphaIdentifier(str.length + ffLen, str);
writenAlphaId = iccHelper.writeAlphaIdentifier(str.length + ffLen, str);
equal(writenAlphaId , str);
equal(iccHelper.readAlphaIdentifier(str.length + ffLen), str);
// UCS2
str = "Mozilla\u8000";
iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str);
writenAlphaId = iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str);
equal(writenAlphaId , str);
// * 2 for each character will be encoded to UCS2 alphabets.
equal(iccHelper.readAlphaIdentifier(str.length * 2 + ffLen), str);
// Test with maximum octets written.
// 1 coding scheme (0x80) and 1 UCS2 character, total 3 octets.
str = "\u694a";
iccHelper.writeAlphaIdentifier(3, str);
writenAlphaId = iccHelper.writeAlphaIdentifier(3, str);
equal(writenAlphaId , str);
equal(iccHelper.readAlphaIdentifier(3), str);
// 1 coding scheme (0x80) and 2 UCS2 characters, total 5 octets.
// numOctets is limited to 4, so only 1 UCS2 character can be written.
str = "\u694a\u69ca";
iccHelper.writeAlphaIdentifier(4, str);
writenAlphaId = iccHelper.writeAlphaIdentifier(4, str);
helper.writeHexOctet(0xff); // dummy octet.
equal(writenAlphaId , str.substring(0, 1));
equal(iccHelper.readAlphaIdentifier(5), str.substring(0, 1));
// Write 0 octet.
iccHelper.writeAlphaIdentifier(0, "1");
writenAlphaId = iccHelper.writeAlphaIdentifier(0, "1");
helper.writeHexOctet(0xff); // dummy octet.
equal(writenAlphaId, null);
equal(iccHelper.readAlphaIdentifier(1), "");
run_next_test();
@ -426,28 +462,32 @@ add_test(function test_write_alpha_id_dialling_number() {
alphaId: "Mozilla",
number: "1234567890"
};
helper.writeAlphaIdDiallingNumber(recordSize, contactW.alphaId,
contactW.number);
let writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
contactW.alphaId,
contactW.number);
let contactR = helper.readAlphaIdDiallingNumber(recordSize);
equal(contactW.alphaId, contactR.alphaId);
equal(contactW.number, contactR.number);
equal(writtenContact.alphaId, contactR.alphaId);
equal(writtenContact.number, contactR.number);
// Write a contact with alphaId encoded in UCS2 and number has '+'.
let contactUCS2 = {
alphaId: "火狐",
number: "+1234567890"
};
helper.writeAlphaIdDiallingNumber(recordSize, contactUCS2.alphaId,
contactUCS2.number);
writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
contactUCS2.alphaId,
contactUCS2.number);
contactR = helper.readAlphaIdDiallingNumber(recordSize);
equal(contactUCS2.alphaId, contactR.alphaId);
equal(contactUCS2.number, contactR.number);
equal(writtenContact.alphaId, contactR.alphaId);
equal(writtenContact.number, contactR.number);
// Write a null contact (Removal).
helper.writeAlphaIdDiallingNumber(recordSize);
writtenContact = helper.writeAlphaIdDiallingNumber(recordSize);
contactR = helper.readAlphaIdDiallingNumber(recordSize);
equal(contactR, null);
equal(writtenContact.alphaId, null);
equal(writtenContact.number, null);
// Write a longer alphaId/dialling number
// Dialling Number : Maximum 20 digits(10 octets).
@ -458,19 +498,21 @@ add_test(function test_write_alpha_id_dialling_number() {
alphaId: "AAAAAAAAABBBBBBBBBCCCCCCCCC",
number: "123456789012345678901234567890",
};
helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId,
longContact.number);
writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
longContact.alphaId,
longContact.number);
contactR = helper.readAlphaIdDiallingNumber(recordSize);
equal(contactR.alphaId, "AAAAAAAAABBBBBBBBB");
equal(contactR.number, "12345678901234567890");
equal(writtenContact.alphaId, contactR.alphaId);
equal(writtenContact.number, contactR.number);
// Add '+' to number and test again.
longContact.number = "+123456789012345678901234567890";
helper.writeAlphaIdDiallingNumber(recordSize, longContact.alphaId,
longContact.number);
writtenContact = helper.writeAlphaIdDiallingNumber(recordSize,
longContact.alphaId,
longContact.number);
contactR = helper.readAlphaIdDiallingNumber(recordSize);
equal(contactR.alphaId, "AAAAAAAAABBBBBBBBB");
equal(contactR.number, "+12345678901234567890");
equal(writtenContact.alphaId, contactR.alphaId);
equal(writtenContact.number, contactR.number);
run_next_test();
});
@ -564,7 +606,8 @@ add_test(function test_write_number_with_length() {
function test(number, expectedNumber) {
expectedNumber = expectedNumber || number;
iccHelper.writeNumberWithLength(number);
let writeNumber = iccHelper.writeNumberWithLength(number);
equal(writeNumber, expectedNumber);
let numLen = helper.readHexOctet();
equal(expectedNumber, iccHelper.readDiallingNumber(numLen));
for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES - numLen); i++) {
@ -589,6 +632,9 @@ add_test(function test_write_number_with_length() {
test("++(01)2*3-4#5,6+7(8)9*0#1,", "+012*34#5,6789*0#1,");
// over maximum 20 digits should be truncated.
test("012345678901234567890123456789", "01234567890123456789");
// null
iccHelper.writeNumberWithLength(null);
for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES + 1); i++) {