Merge b2ginbound to m-c a=merge

This commit is contained in:
Wes Kocher 2015-05-01 17:22:34 -07:00
commit ddda6aed2d
68 changed files with 1013 additions and 80 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="07a1a20b86931ee9911b16df94df60a178825bb2"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<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="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="07a1a20b86931ee9911b16df94df60a178825bb2"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>

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="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="07a1a20b86931ee9911b16df94df60a178825bb2"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="07a1a20b86931ee9911b16df94df60a178825bb2"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<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="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="07a1a20b86931ee9911b16df94df60a178825bb2"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<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="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="07a1a20b86931ee9911b16df94df60a178825bb2"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="07a1a20b86931ee9911b16df94df60a178825bb2"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="07a1a20b86931ee9911b16df94df60a178825bb2"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "8e64346ce8197b50b815a294278797bc144aa3e6",
"git_revision": "07a1a20b86931ee9911b16df94df60a178825bb2",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "1bbaa54b674c42e0d8b2fe31d8b0080901811fa0",
"revision": "99b2099a5fa6ac2567993f2c859d651934556464",
"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="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="07a1a20b86931ee9911b16df94df60a178825bb2"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

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="8e64346ce8197b50b815a294278797bc144aa3e6"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="07a1a20b86931ee9911b16df94df60a178825bb2"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -888,6 +888,9 @@ public:
virtual void EnergyInfoNotification(const BluetoothActivityEnergyInfo& aInfo)
{ }
virtual void BackendErrorNotification(bool aCrashed)
{ }
protected:
BluetoothNotificationHandler()
{ }

View File

@ -538,6 +538,7 @@ void
BluetoothA2dpManager::OnDisconnectError()
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE_VOID(mController);
mController->NotifyCompletion(NS_LITERAL_STRING(ERR_DISCONNECTION_FAILED));
}
@ -582,7 +583,9 @@ BluetoothA2dpManager::Disconnect(BluetoothProfileController* aController)
if (!sBtA2dpInterface) {
BT_LOGR("sBluetoothA2dpInterface is null");
aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
if (aController) {
aController->NotifyCompletion(NS_LITERAL_STRING(ERR_NO_AVAILABLE_RESOURCE));
}
return;
}

View File

@ -24,6 +24,8 @@ using namespace mozilla::ipc;
BEGIN_BLUETOOTH_NAMESPACE
static const int sRetryInterval = 100; // ms
//
// Protocol initialization and setup
//
@ -1148,7 +1150,7 @@ private:
nsresult
operator () (nsString& aArg1, nsString& aArg2, uint32_t& aArg3,
BluetoothSspVariant aArg4, uint32_t& aArg5) const
BluetoothSspVariant& aArg4, uint32_t& aArg5) const
{
BluetoothDaemonPDU& pdu = GetPDU();
@ -1749,6 +1751,20 @@ BluetoothDaemonChannel::GetIO()
#define container(_t, _v, _m) \
( (_t*)( ((const unsigned char*)(_v)) - offsetof(_t, _m) ) )
static bool
IsDaemonRunning()
{
char value[PROPERTY_VALUE_MAX];
NS_WARN_IF(property_get("init.svc.bluetoothd", value, "") < 0);
if (strcmp(value, "running")) {
BT_LOGR("[RESTART] Bluetooth daemon state <%s>", value);
return false;
}
return true;
}
BluetoothDaemonInterface*
BluetoothDaemonInterface::GetInstance()
{
@ -1769,6 +1785,42 @@ BluetoothDaemonInterface::BluetoothDaemonInterface()
BluetoothDaemonInterface::~BluetoothDaemonInterface()
{ }
class BluetoothDaemonInterface::StartDaemonTask final : public Task
{
public:
StartDaemonTask(BluetoothDaemonInterface* aInterface,
const nsACString& aCommand)
: mInterface(aInterface)
, mCommand(aCommand)
{
MOZ_ASSERT(mInterface);
}
void Run() override
{
MOZ_ASSERT(NS_IsMainThread());
BT_LOGR("Start Daemon Task");
// Start Bluetooth daemon again
if (NS_WARN_IF(property_set("ctl.start", mCommand.get()) < 0)) {
mInterface->OnConnectError(CMD_CHANNEL);
}
// We're done if Bluetooth daemon is already running
if (IsDaemonRunning()) {
return;
}
// Otherwise try again later
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new StartDaemonTask(mInterface, mCommand), sRetryInterval);
}
private:
BluetoothDaemonInterface* mInterface;
nsCString mCommand;
};
class BluetoothDaemonInterface::InitResultHandler final
: public BluetoothSetupResultHandler
{
@ -1831,6 +1883,19 @@ BluetoothDaemonInterface::OnConnectSuccess(enum Channel aChannel)
if (NS_WARN_IF(property_set("ctl.start", value.get()) < 0)) {
OnConnectError(CMD_CHANNEL);
}
/*
* If Bluetooth daemon is not running, retry to start it later.
*
* This condition happens when when we restart Bluetooth daemon
* immediately after it crashed, as the daemon state remains 'stopping'
* instead of 'stopped'. Due to the limitation of property service,
* hereby add delay. See Bug 1143925 Comment 41.
*/
if (!IsDaemonRunning()) {
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new StartDaemonTask(this, value), sRetryInterval);
}
}
break;
case CMD_CHANNEL:
@ -1890,33 +1955,40 @@ BluetoothDaemonInterface::OnConnectError(enum Channel aChannel)
}
}
/*
* Three cases for restarting:
* a) during startup
* b) during regular service
* c) during shutdown
* For (a)/(c) cases, mResultHandlerQ contains an element, but case (b)
* mResultHandlerQ shall be empty. The following procedure to recover from crashed
* consists of several steps for case (b).
* 1) Close listen socket.
* 2) Wait for all sockets disconnected and inform BluetoothServiceBluedroid to
* perform the regular stop bluetooth procedure.
* 3) When stop bluetooth procedures complete, fire
* AdapterStateChangedNotification to cleanup all necessary data members and
* deinit ProfileManagers.
* 4) After all resources cleanup, call |StartBluetooth|
*/
void
BluetoothDaemonInterface::OnDisconnect(enum Channel aChannel)
{
MOZ_ASSERT(NS_IsMainThread());
if (mResultHandlerQ.IsEmpty()) {
if (sNotificationHandler) {
// Bluetooth daemon crashed; clear state
sNotificationHandler->AdapterStateChangedNotification(false);
sNotificationHandler = nullptr;
}
return;
}
switch (aChannel) {
case CMD_CHANNEL:
// We don't have to do anything here. Step 4 is triggered
// by the daemon.
break;
case NTF_CHANNEL:
// Cleanup, step 4: Close listen socket
// Cleanup, step 4 (Recovery, step 1): Close listen socket
mListenSocket->Close();
break;
case LISTEN_SOCKET: {
case LISTEN_SOCKET:
if (!mResultHandlerQ.IsEmpty()) {
nsRefPtr<BluetoothResultHandler> res = mResultHandlerQ.ElementAt(0);
mResultHandlerQ.RemoveElementAt(0);
// Cleanup, step 5: Signal success to caller
if (res) {
res->Cleanup();
@ -1924,6 +1996,20 @@ BluetoothDaemonInterface::OnDisconnect(enum Channel aChannel)
}
break;
}
/* For recovery make sure all sockets disconnected, in order to avoid
* the remaining disconnects interfere with the restart procedure.
*/
if (sNotificationHandler && mResultHandlerQ.IsEmpty()) {
if (mListenSocket->GetConnectionStatus() == SOCKET_DISCONNECTED &&
mCmdChannel->GetConnectionStatus() == SOCKET_DISCONNECTED &&
mNtfChannel->GetConnectionStatus() == SOCKET_DISCONNECTED) {
// Assume daemon crashed during regular service; notify
// BluetoothServiceBluedroid to prepare restart-daemon procedure
sNotificationHandler->BackendErrorNotification(true);
sNotificationHandler = nullptr;
}
}
}
class BluetoothDaemonSocketConnector final
@ -2198,16 +2284,18 @@ private:
void
BluetoothDaemonInterface::Cleanup(BluetoothResultHandler* aRes)
{
sNotificationHandler = nullptr;
mResultHandlerQ.AppendElement(aRes);
sNotificationHandler = nullptr;
// Cleanup, step 1: Unregister Socket module
nsresult rv = mProtocol->UnregisterModuleCmd(
0x02, new CleanupResultHandler(this));
if (NS_FAILED(rv)) {
DispatchError(aRes, rv);
return;
}
mResultHandlerQ.AppendElement(aRes);
}
void

View File

@ -24,11 +24,13 @@ class BluetoothDaemonInterface final : public BluetoothInterface
public:
class CleanupResultHandler;
class InitResultHandler;
class StartDaemonTask;
friend class BluetoothDaemonListenSocket;
friend class BluetoothDaemonChannel;
friend class CleanupResultHandler;
friend class InitResultHandler;
friend class StartDaemonTask;
static BluetoothDaemonInterface* GetInstance();

View File

@ -102,6 +102,8 @@ static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sGetDeviceRunnableArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sFetchUuidsRunnableArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sBondingRunnableArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sUnbondingRunnableArray;
static bool sIsRestart(false);
static bool sIsFirstTimeToggleOffBt(false);
/**
* Static callback functions
@ -598,6 +600,8 @@ static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sGetDeviceRunnableArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sBondingRunnableArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sUnbondingRunnableArray;
static bool sAdapterDiscoverable(false);
static bool sIsRestart(false);
static bool sIsFirstTimeToggleOffBt(false);
static uint32_t sAdapterDiscoverableTimeout(0);
/**
@ -2127,7 +2131,11 @@ public:
private:
void Proceed() const
{
sBtInterface->Cleanup(nullptr);
if (!sIsRestart) {
sBtInterface->Cleanup(nullptr);
} else {
BT_LOGR("ProfileDeinitResultHandler::Proceed cancel cleanup() ");
}
}
unsigned char mNumProfiles;
@ -2231,6 +2239,12 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
BT_LOGR("BT_STATE: %d", aState);
if (sIsRestart && aState) {
// daemon restarted, reset flag
BT_LOGR("daemon restarted, reset flag");
sIsRestart = false;
sIsFirstTimeToggleOffBt = false;
}
bool isBtEnabled = (aState == true);
if (!isBtEnabled) {
@ -2279,6 +2293,11 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
BT_LOGR("Fail to start BluetoothOppManager listening");
}
}
// After ProfileManagers deinit and cleanup, now restarts bluetooth daemon
if (sIsRestart && !aState) {
BT_LOGR("sIsRestart and off, now restart");
StartBluetooth(false);
}
#endif
}
@ -3074,3 +3093,39 @@ BluetoothServiceBluedroid::EnergyInfoNotification(
// FIXME: This will be implemented in the later patchset
}
#endif
void
BluetoothServiceBluedroid::BackendErrorNotification(bool aCrashed)
{
MOZ_ASSERT(NS_IsMainThread());
// Recovery step 2 stop bluetooth
if (aCrashed) {
BT_LOGR("Set aRestart = true");
sIsRestart = true;
BT_LOGR("Reocvery step2: stop bluetooth");
#ifdef MOZ_B2G_BT_API_V2
StopBluetooth(false, nullptr);
#else
StopBluetooth(false);
#endif
}
}
void
BluetoothServiceBluedroid::CompleteToggleBt(bool aEnabled)
{
MOZ_ASSERT(NS_IsMainThread());
if (sIsRestart && !aEnabled && sIsFirstTimeToggleOffBt) {
// Both StopBluetooth and AdapterStateChangedNotification
// trigger CompleteToggleBt. We don't need to call CompleteToggleBt again
} else if (sIsRestart && !aEnabled && !sIsFirstTimeToggleOffBt) {
// Recovery step 3: cleanup and deinit Profile managers
BT_LOGR("CompleteToggleBt set sIsFirstTimeToggleOffBt = true");
sIsFirstTimeToggleOffBt = true;
BluetoothService::CompleteToggleBt(aEnabled);
AdapterStateChangedNotification(false);
} else {
BluetoothService::CompleteToggleBt(aEnabled);
}
}

View File

@ -300,7 +300,9 @@ public:
uint8_t aLen) override;
virtual void LeTestModeNotification(BluetoothStatus aStatus,
uint16_t aNumPackets) override;
virtual void BackendErrorNotification(bool aCrashed) override;
virtual void CompleteToggleBt(bool aEnabled) override;
protected:
static nsresult StartGonkBluetooth();
static nsresult StopGonkBluetooth();
@ -527,6 +529,9 @@ public:
virtual void EnergyInfoNotification(
const BluetoothActivityEnergyInfo& aInfo) override;
virtual void BackendErrorNotification(bool aCrashed) override;
virtual void CompleteToggleBt(bool aEnabled) override;
protected:
static nsresult StartGonkBluetooth();
static nsresult StopGonkBluetooth();

View File

@ -1283,6 +1283,7 @@ void
BluetoothHfpManager::OnDisconnectError()
{
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_TRUE_VOID(mController);
mController->NotifyCompletion(NS_LITERAL_STRING(ERR_CONNECTION_FAILED));
}

View File

@ -365,6 +365,9 @@ protected:
virtual nsresult
HandleStartup();
virtual void
CompleteToggleBt(bool aEnabled);
/**
* Called when the startup settings check has completed.
*/
@ -391,7 +394,6 @@ protected:
static BluetoothService*
Create();
void CompleteToggleBt(bool aEnabled);
typedef nsClassHashtable<nsStringHashKey, BluetoothSignalObserverList >
BluetoothSignalObserverTable;

View File

@ -256,6 +256,8 @@ BluetoothGatt::DiscoverServices(ErrorResult& aRv)
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
mDiscoveringServices = true;
mServices.Clear();
BluetoothGattBinding::ClearCachedServicesValue(this);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
@ -292,6 +294,7 @@ BluetoothGatt::HandleServicesDiscovered(const BluetoothValue& aValue)
const InfallibleTArray<BluetoothGattServiceId>& serviceIds =
aValue.get_ArrayOfBluetoothGattServiceId();
mServices.Clear();
for (uint32_t i = 0; i < serviceIds.Length(); i++) {
mServices.AppendElement(new BluetoothGattService(
GetParentObject(), mAppUuid, serviceIds[i]));

View File

@ -149,6 +149,7 @@ BluetoothGattCharacteristic::HandleDescriptorsDiscovered(
const InfallibleTArray<BluetoothGattId>& descriptorIds =
aValue.get_ArrayOfBluetoothGattId();
mDescriptors.Clear();
for (uint32_t i = 0; i < descriptorIds.Length(); i++) {
mDescriptors.AppendElement(new BluetoothGattDescriptor(
GetParentObject(), this, descriptorIds[i]));
@ -194,8 +195,6 @@ void
BluetoothGattCharacteristic::GetValue(JSContext* cx,
JS::MutableHandle<JSObject*> aValue) const
{
MOZ_ASSERT(aValue);
aValue.set(mValue.IsEmpty()
? nullptr
: ArrayBuffer::Create(cx, mValue.Length(), mValue.Elements()));

View File

@ -112,8 +112,6 @@ void
BluetoothGattDescriptor::GetValue(JSContext* cx,
JS::MutableHandle<JSObject*> aValue) const
{
MOZ_ASSERT(aValue);
aValue.set(mValue.IsEmpty()
? nullptr
: ArrayBuffer::Create(cx, mValue.Length(), mValue.Elements()));

View File

@ -85,6 +85,7 @@ BluetoothGattService::HandleIncludedServicesDiscovered(
const InfallibleTArray<BluetoothGattServiceId>& includedServIds =
aValue.get_ArrayOfBluetoothGattServiceId();
mIncludedServices.Clear();
for (uint32_t i = 0; i < includedServIds.Length(); i++) {
mIncludedServices.AppendElement(new BluetoothGattService(
GetParentObject(), mAppUuid, includedServIds[i]));
@ -103,6 +104,7 @@ BluetoothGattService::HandleCharacteristicsDiscovered(
const InfallibleTArray<BluetoothGattCharAttribute>& characteristics =
aValue.get_ArrayOfBluetoothGattCharAttribute();
mCharacteristics.Clear();
for (uint32_t i = 0; i < characteristics.Length(); i++) {
mCharacteristics.AppendElement(new BluetoothGattCharacteristic(
GetParentObject(), this, characteristics[i]));

View File

@ -515,6 +515,9 @@ protected:
virtual nsresult
HandleStartup();
virtual void
CompleteToggleBt(bool aEnabled);
/**
* Called when the startup settings check has completed.
*/
@ -541,9 +544,6 @@ protected:
static BluetoothService*
Create();
void
CompleteToggleBt(bool aEnabled);
typedef nsClassHashtable<nsStringHashKey, BluetoothSignalObserverList >
BluetoothSignalObserverTable;

View File

@ -377,7 +377,8 @@ bool
MP4Reader::IsSupportedAudioMimeType(const nsACString& aMimeType)
{
return (aMimeType.EqualsLiteral("audio/mpeg") ||
aMimeType.EqualsLiteral("audio/mp4a-latm")) &&
aMimeType.EqualsLiteral("audio/mp4a-latm") ||
aMimeType.EqualsLiteral("audio/3gpp")) &&
mPlatform->SupportsMimeType(aMimeType);
}

View File

@ -50,8 +50,9 @@ GonkAudioDecoderManager::GonkAudioDecoderManager(
{
MOZ_COUNT_CTOR(GonkAudioDecoderManager);
MOZ_ASSERT(mAudioChannels);
mUserData.AppendElements(aConfig.mCodecSpecificConfig->Elements(),
aConfig.mCodecSpecificConfig->Length());
mCodecSpecificData = aConfig.mCodecSpecificConfig;
mMimeType = aConfig.mMimeType;
// Pass through mp3 without applying an ADTS header.
if (!aConfig.mMimeType.EqualsLiteral("audio/mp4a-latm")) {
mUseAdts = false;
@ -66,6 +67,7 @@ GonkAudioDecoderManager::~GonkAudioDecoderManager()
android::sp<MediaCodecProxy>
GonkAudioDecoderManager::Init(MediaDataDecoderCallback* aCallback)
{
status_t rv = OK;
if (mLooper != nullptr) {
return nullptr;
}
@ -74,7 +76,7 @@ GonkAudioDecoderManager::Init(MediaDataDecoderCallback* aCallback)
mLooper->setName("GonkAudioDecoderManager");
mLooper->start();
mDecoder = MediaCodecProxy::CreateByType(mLooper, "audio/mp4a-latm", false, nullptr);
mDecoder = MediaCodecProxy::CreateByType(mLooper, mMimeType.get(), false, nullptr);
if (!mDecoder.get()) {
return nullptr;
}
@ -85,8 +87,8 @@ GonkAudioDecoderManager::Init(MediaDataDecoderCallback* aCallback)
}
sp<AMessage> format = new AMessage;
// Fixed values
GADM_LOG("Init Audio channel no:%d, sample-rate:%d", mAudioChannels, mAudioRate);
format->setString("mime", "audio/mp4a-latm");
GADM_LOG("Configure audio mime type:%s, chan no:%d, sample-rate:%d", mMimeType.get(), mAudioChannels, mAudioRate);
format->setString("mime", mMimeType.get());
format->setInt32("channel-count", mAudioChannels);
format->setInt32("sample-rate", mAudioRate);
format->setInt32("aac-profile", mAudioProfile);
@ -95,8 +97,11 @@ GonkAudioDecoderManager::Init(MediaDataDecoderCallback* aCallback)
if (err != OK || !mDecoder->Prepare()) {
return nullptr;
}
status_t rv = mDecoder->Input(mUserData.Elements(), mUserData.Length(), 0,
android::MediaCodec::BUFFER_FLAG_CODECCONFIG);
if (mMimeType.EqualsLiteral("audio/mp4a-latm")) {
rv = mDecoder->Input(mCodecSpecificData->Elements(), mCodecSpecificData->Length(), 0,
android::MediaCodec::BUFFER_FLAG_CODECCONFIG);
}
if (rv == OK) {
return mDecoder;

View File

@ -51,7 +51,6 @@ private:
const uint32_t mAudioChannels;
const uint32_t mAudioRate;
const uint32_t mAudioProfile;
nsTArray<uint8_t> mUserData;
bool mUseAdts;
MediaDataDecoderCallback* mReaderCallback;

View File

@ -65,6 +65,7 @@ bool
GonkDecoderModule::SupportsMimeType(const nsACString& aMimeType)
{
return aMimeType.EqualsLiteral("audio/mp4a-latm") ||
aMimeType.EqualsLiteral("audio/3gpp") ||
aMimeType.EqualsLiteral("video/mp4") ||
aMimeType.EqualsLiteral("video/mp4v-es") ||
aMimeType.EqualsLiteral("video/avc");

View File

@ -69,6 +69,10 @@ protected:
nsTArray<nsRefPtr<MediaRawData>> mQueueSample;
RefPtr<MediaTaskQueue> mTaskQueue;
nsRefPtr<MediaByteBuffer> mCodecSpecificData;
nsAutoCString mMimeType;
};
// Samples are decoded using the GonkDecoder (MediaCodec)

View File

@ -494,7 +494,7 @@ GonkVideoDecoderManager::codecReserved()
sp<Surface> surface;
status_t rv = OK;
// Fixed values
GVDM_LOG("Configure mime type: %s, widht:%d, height:%d", mMimeType.get(), mVideoWidth, mVideoHeight);
GVDM_LOG("Configure video mime type: %s, widht:%d, height:%d", mMimeType.get(), mVideoWidth, mVideoHeight);
format->setString("mime", mMimeType.get());
format->setInt32("width", mVideoWidth);
format->setInt32("height", mVideoHeight);

View File

@ -147,7 +147,6 @@ private:
android::MediaBuffer* mVideoBuffer;
nsRefPtr<MediaByteBuffer> mCodecSpecificData;
MediaDataDecoderCallback* mReaderCallback;
MediaInfo mInfo;
android::sp<VideoResourceListener> mVideoListener;
@ -178,7 +177,6 @@ private:
// The lock protects mPendingVideoBuffers.
Mutex mPendingVideoBuffersLock;
nsAutoCString mMimeType;
};
} // namespace mozilla

View File

@ -0,0 +1,47 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/MozMobileMessageManagerBinding.h"
#include "nsISmsService.h"
namespace mozilla {
namespace dom {
namespace mobilemessage {
#define ASSERT_SMS_EQUALITY(webidlType, webidlState, xpidlState) \
static_assert(static_cast<uint32_t>(webidlType::webidlState) == nsISmsService::xpidlState, \
#webidlType "::" #webidlState " should equal to nsISmsService::" #xpidlState)
/**
* Enum TypeOfNumber
*/
#define ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(webidlState, xpidlState) \
ASSERT_SMS_EQUALITY(TypeOfNumber, webidlState, xpidlState)
ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(Unknown, TYPE_OF_NUMBER_UNKNOWN);
ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(International, TYPE_OF_NUMBER_INTERNATIONAL);
ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(National, TYPE_OF_NUMBER_NATIONAL);
ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(Network_specific, TYPE_OF_NUMBER_NETWORK_SPECIFIC);
ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY(Dedicated_access_short_code, TYPE_OF_NUMBER_DEDICATED_ACCESS_SHORT_CODE);
#undef ASSERT_SMS_TYPE_OF_NUMBER_EQUALITY
/**
* Enum NumberPlanIdentification
*/
#define ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(webidlState, xpidlState) \
ASSERT_SMS_EQUALITY(NumberPlanIdentification, webidlState, xpidlState)
ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(Unknown, NUMBER_PLAN_IDENTIFICATION_UNKNOWN);
ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(Isdn, NUMBER_PLAN_IDENTIFICATION_ISDN);
ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(Data, NUMBER_PLAN_IDENTIFICATION_DATA);
ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(Telex, NUMBER_PLAN_IDENTIFICATION_TELEX);
ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(National, NUMBER_PLAN_IDENTIFICATION_NATIONAL);
ASSERT_SMS_NUMBER_PLAN_IDENTIFICATION_EQUALITY(Private, NUMBER_PLAN_IDENTIFICATION_PRIVATE);
#undef ASSERT_SMS_EQUALITY
} // namespace mobilemessage
} // namespace dom
} // namespace mozilla

View File

@ -17,6 +17,7 @@
#include "nsServiceManagerUtils.h"
#include "nsTArrayHelpers.h"
#include "DOMMobileMessageError.h"
#include "mozilla/dom/Promise.h"
namespace mozilla {
namespace dom {
@ -80,6 +81,11 @@ MobileMessageCallback::MobileMessageCallback(DOMRequest* aDOMRequest)
{
}
MobileMessageCallback::MobileMessageCallback(Promise* aPromise)
: mPromise(aPromise)
{
}
MobileMessageCallback::~MobileMessageCallback()
{
}
@ -280,6 +286,21 @@ MobileMessageCallback::NotifyGetSmscAddressFailed(int32_t aError)
return NotifyError(aError);
}
NS_IMETHODIMP
MobileMessageCallback::NotifySetSmscAddress()
{
mPromise->MaybeResolve(JS::UndefinedHandleValue);
return NS_OK;
}
NS_IMETHODIMP
MobileMessageCallback::NotifySetSmscAddressFailed(int32_t aError)
{
const nsAString& errorStr = ConvertErrorCodeToErrorString(aError);
mPromise->MaybeRejectBrokenly(errorStr);
return NS_OK;
}
} // namesapce mobilemessage
} // namespace dom
} // namespace mozilla

View File

@ -10,6 +10,8 @@
#include "nsCOMPtr.h"
#include "DOMRequest.h"
class Promise;
namespace mozilla {
namespace dom {
namespace mobilemessage {
@ -21,11 +23,13 @@ public:
NS_DECL_NSIMOBILEMESSAGECALLBACK
explicit MobileMessageCallback(DOMRequest* aDOMRequest);
explicit MobileMessageCallback(Promise* aPromise);
private:
~MobileMessageCallback();
nsRefPtr<DOMRequest> mDOMRequest;
nsRefPtr<Promise> mPromise;
nsresult NotifySuccess(JS::Handle<JS::Value> aResult, bool aAsync = false);
nsresult NotifySuccess(nsISupports *aMessage, bool aAsync = false);

View File

@ -15,6 +15,7 @@
#include "mozilla/dom/MozMmsEvent.h"
#include "mozilla/dom/MozMobileMessageManagerBinding.h"
#include "mozilla/dom/MozSmsEvent.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
@ -697,6 +698,72 @@ MobileMessageManager::GetSmscAddress(const Optional<uint32_t>& aServiceId,
return request.forget();
}
already_AddRefed<Promise>
MobileMessageManager::SetSmscAddress(const SmscAddress& aSmscAddress,
const Optional<uint32_t>& aServiceId,
ErrorResult& aRv)
{
nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
if (!smsService) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
// Use the default one unless |serviceId| is available.
uint32_t serviceId;
nsresult rv;
if (aServiceId.WasPassed()) {
serviceId = aServiceId.Value();
} else {
rv = smsService->GetSmsDefaultServiceId(&serviceId);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
}
}
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
if (!global) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
if (aRv.Failed()) {
return nullptr;
}
if (!aSmscAddress.mAddress.WasPassed()) {
NS_WARNING("SmscAddress.address is a mandatory field and can not be omitted.");
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return promise.forget();
}
nsString address = aSmscAddress.mAddress.Value();
TypeOfNumber ton = aSmscAddress.mTypeOfAddress.mTypeOfNumber;
NumberPlanIdentification npi =
aSmscAddress.mTypeOfAddress.mNumberPlanIdentification;
// If the address begins with +, set TON to international no matter what has
// passed in.
if (!address.IsEmpty() && address[0] == '+') {
ton = TypeOfNumber::International;
}
nsCOMPtr<nsIMobileMessageCallback> msgCallback =
new MobileMessageCallback(promise);
rv = smsService->SetSmscAddress(serviceId, address,
static_cast<uint32_t>(ton), static_cast<uint32_t>(npi), msgCallback);
if (NS_FAILED(rv)) {
promise->MaybeReject(rv);
return promise.forget();
}
return promise.forget();
}
} // namespace dom
} // namespace mozilla

View File

@ -13,6 +13,7 @@
class nsISmsService;
class nsIDOMMozSmsMessage;
class nsIDOMMozMmsMessage;
class Promise;
namespace mozilla {
namespace dom {
@ -24,6 +25,7 @@ struct MmsSendParameters;
struct MobileMessageFilter;
class OwningLongOrMozSmsMessageOrMozMmsMessage;
struct SmsSendParameters;
struct SmscAddress;
class MobileMessageManager final : public DOMEventTargetHelper
, public nsIObserver
@ -115,6 +117,11 @@ public:
GetSmscAddress(const Optional<uint32_t>& aServiceId,
ErrorResult& aRv);
already_AddRefed<Promise>
SetSmscAddress(const SmscAddress& aSmscAddress,
const Optional<uint32_t>& aServiceId,
ErrorResult& aRv);
IMPL_EVENT_HANDLER(received)
IMPL_EVENT_HANDLER(retrieving)
IMPL_EVENT_HANDLER(sending)

View File

@ -69,7 +69,20 @@ SmsService::GetSmscAddress(uint32_t aServiceId,
nsIMobileMessageCallback *aRequest)
{
// TODO: bug 878016 - Android backend: implement getSMSCAddress/setSMSCAddress
return NS_OK;
NS_NOTYETIMPLEMENTED("Implement me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
SmsService::SetSmscAddress(uint32_t aServiceId,
const nsAString& aNumber,
uint32_t aTypeOfNumber,
uint32_t aNumberPlanIdentification,
nsIMobileMessageCallback* aRequest)
{
// TODO: bug 878016 - Android backend: implement getSMSCAddress/setSMSCAddress
NS_NOTYETIMPLEMENTED("Implement me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
} // namespace mobilemessage

View File

@ -802,7 +802,7 @@ SmsService.prototype = {
}
},
// An array of slient numbers.
// An array of silent numbers.
_silentNumbers: null,
_isSilentNumber: function(aNumber) {
return this._silentNumbers.indexOf(aNumber) >= 0;
@ -990,6 +990,30 @@ SmsService.prototype = {
});
},
setSmscAddress: function(aServiceId, aNumber, aTypeOfNumber,
aNumberPlanIdentification, aRequest) {
if (aServiceId > (gRadioInterfaces.length - 1)) {
throw Cr.NS_ERROR_INVALID_ARG;
}
let options = {
smscAddress: aNumber,
typeOfNumber: aTypeOfNumber,
numberPlanIdentification: aNumberPlanIdentification
};
gRadioInterfaces[aServiceId].sendWorkerMessage("setSmscAddress",
options,
(aResponse) => {
if (!aResponse.errorMsg) {
aRequest.notifySetSmscAddress();
} else {
aRequest.notifySetSmscAddressFailed(
Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR);
}
});
},
/**
* nsIGonkSmsService interface
*/

View File

@ -10,7 +10,7 @@
"@mozilla.org/sms/gonksmsservice;1"
%}
[scriptable, uuid(4dda515e-05ec-47b1-b750-e42c74576c43)]
[scriptable, uuid(76681431-8261-4540-bab8-24ef3866e8b6)]
interface nsIGonkSmsService : nsISmsService
{
const unsigned short SMS_MESSAGE_ENCODING_7BITS_ALPHABET = 0x00;

View File

@ -4,7 +4,7 @@
#include "nsISupports.idl"
[scriptable, uuid(35279dbc-9f1d-419f-b17a-230fcf49f0c7)]
[scriptable, uuid(b1367554-51c6-4153-b20a-effec50ca827)]
interface nsIMobileMessageCallback : nsISupports
{
/**
@ -54,4 +54,6 @@ interface nsIMobileMessageCallback : nsISupports
*/
void notifyGetSmscAddress(in DOMString aSmscAddress);
void notifyGetSmscAddressFailed(in long error);
void notifySetSmscAddress();
void notifySetSmscAddressFailed(in long error);
};

View File

@ -12,7 +12,7 @@ interface nsIMobileMessageCallback;
#define SMS_SERVICE_CONTRACTID "@mozilla.org/sms/smsservice;1"
%}
[scriptable, uuid(ae688bca-00c9-4d08-945d-e8a5272ad5b1)]
[scriptable, uuid(c8ca5f06-ad76-44b0-a324-9e2910fd37da)]
interface nsISmsService : nsISupports
{
/**
@ -41,22 +41,131 @@ interface nsISmsService : nsISupports
const unsigned short DELIVERY_STATUS_TYPE_PENDING = 2;
const unsigned short DELIVERY_STATUS_TYPE_ERROR = 3;
/**
* Constant definitions of SM-RP type of number as defined in
* |Table 10.5.118: Called party BCD number| of 3GPP TS 24.008.
*/
const unsigned short TYPE_OF_NUMBER_UNKNOWN = 0;
const unsigned short TYPE_OF_NUMBER_INTERNATIONAL = 1;
const unsigned short TYPE_OF_NUMBER_NATIONAL = 2;
const unsigned short TYPE_OF_NUMBER_NETWORK_SPECIFIC = 3;
const unsigned short TYPE_OF_NUMBER_DEDICATED_ACCESS_SHORT_CODE = 4;
/**
* Constant definitions of SM-RP number plan identification as defined in
* |Table 10.5.118: Called party BCD number| of 3GPP TS 24.008.
*/
const unsigned short NUMBER_PLAN_IDENTIFICATION_UNKNOWN = 0;
const unsigned short NUMBER_PLAN_IDENTIFICATION_ISDN = 1;
const unsigned short NUMBER_PLAN_IDENTIFICATION_DATA = 2;
const unsigned short NUMBER_PLAN_IDENTIFICATION_TELEX = 3;
const unsigned short NUMBER_PLAN_IDENTIFICATION_NATIONAL = 4;
const unsigned short NUMBER_PLAN_IDENTIFICATION_PRIVATE = 5;
/**
* The default RIL service ID used for SMS.
*/
readonly attribute unsigned long smsDefaultServiceId;
/**
* Get the information necessary to create a multi-part SMS for a given text.
*
* @param text
* The text message content.
* @param request
* The callback object to use. It invokes
* |notifySegmentInfoForTextGot| on success, or
* |notifyGetSegmentInfoForTextFailed| on failure.
*/
void getSegmentInfoForText(in DOMString text,
in nsIMobileMessageCallback request);
/**
* Send a SMS.
*
* @param serviceId
* The ID of RIL service to use.
* @param number
* Destination number in string.
* @param message
* The text message content.
* @param silent
* |true| to send a silent message. It's used to make a SMS based
* authentication for some services such as mobile billing.
* @param request
* The callback object to use. It invokes |notifyMessageSent| on
* success, or |notifySendMessageFailed| on failure.
* @throws NS_ERROR_INVALID_ARG
* If |serviceId| exceeds the max value of available IDs.
*/
void send(in unsigned long serviceId,
in DOMString number,
in DOMString message,
in boolean silent,
in nsIMobileMessageCallback request);
/**
* Add a number to the list of silent message originators. When receiving a
* SMS sent from one of the numbers in the list, |SmsService| will notify
* observers through the topic "silent-sms-received".
*
* It's used when a SMS based authentication has been initiated and the client
* is waiting for an incoming silent message containing the authentication
* result.
*
* @param number
* Originator number in string.
* @throw NS_ERROR_UNEXPECTED
* If the given number has already been added before.
*/
void addSilentNumber(in DOMString number);
/**
* Remove a number from the silent message originator list.
*
* @param number
* Originator number in string.
* @throws NS_ERROR_INVALID_ARG
* If the number doesn't exist in the list.
*/
void removeSilentNumber(in DOMString number);
/**
* Get the short message service center address of given |serviceId|.
*
* @param serviceId
* The ID of RIL service to use.
* @param request
* The callback object to use. It invokes |notifyGetSmscAddress| on
* success, or |notifyGetSmscAddressFailed| on failure.
* @throws NS_ERROR_INVALID_ARG
* If |serviceId| exceeds the max value of available IDs.
*/
void getSmscAddress(in unsigned long serviceId,
in nsIMobileMessageCallback request);
/**
* Set the short message service center address of given |serviceId|.
*
* @param serviceId
* The ID of RIL service to use.
* @param number
* Number part of the SMSC address.
* @param typeOfNumber
* Type of number of the SMSC address.
* @param numberPlanIdentification
* Number plan identification of the SMSC address.
* @param request
* The callback object to use. It invokes |notifySetSmscAddress| on
* success, or |notifySetSmscAddressFailed| on failure.
* @throws NS_ERROR_INVALID_ARG
* If |serviceId| exceeds the max value of available IDs.
*/
void setSmscAddress(in unsigned long serviceId,
in DOMString number,
in unsigned long typeOfNumber,
in unsigned long numberPlanIdentification,
in nsIMobileMessageCallback request);
};
%{C++

View File

@ -79,6 +79,14 @@ struct GetSmscAddressRequest
uint32_t serviceId;
};
struct SetSmscAddressRequest
{
uint32_t serviceId;
nsString number;
uint32_t typeOfNumber;
uint32_t numberPlanIdentification;
};
union IPCSmsRequest
{
SendMessageRequest;
@ -88,6 +96,7 @@ union IPCSmsRequest
MarkMessageReadRequest;
GetSegmentInfoForTextRequest;
GetSmscAddressRequest;
SetSmscAddressRequest;
};
union IPCMobileMessageCursor

View File

@ -94,6 +94,15 @@ struct ReplyGetSmscAddressFail
int32_t error;
};
struct ReplySetSmscAddress
{
};
struct ReplySetSmscAddressFail
{
int32_t error;
};
union MessageReply
{
ReplyMessageSend;
@ -108,6 +117,8 @@ union MessageReply
ReplyGetSegmentInfoForTextFail;
ReplyGetSmscAddress;
ReplyGetSmscAddressFail;
ReplySetSmscAddress;
ReplySetSmscAddressFail;
};
} // namespace mobilemessage

View File

@ -262,6 +262,12 @@ SmsRequestChild::Recv__delete__(const MessageReply& aReply)
case MessageReply::TReplyGetSmscAddressFail:
mReplyRequest->NotifyGetSmscAddressFailed(aReply.get_ReplyGetSmscAddressFail().error());
break;
case MessageReply::TReplySetSmscAddress:
mReplyRequest->NotifySetSmscAddress();
break;
case MessageReply::TReplySetSmscAddressFail:
mReplyRequest->NotifySetSmscAddressFailed(aReply.get_ReplySetSmscAddressFail().error());
break;
default:
MOZ_CRASH("Received invalid response parameters!");
}

View File

@ -181,6 +181,21 @@ SmsIPCService::GetSmscAddress(uint32_t aServiceId,
return SendRequest(GetSmscAddressRequest(aServiceId), aRequest);
}
NS_IMETHODIMP
SmsIPCService::SetSmscAddress(uint32_t aServiceId,
const nsAString& aNumber,
uint32_t aTypeOfNumber,
uint32_t aNumberPlanIdentification,
nsIMobileMessageCallback* aRequest)
{
return SendRequest(SetSmscAddressRequest(aServiceId,
nsString(aNumber),
aTypeOfNumber,
aNumberPlanIdentification),
aRequest);
}
NS_IMETHODIMP
SmsIPCService::Send(uint32_t aServiceId,
const nsAString& aNumber,

View File

@ -406,6 +406,8 @@ SmsParent::RecvPSmsRequestConstructor(PSmsRequestParent* aActor,
return actor->DoRequest(aRequest.get_GetSegmentInfoForTextRequest());
case IPCSmsRequest::TGetSmscAddressRequest:
return actor->DoRequest(aRequest.get_GetSmscAddressRequest());
case IPCSmsRequest::TSetSmscAddressRequest:
return actor->DoRequest(aRequest.get_SetSmscAddressRequest());
default:
MOZ_CRASH("Unknown type!");
}
@ -574,6 +576,29 @@ SmsRequestParent::DoRequest(const GetSmscAddressRequest& aRequest)
return true;
}
bool
SmsRequestParent::DoRequest(const SetSmscAddressRequest& aRequest)
{
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsISmsService> smsService = do_GetService(SMS_SERVICE_CONTRACTID);
if (smsService) {
rv = smsService->SetSmscAddress(aRequest.serviceId(),
aRequest.number(),
aRequest.typeOfNumber(),
aRequest.numberPlanIdentification(),
this);
} else {
return NS_SUCCEEDED(NotifySetSmscAddressFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
}
if (NS_FAILED(rv)) {
return NS_SUCCEEDED(NotifySetSmscAddressFailed(nsIMobileMessageCallback::INTERNAL_ERROR));
}
return true;
}
bool
SmsRequestParent::DoRequest(const DeleteMessageRequest& aRequest)
{
@ -746,6 +771,18 @@ SmsRequestParent::NotifyGetSmscAddressFailed(int32_t aError)
return SendReply(ReplyGetSmscAddressFail(aError));
}
NS_IMETHODIMP
SmsRequestParent::NotifySetSmscAddress()
{
return SendReply(ReplySetSmscAddress());
}
NS_IMETHODIMP
SmsRequestParent::NotifySetSmscAddressFailed(int32_t aError)
{
return SendReply(ReplySetSmscAddressFail(aError));
}
/*******************************************************************************
* MobileMessageCursorParent
******************************************************************************/

View File

@ -117,6 +117,9 @@ protected:
bool
DoRequest(const GetSmscAddressRequest& aRequest);
bool
DoRequest(const SetSmscAddressRequest& aRequest);
nsresult
SendReply(const MessageReply& aReply);
};

View File

@ -50,6 +50,7 @@ EXPORTS.mozilla.dom += [
]
UNIFIED_SOURCES += [
'Assertions.cpp',
'Constants.cpp',
'DeletedMessageInfo.cpp',
'DOMMobileMessageError.cpp',

View File

@ -52,3 +52,4 @@ qemu = true
[test_ondeleted_event.js]
[test_decode_spanish_fallback.js]
[test_update_gsm_nl_on_mcc_chanages.js]
[test_set_smsc_address.js]

View File

@ -0,0 +1,72 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
const SMSC_ATT = '+13123149810';
const SMSC_ATT_TYPO = '+++1312@@@314$$$9,8,1,0';
const SMSC_ATT_TEXT = '"+13123149810",145';
const SMSC_O2 = '+447802000332';
const SMSC_O2_TEXT = '"+447802000332",145';
const SMSC_DEF = '+123456789';
const SMSC_DEF_TEXT = '"+123456789",145';
const SMSC_TON_UNKNOWN = '0407485455'
const SMSC_TON_UNKNOWN_TEXT = '"0407485455",129';
function getSmscAddress() {
return new Promise((resolve, reject) => {
let req = manager.getSmscAddress();
if (!req) {
reject("manager.getSmscAddress() returns null.");
}
req.onsuccess = function() {
resolve(this.result);
};
req.onerror = function() {
reject(this.error);
};
});
};
startTestBase(function testCaseMain() {
return ensureMobileMessage()
// Verify setting AT&T SMSC address.
.then(() => manager.setSmscAddress({ address:SMSC_ATT }))
.then(() => getSmscAddress())
.then((result) => is(result, SMSC_ATT_TEXT))
// Verify setting O2 SMSC address.
.then(() => manager.setSmscAddress({ address:SMSC_O2 }))
.then(() => getSmscAddress())
.then((result) => is(result, SMSC_O2_TEXT))
// Verify setting AT&T SMSC address with extra illegal characters.
.then(() => manager.setSmscAddress({ address:SMSC_ATT_TYPO }))
.then(() => getSmscAddress())
.then((result) => is(result, SMSC_ATT_TEXT))
// Verify setting a SMSC address with TON=unknown.
.then(() => manager.setSmscAddress({ address:SMSC_TON_UNKNOWN }))
.then(() => getSmscAddress())
.then((result) => is(result, SMSC_TON_UNKNOWN_TEXT))
// Verify setting invalid SMSC address.
.then(() => manager.setSmscAddress({}))
.then(() => Promise.reject("Expect for an error."),
(err) => log("Got expected error: " + err))
.then(() => manager.setSmscAddress({ address:"" }))
.then(() => Promise.reject("Expect for an error."),
(err) => log("Got expected error: " + err))
.then(() => manager.setSmscAddress({ address:"???" }))
.then(() => Promise.reject("Expect for an error."),
(err) => log("Got expected error: " + err))
// Restore to default emulator SMSC address.
.then(() => manager.setSmscAddress({ address:SMSC_DEF }))
.then(() => getSmscAddress())
.then((result) => is(result, SMSC_DEF_TEXT));
});

View File

@ -1494,6 +1494,8 @@ WorkerMessenger.prototype = {
libcutils.property_get("ro.moz.ril.query_icc_count", "false") == "true",
sendStkProfileDownload:
libcutils.property_get("ro.moz.ril.send_stk_profile_dl", "false") == "true",
smscAddressFormat:
libcutils.property_get("ro.moz.ril.smsc_address_format", "text"),
dataRegistrationOnDemand: RILQUIRKS_DATA_REGISTRATION_ON_DEMAND,
subscriptionControl: RILQUIRKS_SUBSCRIPTION_CONTROL,
signalExtraInt: RILQUIRKS_SIGNAL_EXTRA_INT32

View File

@ -1406,6 +1406,30 @@ this.CB_UMTS_MESSAGE_TYPE_CBS = 1;
this.CB_UMTS_MESSAGE_TYPE_SCHEDULE = 2;
this.CB_UMTS_MESSAGE_TYPE_CBS41 = 3;
/**
* Number plan identification defined in
* |Table 10.5.118: Called party BCD number| of 3GPP TS 24.008.
*/
this.CALLED_PARTY_BCD_NPI_UNKNOWN = 0;
this.CALLED_PARTY_BCD_NPI_ISDN = 1;
this.CALLED_PARTY_BCD_NPI_DATA = 3;
this.CALLED_PARTY_BCD_NPI_TELEX = 4;
this.CALLED_PARTY_BCD_NPI_NATIONAL = 8;
this.CALLED_PARTY_BCD_NPI_PRIVATE = 9;
/**
* Array of number plan identification values which can be used to map an
* enumeration to the corresponding value.
*/
this.CALLED_PARTY_BCD_NPI = [
CALLED_PARTY_BCD_NPI_UNKNOWN,
CALLED_PARTY_BCD_NPI_ISDN,
CALLED_PARTY_BCD_NPI_DATA,
CALLED_PARTY_BCD_NPI_TELEX,
CALLED_PARTY_BCD_NPI_NATIONAL,
CALLED_PARTY_BCD_NPI_PRIVATE
];
/**
* GSM PDU constants
*/

View File

@ -86,6 +86,9 @@ let RILQUIRKS_SUBSCRIPTION_CONTROL;
let RILQUIRKS_SIGNAL_EXTRA_INT32;
// Ril quirk to describe the SMSC address format.
let RILQUIRKS_SMSC_ADDRESS_FORMAT;
/**
* The RIL state machine.
*
@ -1728,12 +1731,91 @@ RilObject.prototype = {
* Set the Short Message Service Center address.
*
* @param smscAddress
* Short Message Service Center address in PDU format.
* Number part of the SMSC address.
* @param typeOfNumber
* Type of number in integer, as defined in
* |Table 10.5.118: Called party BCD number| of 3GPP TS 24.008.
* @param numberPlanIdentification
* Number plan identification in integer, as defined in
* |Table 10.5.118: Called party BCD number| of 3GPP TS 24.008.
*/
setSmscAddress: function(options) {
let ton = options.typeOfNumber;
let npi = CALLED_PARTY_BCD_NPI[options.numberPlanIdentification];
// If any of the mandatory arguments is not available, return an error
// immediately.
if (ton === undefined || npi === undefined || !options.smscAddress) {
options.errorMsg = GECKO_ERROR_INVALID_PARAMETER;
this.sendChromeMessage(options);
return;
}
// Remove all illegal characters in the number string for user-input fault
// tolerance.
let numStart = options.smscAddress[0] === "+" ? 1 : 0;
let number = options.smscAddress.substring(0, numStart) +
options.smscAddress.substring(numStart)
.replace(/[^0-9*#abc]/ig, "");
// If the filtered number is an empty string, return an error immediately.
if (number.length === 0) {
options.errorMsg = GECKO_ERROR_INVALID_PARAMETER;
this.sendChromeMessage(options);
return;
}
// Init parcel.
this.SMSC = null;
let Buf = this.context.Buf;
Buf.newParcel(REQUEST_SET_SMSC_ADDRESS, options);
Buf.writeString(options.smscAddress);
// +---+-----------+---------------+
// | 1 | TON | NPI |
// +---+-----------+---------------+
let tosca = (0x1 << 7) + (ton << 4) + npi;
if (RILQUIRKS_SMSC_ADDRESS_FORMAT === "pdu") {
let pduHelper = this.context.GsmPDUHelper;
// Remove the preceding '+', and covert the special BCD digits defined in
// |Called party BCD number| of 3GPP TS 24.008 to corresponding
// hexadecimal values (refer the following table).
//
// +=========+=======+=====+
// | value | digit | hex |
// +========================
// | 1 0 1 0 | * | 0xA |
// | 1 0 1 1 | # | 0xB |
// | 1 1 0 0 | a | 0xC |
// | 1 1 0 1 | b | 0xD |
// | 1 1 1 0 | c | 0xE |
// +=========+=======+=====+
//
// The replace order is reversed intentionally, because if the digits are
// replaced in ascending order, "#" will be converted to "b" and then be
// converted again to "d", which generates incorrect result.
let pureNumber = number.substring(numStart)
.replace(/c/ig, "e")
.replace(/b/ig, "d")
.replace(/a/ig, "c")
.replace(/\#/g, "b")
.replace(/\*/g, "a");
// address length and string length
let length = Math.ceil(pureNumber.length / 2) + 1; // +1 octet for TOA
let strlen = length * 2 + 2; // +2 semi-octets for length octet
Buf.writeInt32(strlen);
pduHelper.writeHexOctet(length);
pduHelper.writeHexOctet(tosca);
pduHelper.writeSwappedNibbleBCD(pureNumber);
Buf.writeStringDelimiter(strlen);
} else /* RILQUIRKS_SMSC_ADDRESS_FORMAT === "text" */ {
let sca;
sca = '"' + number + '"' + ',' + tosca;
Buf.writeString(sca);
}
Buf.sendParcel();
},
@ -5506,7 +5588,17 @@ RilObject.prototype[REQUEST_GET_SMSC_ADDRESS] = function REQUEST_GET_SMSC_ADDRES
options.smscAddress = this.SMSC;
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_SET_SMSC_ADDRESS] = null;
RilObject.prototype[REQUEST_SET_SMSC_ADDRESS] = function REQUEST_SET_SMSC_ADDRESS(length, options) {
if (!options.rilMessageType || options.rilMessageType !== "setSmscAddress") {
return;
}
if (options.rilRequestError) {
optioins.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
}
this.sendChromeMessage(options);
};
RilObject.prototype[REQUEST_REPORT_SMS_MEMORY_STATUS] = function REQUEST_REPORT_SMS_MEMORY_STATUS(length, options) {
this.pendingToReportSmsMemoryStatus = !!options.errorMsg;
};
@ -15398,6 +15490,7 @@ let ContextPool = {
RILQUIRKS_DATA_REGISTRATION_ON_DEMAND = quirks.dataRegistrationOnDemand;
RILQUIRKS_SUBSCRIPTION_CONTROL = quirks.subscriptionControl;
RILQUIRKS_SIGNAL_EXTRA_INT32 = quirks.signalExtraInt;
RILQUIRKS_SMSC_ADDRESS_FORMAT = quirks.smscAddressFormat;
},
setDebugFlag: function(aOptions) {

View File

@ -0,0 +1,71 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
const SMSC_ATT = '+13123149810';
const SMSC_ATT_TYPO = '+++1312@@@314$$$9,8,1,0';
const SMSC_ATT_TEXT = '"+13123149810",145';
const SMSC_ATT_PDU = '07913121139418F0';
const SMSC_O2 = '+447802000332';
const SMSC_O2_TEXT = '"+447802000332",145';
const SMSC_O2_PDU = '0791448720003023';
const SMSC_TON_UNKNOWN = '0407485455'
const SMSC_TON_UNKNOWN_TEXT = '"0407485455",129';
const SMSC_TON_UNKNOWN_PDU = '06814070844555';
function run_test() {
run_next_test();
}
function setSmsc(context, smsc, ton, npi, expected) {
context.Buf.sendParcel = function() {
equal(this.readString(), expected);
};
context.RIL.setSmscAddress({
smscAddress: smsc,
typeOfNumber: ton,
numberPlanIdentification: npi
});
}
add_test(function test_setSmscAddress() {
let worker = newUint8Worker();
let context = worker.ContextPool._contexts[0];
let parcelTypes = [];
context.Buf.newParcel = (type, options) => parcelTypes.push(type);
// Test text mode.
worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "text";
setSmsc(context, SMSC_ATT, 1, 1, SMSC_ATT_TEXT);
equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
setSmsc(context, SMSC_O2, 1, 1, SMSC_O2_TEXT);
equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
setSmsc(context, SMSC_ATT_TYPO, 1, 1, SMSC_ATT_TEXT);
equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
setSmsc(context, SMSC_TON_UNKNOWN, 0, 1, SMSC_TON_UNKNOWN_TEXT);
equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
// Test pdu mode.
worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "pdu";
setSmsc(context, SMSC_ATT, 1, 1, SMSC_ATT_PDU);
equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
setSmsc(context, SMSC_O2, 1, 1, SMSC_O2_PDU);
equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
setSmsc(context, SMSC_ATT_TYPO, 1, 1, SMSC_ATT_PDU);
equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
setSmsc(context, SMSC_TON_UNKNOWN, 0, 1, SMSC_TON_UNKNOWN_PDU);
equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS);
run_next_test();
});

View File

@ -22,6 +22,7 @@ skip-if = true
[test_ril_worker_sms_nl_tables.js]
[test_ril_worker_sms_gsmpduhelper.js]
[test_ril_worker_sms_segment_info.js]
[test_ril_worker_smsc_address.js]
[test_ril_worker_mmi.js]
[test_ril_worker_mmi_cf.js]
[test_ril_worker_cf.js]

View File

@ -75,6 +75,45 @@ dictionary MobileMessageFilter
[EnforceRange] unsigned long long? threadId = 0;
};
/**
* TON defined in |Table 10.5.118: Called party BCD number| of 3GPP TS 24.008.
* It's used in SM-RL originator / destination address element as defined in
* |8.2.5.2 Destination address element| of 3GPP TS 24.011.
*/
enum TypeOfNumber { "unknown", "international", "national", "network-specific",
"dedicated-access-short-code" };
/**
* NPI defined in |Table 10.5.118: Called party BCD number| of 3GPP TS 24.008.
* It's used in SM-RL originator / destination address element as defined in
* |8.2.5.2 Destination address element| of 3GPP TS 24.011.
*/
enum NumberPlanIdentification { "unknown", "isdn", "data", "telex", "national",
"private" };
/**
* Type of address used in SmscAddress.
*
* As described in |3.1 Parameters Definitions| of 3GPP TS 27.005, the default
* value of <tosca> should be 129 (typeOfNumber=unknown,
* numberPlanIdentification=isdn) if the number does not begin with '+'.
*
* |setSmscAddress| updates typeOfNumber to international automatically if the
* given number begins with '+'.
*/
dictionary TypeOfAddress {
TypeOfNumber typeOfNumber = "unknown";
NumberPlanIdentification numberPlanIdentification = "isdn";
};
/**
* SMSC address.
*/
dictionary SmscAddress {
DOMString address;
TypeOfAddress typeOfAddress;
};
[Pref="dom.sms.enabled",
CheckPermissions="sms",
AvailableIn="CertifiedApps"]
@ -157,6 +196,22 @@ interface MozMobileMessageManager : EventTarget
[Throws]
DOMRequest getSmscAddress(optional unsigned long serviceId);
/**
* Set the SMSC address.
*
* @param smscAddress
* SMSC address to use.
* Reject if smscAddress.address does not present.
* @param serviceId (optional)
* The ID of the RIL service which needs to be specified under
* the multi-sim scenario.
* @return a Promise
* Resolve if success. Otherwise, reject with error cause.
*/
[NewObject]
Promise<void> setSmscAddress(optional SmscAddress smscAddress,
optional unsigned long serviceId);
attribute EventHandler onreceived;
attribute EventHandler onretrieving;
attribute EventHandler onsending;

View File

@ -21,7 +21,7 @@ interface nsITabParent;
interface nsIURI;
interface nsIWebBrowserChrome;
[scriptable, uuid(e28f810b-9b49-4927-a4be-62a74fadfe21)]
[scriptable, uuid(b6c44689-f97e-4f32-a723-29eeddfbdc53)]
interface nsIWindowCreator2 : nsIWindowCreator {
@ -59,4 +59,14 @@ interface nsIWindowCreator2 : nsIWindowCreator {
in nsIURI uri,
in nsITabParent aOpeningTab,
out boolean cancel);
/**
* B2G multi-screen support. When open another top-level window on b2g,
* a screen ID is needed for identifying which screen this window is
* opened to.
* @param aScreenId Differentiate screens of windows. It is platform-
* specific due to the hardware limitation for now.
*/
[noscript]
void setScreenId(in uint32_t aScreenId);
};

View File

@ -614,6 +614,17 @@ nsAppStartup::CreateChromeWindow(nsIWebBrowserChrome *aParent,
// nsAppStartup->nsIWindowCreator2
//
NS_IMETHODIMP
nsAppStartup::SetScreenId(uint32_t aScreenId)
{
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
if (!appShell) {
return NS_ERROR_FAILURE;
}
return appShell->SetScreenId(aScreenId);
}
NS_IMETHODIMP
nsAppStartup::CreateChromeWindow2(nsIWebBrowserChrome *aParent,
uint32_t aChromeFlags,

View File

@ -639,7 +639,6 @@ StartBootAnimation()
pthread_create(&sAnimationThread, nullptr, AnimationThread, nullptr);
}
void
StopBootAnimation()
{

View File

@ -128,16 +128,15 @@ GonkDisplayJB::GonkDisplayJB()
#else
sp<Surface> stc = new Surface(producer);
#endif
mSTClient = stc;
mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_BUFFER_COUNT, 2);
mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_USAGE,
GRALLOC_USAGE_HW_FB |
GRALLOC_USAGE_HW_RENDER |
GRALLOC_USAGE_HW_COMPOSER);
mList = (hwc_display_contents_1_t *)malloc(sizeof(*mList) + (sizeof(hwc_layer_1_t)*2));
if (mHwc) {
uint32_t usage = GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER;
if (mFBDevice) {
// If device uses fb, they can not use single buffer for boot animation
mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_BUFFER_COUNT, 2);
mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_USAGE, usage);
} else if (mHwc) {
#if ANDROID_VERSION >= 21
if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_4) {
mHwc->setPowerMode(mHwc, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_NORMAL);
@ -147,9 +146,11 @@ GonkDisplayJB::GonkDisplayJB()
#else
mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, 0);
#endif
// For devices w/ hwc v1.0 or no hwc, this buffer can not be created,
// only create this buffer for devices w/ hwc version > 1.0.
mBootAnimBuffer = mAlloc->createGraphicBuffer(mWidth, mHeight, surfaceformat, usage, &err);
}
ALOGI("Starting bootanimation with (%d) format framebuffer", surfaceformat);
StartBootAnimation();
}
@ -166,7 +167,9 @@ GonkDisplayJB::~GonkDisplayJB()
ANativeWindow*
GonkDisplayJB::GetNativeWindow()
{
StopBootAnimation();
if (!mBootAnimBuffer.get()) {
StopBootAnimation();
}
return mSTClient.get();
}
@ -232,6 +235,11 @@ GonkDisplayJB::GetDispSurface()
bool
GonkDisplayJB::SwapBuffers(EGLDisplay dpy, EGLSurface sur)
{
if (mBootAnimBuffer.get()) {
StopBootAnimation();
mBootAnimBuffer = nullptr;
}
// Should be called when composition rendering is complete for a frame.
// Only HWC v1.0 needs this call.
// HWC > v1.0 case, do not call compositionComplete().
@ -307,6 +315,9 @@ GonkDisplayJB::Post(buffer_handle_t buf, int fence)
ANativeWindowBuffer*
GonkDisplayJB::DequeueBuffer()
{
if (mBootAnimBuffer.get()) {
return static_cast<ANativeWindowBuffer*>(mBootAnimBuffer.get());
}
ANativeWindowBuffer *buf;
mSTClient->dequeueBuffer(mSTClient.get(), &buf, &mFence);
return buf;
@ -316,14 +327,20 @@ bool
GonkDisplayJB::QueueBuffer(ANativeWindowBuffer* buf)
{
bool success = Post(buf->handle, -1);
int error = mSTClient->queueBuffer(mSTClient.get(), buf, mFence);
int error = 0;
if (!mBootAnimBuffer.get()) {
error = mSTClient->queueBuffer(mSTClient.get(), buf, mFence);
}
return error == 0 && success;
}
void
GonkDisplayJB::UpdateDispSurface(EGLDisplay dpy, EGLSurface sur)
{
if (mBootAnimBuffer.get()) {
StopBootAnimation();
mBootAnimBuffer = nullptr;
}
eglSwapBuffers(dpy, sur);
}

View File

@ -63,6 +63,7 @@ private:
android::sp<android::DisplaySurface> mDispSurface;
android::sp<ANativeWindow> mSTClient;
android::sp<android::IGraphicBufferAlloc> mAlloc;
android::sp<android::GraphicBuffer> mBootAnimBuffer;
int mFence;
hwc_display_contents_1_t* mList;
uint32_t mWidth;

View File

@ -316,7 +316,7 @@ KeyEventDispatcher::DispatchKeyEventInternal(uint32_t aEventMessage)
event.modifiers = getDOMModifiers(mData.metaState);
event.location = mDOMKeyLocation;
event.time = mData.timeMs;
return nsWindow::DispatchInputEvent(event);
return nsWindow::DispatchKeyInput(event);
}
void

View File

@ -45,7 +45,7 @@
#include "BasicLayers.h"
#include "libdisplay/GonkDisplay.h"
#include "pixelflinger/format.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/TextEvents.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/APZCTreeManager.h"
@ -198,7 +198,7 @@ nsWindow::ConfigureAPZControllerThread()
}
/*static*/ nsEventStatus
nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent)
nsWindow::DispatchKeyInput(WidgetKeyboardEvent& aEvent)
{
if (!gFocusedWindow) {
return nsEventStatus_eIgnore;

View File

@ -39,7 +39,7 @@ public:
NS_DECL_ISUPPORTS_INHERITED
static void DoDraw(void);
static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent);
static nsEventStatus DispatchKeyInput(mozilla::WidgetKeyboardEvent& aEvent);
static void DispatchTouchInput(mozilla::MultiTouchInput& aInput);
NS_IMETHOD Create(nsIWidget *aParent,

View File

@ -94,8 +94,9 @@ struct nsWidgetInitData {
mBorderStyle(eBorderStyle_default),
mPopupHint(ePopupTypePanel),
mPopupLevel(ePopupLevelTop),
clipChildren(false),
clipSiblings(false),
mScreenId(0),
clipChildren(false),
clipSiblings(false),
mDropShadow(false),
mListenForResizes(false),
mUnicode(true),
@ -113,6 +114,10 @@ struct nsWidgetInitData {
nsBorderStyle mBorderStyle;
nsPopupType mPopupHint;
nsPopupLevel mPopupLevel;
// B2G multi-screen support. Screen ID is for differentiating screens of
// windows, and due to the hardware limitation, it is platform-specific for
// now, which align with the value of display type defined in HWC.
uint32_t mScreenId;
// when painting exclude area occupied by child windows and sibling windows
bool clipChildren, clipSiblings, mDropShadow;
bool mListenForResizes;

View File

@ -58,11 +58,12 @@ using namespace mozilla;
class nsIAppShell;
nsAppShellService::nsAppShellService() :
nsAppShellService::nsAppShellService() :
mXPCOMWillShutDown(false),
mXPCOMShuttingDown(false),
mModalWindowCount(0),
mApplicationProvidedHiddenWindow(false)
mApplicationProvidedHiddenWindow(false),
mScreenId(0)
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
@ -90,6 +91,13 @@ nsAppShellService::CreateHiddenWindow()
return CreateHiddenWindowHelper(false);
}
NS_IMETHODIMP
nsAppShellService::SetScreenId(uint32_t aScreenId)
{
mScreenId = aScreenId;
return NS_OK;
}
void
nsAppShellService::EnsurePrivateHiddenWindow()
{
@ -600,6 +608,13 @@ nsAppShellService::JustCreateTopWindow(nsIXULWindow *aParent,
widgetInitData.mRTL = isRTL;
}
#ifdef MOZ_WIDGET_GONK
// B2G multi-screen support. Screen ID is for differentiating screens of
// windows, and due to the hardware limitation, it is platform-specific for
// now, which align with the value of display type defined in HWC.
widgetInitData.mScreenId = mScreenId;
#endif
nsresult rv = window->Initialize(parent, center ? aParent : nullptr,
aUrl, aInitialWidth, aInitialHeight,
aIsHiddenWindow, aOpeningTab, widgetInitData);

View File

@ -51,6 +51,7 @@ protected:
bool mXPCOMShuttingDown;
uint16_t mModalWindowCount;
bool mApplicationProvidedHiddenWindow;
uint32_t mScreenId;
};
#endif

View File

@ -18,7 +18,7 @@ interface nsITabParent;
#include "js/TypeDecls.h"
%}
[scriptable, uuid(41a2f0c6-3ca1-44f9-8efa-744a43aa399d)]
[scriptable, uuid(83f23c7e-6ce0-433f-9fe2-f287ae8c6e0c)]
interface nsIAppShellService : nsISupports
{
/**
@ -60,6 +60,16 @@ interface nsIAppShellService : nsISupports
void destroyHiddenWindow();
/**
* B2G multi-screen support. When open another top-level window on b2g,
* a screen ID is needed for identifying which screen this window is
* opened to.
* @param aScreenId Differentiate screens of windows. It is platform-
* specific due to the hardware limitation for now.
*/
[noscript]
void setScreenId(in uint32_t aScreenId);
/**
* Return the (singleton) application hidden window, automatically created
* and maintained by this AppShellService.