mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound.
This commit is contained in:
commit
849edcd80b
@ -188,6 +188,7 @@ let FormAssistant = {
|
|||||||
addEventListener("beforeunload", this, true, false);
|
addEventListener("beforeunload", this, true, false);
|
||||||
addEventListener("input", this, true, false);
|
addEventListener("input", this, true, false);
|
||||||
addEventListener("keydown", this, true, false);
|
addEventListener("keydown", this, true, false);
|
||||||
|
addEventListener("keyup", this, true, false);
|
||||||
addMessageListener("Forms:Select:Choice", this);
|
addMessageListener("Forms:Select:Choice", this);
|
||||||
addMessageListener("Forms:Input:Value", this);
|
addMessageListener("Forms:Input:Value", this);
|
||||||
addMessageListener("Forms:Select:Blur", this);
|
addMessageListener("Forms:Select:Blur", this);
|
||||||
@ -261,6 +262,7 @@ let FormAssistant = {
|
|||||||
// current input field has changed.
|
// current input field has changed.
|
||||||
EditAction: function fa_editAction() {
|
EditAction: function fa_editAction() {
|
||||||
if (this._editing) {
|
if (this._editing) {
|
||||||
|
this._editing = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.sendKeyboardState(this.focusedElement);
|
this.sendKeyboardState(this.focusedElement);
|
||||||
@ -359,12 +361,15 @@ let FormAssistant = {
|
|||||||
this._editing = true;
|
this._editing = true;
|
||||||
|
|
||||||
// We use 'setTimeout' to wait until the input element accomplishes the
|
// We use 'setTimeout' to wait until the input element accomplishes the
|
||||||
// change in selection range or text content.
|
// change in selection range.
|
||||||
content.setTimeout(function() {
|
content.setTimeout(function() {
|
||||||
this.updateSelection();
|
this.updateSelection();
|
||||||
this._editing = false;
|
|
||||||
}.bind(this), 0);
|
}.bind(this), 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "keyup":
|
||||||
|
this._editing = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -31,7 +31,9 @@ window.addEventListener('load', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('unload', function() {
|
window.addEventListener('unload', function() {
|
||||||
Services.obs.removeObserver(runAppObj, 'browser-ui-startup-complete');
|
if (runAppObj) {
|
||||||
|
Services.obs.removeObserver(runAppObj, 'browser-ui-startup-complete');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function AppRunner(aName) {
|
function AppRunner(aName) {
|
||||||
|
@ -611,6 +611,9 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
|
|||||||
// don't keep trying to decode if the decoder doesn't want to.
|
// don't keep trying to decode if the decoder doesn't want to.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (err != OK && err != -ETIMEDOUT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -664,6 +667,9 @@ bool OmxDecoder::ReadAudio(AudioFrame *aFrame, int64_t aSeekTimeUs)
|
|||||||
else if (err == UNKNOWN_ERROR) {
|
else if (err == UNKNOWN_ERROR) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (err != OK && err != -ETIMEDOUT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
#include "mozilla/Hal.h"
|
#include "mozilla/Hal.h"
|
||||||
#include "AudioManager.h"
|
#include "AudioManager.h"
|
||||||
#include "android_audio/AudioSystem.h"
|
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "AudioChannelService.h"
|
#include "AudioChannelService.h"
|
||||||
@ -36,6 +35,8 @@ using namespace mozilla;
|
|||||||
#define HEADPHONES_STATUS_UNKNOWN NS_LITERAL_STRING("unknown").get()
|
#define HEADPHONES_STATUS_UNKNOWN NS_LITERAL_STRING("unknown").get()
|
||||||
#define BLUETOOTH_SCO_STATUS_CHANGED "bluetooth-sco-status-changed"
|
#define BLUETOOTH_SCO_STATUS_CHANGED "bluetooth-sco-status-changed"
|
||||||
|
|
||||||
|
static void BinderDeadCallback(status_t aErr);
|
||||||
|
static void InternalSetAudioRoutes(SwitchState aState);
|
||||||
// Refer AudioService.java from Android
|
// Refer AudioService.java from Android
|
||||||
static int sMaxStreamVolumeTbl[AUDIO_STREAM_CNT] = {
|
static int sMaxStreamVolumeTbl[AUDIO_STREAM_CNT] = {
|
||||||
5, // voice call
|
5, // voice call
|
||||||
@ -51,9 +52,48 @@ static int sMaxStreamVolumeTbl[AUDIO_STREAM_CNT] = {
|
|||||||
15, // FM
|
15, // FM
|
||||||
};
|
};
|
||||||
// A bitwise variable for recording what kind of headset is attached.
|
// A bitwise variable for recording what kind of headset is attached.
|
||||||
static int sHeadsetState;
|
static int sHeadsetState = SWITCH_STATE_OFF;
|
||||||
static int kBtSampleRate = 8000;
|
static int kBtSampleRate = 8000;
|
||||||
|
|
||||||
|
class RecoverTask : public nsRunnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RecoverTask() {}
|
||||||
|
NS_IMETHODIMP Run() {
|
||||||
|
nsCOMPtr<nsIAudioManager> am = do_GetService(NS_AUDIOMANAGER_CONTRACTID);
|
||||||
|
NS_ENSURE_TRUE(am, NS_OK);
|
||||||
|
for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
|
||||||
|
AudioSystem::initStreamVolume(static_cast<audio_stream_type_t>(i), 0,
|
||||||
|
sMaxStreamVolumeTbl[i]);
|
||||||
|
int32_t volidx = 0;
|
||||||
|
am->GetStreamVolumeIndex(i, &volidx);
|
||||||
|
am->SetStreamVolumeIndex(static_cast<audio_stream_type_t>(i),
|
||||||
|
volidx);
|
||||||
|
}
|
||||||
|
if (sHeadsetState & AUDIO_DEVICE_OUT_WIRED_HEADSET)
|
||||||
|
InternalSetAudioRoutes(SWITCH_STATE_HEADSET);
|
||||||
|
else if (sHeadsetState & AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
|
||||||
|
InternalSetAudioRoutes(SWITCH_STATE_HEADPHONE);
|
||||||
|
else
|
||||||
|
InternalSetAudioRoutes(SWITCH_STATE_OFF);
|
||||||
|
|
||||||
|
int32_t phoneState = nsIAudioManager::PHONE_STATE_INVALID;
|
||||||
|
am->GetPhoneState(&phoneState);
|
||||||
|
AudioSystem::setPhoneState(phoneState);
|
||||||
|
|
||||||
|
AudioSystem::get_audio_flinger();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
BinderDeadCallback(status_t aErr)
|
||||||
|
{
|
||||||
|
if (aErr == DEAD_OBJECT) {
|
||||||
|
NS_DispatchToMainThread(new RecoverTask());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsDeviceOn(audio_devices_t device)
|
IsDeviceOn(audio_devices_t device)
|
||||||
{
|
{
|
||||||
@ -145,7 +185,7 @@ AudioManager::Observe(nsISupports* aSubject,
|
|||||||
const PRUnichar* aData)
|
const PRUnichar* aData)
|
||||||
{
|
{
|
||||||
if (!strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED)) {
|
if (!strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED)) {
|
||||||
if (aData) {
|
if (NS_strlen(aData) > 0) {
|
||||||
String8 cmd;
|
String8 cmd;
|
||||||
cmd.appendFormat("bt_samplerate=%d", kBtSampleRate);
|
cmd.appendFormat("bt_samplerate=%d", kBtSampleRate);
|
||||||
AudioSystem::setParameters(0, cmd);
|
AudioSystem::setParameters(0, cmd);
|
||||||
@ -214,10 +254,13 @@ AudioManager::AudioManager() : mPhoneState(PHONE_STATE_CURRENT),
|
|||||||
for (int loop = 0; loop < AUDIO_STREAM_CNT; loop++) {
|
for (int loop = 0; loop < AUDIO_STREAM_CNT; loop++) {
|
||||||
AudioSystem::initStreamVolume(static_cast<audio_stream_type_t>(loop), 0,
|
AudioSystem::initStreamVolume(static_cast<audio_stream_type_t>(loop), 0,
|
||||||
sMaxStreamVolumeTbl[loop]);
|
sMaxStreamVolumeTbl[loop]);
|
||||||
|
mCurrentStreamVolumeTbl[loop] = sMaxStreamVolumeTbl[loop];
|
||||||
}
|
}
|
||||||
// Force publicnotification to output at maximal volume
|
// Force publicnotification to output at maximal volume
|
||||||
AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_ENFORCED_AUDIBLE),
|
AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_ENFORCED_AUDIBLE),
|
||||||
sMaxStreamVolumeTbl[AUDIO_STREAM_ENFORCED_AUDIBLE]);
|
sMaxStreamVolumeTbl[AUDIO_STREAM_ENFORCED_AUDIBLE]);
|
||||||
|
|
||||||
|
AudioSystem::setErrorCallback(BinderDeadCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioManager::~AudioManager() {
|
AudioManager::~AudioManager() {
|
||||||
@ -225,7 +268,7 @@ AudioManager::~AudioManager() {
|
|||||||
|
|
||||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||||
if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_SCO_STATUS_CHANGED))) {
|
if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_SCO_STATUS_CHANGED))) {
|
||||||
NS_WARNING("Failed to add bluetooth-sco-status-changed oberver!");
|
NS_WARNING("Failed to remove bluetooth-sco-status-changed oberver!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,6 +453,7 @@ AudioManager::SetFmRadioAudioEnabled(bool aFmRadioAudioEnabled)
|
|||||||
int32_t volIndex = 0;
|
int32_t volIndex = 0;
|
||||||
AudioSystem::getStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_MUSIC), &volIndex);
|
AudioSystem::getStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_MUSIC), &volIndex);
|
||||||
AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_FM), volIndex);
|
AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_FM), volIndex);
|
||||||
|
mCurrentStreamVolumeTbl[AUDIO_STREAM_FM] = volIndex;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
} else {
|
} else {
|
||||||
@ -425,16 +469,17 @@ AudioManager::SetStreamVolumeIndex(int32_t aStream, int32_t aIndex) {
|
|||||||
// sync fm volume with music stream type
|
// sync fm volume with music stream type
|
||||||
if (aStream == AUDIO_STREAM_MUSIC && IsDeviceOn(AUDIO_DEVICE_OUT_FM)) {
|
if (aStream == AUDIO_STREAM_MUSIC && IsDeviceOn(AUDIO_DEVICE_OUT_FM)) {
|
||||||
AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_FM), aIndex);
|
AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_FM), aIndex);
|
||||||
|
mCurrentStreamVolumeTbl[AUDIO_STREAM_FM] = aIndex;
|
||||||
}
|
}
|
||||||
|
mCurrentStreamVolumeTbl[aStream] = aIndex;
|
||||||
|
|
||||||
return status ? NS_ERROR_FAILURE : NS_OK;
|
return status ? NS_ERROR_FAILURE : NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
AudioManager::GetStreamVolumeIndex(int32_t aStream, int32_t* aIndex) {
|
AudioManager::GetStreamVolumeIndex(int32_t aStream, int32_t* aIndex) {
|
||||||
status_t status =
|
*aIndex = mCurrentStreamVolumeTbl[aStream];
|
||||||
AudioSystem::getStreamVolumeIndex(static_cast<audio_stream_type_t>(aStream), aIndex);
|
return NS_OK;
|
||||||
return status ? NS_ERROR_FAILURE : NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "nsIAudioManager.h"
|
#include "nsIAudioManager.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "AudioChannelAgent.h"
|
#include "AudioChannelAgent.h"
|
||||||
|
#include "android_audio/AudioSystem.h"
|
||||||
|
|
||||||
// {b2b51423-502d-4d77-89b3-7786b562b084}
|
// {b2b51423-502d-4d77-89b3-7786b562b084}
|
||||||
#define NS_AUDIOMANAGER_CID {0x94f6fd70, 0x7615, 0x4af9, \
|
#define NS_AUDIOMANAGER_CID {0x94f6fd70, 0x7615, 0x4af9, \
|
||||||
@ -51,6 +52,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
int32_t mPhoneState;
|
int32_t mPhoneState;
|
||||||
|
int mCurrentStreamVolumeTbl[AUDIO_STREAM_CNT];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsAutoPtr<mozilla::hal::SwitchObserver> mObserver;
|
nsAutoPtr<mozilla::hal::SwitchObserver> mObserver;
|
||||||
|
@ -10170,10 +10170,7 @@ let ICCRecordHelper = {
|
|||||||
", spnDisplayCondition = " + spnDisplayCondition);
|
", spnDisplayCondition = " + spnDisplayCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
RIL.iccInfoPrivate.SPN = {
|
RIL.iccInfoPrivate.spnDisplayCondition = spnDisplayCondition;
|
||||||
spn : spn,
|
|
||||||
spnDisplayCondition : spnDisplayCondition,
|
|
||||||
};
|
|
||||||
RIL.iccInfo.spn = spn;
|
RIL.iccInfo.spn = spn;
|
||||||
ICCUtilsHelper.updateDisplayCondition();
|
ICCUtilsHelper.updateDisplayCondition();
|
||||||
ICCUtilsHelper.handleICCInfoChange();
|
ICCUtilsHelper.handleICCInfoChange();
|
||||||
@ -11138,11 +11135,11 @@ let ICCUtilsHelper = {
|
|||||||
// isDisplaySpnRequired = false
|
// isDisplaySpnRequired = false
|
||||||
let iccInfo = RIL.iccInfo;
|
let iccInfo = RIL.iccInfo;
|
||||||
let iccInfoPriv = RIL.iccInfoPrivate;
|
let iccInfoPriv = RIL.iccInfoPrivate;
|
||||||
let iccSpn = iccInfoPriv.SPN;
|
let displayCondition = iccInfoPriv.spnDisplayCondition;
|
||||||
let origIsDisplayNetworkNameRequired = iccInfo.isDisplayNetworkNameRequired;
|
let origIsDisplayNetworkNameRequired = iccInfo.isDisplayNetworkNameRequired;
|
||||||
let origIsDisplaySPNRequired = iccInfo.isDisplaySpnRequired;
|
let origIsDisplaySPNRequired = iccInfo.isDisplaySpnRequired;
|
||||||
|
|
||||||
if (!iccSpn) {
|
if (displayCondition === undefined) {
|
||||||
iccInfo.isDisplayNetworkNameRequired = true;
|
iccInfo.isDisplayNetworkNameRequired = true;
|
||||||
iccInfo.isDisplaySpnRequired = false;
|
iccInfo.isDisplaySpnRequired = false;
|
||||||
} else if (RIL._isCdma) {
|
} else if (RIL._isCdma) {
|
||||||
@ -11153,9 +11150,9 @@ let ICCUtilsHelper = {
|
|||||||
|
|
||||||
iccInfo.isDisplayNetworkNameRequired = false;
|
iccInfo.isDisplayNetworkNameRequired = false;
|
||||||
|
|
||||||
// If display condition is false, we don't even need to check network id
|
// If display condition is 0x0, we don't even need to check network id
|
||||||
// or system id.
|
// or system id.
|
||||||
if (iccSpn.spnDisplayCondition == false) {
|
if (displayCondition == 0x0) {
|
||||||
iccInfo.isDisplaySpnRequired = false;
|
iccInfo.isDisplaySpnRequired = false;
|
||||||
} else {
|
} else {
|
||||||
// CDMA SPN Display condition dosen't specify whenever network name is
|
// CDMA SPN Display condition dosen't specify whenever network name is
|
||||||
@ -11227,11 +11224,7 @@ let ICCUtilsHelper = {
|
|||||||
// EF_SPDI contains a list of PLMNs in which the Service Provider Name
|
// EF_SPDI contains a list of PLMNs in which the Service Provider Name
|
||||||
// shall be displayed.
|
// shall be displayed.
|
||||||
iccInfo.isDisplaySpnRequired = true;
|
iccInfo.isDisplaySpnRequired = true;
|
||||||
if (iccSpn.spnDisplayCondition & 0x01) {
|
iccInfo.isDisplayNetworkNameRequired = (displayCondition & 0x01) != 0;
|
||||||
iccInfo.isDisplayNetworkNameRequired = true;
|
|
||||||
} else {
|
|
||||||
iccInfo.isDisplayNetworkNameRequired = false;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// The second bit of display condition tells us if we should display
|
// The second bit of display condition tells us if we should display
|
||||||
// registered PLMN.
|
// registered PLMN.
|
||||||
@ -11240,13 +11233,8 @@ let ICCUtilsHelper = {
|
|||||||
// We didn't found the requirement of displaying network name if
|
// We didn't found the requirement of displaying network name if
|
||||||
// current PLMN isn't HPLMN nor one of PLMN in SPDI. So we keep
|
// current PLMN isn't HPLMN nor one of PLMN in SPDI. So we keep
|
||||||
// isDisplayNetworkNameRequired false.
|
// isDisplayNetworkNameRequired false.
|
||||||
if (iccSpn.spnDisplayCondition & 0x02) {
|
iccInfo.isDisplayNetworkNameRequired = false;
|
||||||
iccInfo.isDisplayNetworkNameRequired = false;
|
iccInfo.isDisplaySpnRequired = (displayCondition & 0x02) == 0;
|
||||||
iccInfo.isDisplaySpnRequired = false;
|
|
||||||
} else {
|
|
||||||
iccInfo.isDisplayNetworkNameRequired = false;
|
|
||||||
iccInfo.isDisplaySpnRequired = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12069,9 +12057,7 @@ let RuimRecordHelper = {
|
|||||||
debug("CDMA SPN: " + RIL.iccInfo.spn +
|
debug("CDMA SPN: " + RIL.iccInfo.spn +
|
||||||
", Display condition: " + displayCondition);
|
", Display condition: " + displayCondition);
|
||||||
}
|
}
|
||||||
RIL.iccInfoPrivate.SPN = {
|
RIL.iccInfoPrivate.spnDisplayCondition = displayCondition;
|
||||||
spnDisplayCondition: displayCondition
|
|
||||||
};
|
|
||||||
Buf.seekIncoming((octetLen - readLen) * PDU_HEX_OCTET_SIZE);
|
Buf.seekIncoming((octetLen - readLen) * PDU_HEX_OCTET_SIZE);
|
||||||
Buf.readStringDelimiter(strLen);
|
Buf.readStringDelimiter(strLen);
|
||||||
}
|
}
|
||||||
|
@ -975,9 +975,7 @@ add_test(function test_spn_display_condition() {
|
|||||||
expectedIsDisplayNetworkNameRequired,
|
expectedIsDisplayNetworkNameRequired,
|
||||||
expectedIsDisplaySPNRequired,
|
expectedIsDisplaySPNRequired,
|
||||||
callback) {
|
callback) {
|
||||||
RIL.iccInfoPrivate.SPN = {
|
RIL.iccInfoPrivate.spnDisplayCondition = iccDisplayCondition;
|
||||||
spnDisplayCondition: iccDisplayCondition
|
|
||||||
};
|
|
||||||
RIL.iccInfo = {
|
RIL.iccInfo = {
|
||||||
mcc: iccMcc,
|
mcc: iccMcc,
|
||||||
mnc: iccMnc
|
mnc: iccMnc
|
||||||
|
@ -143,7 +143,7 @@ add_test(function test_read_cdmaspn() {
|
|||||||
|
|
||||||
worker.RuimRecordHelper.readSPN();
|
worker.RuimRecordHelper.readSPN();
|
||||||
do_check_eq(worker.RIL.iccInfo.spn, expectedSpn);
|
do_check_eq(worker.RIL.iccInfo.spn, expectedSpn);
|
||||||
do_check_eq(worker.RIL.iccInfoPrivate.SPN.spnDisplayCondition,
|
do_check_eq(worker.RIL.iccInfoPrivate.spnDisplayCondition,
|
||||||
expectedDisplayCondition);
|
expectedDisplayCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ add_test(function test_read_cdmaspn() {
|
|||||||
String.fromCharCode(0x592a) +
|
String.fromCharCode(0x592a) +
|
||||||
String.fromCharCode(0x96fb) +
|
String.fromCharCode(0x96fb) +
|
||||||
String.fromCharCode(0x4fe1),
|
String.fromCharCode(0x4fe1),
|
||||||
true);
|
0x1);
|
||||||
|
|
||||||
// Test when there's no tailing 0xff in spn string.
|
// Test when there's no tailing 0xff in spn string.
|
||||||
testReadSpn([0x01, 0x04, 0x06, 0x4e, 0x9e, 0x59, 0x2a, 0x96,
|
testReadSpn([0x01, 0x04, 0x06, 0x4e, 0x9e, 0x59, 0x2a, 0x96,
|
||||||
@ -165,7 +165,7 @@ add_test(function test_read_cdmaspn() {
|
|||||||
String.fromCharCode(0x592a) +
|
String.fromCharCode(0x592a) +
|
||||||
String.fromCharCode(0x96fb) +
|
String.fromCharCode(0x96fb) +
|
||||||
String.fromCharCode(0x4fe1),
|
String.fromCharCode(0x4fe1),
|
||||||
true);
|
0x1);
|
||||||
|
|
||||||
run_next_test();
|
run_next_test();
|
||||||
});
|
});
|
||||||
@ -199,9 +199,7 @@ add_test(function test_cdma_spn_display_condition() {
|
|||||||
currentSystemId, currentNetworkId,
|
currentSystemId, currentNetworkId,
|
||||||
expectUpdateDisplayCondition,
|
expectUpdateDisplayCondition,
|
||||||
expectIsDisplaySPNRequired) {
|
expectIsDisplaySPNRequired) {
|
||||||
RIL.iccInfoPrivate.SPN = {
|
RIL.iccInfoPrivate.spnDisplayCondition = ruimDisplayCondition;
|
||||||
spnDisplayCondition: ruimDisplayCondition
|
|
||||||
};
|
|
||||||
RIL.cdmaHome = {
|
RIL.cdmaHome = {
|
||||||
systemId: homeSystemIds,
|
systemId: homeSystemIds,
|
||||||
networkId: homeNetworkIds
|
networkId: homeNetworkIds
|
||||||
@ -217,16 +215,16 @@ add_test(function test_cdma_spn_display_condition() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// SPN is not required when ruimDisplayCondition is false.
|
// SPN is not required when ruimDisplayCondition is false.
|
||||||
testDisplayCondition(false, [123], [345], 123, 345, true, false);
|
testDisplayCondition(0x0, [123], [345], 123, 345, true, false);
|
||||||
|
|
||||||
// System id and network id are all match.
|
// System id and network id are all match.
|
||||||
testDisplayCondition(true, [123], [345], 123, 345, true, true);
|
testDisplayCondition(0x1, [123], [345], 123, 345, true, true);
|
||||||
|
|
||||||
// Network is 65535, we should only need to match system id.
|
// Network is 65535, we should only need to match system id.
|
||||||
testDisplayCondition(true, [123], [65535], 123, 345, false, true);
|
testDisplayCondition(0x1, [123], [65535], 123, 345, false, true);
|
||||||
|
|
||||||
// Not match.
|
// Not match.
|
||||||
testDisplayCondition(true, [123], [456], 123, 345, true, false);
|
testDisplayCondition(0x1, [123], [456], 123, 345, true, false);
|
||||||
|
|
||||||
run_next_test();
|
run_next_test();
|
||||||
});
|
});
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
# 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/.
|
|
||||||
|
|
||||||
[marionette]
|
|
||||||
es_server = buildbot-es.metrics.sjc1.mozilla.com:9200
|
|
||||||
rest_server = http://brasstacks.mozilla.com/autologserver/
|
|
||||||
|
|
||||||
[tests]
|
|
||||||
marionette = tests/unit-tests.ini
|
|
||||||
marionette-gaia = $homedir$/gaia/tests
|
|
||||||
|
|
@ -1,222 +0,0 @@
|
|||||||
# 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/.
|
|
||||||
|
|
||||||
# This function will run the pulse build watcher,
|
|
||||||
# then on detecting a build, it will run the tests
|
|
||||||
# using that build.
|
|
||||||
|
|
||||||
import ConfigParser
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import traceback
|
|
||||||
import urllib
|
|
||||||
import mozlog
|
|
||||||
import shutil
|
|
||||||
from optparse import OptionParser
|
|
||||||
from threading import Thread, RLock
|
|
||||||
from manifestparser import TestManifest
|
|
||||||
from runtests import MarionetteTestRunner
|
|
||||||
from marionette import Marionette
|
|
||||||
from mozinstall import install
|
|
||||||
|
|
||||||
from mozillapulse.config import PulseConfiguration
|
|
||||||
from mozillapulse.consumers import GenericConsumer
|
|
||||||
|
|
||||||
|
|
||||||
class B2GPulseConsumer(GenericConsumer):
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
super(B2GPulseConsumer, self).__init__(PulseConfiguration(**kwargs),
|
|
||||||
'org.mozilla.exchange.b2g',
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class B2GAutomation:
|
|
||||||
def __init__(self, tests, testfile=None,
|
|
||||||
es_server=None, rest_server=None, testgroup='marionette'):
|
|
||||||
self.logger = mozlog.getLogger('B2G_AUTOMATION')
|
|
||||||
self.tests = tests
|
|
||||||
self.testfile = testfile
|
|
||||||
self.es_server = es_server
|
|
||||||
self.rest_server = rest_server
|
|
||||||
self.testgroup = testgroup
|
|
||||||
self.lock = RLock()
|
|
||||||
|
|
||||||
self.logger.info("Testlist: %s" % self.tests)
|
|
||||||
|
|
||||||
pulse = B2GPulseConsumer(applabel='b2g_build_listener')
|
|
||||||
pulse.configure(topic='#', callback=self.on_build)
|
|
||||||
|
|
||||||
if not self.testfile:
|
|
||||||
self.logger.info('waiting for pulse messages...')
|
|
||||||
pulse.listen()
|
|
||||||
else:
|
|
||||||
t = Thread(target=pulse.listen)
|
|
||||||
t.daemon = True
|
|
||||||
t.start()
|
|
||||||
f = open(self.testfile, 'r')
|
|
||||||
data = json.loads(f.read())
|
|
||||||
self.on_build(data, None)
|
|
||||||
|
|
||||||
def get_test_list(self, manifest):
|
|
||||||
self.logger.info("Reading test manifest: %s" % manifest)
|
|
||||||
mft = TestManifest()
|
|
||||||
mft.read(manifest)
|
|
||||||
|
|
||||||
# In the future if we want to add in more processing to the manifest
|
|
||||||
# here is where you'd do that. Right now, we just return a list of
|
|
||||||
# tests
|
|
||||||
testlist = []
|
|
||||||
for i in mft.active_tests(exists=False, disabled=False):
|
|
||||||
testlist.append(i["path"])
|
|
||||||
|
|
||||||
return testlist
|
|
||||||
|
|
||||||
def on_build(self, data, msg):
|
|
||||||
# Found marionette build! Install it
|
|
||||||
if msg is not None:
|
|
||||||
msg.ack()
|
|
||||||
self.lock.acquire()
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.logger.info("got pulse message! %s" % repr(data))
|
|
||||||
if "buildurl" in data["payload"]:
|
|
||||||
directory = self.install_build(data['payload']['buildurl'])
|
|
||||||
rev = data["payload"]["commit"]
|
|
||||||
if directory == None:
|
|
||||||
self.logger.info("Failed to return build directory")
|
|
||||||
else:
|
|
||||||
self.run_marionette(directory, rev)
|
|
||||||
self.cleanup(directory)
|
|
||||||
else:
|
|
||||||
self.logger.error("Failed to find buildurl in msg, not running test")
|
|
||||||
|
|
||||||
except:
|
|
||||||
self.logger.exception("error while processing build")
|
|
||||||
|
|
||||||
self.lock.release()
|
|
||||||
|
|
||||||
# Download the build and untar it, return the directory it untared to
|
|
||||||
def install_build(self, url):
|
|
||||||
try:
|
|
||||||
self.logger.info("Installing build from url: %s" % url)
|
|
||||||
buildfile = os.path.abspath("b2gtarball.tar.gz")
|
|
||||||
urllib.urlretrieve(url, buildfile)
|
|
||||||
except:
|
|
||||||
self.logger.exception("Failed to download build")
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.logger.info("Untarring build")
|
|
||||||
# Extract to the same local directory where we downloaded the build
|
|
||||||
# to. This defaults to the local directory where our script runs
|
|
||||||
dest = os.path.join(os.path.dirname(buildfile), 'downloadedbuild')
|
|
||||||
if (os.access(dest, os.F_OK)):
|
|
||||||
shutil.rmtree(dest)
|
|
||||||
install(buildfile, dest)
|
|
||||||
# This should extract into a qemu directory
|
|
||||||
qemu = os.path.join(dest, 'qemu')
|
|
||||||
if os.path.exists(qemu):
|
|
||||||
return qemu
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
except:
|
|
||||||
self.logger.exception("Failed to untar file")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def run_marionette(self, dir, rev):
|
|
||||||
self.logger.info("Starting test run for revision: %s" % rev)
|
|
||||||
runner = MarionetteTestRunner(emulator=True,
|
|
||||||
homedir=dir,
|
|
||||||
autolog=True,
|
|
||||||
revision=rev,
|
|
||||||
logger=self.logger,
|
|
||||||
es_server=self.es_server,
|
|
||||||
rest_server=self.rest_server,
|
|
||||||
testgroup=self.testgroup)
|
|
||||||
for test in self.tests:
|
|
||||||
manifest = test[1].replace('$homedir$', os.path.dirname(dir))
|
|
||||||
testgroup = test[0]
|
|
||||||
runner.testgroup = testgroup
|
|
||||||
runner.run_tests([manifest], 'b2g')
|
|
||||||
|
|
||||||
def cleanup(self, dir):
|
|
||||||
self.logger.info("Cleaning up")
|
|
||||||
if os.path.exists("b2gtarball.tar.gz"):
|
|
||||||
os.remove("b2gtarball.tar.gz")
|
|
||||||
if os.path.exists(dir):
|
|
||||||
shutil.rmtree(dir)
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = OptionParser(usage="%prog <options>")
|
|
||||||
parser.add_option("--config", action="store", dest="config_file",
|
|
||||||
default="automation.conf",
|
|
||||||
help="Specify the configuration file")
|
|
||||||
parser.add_option("--testfile", action="store", dest="testfile",
|
|
||||||
help = "Start in test mode without using pulse, "
|
|
||||||
"utilizing the pulse message defined in the specified file")
|
|
||||||
parser.add_option("--test-manifest", action="store", dest="testmanifest",
|
|
||||||
default = os.path.join("tests","unit-tests.ini"),
|
|
||||||
help="Specify the test manifest, defaults to tests/all-tests.ini")
|
|
||||||
parser.add_option("--log-file", action="store", dest="logfile",
|
|
||||||
default="b2gautomation.log",
|
|
||||||
help="Log file to store results, defaults to b2gautomation.log")
|
|
||||||
|
|
||||||
LOG_LEVELS = ("DEBUG", "INFO", "WARNING", "ERROR")
|
|
||||||
LEVEL_STRING = ", ".join(LOG_LEVELS)
|
|
||||||
parser.add_option("--log-level", action="store", type="choice",
|
|
||||||
dest="loglevel", default="DEBUG", choices=LOG_LEVELS,
|
|
||||||
help = "One of %s for logging level, defaults to debug" % LEVEL_STRING)
|
|
||||||
options, args = parser.parse_args()
|
|
||||||
|
|
||||||
cfg = ConfigParser.ConfigParser()
|
|
||||||
cfg.read(options.config_file)
|
|
||||||
try:
|
|
||||||
es_server = cfg.get('marionette', 'es_server')
|
|
||||||
except:
|
|
||||||
# let mozautolog provide the default
|
|
||||||
es_server = None
|
|
||||||
try:
|
|
||||||
rest_server = cfg.get('marionette', 'rest_server')
|
|
||||||
except:
|
|
||||||
# let mozautolog provide the default
|
|
||||||
rest_server = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
tests = cfg.items('tests')
|
|
||||||
except:
|
|
||||||
tests = [('marionette', options.testmanifest)]
|
|
||||||
|
|
||||||
if not options.testmanifest:
|
|
||||||
parser.print_usage()
|
|
||||||
parser.exit()
|
|
||||||
|
|
||||||
if not os.path.exists(options.testmanifest):
|
|
||||||
print "Could not find manifest file: %s" % options.testmanifest
|
|
||||||
parser.print_usage()
|
|
||||||
parser.exit()
|
|
||||||
|
|
||||||
# Set up the logger
|
|
||||||
if os.path.exists(options.logfile):
|
|
||||||
os.remove(options.logfile)
|
|
||||||
|
|
||||||
logger = mozlog.getLogger("B2G_AUTOMATION", options.logfile)
|
|
||||||
if options.loglevel:
|
|
||||||
logger.setLevel(getattr(mozlog, options.loglevel, "DEBUG"))
|
|
||||||
logger.addHandler(logging.StreamHandler())
|
|
||||||
|
|
||||||
try:
|
|
||||||
b2gauto = B2GAutomation(tests,
|
|
||||||
testfile=options.testfile,
|
|
||||||
es_server=es_server,
|
|
||||||
rest_server=rest_server)
|
|
||||||
except:
|
|
||||||
s = traceback.format_exc()
|
|
||||||
logger.error(s)
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
|||||||
# 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/.
|
|
||||||
|
|
||||||
from git import *
|
|
||||||
from optparse import OptionParser
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def updategaia(repopath):
|
|
||||||
b2g = Repo(repopath)
|
|
||||||
gaia = Repo(os.path.join(repopath, 'gaia'))
|
|
||||||
|
|
||||||
gaia_submodule = None
|
|
||||||
for submodule in b2g.submodules:
|
|
||||||
if 'gaia' in submodule.name:
|
|
||||||
gaia_submodule = submodule
|
|
||||||
assert(gaia_submodule)
|
|
||||||
gaia_submodule_commit = gaia_submodule.hexsha
|
|
||||||
print 'gaia_submodule_commit', gaia_submodule_commit
|
|
||||||
|
|
||||||
gaia.heads.master.checkout()
|
|
||||||
print 'pulling from gaia origin/master'
|
|
||||||
gaia.remotes.origin.pull('master')
|
|
||||||
gaia_new_head = gaia.heads.master.commit.hexsha
|
|
||||||
print 'gaia_new_head', gaia_new_head
|
|
||||||
|
|
||||||
if gaia_submodule_commit == gaia_new_head:
|
|
||||||
print 'no change, exiting with code 10'
|
|
||||||
sys.exit(10)
|
|
||||||
|
|
||||||
def commitgaia(repopath):
|
|
||||||
b2g = Repo(repopath)
|
|
||||||
gaia = Repo(os.path.join(repopath, 'gaia'))
|
|
||||||
|
|
||||||
gaia_submodule = None
|
|
||||||
for submodule in b2g.submodules:
|
|
||||||
if 'gaia' in submodule.name:
|
|
||||||
gaia_submodule = submodule
|
|
||||||
assert(gaia_submodule)
|
|
||||||
|
|
||||||
gaia_submodule.binsha = gaia_submodule.module().head.commit.binsha
|
|
||||||
b2g.index.add([gaia_submodule])
|
|
||||||
commit = b2g.index.commit('Update gaia')
|
|
||||||
print 'pushing to B2G origin/master'
|
|
||||||
b2g.remotes.origin.push(b2g.head.reference)
|
|
||||||
print 'done!'
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
parser = OptionParser(usage='%prog [options]')
|
|
||||||
parser.add_option("--repo",
|
|
||||||
action = "store", dest = "repo",
|
|
||||||
help = "path to B2G repo")
|
|
||||||
parser.add_option("--updategaia",
|
|
||||||
action = "store_true", dest = "updategaia",
|
|
||||||
help = "update the Gaia submodule to HEAD")
|
|
||||||
parser.add_option("--commitgaia",
|
|
||||||
action = "store_true", dest = "commitgaia",
|
|
||||||
help = "commit current Gaia submodule HEAD")
|
|
||||||
options, tests = parser.parse_args()
|
|
||||||
|
|
||||||
if not options.repo:
|
|
||||||
raise 'must specify --repo /path/to/B2G'
|
|
||||||
|
|
||||||
if options.updategaia:
|
|
||||||
updategaia(options.repo)
|
|
||||||
elif options.commitgaia:
|
|
||||||
commitgaia(options.repo)
|
|
||||||
else:
|
|
||||||
raise 'No command specified'
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
# 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/.
|
|
||||||
|
|
||||||
from marionette import Marionette, HTMLElement
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
# launch Fennec with Marionette before starting this test!
|
|
||||||
m = Marionette(host='localhost', port=2828)
|
|
||||||
assert(m.start_session())
|
|
||||||
assert(10 == m.execute_script('return 10;'))
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
|||||||
# 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/.
|
|
||||||
|
|
||||||
import threading
|
|
||||||
from testserver import TestServer
|
|
||||||
from marionette import Marionette, HTMLElement
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
# start the test server
|
|
||||||
server = TestServer(2626)
|
|
||||||
thread = threading.Thread(target=server.run)
|
|
||||||
thread.daemon = True
|
|
||||||
thread.start()
|
|
||||||
|
|
||||||
# run some trivial unit tests which just verify the protocol
|
|
||||||
m = Marionette(host='localhost', port=2626)
|
|
||||||
assert(m.status()['os']['arch'] == 'x86')
|
|
||||||
assert(m.start_session())
|
|
||||||
assert(m.get_session_capabilities()['javascriptEnabled'] == True)
|
|
||||||
assert(m.current_window_handle == server.TEST_CURRENT_WINDOW)
|
|
||||||
assert(m.window == server.TEST_CURRENT_WINDOW)
|
|
||||||
assert(m.window_handles == server.TEST_WINDOW_LIST)
|
|
||||||
assert(m.switch_to_window('window2'))
|
|
||||||
assert(m.window == 'window2')
|
|
||||||
assert(m.close_window('window2'))
|
|
||||||
assert(m.set_script_timeout(1000))
|
|
||||||
assert(m.set_search_timeout(500))
|
|
||||||
assert(m.get_url() == server.TEST_URL)
|
|
||||||
assert(m.navigate(server.TEST_URL))
|
|
||||||
assert(m.go_back())
|
|
||||||
assert(m.go_forward())
|
|
||||||
assert(m.refresh())
|
|
||||||
assert(m.execute_script(server.TEST_EXECUTE_SCRIPT))
|
|
||||||
assert(m.execute_js_script(server.TEST_EXECUTE_SCRIPT))
|
|
||||||
assert(m.execute_js_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS))
|
|
||||||
assert(m.execute_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS))
|
|
||||||
assert(m.execute_async_script(server.TEST_EXECUTE_SCRIPT))
|
|
||||||
assert(m.execute_async_script(server.TEST_EXECUTE_SCRIPT, server.TEST_EXECUTE_SCRIPT_ARGS))
|
|
||||||
assert(str(m.find_element(HTMLElement.CLASS, 'heading')) == server.TEST_FIND_ELEMENT)
|
|
||||||
assert([str(x) for x in m.find_elements(HTMLElement.TAG, 'p')] == server.TEST_FIND_ELEMENTS)
|
|
||||||
assert(str(m.find_element(HTMLElement.CLASS, 'heading').find_element(HTMLElement.TAG, 'h1')) == server.TEST_FIND_ELEMENT)
|
|
||||||
assert([str(x) for x in m.find_element(HTMLElement.ID, 'div1').find_elements(HTMLElement.SELECTOR, '.main')] == \
|
|
||||||
server.TEST_FIND_ELEMENTS)
|
|
||||||
assert(m.find_element(HTMLElement.ID, 'id1').click())
|
|
||||||
assert(m.find_element(HTMLElement.ID, 'id2').text() == server.TEST_GET_TEXT)
|
|
||||||
assert(m.find_element(HTMLElement.ID, 'id3').send_keys('Mozilla Firefox'))
|
|
||||||
assert(m.find_element(HTMLElement.ID, 'id3').value() == server.TEST_GET_VALUE)
|
|
||||||
assert(m.find_element(HTMLElement.ID, 'id3').clear())
|
|
||||||
assert(m.find_element(HTMLElement.ID, 'id3').is_selected())
|
|
||||||
assert(m.find_element(HTMLElement.ID, 'id1').equals(m.find_element(HTMLElement.TAG, 'p')))
|
|
||||||
assert(m.find_element(HTMLElement.ID, 'id3').is_enabled())
|
|
||||||
assert(m.find_element(HTMLElement.ID, 'id3').displayed())
|
|
||||||
assert(m.find_element(HTMLElement.ID, 'id3').get_attribute('value') == server.TEST_GET_VALUE)
|
|
||||||
assert(m.delete_session())
|
|
||||||
|
|
||||||
# verify a session is started automatically for us if needed
|
|
||||||
assert(m.switch_to_frame('frame1'))
|
|
||||||
assert(m.switch_to_frame(1))
|
|
||||||
assert(m.switch_to_frame(m.find_element(HTMLElement.ID, 'frameid')))
|
|
||||||
assert(m.switch_to_frame())
|
|
||||||
assert(m.current_window_handle == server.TEST_CURRENT_WINDOW)
|
|
||||||
assert(m.set_context(m.CONTEXT_CHROME))
|
|
||||||
assert(m.delete_session())
|
|
@ -1,203 +0,0 @@
|
|||||||
# 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/.
|
|
||||||
|
|
||||||
import json
|
|
||||||
import select
|
|
||||||
import socket
|
|
||||||
|
|
||||||
class TestServer(object):
|
|
||||||
""" A test Marionette server which can be used to test the Marionette
|
|
||||||
protocol. Each request will trigger a canned response; see
|
|
||||||
process_command().
|
|
||||||
"""
|
|
||||||
|
|
||||||
TEST_URL = 'http://www.mozilla.org'
|
|
||||||
TEST_CURRENT_WINDOW = 'window1'
|
|
||||||
TEST_WINDOW_LIST = ['window1', 'window2', 'window3']
|
|
||||||
TEST_EXECUTE_RETURN_VALUE = 10
|
|
||||||
TEST_EXECUTE_SCRIPT = 'return 2 * 5;'
|
|
||||||
TEST_EXECUTE_SCRIPT_ARGS = 'testing'
|
|
||||||
TEST_FIND_ELEMENT = 'element1'
|
|
||||||
TEST_FIND_ELEMENTS = ['element1', 'element2', 'element3']
|
|
||||||
TEST_GET_TEXT = 'first name'
|
|
||||||
TEST_GET_VALUE = 'Mozilla Firefox'
|
|
||||||
|
|
||||||
# canned responses for test messages
|
|
||||||
test_responses = {
|
|
||||||
'newSession': { 'value': 'a65bef90b145' },
|
|
||||||
'getMarionetteID': { 'id': 'conn0.marionette' },
|
|
||||||
'deleteSession': { 'ok': True },
|
|
||||||
'setScriptTimeout': { 'ok': True },
|
|
||||||
'setSearchTimeout': { 'ok': True },
|
|
||||||
'getWindow': { 'value': TEST_CURRENT_WINDOW },
|
|
||||||
'getWindows': { 'values': TEST_WINDOW_LIST },
|
|
||||||
'closeWindow': { 'ok': True },
|
|
||||||
'switchToWindow': { 'ok': True },
|
|
||||||
'switchToFrame': { 'ok': True },
|
|
||||||
'setContext': { 'ok': True },
|
|
||||||
'getUrl' : { 'value': TEST_URL },
|
|
||||||
'goUrl': { 'ok': True },
|
|
||||||
'goBack': { 'ok': True },
|
|
||||||
'goForward': { 'ok': True },
|
|
||||||
'refresh': { 'ok': True },
|
|
||||||
'executeScript': { 'value': TEST_EXECUTE_RETURN_VALUE },
|
|
||||||
'executeAsyncScript': { 'value': TEST_EXECUTE_RETURN_VALUE },
|
|
||||||
'executeJSScript': { 'value': TEST_EXECUTE_RETURN_VALUE },
|
|
||||||
'findElement': { 'value': TEST_FIND_ELEMENT },
|
|
||||||
'findElements': { 'values': TEST_FIND_ELEMENTS },
|
|
||||||
'clickElement': { 'ok': True },
|
|
||||||
'getElementText': { 'value': TEST_GET_TEXT },
|
|
||||||
'sendKeysToElement': { 'ok': True },
|
|
||||||
'clearElement': { 'ok': True },
|
|
||||||
'isElementSelected': { 'value': True },
|
|
||||||
'elementsEqual': { 'value': True },
|
|
||||||
'isElementEnabled': { 'value': True },
|
|
||||||
'isElementDisplayed': { 'value': True },
|
|
||||||
'getElementAttribute': { 'value': TEST_GET_VALUE },
|
|
||||||
'getSessionCapabilities': { 'value': {
|
|
||||||
"cssSelectorsEnabled": True,
|
|
||||||
"browserName": "firefox",
|
|
||||||
"handlesAlerts": True,
|
|
||||||
"javascriptEnabled": True,
|
|
||||||
"nativeEvents": True,
|
|
||||||
"platform": 'linux',
|
|
||||||
"takeScreenshot": False,
|
|
||||||
"version": "10.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'getStatus': { 'value': {
|
|
||||||
"os": {
|
|
||||||
"arch": "x86",
|
|
||||||
"name": "linux",
|
|
||||||
"version": "unknown"
|
|
||||||
},
|
|
||||||
"build": {
|
|
||||||
"revision": "unknown",
|
|
||||||
"time": "unknown",
|
|
||||||
"version": "unknown"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# canned error responses for test messages
|
|
||||||
error_responses = {
|
|
||||||
'executeScript': { 'error': { 'message': 'JavaScript error', 'status': 17 } },
|
|
||||||
'executeAsyncScript': { 'error': { 'message': 'Script timed out', 'status': 28 } },
|
|
||||||
'findElement': { 'error': { 'message': 'Element not found', 'status': 7 } },
|
|
||||||
'findElements': { 'error': { 'message': 'XPath is invalid', 'status': 19 } },
|
|
||||||
'closeWindow': { 'error': { 'message': 'No such window', 'status': 23 } },
|
|
||||||
'getWindow': { 'error': { 'message': 'No such window', 'status': 23 } },
|
|
||||||
'clickElement': { 'error': { 'message': 'Element no longer exists', 'status': 10 } },
|
|
||||||
'sendKeysToElement': { 'error': { 'message': 'Element is not visible on the page', 'status': 11 } },
|
|
||||||
'switchToFrame': { 'error': { 'message': 'No such frame', 'status': 8 } }
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, port):
|
|
||||||
self.port = port
|
|
||||||
|
|
||||||
self.srvsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
self.srvsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
||||||
self.srvsock.bind(("", port))
|
|
||||||
self.srvsock.listen(5)
|
|
||||||
self.descriptors = [self.srvsock]
|
|
||||||
self.responses = self.test_responses
|
|
||||||
print 'TestServer started on port %s' % port
|
|
||||||
|
|
||||||
def _recv_n_bytes(self, sock, n):
|
|
||||||
""" Convenience method for receiving exactly n bytes from
|
|
||||||
self.sock (assuming it's open and connected).
|
|
||||||
"""
|
|
||||||
data = ''
|
|
||||||
while len(data) < n:
|
|
||||||
chunk = sock.recv(n - len(data))
|
|
||||||
if chunk == '':
|
|
||||||
break
|
|
||||||
data += chunk
|
|
||||||
return data
|
|
||||||
|
|
||||||
def receive(self, sock):
|
|
||||||
""" Receive the next complete response from the server, and return
|
|
||||||
it as a dict. Each response from the server is prepended by
|
|
||||||
len(message) + ':'.
|
|
||||||
"""
|
|
||||||
assert(sock)
|
|
||||||
response = sock.recv(10)
|
|
||||||
sep = response.find(':')
|
|
||||||
if sep == -1:
|
|
||||||
return None
|
|
||||||
length = response[0:sep]
|
|
||||||
response = response[sep + 1:]
|
|
||||||
response += self._recv_n_bytes(sock, int(length) + 1 + len(length) - 10)
|
|
||||||
print 'received', response
|
|
||||||
return json.loads(response)
|
|
||||||
|
|
||||||
def send(self, sock, msg):
|
|
||||||
print 'msg', msg
|
|
||||||
data = json.dumps(msg)
|
|
||||||
print 'sending %s' % data
|
|
||||||
sock.send('%s:%s' % (len(data), data))
|
|
||||||
|
|
||||||
def accept_new_connection(self):
|
|
||||||
newsock, (remhost, remport) = self.srvsock.accept()
|
|
||||||
self.descriptors.append( newsock )
|
|
||||||
str = 'Client connected %s:%s\r\n' % (remhost, remport)
|
|
||||||
print str
|
|
||||||
self.send(newsock, {'from': 'root',
|
|
||||||
'applicationType': 'gecko',
|
|
||||||
'traits': []})
|
|
||||||
|
|
||||||
def process_command(self, data):
|
|
||||||
command = data['type']
|
|
||||||
|
|
||||||
if command == 'use_test_responses':
|
|
||||||
self.responses = self.test_responses
|
|
||||||
return { 'ok': True }
|
|
||||||
elif command == 'use_error_responses':
|
|
||||||
self.responses = self.error_responses
|
|
||||||
return { 'ok': True }
|
|
||||||
|
|
||||||
if command in self.responses:
|
|
||||||
response = self.responses[command]
|
|
||||||
else:
|
|
||||||
response = { 'error': { 'message': 'unknown command: %s' % command, 'status': 500} }
|
|
||||||
|
|
||||||
if command not in ('newSession', 'getStatus', 'getMarionetteID') and 'session' not in data:
|
|
||||||
response = { 'error': { 'message': 'no session specified', 'status': 500 } }
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
while 1:
|
|
||||||
# Await an event on a readable socket descriptor
|
|
||||||
(sread, swrite, sexc) = select.select( self.descriptors, [], [] )
|
|
||||||
# Iterate through the tagged read descriptors
|
|
||||||
for sock in sread:
|
|
||||||
# Received a connect to the server (listening) socket
|
|
||||||
if sock == self.srvsock:
|
|
||||||
self.accept_new_connection()
|
|
||||||
else:
|
|
||||||
# Received something on a client socket
|
|
||||||
try:
|
|
||||||
data = self.receive(sock)
|
|
||||||
except:
|
|
||||||
data = None
|
|
||||||
# Check to see if the peer socket closed
|
|
||||||
if data is None:
|
|
||||||
host,port = sock.getpeername()
|
|
||||||
str = 'Client disconnected %s:%s\r\n' % (host, port)
|
|
||||||
print str
|
|
||||||
sock.close
|
|
||||||
self.descriptors.remove(sock)
|
|
||||||
else:
|
|
||||||
if 'type' in data:
|
|
||||||
msg = self.process_command(data)
|
|
||||||
else:
|
|
||||||
msg = 'command: %s' % json.dumps(data)
|
|
||||||
self.send(sock, msg)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
server = TestServer(2626)
|
|
||||||
server.run()
|
|
@ -184,7 +184,6 @@
|
|||||||
"dom/browser-element/mochitest/test_browserElement_inproc_CloseApp.html":"",
|
"dom/browser-element/mochitest/test_browserElement_inproc_CloseApp.html":"",
|
||||||
"dom/browser-element/mochitest/test_browserElement_inproc_CloseFromOpener.html":"",
|
"dom/browser-element/mochitest/test_browserElement_inproc_CloseFromOpener.html":"",
|
||||||
"dom/browser-element/":"",
|
"dom/browser-element/":"",
|
||||||
"dom/contacts/":"",
|
|
||||||
|
|
||||||
"dom/devicestorage/test/test_basic.html":"",
|
"dom/devicestorage/test/test_basic.html":"",
|
||||||
"dom/devicestorage/test/test_lastModificationFilter.html":"",
|
"dom/devicestorage/test/test_lastModificationFilter.html":"",
|
||||||
|
@ -451,7 +451,8 @@ Java_org_mozilla_gecko_GeckoSmsManager_notifySmsDeleted(JNIEnv* jenv, jclass,
|
|||||||
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
||||||
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
request->NotifyMessageDeleted(mDeleted);
|
// For android, we support only single SMS deletion.
|
||||||
|
request->NotifyMessageDeleted(&mDeleted, 1);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user