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("input", this, true, false);
|
||||
addEventListener("keydown", this, true, false);
|
||||
addEventListener("keyup", this, true, false);
|
||||
addMessageListener("Forms:Select:Choice", this);
|
||||
addMessageListener("Forms:Input:Value", this);
|
||||
addMessageListener("Forms:Select:Blur", this);
|
||||
@ -261,6 +262,7 @@ let FormAssistant = {
|
||||
// current input field has changed.
|
||||
EditAction: function fa_editAction() {
|
||||
if (this._editing) {
|
||||
this._editing = false;
|
||||
return;
|
||||
}
|
||||
this.sendKeyboardState(this.focusedElement);
|
||||
@ -359,12 +361,15 @@ let FormAssistant = {
|
||||
this._editing = true;
|
||||
|
||||
// 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() {
|
||||
this.updateSelection();
|
||||
this._editing = false;
|
||||
}.bind(this), 0);
|
||||
break;
|
||||
|
||||
case "keyup":
|
||||
this._editing = false;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -31,7 +31,9 @@ window.addEventListener('load', 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) {
|
||||
|
@ -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.
|
||||
return false;
|
||||
}
|
||||
else if (err != OK && err != -ETIMEDOUT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -664,6 +667,9 @@ bool OmxDecoder::ReadAudio(AudioFrame *aFrame, int64_t aSeekTimeUs)
|
||||
else if (err == UNKNOWN_ERROR) {
|
||||
return false;
|
||||
}
|
||||
else if (err != OK && err != -ETIMEDOUT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
#include "mozilla/Hal.h"
|
||||
#include "AudioManager.h"
|
||||
#include "android_audio/AudioSystem.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "AudioChannelService.h"
|
||||
@ -36,6 +35,8 @@ using namespace mozilla;
|
||||
#define HEADPHONES_STATUS_UNKNOWN NS_LITERAL_STRING("unknown").get()
|
||||
#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
|
||||
static int sMaxStreamVolumeTbl[AUDIO_STREAM_CNT] = {
|
||||
5, // voice call
|
||||
@ -51,9 +52,48 @@ static int sMaxStreamVolumeTbl[AUDIO_STREAM_CNT] = {
|
||||
15, // FM
|
||||
};
|
||||
// A bitwise variable for recording what kind of headset is attached.
|
||||
static int sHeadsetState;
|
||||
static int sHeadsetState = SWITCH_STATE_OFF;
|
||||
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
|
||||
IsDeviceOn(audio_devices_t device)
|
||||
{
|
||||
@ -145,7 +185,7 @@ AudioManager::Observe(nsISupports* aSubject,
|
||||
const PRUnichar* aData)
|
||||
{
|
||||
if (!strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED)) {
|
||||
if (aData) {
|
||||
if (NS_strlen(aData) > 0) {
|
||||
String8 cmd;
|
||||
cmd.appendFormat("bt_samplerate=%d", kBtSampleRate);
|
||||
AudioSystem::setParameters(0, cmd);
|
||||
@ -214,10 +254,13 @@ AudioManager::AudioManager() : mPhoneState(PHONE_STATE_CURRENT),
|
||||
for (int loop = 0; loop < AUDIO_STREAM_CNT; loop++) {
|
||||
AudioSystem::initStreamVolume(static_cast<audio_stream_type_t>(loop), 0,
|
||||
sMaxStreamVolumeTbl[loop]);
|
||||
mCurrentStreamVolumeTbl[loop] = sMaxStreamVolumeTbl[loop];
|
||||
}
|
||||
// Force publicnotification to output at maximal volume
|
||||
AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_ENFORCED_AUDIBLE),
|
||||
sMaxStreamVolumeTbl[AUDIO_STREAM_ENFORCED_AUDIBLE]);
|
||||
|
||||
AudioSystem::setErrorCallback(BinderDeadCallback);
|
||||
}
|
||||
|
||||
AudioManager::~AudioManager() {
|
||||
@ -225,7 +268,7 @@ AudioManager::~AudioManager() {
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
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;
|
||||
AudioSystem::getStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_MUSIC), &volIndex);
|
||||
AudioSystem::setStreamVolumeIndex(static_cast<audio_stream_type_t>(AUDIO_STREAM_FM), volIndex);
|
||||
mCurrentStreamVolumeTbl[AUDIO_STREAM_FM] = volIndex;
|
||||
}
|
||||
return NS_OK;
|
||||
} else {
|
||||
@ -425,16 +469,17 @@ AudioManager::SetStreamVolumeIndex(int32_t aStream, int32_t aIndex) {
|
||||
// sync fm volume with music stream type
|
||||
if (aStream == AUDIO_STREAM_MUSIC && IsDeviceOn(AUDIO_DEVICE_OUT_FM)) {
|
||||
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;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AudioManager::GetStreamVolumeIndex(int32_t aStream, int32_t* aIndex) {
|
||||
status_t status =
|
||||
AudioSystem::getStreamVolumeIndex(static_cast<audio_stream_type_t>(aStream), aIndex);
|
||||
return status ? NS_ERROR_FAILURE : NS_OK;
|
||||
*aIndex = mCurrentStreamVolumeTbl[aStream];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "nsIAudioManager.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "AudioChannelAgent.h"
|
||||
#include "android_audio/AudioSystem.h"
|
||||
|
||||
// {b2b51423-502d-4d77-89b3-7786b562b084}
|
||||
#define NS_AUDIOMANAGER_CID {0x94f6fd70, 0x7615, 0x4af9, \
|
||||
@ -51,6 +52,7 @@ public:
|
||||
|
||||
protected:
|
||||
int32_t mPhoneState;
|
||||
int mCurrentStreamVolumeTbl[AUDIO_STREAM_CNT];
|
||||
|
||||
private:
|
||||
nsAutoPtr<mozilla::hal::SwitchObserver> mObserver;
|
||||
|
@ -10170,10 +10170,7 @@ let ICCRecordHelper = {
|
||||
", spnDisplayCondition = " + spnDisplayCondition);
|
||||
}
|
||||
|
||||
RIL.iccInfoPrivate.SPN = {
|
||||
spn : spn,
|
||||
spnDisplayCondition : spnDisplayCondition,
|
||||
};
|
||||
RIL.iccInfoPrivate.spnDisplayCondition = spnDisplayCondition;
|
||||
RIL.iccInfo.spn = spn;
|
||||
ICCUtilsHelper.updateDisplayCondition();
|
||||
ICCUtilsHelper.handleICCInfoChange();
|
||||
@ -11138,11 +11135,11 @@ let ICCUtilsHelper = {
|
||||
// isDisplaySpnRequired = false
|
||||
let iccInfo = RIL.iccInfo;
|
||||
let iccInfoPriv = RIL.iccInfoPrivate;
|
||||
let iccSpn = iccInfoPriv.SPN;
|
||||
let displayCondition = iccInfoPriv.spnDisplayCondition;
|
||||
let origIsDisplayNetworkNameRequired = iccInfo.isDisplayNetworkNameRequired;
|
||||
let origIsDisplaySPNRequired = iccInfo.isDisplaySpnRequired;
|
||||
|
||||
if (!iccSpn) {
|
||||
if (displayCondition === undefined) {
|
||||
iccInfo.isDisplayNetworkNameRequired = true;
|
||||
iccInfo.isDisplaySpnRequired = false;
|
||||
} else if (RIL._isCdma) {
|
||||
@ -11153,9 +11150,9 @@ let ICCUtilsHelper = {
|
||||
|
||||
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.
|
||||
if (iccSpn.spnDisplayCondition == false) {
|
||||
if (displayCondition == 0x0) {
|
||||
iccInfo.isDisplaySpnRequired = false;
|
||||
} else {
|
||||
// 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
|
||||
// shall be displayed.
|
||||
iccInfo.isDisplaySpnRequired = true;
|
||||
if (iccSpn.spnDisplayCondition & 0x01) {
|
||||
iccInfo.isDisplayNetworkNameRequired = true;
|
||||
} else {
|
||||
iccInfo.isDisplayNetworkNameRequired = false;
|
||||
}
|
||||
iccInfo.isDisplayNetworkNameRequired = (displayCondition & 0x01) != 0;
|
||||
} else {
|
||||
// The second bit of display condition tells us if we should display
|
||||
// registered PLMN.
|
||||
@ -11240,13 +11233,8 @@ let ICCUtilsHelper = {
|
||||
// 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
|
||||
// isDisplayNetworkNameRequired false.
|
||||
if (iccSpn.spnDisplayCondition & 0x02) {
|
||||
iccInfo.isDisplayNetworkNameRequired = false;
|
||||
iccInfo.isDisplaySpnRequired = false;
|
||||
} else {
|
||||
iccInfo.isDisplayNetworkNameRequired = false;
|
||||
iccInfo.isDisplaySpnRequired = true;
|
||||
}
|
||||
iccInfo.isDisplayNetworkNameRequired = false;
|
||||
iccInfo.isDisplaySpnRequired = (displayCondition & 0x02) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12069,9 +12057,7 @@ let RuimRecordHelper = {
|
||||
debug("CDMA SPN: " + RIL.iccInfo.spn +
|
||||
", Display condition: " + displayCondition);
|
||||
}
|
||||
RIL.iccInfoPrivate.SPN = {
|
||||
spnDisplayCondition: displayCondition
|
||||
};
|
||||
RIL.iccInfoPrivate.spnDisplayCondition = displayCondition;
|
||||
Buf.seekIncoming((octetLen - readLen) * PDU_HEX_OCTET_SIZE);
|
||||
Buf.readStringDelimiter(strLen);
|
||||
}
|
||||
|
@ -975,9 +975,7 @@ add_test(function test_spn_display_condition() {
|
||||
expectedIsDisplayNetworkNameRequired,
|
||||
expectedIsDisplaySPNRequired,
|
||||
callback) {
|
||||
RIL.iccInfoPrivate.SPN = {
|
||||
spnDisplayCondition: iccDisplayCondition
|
||||
};
|
||||
RIL.iccInfoPrivate.spnDisplayCondition = iccDisplayCondition;
|
||||
RIL.iccInfo = {
|
||||
mcc: iccMcc,
|
||||
mnc: iccMnc
|
||||
|
@ -143,7 +143,7 @@ add_test(function test_read_cdmaspn() {
|
||||
|
||||
worker.RuimRecordHelper.readSPN();
|
||||
do_check_eq(worker.RIL.iccInfo.spn, expectedSpn);
|
||||
do_check_eq(worker.RIL.iccInfoPrivate.SPN.spnDisplayCondition,
|
||||
do_check_eq(worker.RIL.iccInfoPrivate.spnDisplayCondition,
|
||||
expectedDisplayCondition);
|
||||
}
|
||||
|
||||
@ -156,7 +156,7 @@ add_test(function test_read_cdmaspn() {
|
||||
String.fromCharCode(0x592a) +
|
||||
String.fromCharCode(0x96fb) +
|
||||
String.fromCharCode(0x4fe1),
|
||||
true);
|
||||
0x1);
|
||||
|
||||
// Test when there's no tailing 0xff in spn string.
|
||||
testReadSpn([0x01, 0x04, 0x06, 0x4e, 0x9e, 0x59, 0x2a, 0x96,
|
||||
@ -165,7 +165,7 @@ add_test(function test_read_cdmaspn() {
|
||||
String.fromCharCode(0x592a) +
|
||||
String.fromCharCode(0x96fb) +
|
||||
String.fromCharCode(0x4fe1),
|
||||
true);
|
||||
0x1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
@ -199,9 +199,7 @@ add_test(function test_cdma_spn_display_condition() {
|
||||
currentSystemId, currentNetworkId,
|
||||
expectUpdateDisplayCondition,
|
||||
expectIsDisplaySPNRequired) {
|
||||
RIL.iccInfoPrivate.SPN = {
|
||||
spnDisplayCondition: ruimDisplayCondition
|
||||
};
|
||||
RIL.iccInfoPrivate.spnDisplayCondition = ruimDisplayCondition;
|
||||
RIL.cdmaHome = {
|
||||
systemId: homeSystemIds,
|
||||
networkId: homeNetworkIds
|
||||
@ -217,16 +215,16 @@ add_test(function test_cdma_spn_display_condition() {
|
||||
};
|
||||
|
||||
// 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.
|
||||
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.
|
||||
testDisplayCondition(true, [123], [65535], 123, 345, false, true);
|
||||
testDisplayCondition(0x1, [123], [65535], 123, 345, false, true);
|
||||
|
||||
// Not match.
|
||||
testDisplayCondition(true, [123], [456], 123, 345, true, false);
|
||||
testDisplayCondition(0x1, [123], [456], 123, 345, true, false);
|
||||
|
||||
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_CloseFromOpener.html":"",
|
||||
"dom/browser-element/":"",
|
||||
"dom/contacts/":"",
|
||||
|
||||
"dom/devicestorage/test/test_basic.html":"",
|
||||
"dom/devicestorage/test/test_lastModificationFilter.html":"",
|
||||
|
@ -451,7 +451,8 @@ Java_org_mozilla_gecko_GeckoSmsManager_notifySmsDeleted(JNIEnv* jenv, jclass,
|
||||
AndroidBridge::Bridge()->DequeueSmsRequest(mRequestId);
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user