Merge m-c to inbound.

This commit is contained in:
Ryan VanderMeulen 2013-09-26 21:40:22 -04:00
commit af5e51f375
79 changed files with 1201 additions and 711 deletions

View File

@ -9,10 +9,8 @@
<![CDATA[
function doTest()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var accRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(Components.interfaces.nsIAccessibleRetrieval);
var accRetrieval = SpecialPowers.Cc["@mozilla.org/accessibleRetrieval;1"].
getService(SpecialPowers.Ci.nsIAccessibleRetrieval);
var treecol = document.getElementById("col");
var x = treecol.boxObject.screenX;

View File

@ -1 +1,2 @@
load 471493.xul
# Disabled because it causes assertions/crashes in later crashtests, see bug 918246
skip load 471493.xul

View File

@ -0,0 +1,25 @@
{
"config_version": 2,
"tooltool_manifest": "releng-emulator-ics.tt",
"mock_target": "mozilla-centos6-x86_64",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
"build_targets": ["droid", "package-emulator", "package-tests"],
"upload_files": [
"{workdir}/out/target/product/generic/*.tar.bz2",
"{workdir}/out/target/product/generic/tests/*.zip",
"{workdir}/out/emulator.tar.gz",
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
"{workdir}/sources.xml"
],
"upload_platform": "emulator-ics",
"gecko_l10n_root": "http://hg.mozilla.org/l10n-central",
"gaia": {
"l10n": {
"vcs": "hgtool",
"root": "http://hg.mozilla.org/gaia-l10n"
}
},
"b2g_manifest": "emulator.xml",
"b2g_manifest_branch": "master"
}

View File

@ -0,0 +1,2 @@
[
]

View File

@ -1,4 +1,4 @@
{
"revision": "43bc58df001f2b870fd2d1eb80723cfdccdc7b67",
"revision": "c9f88878f616a439db6c6be66378af79249f7528",
"repo_path": "/integration/gaia-central"
}

View File

@ -874,18 +874,27 @@ SocialToolbar = {
let toggleNotificationsCommand = document.getElementById("Social:ToggleNotifications");
toggleNotificationsCommand.setAttribute("hidden", !socialEnabled);
let parent = document.getElementById("social-notification-panel");
while (parent.hasChildNodes()) {
let frame = parent.firstChild;
SharedFrame.forgetGroup(frame.id);
parent.removeChild(frame);
}
// we need to remove buttons and frames if !socialEnabled or the provider
// has changed (frame origin does not match current provider). We only
// remove frames that are "attached" to buttons in this toolbar button since
// other buttons may also be using grouped frames.
let tbi = document.getElementById("social-provider-button");
if (tbi) {
// buttons after social-provider-button are ambient icons
while (tbi.nextSibling) {
tbi.parentNode.removeChild(tbi.nextSibling);
let next = tbi.nextSibling;
let currentOrigin = Social.provider ? Social.provider.origin : null;
while (next) {
let button = next;
next = next.nextSibling;
// get the frame for this button
let frameId = button.getAttribute("notificationFrameId");
let frame = document.getElementById(frameId);
if (!socialEnabled || frame.getAttribute("origin") != currentOrigin) {
SharedFrame.forgetGroup(frame.id);
frame.parentNode.removeChild(frame);
button.parentNode.removeChild(button);
}
}
}
},

View File

@ -259,7 +259,7 @@ panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .a
#wrapper-urlbar-container > #urlbar-container > #urlbar {
-moz-user-input: disabled;
cursor: -moz-grab;
cursor: grab;
}
#PopupAutoComplete {

View File

@ -11,7 +11,7 @@
#placesTreechildren::-moz-tree-cell(grippyRow),
#placesTreechildren::-moz-tree-cell-text(grippyRow),
#placesTreechildren::-moz-tree-image(grippyRow) {
cursor: -moz-grab;
cursor: grab;
}

View File

@ -1499,7 +1499,7 @@
</binding>
<binding id="click-to-play-plugins-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
<content align="start" class="click-to-play-plugins-notification-content">
<content align="start" style="width: &pluginNotification.width;;">
<xul:vbox flex="1" align="stretch" class="popup-notification-main-box"
xbl:inherits="popupid">
<xul:hbox class="click-to-play-plugins-notification-description-box" flex="1" align="start">

View File

@ -19,7 +19,7 @@
# The installer's certificate name and issuer expected by the stub installer
!define CertNameDownload "Mozilla Corporation"
!define CertIssuerDownload "Thawte Code Signing CA - G2"
!define CertIssuerDownload "DigiCert Assured ID Code Signing CA-1"
# Dialog units are used so the UI displays correctly with the system's DPI
# settings.

View File

@ -19,7 +19,7 @@
# The installer's certificate name and issuer expected by the stub installer
!define CertNameDownload "Mozilla Corporation"
!define CertIssuerDownload "Thawte Code Signing CA - G2"
!define CertIssuerDownload "DigiCert Assured ID Code Signing CA-1"
# Dialog units are used so the UI displays correctly with the system's DPI
# settings.

View File

@ -23,7 +23,7 @@
# The installer's certificate name and issuer expected by the stub installer
!define CertNameDownload "Mozilla Corporation"
!define CertIssuerDownload "Thawte Code Signing CA - G2"
!define CertIssuerDownload "DigiCert Assured ID Code Signing CA-1"
# Dialog units are used so the UI displays correctly with the system's DPI
# settings.

View File

@ -68,6 +68,23 @@ const IDB = {
return deferred.promise;
},
update: function(project) {
let deferred = promise.defer();
var transaction = IDB._db.transaction(["projects"], "readwrite");
var objectStore = transaction.objectStore("projects");
var request = objectStore.put(project);
request.onerror = function(event) {
deferred.reject("Unable to update project to the AppProjects indexedDB: " +
this.error.name + " - " + this.error.message );
};
request.onsuccess = function() {
deferred.resolve();
};
return deferred.promise;
},
remove: function(location) {
let deferred = promise.defer();
@ -110,6 +127,8 @@ const AppProjects = {
// The packaged app local path is a valid id, but only on the client.
// This origin will be used to generate the true id of an app:
// its manifest URL.
// If the app ends up specifying an explicit origin in its manifest,
// we will override this random UUID on app install.
packagedAppOrigin: generateUUID().toString().slice(1, -1)
};
return IDB.add(project).then(function () {
@ -131,6 +150,14 @@ const AppProjects = {
});
},
update: function (project) {
return IDB.update({
type: project.type,
location: project.location,
packagedAppOrigin: project.packagedAppOrigin
}).then(() => project);
},
remove: function(location) {
return IDB.remove(location).then(function () {
let projects = store.object.projects;

View File

@ -208,9 +208,15 @@ let UI = {
},
install: function(project) {
let install;
if (project.type == "packaged") {
install = installPackaged(this.connection.client, this.listTabsResponse.webappsActor, project.location, project.packagedAppOrigin);
return installPackaged(this.connection.client, this.listTabsResponse.webappsActor, project.location, project.packagedAppOrigin)
.then(({ appId }) => {
// If the packaged app specified a custom origin override,
// we need to update the local project origin
project.packagedAppOrigin = appId;
// And ensure the indexed db on disk is also updated
AppProjects.update(project);
});
} else {
let manifestURLObject = Services.io.newURI(project.location, null, null);
let origin = Services.io.newURI(manifestURLObject.prePath, null, null);
@ -219,9 +225,8 @@ let UI = {
origin: origin.spec,
manifestURL: project.location
};
install = installHosted(this.connection.client, this.listTabsResponse.webappsActor, appId, metadata, project.manifest);
return installHosted(this.connection.client, this.listTabsResponse.webappsActor, appId, metadata, project.manifest);
}
return install;
},
start: function(project) {

View File

@ -4522,6 +4522,7 @@ var Utils = {
case "CSP":
case "Invalid HSTS Headers":
case "Insecure Password Field":
case "SSL":
return CATEGORY_SECURITY;
default:

View File

@ -21,7 +21,7 @@
!define NO_UNINSTALL_SURVEY
!define CERTIFICATE_NAME "Mozilla Corporation"
!define CERTIFICATE_ISSUER "Thawte Code Signing CA - G2"
!define CERTIFICATE_ISSUER "DigiCert Assured ID Code Signing CA-1"
# LSP_CATEGORIES is the permitted LSP categories for the application. Each LSP
# category value is ANDed together to set multiple permitted categories.

View File

@ -212,7 +212,7 @@ Section "MaintenanceService"
; These keys are used to bypass the installation dir is a valid installation
; check from the service so that tests can be run.
; WriteRegStr HKLM "${FallbackKey}\0" "name" "Mozilla Corporation"
; WriteRegStr HKLM "${FallbackKey}\0" "issuer" "Thawte Code Signing CA - G2"
; WriteRegStr HKLM "${FallbackKey}\0" "issuer" "DigiCert Assured ID Code Signing CA-1"
${If} ${RunningX64}
SetRegView lastused
${EndIf}

View File

@ -672,6 +672,13 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY pluginActivateAlways.label "Allow and Remember">
<!ENTITY pluginBlockNow.label "Block Plugin">
<!-- LOCALIZATION NOTE: (pluginNotification.width): This is used to determine the
width of the plugin popup notification that can appear if a plugin has been
blocked on a page. Should be wide enough to fit the pluginActivateNow.label
and pluginActivateAlways.label strings above on a single line. This must be
a CSS length value. -->
<!ENTITY pluginNotification.width "28em">
<!ENTITY tabCrashed.header "Tab crashed">
<!ENTITY tabCrashed.message "Well, this is embarrassing. We tried to display this Web page, but it's not responding.">
<!ENTITY tabCrashed.checkSendReport "Tell &vendorShortName; about this crash so they can fix it.">

View File

@ -2,10 +2,6 @@
padding: 0px;
}
.click-to-play-plugins-notification-content {
width: 28em;
}
.click-to-play-plugins-notification-center-box {
border: 1px solid ThreeDShadow;
margin: 10px;

View File

@ -19,8 +19,10 @@ if __name__ == '__main__':
# This is meant as a temporary workaround until issues with many targets
# and prerequisites is addressed. Bug 874210 tracks.
#
# The default recursion limit for CPython is 1000.
try:
sys.setrecursionlimit(2 * sys.getrecursionlimit())
sys.setrecursionlimit(10000)
except Exception:
print >>sys.stderr, 'Unable to increase Python recursion limit.'

View File

@ -737,6 +737,14 @@ public:
return sXPConnect;
}
/**
* Report simple error message to the browser console
* @param aErrorText the error message
* @param classification Name of the module reporting error
*/
static void LogSimpleConsoleError(const nsAString& aErrorText,
const char * classification);
/**
* Report a non-localized error message to the error console.
* @param aErrorText the error message

View File

@ -3014,6 +3014,24 @@ nsresult nsContentUtils::FormatLocalizedString(PropertiesFile aFile,
getter_Copies(aResult));
}
/* static */ void
nsContentUtils::LogSimpleConsoleError(const nsAString& aErrorText,
const char * classification)
{
nsCOMPtr<nsIScriptError> scriptError =
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
if (scriptError) {
nsCOMPtr<nsIConsoleService> console =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (console && NS_SUCCEEDED(scriptError->Init(aErrorText, EmptyString(),
EmptyString(), 0, 0,
nsIScriptError::errorFlag,
classification))) {
console->LogMessage(scriptError);
}
}
}
/* static */ nsresult
nsContentUtils::ReportToConsole(uint32_t aErrorFlags,
const nsACString& aCategory,

View File

@ -30,99 +30,293 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(MediaRecorder, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(MediaRecorder, nsDOMEventTargetHelper)
// This task is used for triggering the creating blob object and it runs at main thread.
class MediaRecorder::PushBlobTask : public nsRunnable
/**
* Session is an object to represent a single recording event.
* In original design, all recording context is stored in MediaRecorder, which causes
* a problem if someone calls MediaRecoder::Stop and MedaiRecorder::Start quickly.
* To prevent blocking main thread, media encoding is executed in a second thread,
* named as Read Thread. For the same reason, we do not wait Read Thread shutdown in
* MediaRecorder::Stop. If someone call MediaRecoder::Start before Read Thread shutdown,
* the same recording context in MediaRecoder might be access by two Reading Threads,
* which cause a problem.
* In the new design, we put recording context into Session object, including Read
* Thread. Each Session has its own recording context and Read Thread, problem is been
* resolved.
*
* Life cycle of a Session object.
* 1) Initialization Stage (in main thread)
* Setup media streams in MSG, and bind MediaEncoder with Source Stream.
* Resource allocation, such as encoded data cache buffer and MediaEncoder.
* Create read thread.
* Automatically switch to Extract stage in the end of this stage.
* 2) Extract Stage (in Read Thread)
* Pull encoded A/V frames from MediaEncoder, dispatch to OnDataAvailable handler.
* Unless a client calls Session::Stop, Session object keeps stay in this stage.
* 3) Destroy Stage (in main thread)
* Switch from Extract stage to Destroy stage by calling Session::Stop.
* Release session resource and remove associated streams from MSG.
*
* Lifetime of a Session object.
* 1) MediaRecorder creates a Session in MediaRecorder::Start function.
* 2) A Session is destroyed in DestroyRunnable after MediaRecorder::Stop being called
* _and_ all encoded media data been passed to OnDataAvailable handler.
*/
class MediaRecorder::Session
{
public:
PushBlobTask(MediaRecorder* recorder)
: mRecorder(recorder) {}
NS_IMETHODIMP Run()
{
MOZ_ASSERT(NS_IsMainThread());
nsresult rv = mRecorder->CreateAndDispatchBlobEvent();
if (NS_FAILED(rv)) {
mRecorder->NotifyError(rv);
}
return NS_OK;
}
MediaRecorder* mRecorder;
};
// This task is for firing the error message from encoder and it runs in main thread
class MediaRecorder::PushErrorMessageTask : public nsRunnable
{
public:
PushErrorMessageTask(MediaRecorder* recorder, nsresult aError)
: mRecorder(recorder),
mError(aError) { }
NS_IMETHODIMP Run()
{
MOZ_ASSERT(NS_IsMainThread());
mRecorder->NotifyError(mError);
return NS_OK;
}
private:
MediaRecorder* mRecorder;
nsresult mError;
};
// This class is used for avoiding abort by directly use the NS_NewRunnableMethod and invoke ExtractEncodedData function
// The abort is checking if the destructor runs at main thread during the cycle-collect step in nsDOMEventTargetHelper
class MediaRecorder::ExtractEncodedDataTask : public nsRunnable
{
public:
ExtractEncodedDataTask(MediaRecorder* aRecorder, MediaEncoder* aEncoder)
: mRecorder(aRecorder),
mEncoder(aEncoder) {}
class ReleaseEncoderThreadTask : public nsRunnable
// Main thread task.
// Create a blob event and send back to client.
class PushBlobRunnable : public nsRunnable
{
public:
ReleaseEncoderThreadTask(already_AddRefed<MediaRecorder> recorder)
: mRecorder(recorder) {}
PushBlobRunnable(Session* aSession)
: mSession(aSession)
{ }
NS_IMETHODIMP Run()
{
MOZ_ASSERT(NS_IsMainThread());
mRecorder->mReadThread->Shutdown();
mRecorder->mReadThread = nullptr;
// Setting mState to Inactive here is for the case where SourceStream
// ends itself, thus the recorder should stop itself too.
mRecorder->mState = RecordingState::Inactive;
mRecorder->DispatchSimpleEvent(NS_LITERAL_STRING("stop"));
MediaRecorder *recorder = mSession->mRecorder;
nsresult rv = recorder->CreateAndDispatchBlobEvent(mSession);
if (NS_FAILED(rv)) {
recorder->NotifyError(rv);
}
return NS_OK;
}
private:
nsRefPtr<MediaRecorder> mRecorder;
Session *mSession;
};
NS_IMETHODIMP Run()
// Record thread task.
// Fetch encoded Audio/Video data from MediaEncoder.
class ExtractRunnable : public nsRunnable
{
MOZ_ASSERT(!NS_IsMainThread());
mRecorder->ExtractEncodedData();
NS_DispatchToMainThread(new ReleaseEncoderThreadTask(mRecorder.forget()));
return NS_OK;
public:
ExtractRunnable(Session *aSession)
: mSession(aSession) {}
NS_IMETHODIMP Run()
{
MOZ_ASSERT(NS_GetCurrentThread() == mSession->mReadThread);
mSession->Extract();
return NS_OK;
}
private:
Session *mSession;
};
// Main thread task.
// To delete RecordingSession object.
class DestroyRunnable : public nsRunnable
{
public:
DestroyRunnable(Session *aSession)
: mSession(aSession) {}
NS_IMETHODIMP Run()
{
MOZ_ASSERT(NS_IsMainThread() && mSession.get());
MediaRecorder *recorder = mSession->mRecorder;
// If MediaRecoder is not in Inactive mode, call MediaRecoder::Stop
// and dispatch DestroyRunnable again.
if (recorder->mState != RecordingState::Inactive) {
ErrorResult result;
recorder->Stop(result);
NS_DispatchToMainThread(new DestroyRunnable(mSession.forget()));
return NS_OK;
}
// Dispatch stop event and clear MIME type.
recorder->DispatchSimpleEvent(NS_LITERAL_STRING("stop"));
recorder->SetMimeType(NS_LITERAL_STRING(""));
// Delete session object.
mSession = nullptr;
return NS_OK;
}
private:
nsAutoPtr<Session> mSession;
};
friend class PushBlobRunnable;
friend class ExtractRunnable;
friend class DestroyRunnable;
public:
Session(MediaRecorder* aRecorder, int32_t aTimeSlice)
: mRecorder(aRecorder),
mTimeSlice(aTimeSlice)
{
MOZ_ASSERT(NS_IsMainThread());
mEncodedBufferCache = new EncodedBufferCache(MAX_ALLOW_MEMORY_BUFFER);
}
// Only DestroyRunnable is allowed to delete Session object.
~Session()
{
MOZ_ASSERT(NS_IsMainThread());
if (mInputPort.get()) {
mInputPort->Destroy();
}
if (mTrackUnionStream.get()) {
mTrackUnionStream->Destroy();
}
}
void Start()
{
MOZ_ASSERT(NS_IsMainThread());
SetupStreams();
// Create a thread to read encode media data from MediaEncoder.
if (!mReadThread) {
nsresult rv = NS_NewNamedThread("Media Encoder", getter_AddRefs(mReadThread));
if (NS_FAILED(rv)) {
mRecorder->NotifyError(rv);
return;
}
}
mReadThread->Dispatch(new ExtractRunnable(this), NS_DISPATCH_NORMAL);
}
void Stop()
{
MOZ_ASSERT(NS_IsMainThread());
// Shutdown mEncoder to stop Session::Extract
if (mInputPort.get())
{
mInputPort->Destroy();
mInputPort = nullptr;
}
if (mTrackUnionStream.get())
{
mTrackUnionStream->Destroy();
mTrackUnionStream = nullptr;
}
}
void Pause()
{
MOZ_ASSERT(NS_IsMainThread() && mTrackUnionStream);
mTrackUnionStream->ChangeExplicitBlockerCount(-1);
}
void Resume()
{
MOZ_ASSERT(NS_IsMainThread() && mTrackUnionStream);
mTrackUnionStream->ChangeExplicitBlockerCount(1);
}
already_AddRefed<nsIDOMBlob> GetEncodedData()
{
nsString mimeType;
mRecorder->GetMimeType(mimeType);
return mEncodedBufferCache->ExtractBlob(mimeType);
}
private:
// Pull encoded meida data from MediaEncoder and put into EncodedBufferCache.
// Destroy this session object in the end of this function.
void Extract()
{
MOZ_ASSERT(NS_GetCurrentThread() == mReadThread);
TimeStamp lastBlobTimeStamp = TimeStamp::Now();
// Whether push encoded data back to onDataAvailable automatically.
const bool pushBlob = (mTimeSlice > 0) ? true : false;
do {
// Pull encoded media data from MediaEncoder
nsTArray<nsTArray<uint8_t> > encodedBuf;
nsString mimeType;
mEncoder->GetEncodedData(&encodedBuf, mimeType);
mRecorder->SetMimeType(mimeType);
// Append pulled data into cache buffer.
for (uint32_t i = 0; i < encodedBuf.Length(); i++) {
mEncodedBufferCache->AppendBuffer(encodedBuf[i]);
}
if (pushBlob) {
if ((TimeStamp::Now() - lastBlobTimeStamp).ToMilliseconds() > mTimeSlice) {
NS_DispatchToMainThread(new PushBlobRunnable(this));
lastBlobTimeStamp = TimeStamp::Now();
}
}
} while (!mEncoder->IsShutdown());
// Flush out remainding encoded data.
NS_DispatchToMainThread(new PushBlobRunnable(this));
// Destroy this session object in main thread.
NS_DispatchToMainThread(new DestroyRunnable(this));
}
// Bind media source with MediaEncoder to receive raw media data.
void SetupStreams()
{
MOZ_ASSERT(NS_IsMainThread());
MediaStreamGraph* gm = mRecorder->mStream->GetStream()->Graph();
mTrackUnionStream = gm->CreateTrackUnionStream(nullptr);
MOZ_ASSERT(mTrackUnionStream, "CreateTrackUnionStream failed");
mTrackUnionStream->SetAutofinish(true);
mInputPort = mTrackUnionStream->AllocateInputPort(mRecorder->mStream->GetStream(), MediaInputPort::FLAG_BLOCK_OUTPUT);
// Allocate encoder and bind with union stream.
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""));
MOZ_ASSERT(mEncoder, "CreateEncoder failed");
if (mEncoder) {
mTrackUnionStream->AddListener(mEncoder);
}
}
private:
// Hold a reference to MediaRecoder to make sure MediaRecoder be
// destroyed after all session object dead.
nsRefPtr<MediaRecorder> mRecorder;
nsRefPtr<MediaEncoder> mEncoder;
// Pause/ Resume controller.
nsRefPtr<ProcessedMediaStream> mTrackUnionStream;
nsRefPtr<MediaInputPort> mInputPort;
// Runnable thread for read data from MediaEncode.
nsCOMPtr<nsIThread> mReadThread;
// MediaEncoder pipeline.
nsRefPtr<MediaEncoder> mEncoder;
// A buffer to cache encoded meda data.
nsAutoPtr<EncodedBufferCache> mEncodedBufferCache;
// The interval of passing encoded data from EncodedBufferCache to onDataAvailable
// handler. "mTimeSlice < 0" means Session object does not push encoded data to
// onDataAvailable, instead, it passive wait the client side pull encoded data
// by calling requestData API.
const int32_t mTimeSlice;
};
MediaRecorder::~MediaRecorder()
{
if (mStreamPort) {
mStreamPort->Destroy();
}
if (mTrackUnionStream) {
mTrackUnionStream->Destroy();
}
MOZ_ASSERT(mSession == nullptr);
}
void
@ -134,31 +328,26 @@ MediaRecorder::Init(nsPIDOMWindow* aOwnerWindow)
}
MediaRecorder::MediaRecorder(DOMMediaStream& aStream)
: mTimeSlice(0),
mState(RecordingState::Inactive)
: mState(RecordingState::Inactive),
mSession(nullptr),
mMutex("Session.Data.Mutex")
{
mStream = &aStream;
SetIsDOMBinding();
}
void
MediaRecorder::ExtractEncodedData()
MediaRecorder::SetMimeType(const nsString &aMimeType)
{
TimeStamp lastBlobTimeStamp = TimeStamp::Now();
do {
nsTArray<nsTArray<uint8_t> > outputBufs;
mEncoder->GetEncodedData(&outputBufs, mMimeType);
for (uint32_t i = 0; i < outputBufs.Length(); i++) {
mEncodedBufferCache->AppendBuffer(outputBufs[i]);
}
MutexAutoLock lock(mMutex);
mMimeType = aMimeType;
}
if (mTimeSlice > 0 && (TimeStamp::Now() - lastBlobTimeStamp).ToMilliseconds() > mTimeSlice) {
NS_DispatchToMainThread(new PushBlobTask(this));
lastBlobTimeStamp = TimeStamp::Now();
}
} while (!mEncoder->IsShutdown());
NS_DispatchToMainThread(new PushBlobTask(this));
void
MediaRecorder::GetMimeType(nsString &aMimeType)
{
MutexAutoLock lock(mMutex);
aMimeType = mMimeType;
}
void
@ -174,53 +363,25 @@ MediaRecorder::Start(const Optional<int32_t>& aTimeSlice, ErrorResult& aResult)
return;
}
int32_t timeSlice = 0;
if (aTimeSlice.WasPassed()) {
if (aTimeSlice.Value() < 0) {
aResult.Throw(NS_ERROR_INVALID_ARG);
return;
}
mTimeSlice = aTimeSlice.Value();
} else {
mTimeSlice = 0;
}
// Create a TrackUnionStream to support Pause/Resume by using ChangeExplicitBlockerCount
MediaStreamGraph* gm = mStream->GetStream()->Graph();
mTrackUnionStream = gm->CreateTrackUnionStream(nullptr);
MOZ_ASSERT(mTrackUnionStream, "CreateTrackUnionStream failed");
timeSlice = aTimeSlice.Value();
}
if (!CheckPrincipal()) {
aResult.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
if (mEncodedBufferCache == nullptr) {
mEncodedBufferCache = new EncodedBufferCache(MAX_ALLOW_MEMORY_BUFFER);
}
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""));
MOZ_ASSERT(mEncoder, "CreateEncoder failed");
mTrackUnionStream->SetAutofinish(true);
mStreamPort = mTrackUnionStream->AllocateInputPort(mStream->GetStream(), MediaInputPort::FLAG_BLOCK_OUTPUT);
if (mEncoder) {
mTrackUnionStream->AddListener(mEncoder);
} else {
aResult.Throw(NS_ERROR_DOM_ABORT_ERR);
}
if (!mReadThread) {
nsresult rv = NS_NewNamedThread("Media Encoder",
getter_AddRefs(mReadThread));
if (NS_FAILED(rv)) {
aResult.Throw(rv);
return;
}
nsRefPtr<ExtractEncodedDataTask> event = new ExtractEncodedDataTask(this, mEncoder);
mReadThread->Dispatch(event, NS_DISPATCH_NORMAL);
mState = RecordingState::Recording;
}
mState = RecordingState::Recording;
// Start a session
mSession = new Session(this, timeSlice);
mSession->Start();
}
void
@ -230,13 +391,11 @@ MediaRecorder::Stop(ErrorResult& aResult)
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
mSession->Stop();
mSession = nullptr;
mState = RecordingState::Inactive;
mStreamPort->Destroy();
mStreamPort = nullptr;
mTrackUnionStream->Destroy();
mTrackUnionStream = nullptr;
}
void
@ -246,9 +405,14 @@ MediaRecorder::Pause(ErrorResult& aResult)
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
mTrackUnionStream->ChangeExplicitBlockerCount(-1);
mState = RecordingState::Paused;
MOZ_ASSERT(mSession != nullptr);
if (mSession) {
mSession->Pause();
mState = RecordingState::Paused;
}
}
void
@ -258,8 +422,12 @@ MediaRecorder::Resume(ErrorResult& aResult)
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
mTrackUnionStream->ChangeExplicitBlockerCount(1);
mState = RecordingState::Recording;
MOZ_ASSERT(mSession != nullptr);
if (mSession) {
mSession->Resume();
mState = RecordingState::Recording;
}
}
void
@ -269,8 +437,11 @@ MediaRecorder::RequestData(ErrorResult& aResult)
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
NS_DispatchToMainThread(NS_NewRunnableMethod(this, &MediaRecorder::CreateAndDispatchBlobEvent),
NS_DISPATCH_NORMAL);
NS_DispatchToMainThread(
NS_NewRunnableMethodWithArg<Session *>(this,
&MediaRecorder::CreateAndDispatchBlobEvent, mSession),
NS_DISPATCH_NORMAL);
}
JSObject*
@ -301,7 +472,7 @@ MediaRecorder::Constructor(const GlobalObject& aGlobal,
}
nsresult
MediaRecorder::CreateAndDispatchBlobEvent()
MediaRecorder::CreateAndDispatchBlobEvent(Session *aSession)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
@ -313,7 +484,7 @@ MediaRecorder::CreateAndDispatchBlobEvent()
BlobEventInitInitializer init;
init.mBubbles = false;
init.mCancelable = false;
init.mData = mEncodedBufferCache->ExtractBlob(mMimeType);
init.mData = aSession->GetEncodedData();
nsRefPtr<BlobEvent> event =
BlobEvent::Constructor(this,
NS_LITERAL_STRING("dataavailable"),

View File

@ -36,9 +36,8 @@ namespace dom {
class MediaRecorder : public nsDOMEventTargetHelper
{
class ExtractEncodedDataTask;
class PushBlobTask;
class PushErrorMessageTask;
class Session;
public:
MediaRecorder(DOMMediaStream&);
virtual ~MediaRecorder();
@ -71,7 +70,7 @@ public:
// The current state of the MediaRecorder object.
RecordingState State() const { return mState; }
// Return the current encoding MIME type selected by the MediaEncoder.
void GetMimeType(nsString &aMimeType) { aMimeType = mMimeType; }
void GetMimeType(nsString &aMimeType);
static already_AddRefed<MediaRecorder>
Constructor(const GlobalObject& aGlobal,
@ -83,45 +82,33 @@ public:
IMPL_EVENT_HANDLER(stop)
IMPL_EVENT_HANDLER(warning)
friend class ExtractEncodedData;
protected:
void Init(nsPIDOMWindow* aOwnerWindow);
// Copy encoded data from encoder to EncodedBufferCache. This function runs in the Media Encoder Thread.
void ExtractEncodedData();
MediaRecorder& operator = (const MediaRecorder& x) MOZ_DELETE;
// Create dataavailable event with Blob data and it runs in main thread
nsresult CreateAndDispatchBlobEvent();
nsresult CreateAndDispatchBlobEvent(Session *session);
// Creating a simple event to notify UA simple event.
void DispatchSimpleEvent(const nsAString & aStr);
// Creating a error event with message.
void NotifyError(nsresult aRv);
// Check if the recorder's principal is the subsume of mediaStream
bool CheckPrincipal();
// Set encoded MIME type.
void SetMimeType(const nsString &aMimeType);
MediaRecorder(const MediaRecorder& x) MOZ_DELETE; // prevent bad usage
// Runnable thread for read data from mediaEncoder. It starts at MediaRecorder::Start() and stops at MediaRecorder::Stop().
nsCOMPtr<nsIThread> mReadThread;
// The MediaEncoder object initializes on start() and destroys in ~MediaRecorder.
nsRefPtr<MediaEncoder> mEncoder;
// MediaStream passed from js context
nsRefPtr<DOMMediaStream> mStream;
// This media stream is used for notifying raw data to encoder and can be blocked.
nsRefPtr<ProcessedMediaStream> mTrackUnionStream;
// This is used for destroing the inputport when destroy the mediaRecorder
nsRefPtr<MediaInputPort> mStreamPort;
// This object creates on start() and destroys in ~MediaRecorder.
nsAutoPtr<EncodedBufferCache> mEncodedBufferCache;
// It specifies the container format as well as the audio and video capture formats.
nsString mMimeType;
// The interval of timer passed from Start(). On every mTimeSlice milliseconds, if there are buffers store in the EncodedBufferCache,
// a dataavailable event will be fired.
int32_t mTimeSlice;
// The current state of the MediaRecorder object.
RecordingState mState;
// Current recording session.
Session *mSession;
// Thread safe for mMimeType.
Mutex mMutex;
// It specifies the container format as well as the audio and video capture formats.
nsString mMimeType;
};
}

View File

@ -128,6 +128,7 @@ MOCHITEST_FILES = \
test_mediarecorder_record_no_timeslice.html \
test_mediarecorder_reload_crash.html \
test_mediarecorder_record_immediate_stop.html \
test_mediarecorder_record_session.html \
test_media_selection.html \
test_playback.html \
test_seekLies.html \

View File

@ -0,0 +1,72 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=909670
-->
<head>
<meta charset="utf-8">
<title>Test for Media Recoder recording session</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
var manager = new MediaTestManager;
function startTest(test, token) {
var element = document.createElement('audio');
element.token = token;
manager.started(token);
element.src = test.name;
element.test = test;
element.stream = element.mozCaptureStream();
var mStopCount = 0;
// Start and stop recording session three times continuously.
var mExpectStopCount = 3;
var mediaRecorder = new MediaRecorder(element.stream);
// Stop callback.
// Suppose to receive mExpectStopCount
mediaRecorder.onstop = function stopCallback() {
mStopCount++;
info("MediaRecorder.onstop callback: (" + mStopCount + ")");
if (mExpectStopCount === mStopCount)
{
manager.finished(token);
}
}
// data avaliable.
mediaRecorder.ondataavailable = function(evt) {}
mediaRecorder.onerror = function(err) {
ok(false, 'Unexpected error fired with:' + err);
}
mediaRecorder.onwarning = function() {
ok(false, 'Unexpected warning fired');
}
element.oncanplaythrough = function () {
for (var i = 0; i < mExpectStopCount; i++) {
mediaRecorder.start(1000);
mediaRecorder.stop();
}
}
element.play();
}
manager.runTests(gMediaRecorderTests, startTest);
</script>
</pre>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -109,7 +109,7 @@ function newIncomingParcel(fakeParcelSize, response, request, data) {
++writeIndex;
}
function writeUint32(value) {
function writeInt32(value) {
writeUint8(value & 0xff);
writeUint8((value >> 8) & 0xff);
writeUint8((value >> 16) & 0xff);
@ -128,8 +128,8 @@ function newIncomingParcel(fakeParcelSize, response, request, data) {
}
writeParcelSize(fakeParcelSize);
writeUint32(response);
writeUint32(request);
writeInt32(response);
writeInt32(request);
// write parcel data
for (let ii = 0; ii < data.length; ++ii) {

View File

@ -42,10 +42,10 @@ add_test(function test_change_call_barring_password() {
function do_test(facility, pin, newPin) {
buf.sendParcel = function fakeSendParcel () {
// Request Type.
do_check_eq(this.readUint32(), REQUEST_CHANGE_BARRING_PASSWORD);
do_check_eq(this.readInt32(), REQUEST_CHANGE_BARRING_PASSWORD);
// Token : we don't care.
this.readUint32();
this.readInt32();
let parcel = this.readStringList();
do_check_eq(parcel.length, 3);

View File

@ -51,7 +51,7 @@ add_test_incoming_parcel(null,
function test_normal_parcel_handling(worker) {
do_check_throws(function normal_handler() {
// reads exactly the same size, should not throw anything.
worker.Buf.readUint32();
worker.Buf.readInt32();
});
}
);

View File

@ -31,7 +31,7 @@ function newWorkerWithParcel(parcelBuf) {
return buf[index++];
};
worker.Buf.readUint32 = function () {
worker.Buf.readInt32 = function () {
return buf[index++];
};

View File

@ -106,7 +106,7 @@ add_test(function test_queryCallForwardStatus_unconditional() {
});
};
worker.Buf.readUint32 = function fakeReadUint32() {
worker.Buf.readInt32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};

View File

@ -30,7 +30,7 @@ add_test(function test_queryCLIP_provisioned() {
let workerHelper = _getWorker();
let worker = workerHelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
worker.Buf.readInt32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};
@ -58,7 +58,7 @@ add_test(function test_getCLIP_error_generic_failure_invalid_length() {
let workerHelper = _getWorker();
let worker = workerHelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
worker.Buf.readInt32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};

View File

@ -85,7 +85,7 @@ add_test(function test_getCLIR_n0_m1() {
let workerHelper = _getWorker();
let worker = workerHelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
worker.Buf.readInt32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};
@ -117,7 +117,7 @@ add_test(function test_getCLIR_error_generic_failure_invalid_length() {
let workerHelper = _getWorker();
let worker = workerHelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
worker.Buf.readInt32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};

View File

@ -74,7 +74,7 @@ add_test(function test_queryCallWaiting_success_enabled_true() {
let workerHelper = _getWorker();
let worker = workerHelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
worker.Buf.readInt32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};
@ -104,7 +104,7 @@ add_test(function test_queryCallWaiting_success_enabled_false() {
let workerHelper = _getWorker();
let worker = workerHelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
worker.Buf.readInt32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};

View File

@ -492,13 +492,13 @@ add_test(function test_icc_get_card_lock_state_fdn() {
buf.sendParcel = function () {
// Request Type.
do_check_eq(this.readUint32(), REQUEST_QUERY_FACILITY_LOCK)
do_check_eq(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK)
// Token : we don't care.
this.readUint32();
this.readInt32();
// String Array Length.
do_check_eq(this.readUint32(), worker.RILQUIRKS_V5_LEGACY ? 3 : 4);
do_check_eq(this.readInt32(), worker.RILQUIRKS_V5_LEGACY ? 3 : 4);
// Facility.
do_check_eq(this.readString(), ICC_CB_FACILITY_FDN);
@ -513,7 +513,7 @@ add_test(function test_icc_get_card_lock_state_fdn() {
if (!worker.RILQUIRKS_V5_LEGACY) {
// AID. Ignore because it's from modem.
this.readUint32();
this.readInt32();
}
run_next_test();
@ -759,7 +759,7 @@ add_test(function test_read_pbr() {
];
// Write data size
buf.writeUint32(pbr_1.length * 2);
buf.writeInt32(pbr_1.length * 2);
// Write pbr
for (let i = 0; i < pbr_1.length; i++) {
@ -820,7 +820,7 @@ add_test(function test_read_email() {
0x6F, 0x6D, 0x02, 0x23];
// Write data size
buf.writeUint32(email_1.length * 2);
buf.writeInt32(email_1.length * 2);
// Write email
for (let i = 0; i < email_1.length; i++) {
@ -888,32 +888,32 @@ add_test(function test_update_email() {
count++;
// Request Type.
do_check_eq(this.readUint32(), REQUEST_SIM_IO);
do_check_eq(this.readInt32(), REQUEST_SIM_IO);
// Token : we don't care
this.readUint32();
this.readInt32();
// command.
do_check_eq(this.readUint32(), ICC_COMMAND_UPDATE_RECORD);
do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
// fileId.
do_check_eq(this.readUint32(), fileId);
do_check_eq(this.readInt32(), fileId);
// pathId.
do_check_eq(this.readString(),
EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
// p1.
do_check_eq(this.readUint32(), recordNumber);
do_check_eq(this.readInt32(), recordNumber);
// p2.
do_check_eq(this.readUint32(), READ_RECORD_ABSOLUTE_MODE);
do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
// p3.
do_check_eq(this.readUint32(), recordSize);
do_check_eq(this.readInt32(), recordSize);
// data.
let strLen = this.readUint32();
let strLen = this.readInt32();
let email;
if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) {
email = pduHelper.read8BitUnpackedToString(recordSize);
@ -930,7 +930,7 @@ add_test(function test_update_email() {
if (!worker.RILQUIRKS_V5_LEGACY) {
// AID. Ignore because it's from modem.
this.readUint32();
this.readInt32();
}
if (count == NUM_TESTS) {
@ -962,7 +962,7 @@ add_test(function test_read_anr() {
0x54, 0xF6, 0xFF, 0xFF];
// Write data size
buf.writeUint32(anr_1.length * 2);
buf.writeInt32(anr_1.length * 2);
// Write anr
for (let i = 0; i < anr_1.length; i++) {
@ -1029,32 +1029,32 @@ add_test(function test_update_anr() {
count++;
// Request Type.
do_check_eq(this.readUint32(), REQUEST_SIM_IO);
do_check_eq(this.readInt32(), REQUEST_SIM_IO);
// Token : we don't care
this.readUint32();
this.readInt32();
// command.
do_check_eq(this.readUint32(), ICC_COMMAND_UPDATE_RECORD);
do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
// fileId.
do_check_eq(this.readUint32(), fileId);
do_check_eq(this.readInt32(), fileId);
// pathId.
do_check_eq(this.readString(),
EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
// p1.
do_check_eq(this.readUint32(), recordNumber);
do_check_eq(this.readInt32(), recordNumber);
// p2.
do_check_eq(this.readUint32(), READ_RECORD_ABSOLUTE_MODE);
do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
// p3.
do_check_eq(this.readUint32(), recordSize);
do_check_eq(this.readInt32(), recordSize);
// data.
let strLen = this.readUint32();
let strLen = this.readInt32();
// EF_AAS, ignore.
pduHelper.readHexOctet();
do_check_eq(pduHelper.readNumberWithLength(), expectedANR);
@ -1073,7 +1073,7 @@ add_test(function test_update_anr() {
if (!worker.RILQUIRKS_V5_LEGACY) {
// AID. Ignore because it's from modem.
this.readUint32();
this.readInt32();
}
if (count == NUM_TESTS) {
@ -1103,7 +1103,7 @@ add_test(function test_read_iap() {
let iap_1 = [0x01, 0x02];
// Write data size/
buf.writeUint32(iap_1.length * 2);
buf.writeInt32(iap_1.length * 2);
// Write iap.
for (let i = 0; i < iap_1.length; i++) {
@ -1172,32 +1172,32 @@ add_test(function test_update_iap() {
function do_test(expectedIAP) {
buf.sendParcel = function () {
// Request Type.
do_check_eq(this.readUint32(), REQUEST_SIM_IO);
do_check_eq(this.readInt32(), REQUEST_SIM_IO);
// Token : we don't care
this.readUint32();
this.readInt32();
// command.
do_check_eq(this.readUint32(), ICC_COMMAND_UPDATE_RECORD);
do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
// fileId.
do_check_eq(this.readUint32(), fileId);
do_check_eq(this.readInt32(), fileId);
// pathId.
do_check_eq(this.readString(),
EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
// p1.
do_check_eq(this.readUint32(), recordNumber);
do_check_eq(this.readInt32(), recordNumber);
// p2.
do_check_eq(this.readUint32(), READ_RECORD_ABSOLUTE_MODE);
do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
// p3.
do_check_eq(this.readUint32(), recordSize);
do_check_eq(this.readInt32(), recordSize);
// data.
let strLen = this.readUint32();
let strLen = this.readInt32();
for (let i = 0; i < recordSize; i++) {
do_check_eq(expectedIAP[i], pduHelper.readHexOctet());
}
@ -1208,7 +1208,7 @@ add_test(function test_update_iap() {
if (!worker.RILQUIRKS_V5_LEGACY) {
// AID. Ignore because it's from modem.
this.readUint32();
this.readInt32();
}
run_next_test();
@ -1246,28 +1246,28 @@ add_test(function test_update_adn_like() {
buf.sendParcel = function () {
// Request Type.
do_check_eq(this.readUint32(), REQUEST_SIM_IO);
do_check_eq(this.readInt32(), REQUEST_SIM_IO);
// Token : we don't care
this.readUint32();
this.readInt32();
// command.
do_check_eq(this.readUint32(), ICC_COMMAND_UPDATE_RECORD);
do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
// fileId.
do_check_eq(this.readUint32(), fileId);
do_check_eq(this.readInt32(), fileId);
// pathId.
do_check_eq(this.readString(), EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
// p1.
do_check_eq(this.readUint32(), 1);
do_check_eq(this.readInt32(), 1);
// p2.
do_check_eq(this.readUint32(), READ_RECORD_ABSOLUTE_MODE);
do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
// p3.
do_check_eq(this.readUint32(), 0x20);
do_check_eq(this.readInt32(), 0x20);
// data.
let contact = pdu.readAlphaIdDiallingNumber(0x20);
@ -1283,7 +1283,7 @@ add_test(function test_update_adn_like() {
if (!worker.RILQUIRKS_V5_LEGACY) {
// AID. Ignore because it's from modem.
this.readUint32();
this.readInt32();
}
if (fileId == ICC_EF_FDN) {
@ -1313,7 +1313,7 @@ add_test(function test_find_free_record_id() {
function writeRecord (record) {
// Write data size
buf.writeUint32(record.length * 2);
buf.writeInt32(record.length * 2);
for (let i = 0; i < record.length; i++) {
pduHelper.writeHexOctet(record[i]);
@ -1733,10 +1733,10 @@ add_test(function test_set_icc_card_lock_facility_lock() {
function do_test(aLock, aPassword, aEnabled) {
buf.sendParcel = function fakeSendParcel () {
// Request Type.
do_check_eq(this.readUint32(), REQUEST_SET_FACILITY_LOCK);
do_check_eq(this.readInt32(), REQUEST_SET_FACILITY_LOCK);
// Token : we don't care
this.readUint32();
this.readInt32();
let parcel = this.readStringList();
do_check_eq(parcel.length, 5);
@ -1783,14 +1783,14 @@ add_test(function test_unlock_card_lock_corporateLocked() {
function do_test(aLock, aPassword) {
buf.sendParcel = function fakeSendParcel () {
// Request Type.
do_check_eq(this.readUint32(), REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE);
do_check_eq(this.readInt32(), REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE);
// Token : we don't care
this.readUint32();
this.readInt32();
let lockType = GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[aLock];
// Lock Type
do_check_eq(this.readUint32(), lockType);
do_check_eq(this.readInt32(), lockType);
// Pin/Puk.
do_check_eq(this.readString(), aPassword);
@ -1867,7 +1867,7 @@ add_test(function test_reading_ad_and_parsing_mcc_mnc() {
}
// Write data size
buf.writeUint32(ad.length * 2);
buf.writeInt32(ad.length * 2);
// Write data
for (let i = 0; i < ad.length; i++) {

View File

@ -435,7 +435,7 @@ add_test(function test_sendMMI_call_forwarding_interrogation() {
let workerhelper = getWorker();
let worker = workerhelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
worker.Buf.readInt32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};
@ -477,7 +477,7 @@ add_test(function test_sendMMI_call_forwarding_interrogation_no_rules() {
let workerhelper = getWorker();
let worker = workerhelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
worker.Buf.readInt32 = function fakeReadUint32() {
return 0;
};
@ -771,7 +771,7 @@ add_test(function test_sendMMI_call_barring_BAIC_interrogation_voice() {
let workerhelper = getWorker();
let worker = workerhelper.worker;
worker.Buf.readUint32List = function fakeReadUint32List() {
worker.Buf.readInt32List = function fakeReadUint32List() {
return [1];
};
@ -954,7 +954,7 @@ add_test(function test_sendMMI_call_waiting_interrogation() {
let workerhelper = getWorker();
let worker = workerhelper.worker;
worker.Buf.readUint32 = function fakeReadUint32() {
worker.Buf.readInt32 = function fakeReadUint32() {
return worker.Buf.int32Array.pop();
};

View File

@ -82,7 +82,7 @@ add_test(function test_read_cdmahome() {
let cdmaHome = [0xc1, 0x34, 0xff, 0xff, 0x00];
// Write data size
buf.writeUint32(cdmaHome.length * 2);
buf.writeInt32(cdmaHome.length * 2);
// Write cdma home file.
for (let i = 0; i < cdmaHome.length; i++) {
@ -128,7 +128,7 @@ add_test(function test_read_cdmaspn() {
function testReadSpn(file, expectedSpn, expectedDisplayCondition) {
io.loadTransparentEF = function fakeLoadTransparentEF(options) {
// Write data size
buf.writeUint32(file.length * 2);
buf.writeInt32(file.length * 2);
// Write file.
for (let i = 0; i < file.length; i++) {

View File

@ -92,16 +92,16 @@ add_test(function test_stk_terminal_response() {
buf.sendParcel = function () {
// Type
do_check_eq(this.readUint32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
do_check_eq(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
// Token : we don't care
this.readUint32();
this.readInt32();
// Data Size, 44 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
// TLV_DEVICE_ID_SIZE(4) +
// TLV_RESULT_SIZE(3) +
// TEXT LENGTH(10))
do_check_eq(this.readUint32(), 44);
do_check_eq(this.readInt32(), 44);
// Command Details, Type-Length-Value
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
@ -748,16 +748,16 @@ add_test(function test_stk_event_download_location_status() {
buf.sendParcel = function () {
// Type
do_check_eq(this.readUint32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
do_check_eq(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
// Token : we don't care
this.readUint32();
this.readInt32();
// Data Size, 42 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) +
// TLV_EVENT_LIST_SIZE(3) +
// TLV_LOCATION_STATUS_SIZE(3) +
// TLV_LOCATION_INFO_GSM_SIZE(9))
do_check_eq(this.readUint32(), 42);
do_check_eq(this.readInt32(), 42);
// BER tag
do_check_eq(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
@ -830,15 +830,15 @@ add_test(function test_stk_event_download_language_selection() {
buf.sendParcel = function () {
// Type
do_check_eq(this.readUint32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
do_check_eq(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
// Token : we don't care
this.readUint32();
this.readInt32();
// Data Size, 26 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) +
// TLV_EVENT_LIST_SIZE(3) +
// TLV_LANGUAGE(4))
do_check_eq(this.readUint32(), 26);
do_check_eq(this.readInt32(), 26);
// BER tag
do_check_eq(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
@ -888,13 +888,13 @@ add_test(function test_stk_event_download_user_activity() {
buf.sendParcel = function () {
// Type
do_check_eq(this.readUint32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
do_check_eq(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
// Token : we don't care
this.readUint32();
this.readInt32();
// Data Size, 18 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3))
do_check_eq(this.readUint32(), 18);
do_check_eq(this.readInt32(), 18);
// BER tag
do_check_eq(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
@ -936,13 +936,13 @@ add_test(function test_stk_event_download_idle_screen_available() {
buf.sendParcel = function () {
// Type
do_check_eq(this.readUint32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
do_check_eq(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
// Token : we don't care
this.readUint32();
this.readInt32();
// Data Size, 18 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3))
do_check_eq(this.readUint32(), 18);
do_check_eq(this.readInt32(), 18);
// BER tag
do_check_eq(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);

View File

@ -72,7 +72,7 @@ add_test(function test_queryVoicePrivacyMode_success_enabled_true() {
let workerHelper = _getWorker();
let worker = workerHelper.worker;
worker.Buf.readUint32List = function fakeReadUint32List() {
worker.Buf.readInt32List = function fakeReadUint32List() {
return [1];
};
@ -95,7 +95,7 @@ add_test(function test_queryVoicePrivacyMode_success_enabled_false() {
let workerHelper = _getWorker();
let worker = workerHelper.worker;
worker.Buf.readUint32List = function fakeReadUint32List() {
worker.Buf.readInt32List = function fakeReadUint32List() {
return [0];
};

View File

@ -262,22 +262,22 @@ let Buf = {
return this.readUint8() | this.readUint8() << 8;
},
readUint32: function readUint32() {
readInt32: function readInt32() {
return this.readUint8() | this.readUint8() << 8 |
this.readUint8() << 16 | this.readUint8() << 24;
},
readUint32List: function readUint32List() {
let length = this.readUint32();
readInt32List: function readInt32List() {
let length = this.readInt32();
let ints = [];
for (let i = 0; i < length; i++) {
ints.push(this.readUint32());
ints.push(this.readInt32());
}
return ints;
},
readString: function readString() {
let string_len = this.readUint32();
let string_len = this.readInt32();
if (string_len < 0 || string_len >= this.INT32_MAX) {
return null;
}
@ -293,7 +293,7 @@ let Buf = {
},
readStringList: function readStringList() {
let num_strings = this.readUint32();
let num_strings = this.readInt32();
let strings = [];
for (let i = 0; i < num_strings; i++) {
strings.push(this.readString());
@ -349,7 +349,7 @@ let Buf = {
this.writeUint8((value >> 8) & 0xff);
},
writeUint32: function writeUint32(value) {
writeInt32: function writeInt32(value) {
this.writeUint8(value & 0xff);
this.writeUint8((value >> 8) & 0xff);
this.writeUint8((value >> 16) & 0xff);
@ -358,10 +358,10 @@ let Buf = {
writeString: function writeString(value) {
if (value == null) {
this.writeUint32(-1);
this.writeInt32(-1);
return;
}
this.writeUint32(value.length);
this.writeInt32(value.length);
for (let i = 0; i < value.length; i++) {
this.writeUint16(value.charCodeAt(i));
}
@ -372,7 +372,7 @@ let Buf = {
},
writeStringList: function writeStringList(strings) {
this.writeUint32(strings.length);
this.writeInt32(strings.length);
for (let i = 0; i < strings.length; i++) {
this.writeString(strings[i]);
}
@ -587,7 +587,7 @@ let Buf = {
* may call multiple read functions to extract data from the incoming buffer.
*/
//processParcel: function processParcel() {
// let something = this.readUint32();
// let something = this.readInt32();
// ...
//},

View File

@ -3337,11 +3337,11 @@ WifiWorker.prototype = {
this.queueRequest(false, function(data) {
if (this.tetheringSettings[SETTINGS_WIFI_TETHERING_ENABLED] ||
WifiManager.tetheringState != "UNINITIALIZED") {
this.disconnectedByWifi = true;
this.setWifiApEnabled(false, this.notifyTetheringOff.bind(this));
} else {
this.requestDone();
}
this.disconnectedByWifi = true;
}.bind(this));
}
@ -3366,11 +3366,11 @@ WifiWorker.prototype = {
if (enabled) {
this.queueRequest(false, function(data) {
if (WifiManager.enabled || WifiManager.state != "UNINITIALIZED") {
this.disconnectedByWifiTethering = true;
this.setWifiEnabled(false, this._setWifiEnabledCallback.bind(this));
} else {
this.requestDone();
}
this.disconnectedByWifiTethering = true;
}.bind(this));
}

View File

@ -1,31 +1,34 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:mathml="http://www.w3.org/1998/Math/MathML">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:mathml="http://www.w3.org/1998/Math/MathML" class="reftest-wait">
<mathml:mfenced/>
<script><![CDATA[
var docviewer;
function do_onload() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var navigator1 = parent.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebNavigation);
var docShell = navigator1.QueryInterface(Components.interfaces.nsIDocShell);
docviewer = docShell.contentViewer.QueryInterface(Components.interfaces.nsIMarkupDocumentViewer);
var navigator1 = SpecialPowers.wrap(parent).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor).getInterface(SpecialPowers.Ci.nsIWebNavigation);
var docShell = navigator1.QueryInterface(SpecialPowers.Ci.nsIDocShell);
docviewer = docShell.contentViewer.QueryInterface(SpecialPowers.Ci.nsIMarkupDocumentViewer);
setTimeout(function() {window.location.reload()}, 500);
setTimeout(doe,50, 0.2);
setTimeout(function() {
clearTimeout(timer);
docviewer.textZoom = 1;
document.documentElement.removeAttribute("class");
}, 500);
setTimeout(doe,50, 0.2);
}
do_onload();
var timer;
function doe(i) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
docviewer.textZoom += i;
docviewer.textZoom += i;
if (docviewer.textZoom >=4)
i = -0.2;
if (docviewer.textZoom >=4)
i = -0.2;
if (docviewer.textZoom <=0)
i = 0.2;
window.status = docviewer.textZoom;
setTimeout(doe, 50, i);
if (docviewer.textZoom <=0)
i = 0.2;
window.status = docviewer.textZoom;
timer = setTimeout(doe, 50, i);
}
]]></script>
</html>

View File

@ -201,6 +201,7 @@
<activity android:name="org.mozilla.gecko.Restarter"
android:process="@ANDROID_PACKAGE_NAME@Restarter"
android:noHistory="true"
android:theme="@style/Gecko">
<intent-filter>
<action android:name="org.mozilla.gecko.restart"/>

View File

@ -2268,8 +2268,12 @@ abstract public class BrowserApp extends GeckoApp
// HomePager.OnNewTabsListener
@Override
public void onNewTabs(String[] urls) {
final EnumSet<OnUrlOpenListener.Flags> flags = EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB);
for (String url : urls) {
openUrl(url, true);
if (!maybeSwitchToTab(url, flags)) {
openUrl(url, true);
}
}
}

View File

@ -2132,8 +2132,6 @@ abstract public class GeckoApp
Intent intent = new Intent(action);
intent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, RESTARTER_CLASS);
/* TODO: addEnvToIntent(intent); */
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
if (args != null)
intent.putExtra("args", args);
intent.putExtra("didRestart", true);

View File

@ -666,7 +666,6 @@ RES_DRAWABLE_MDPI = \
res/drawable-mdpi/icon_most_recent.png \
res/drawable-mdpi/icon_most_recent_empty.png \
res/drawable-mdpi/icon_most_visited.png \
res/drawable-mdpi/icon_most_visited_empty.png \
res/drawable-mdpi/icon_openinapp.png \
res/drawable-mdpi/icon_pageaction.png \
res/drawable-mdpi/icon_reading_list_empty.png \
@ -782,7 +781,6 @@ RES_DRAWABLE_HDPI = \
res/drawable-hdpi/icon_most_recent.png \
res/drawable-hdpi/icon_most_recent_empty.png \
res/drawable-hdpi/icon_most_visited.png \
res/drawable-hdpi/icon_most_visited_empty.png \
res/drawable-hdpi/icon_openinapp.png \
res/drawable-hdpi/icon_pageaction.png \
res/drawable-hdpi/icon_reading_list_empty.png \
@ -884,7 +882,6 @@ RES_DRAWABLE_XHDPI = \
res/drawable-xhdpi/icon_most_recent.png \
res/drawable-xhdpi/icon_most_recent_empty.png \
res/drawable-xhdpi/icon_most_visited.png \
res/drawable-xhdpi/icon_most_visited_empty.png \
res/drawable-xhdpi/icon_openinapp.png \
res/drawable-xhdpi/icon_pageaction.png \
res/drawable-xhdpi/icon_reading_list_empty.png \

View File

@ -15,6 +15,8 @@ public class Restarter extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(LOGTAG, "Trying to restart " + AppConstants.MOZ_APP_NAME);
try {
int countdown = 40;
@ -46,15 +48,10 @@ public class Restarter extends Activity {
Bundle b = getIntent().getExtras();
if (b != null)
intent.putExtras(b);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Log.i(LOGTAG, intent.toString());
startActivity(intent);
} catch (Exception e) {
Log.i(LOGTAG, e.toString());
}
// Give the new process time to start before we die
GeckoAppShell.waitForAnotherGeckoProc();
System.exit(0);
}
}

View File

@ -47,11 +47,8 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.EnumSet;
@ -87,9 +84,6 @@ public class TopSitesPage extends HomeFragment {
// Grid of top sites
private TopSitesGridView mGrid;
// Reference to the View to display when there are no results.
private View mEmptyView;
// Banner to show snippets.
private HomeBanner mBanner;
@ -224,7 +218,6 @@ public class TopSitesPage extends HomeFragment {
super.onDestroyView();
mList = null;
mGrid = null;
mEmptyView = null;
mListAdapter = null;
mGridAdapter = null;
}
@ -466,20 +459,6 @@ public class TopSitesPage extends HomeFragment {
if (c != null && c.getCount() > 0) {
return;
}
if (mEmptyView == null) {
// Set empty page view. We delay this so that the empty view won't flash.
ViewStub emptyViewStub = (ViewStub) getView().findViewById(R.id.home_empty_view_stub);
mEmptyView = emptyViewStub.inflate();
final ImageView emptyIcon = (ImageView) mEmptyView.findViewById(R.id.home_empty_image);
emptyIcon.setImageResource(R.drawable.icon_most_visited_empty);
final TextView emptyText = (TextView) mEmptyView.findViewById(R.id.home_empty_text);
emptyText.setText(R.string.home_most_visited_empty);
mList.setEmptyView(mEmptyView);
}
}
private static class TopSitesLoader extends SimpleCursorLoader {

View File

@ -280,7 +280,6 @@ size. -->
<!ENTITY home_last_tabs_empty "Your recent tabs show up here.">
<!ENTITY home_most_recent_title "Most recent">
<!ENTITY home_most_recent_empty "Websites you visited most recently show up here.">
<!ENTITY home_most_visited_title "Most visited">
<!ENTITY home_reading_list_empty "Articles you save for later show up here.">
<!-- Localization note (home_reading_list_hint): The "TIP" string is synonymous to "hint", "clue", etc. This string is displayed
as an advisory message on how to add content to the reading list when the reading list empty.
@ -291,7 +290,6 @@ size. -->
as alternate text for accessibility. It is not visible in the UI. -->
<!ENTITY home_reading_list_hint_accessible "TIP: Save articles to your reading list by long pressing the reader mode button when it appears in the title bar.">
<!ENTITY home_most_visited_empty "Websites you visit most frequently show up here.">
<!ENTITY pin_site_dialog_hint "Enter a search keyword">
<!ENTITY filepicker_title "Choose File">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -6,7 +6,7 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/url_bar_bg">
android:background="@color/background_light">
<LinearLayout android:id="@+id/prompt"
android:focusable="true"
@ -20,16 +20,15 @@
<TextView android:id="@+id/suggestions_prompt_title"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:textColor="@color/url_bar_title"
android:layout_marginLeft="6dip"
android:textSize="14sp"
android:layout_weight="1" />
android:layout_weight="1"
android:textAppearance="@style/TextAppearance.Widget.SuggestionsPrompt"/>
<TextView android:id="@+id/suggestions_prompt_yes"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="14sp"
android:layout_marginLeft="15dip"
android:textAppearance="@style/TextAppearance.Widget.SuggestionsPrompt"
android:background="@drawable/suggestion_selector"
android:paddingLeft="15dp"
android:paddingRight="15dp"
@ -41,8 +40,8 @@
<TextView android:id="@+id/suggestions_prompt_no"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="14sp"
android:layout_marginLeft="6dip"
android:textAppearance="@style/TextAppearance.Widget.SuggestionsPrompt"
android:background="@drawable/suggestion_selector"
android:nextFocusRight="@+id/suggestions_prompt_no"
android:paddingLeft="15dp"

View File

@ -8,11 +8,6 @@
android:layout_height="fill_parent"
android:orientation="vertical">
<ViewStub android:id="@+id/home_empty_view_stub"
android:layout="@layout/home_empty_page"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<org.mozilla.gecko.home.HomeListView
android:id="@+id/list"
style="@style/Widget.TopSitesListView"

View File

@ -312,6 +312,10 @@
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
<style name="TextAppearance.Widget.SuggestionsPrompt" parent="TextAppearance.Small">
<item name="android:textColor">@color/url_bar_title</item>
</style>
<style name="TextAppearance.Widget.Home" />
<style name="TextAppearance.Widget.Home.Header" parent="TextAppearance.Small">

View File

@ -259,8 +259,6 @@
<string name="home_last_tabs_empty">&home_last_tabs_empty;</string>
<string name="home_most_recent_title">&home_most_recent_title;</string>
<string name="home_most_recent_empty">&home_most_recent_empty;</string>
<string name="home_most_visited_title">&home_most_visited_title;</string>
<string name="home_most_visited_empty">&home_most_visited_empty;</string>
<string name="home_reading_list_empty">&home_reading_list_empty;</string>
<string name="home_reading_list_hint">&home_reading_list_hint;</string>
<string name="home_reading_list_hint_accessible">&home_reading_list_hint_accessible;</string>

View File

@ -1,7 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<!DOCTYPE html [
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
%brandDTD;
<!ENTITY % abouthomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
%abouthomeDTD;
]>
<!-- 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
@ -9,6 +15,7 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&abouthome.title;</title>
<link rel="icon" type="image/png" sizes="64x64" href="chrome://branding/content/favicon64.png" />
</head>
<body>

View File

@ -17,6 +17,7 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&privatebrowsingpage.title;</title>
<meta name="viewport" content="width=device-width, initial-scale=1; user-scalable=no"/>
<link rel="stylesheet" href="chrome://browser/skin/aboutPrivateBrowsing.css" type="text/css" media="all"/>
<link rel="icon" type="image/png" href="chrome://branding/content/favicon32.png" />

View File

@ -0,0 +1,5 @@
<!-- 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/. -->
<!ENTITY abouthome.title "&brandShortName; Home">

View File

@ -14,6 +14,7 @@
locale/@AB_CD@/browser/aboutDownloads.dtd (%chrome/aboutDownloads.dtd)
locale/@AB_CD@/browser/aboutDownloads.properties (%chrome/aboutDownloads.properties)
locale/@AB_CD@/browser/aboutFeedback.dtd (%chrome/aboutFeedback.dtd)
locale/@AB_CD@/browser/aboutHome.dtd (%chrome/aboutHome.dtd)
locale/@AB_CD@/browser/aboutPrivateBrowsing.dtd (%chrome/aboutPrivateBrowsing.dtd)
locale/@AB_CD@/browser/aboutReader.properties (%chrome/aboutReader.properties)
#ifdef MOZ_SERVICES_HEALTHREPORT

View File

@ -113,9 +113,9 @@
#include "nsXPCOMCIDInternal.h"
#include "nsComponentManagerUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsIConsoleService.h"
#include "PSMRunnable.h"
#include "SharedSSLState.h"
#include "nsContentUtils.h"
#include "ssl.h"
#include "secerr.h"
@ -213,11 +213,7 @@ LogInvalidCertError(TransportSecurityInfo *socketInfo,
socketInfo->GetErrorLogMessage(errorCode, errorMessageType, message);
if (!message.IsEmpty()) {
nsCOMPtr<nsIConsoleService> console;
console = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (console) {
console->LogStringMessage(message.get());
}
nsContentUtils::LogSimpleConsoleError(message, "SSL");
}
}

View File

@ -18,7 +18,7 @@
#include "nsProxyRelease.h"
#include "PSMRunnable.h"
#include "ScopedNSSTypes.h"
#include "nsIConsoleService.h"
#include "nsContentUtils.h"
#include "nsIHttpChannelInternal.h"
#include "nsNetUtil.h"
#include "SharedSSLState.h"
@ -1042,16 +1042,14 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
// localized.
if (!siteSupportsSafeRenego &&
ioLayerHelpers.getWarnLevelMissingRFC5746() > 0) {
nsCOMPtr<nsIConsoleService> console = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (console) {
nsXPIDLCString hostName;
infoObject->GetHostName(getter_Copies(hostName));
nsXPIDLCString hostName;
infoObject->GetHostName(getter_Copies(hostName));
nsAutoString msg;
msg.Append(NS_ConvertASCIItoUTF16(hostName));
msg.Append(NS_LITERAL_STRING(" : server does not support RFC 5746, see CVE-2009-3555"));
console->LogStringMessage(msg.get());
}
nsAutoString msg;
msg.Append(NS_ConvertASCIItoUTF16(hostName));
msg.Append(NS_LITERAL_STRING(" : server does not support RFC 5746, see CVE-2009-3555"));
nsContentUtils::LogSimpleConsoleError(msg, "SSL");
}
ScopedCERTCertificate serverCert(SSL_PeerCertificate(fd));

View File

@ -37,6 +37,7 @@
#include "ScopedNSSTypes.h"
#include "SharedSSLState.h"
#include "mozilla/Preferences.h"
#include "nsContentUtils.h"
#include "ssl.h"
#include "secerr.h"
@ -668,11 +669,7 @@ nsHandleSSLError(nsNSSSocketInfo *socketInfo,
socketInfo->GetErrorLogMessage(err, errtype, errorString);
if (!errorString.IsEmpty()) {
nsCOMPtr<nsIConsoleService> console;
console = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (console) {
console->LogStringMessage(errorString.get());
}
nsContentUtils::LogSimpleConsoleError(errorString, "SSL");
}
}

View File

@ -3,6 +3,8 @@
include ../../testing/crashtest/sanity/crashtests.list
include ../../accessible/tests/crashtests/crashtests.list
include ../../content/base/crashtests/crashtests.list
include ../../content/canvas/crashtests/crashtests.list
include ../../content/events/crashtests/crashtests.list

View File

@ -189,7 +189,6 @@
"content/html/content/test/test_iframe_sandbox_plugins.html":"plugins not supported",
"content/html/content/test/test_object_plugin_nav.html":"plugins not supported",
"content/html/document/test/test_bug199692.html":"needs popup to be sized to 600*600",
"content/html/document/test/test_bug741266.html":"needs control of popup window size",
"docshell/test/navigation/test_popup-navigates-children.html":"Needs multiple window.open support, also uses docshelltreenode",
"docshell/test/test_bug590573.html":"queryinterfaces into webnavigation, might suffer from something similar as bug 823022",
@ -208,7 +207,6 @@
"content/base/test/csp/test_CSP_bug916446.html":"observer not working",
"content/base/test/test_CrossSiteXHR_origin.html":"https not working, bug 907770",
"content/base/test/test_bug326337.html":"popup windows don't have specialpowers installed, could be solved with sendmessage/receivemessage",
"content/base/test/test_plugin_freezing.html":"",
"content/base/test/test_bug466409.html":"",
"content/base/test/test_bug482935.html":"",

View File

@ -14,7 +14,20 @@ let container = homescreen.contentWindow.document.getElementById('test-container
function openWindow(aEvent) {
var popupIframe = aEvent.detail.frameElement;
popupIframe.setAttribute('style', 'position: absolute; left: 0; top: 300px; background: white; ');
popupIframe.setAttribute('style', 'position: absolute; left: 0; top: 0px; background: white;');
// This is to size the iframe to what is requested in the window.open call,
// e.g. window.open("", "", "width=600,height=600");
if (aEvent.detail.features.indexOf('width') != -1) {
let width = aEvent.detail.features.substr(aEvent.detail.features.indexOf('width')+6);
width = width.substr(0,width.indexOf(',') == -1 ? width.length : width.indexOf(','));
popupIframe.style.width = width + 'px';
}
if (aEvent.detail.features.indexOf('height') != -1) {
let height = aEvent.detail.features.substr(aEvent.detail.features.indexOf('height')+7);
height = height.substr(0, height.indexOf(',') == -1 ? height.length : height.indexOf(','));
popupIframe.style.height = height + 'px';
}
popupIframe.addEventListener('mozbrowserclose', function(e) {
container.parentNode.removeChild(popupIframe);
@ -26,6 +39,11 @@ function openWindow(aEvent) {
popupIframe.addEventListener('mozbrowserloadstart', function(e) {
popupIframe.focus();
let mm = popupIframe.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
mm.loadFrameScript(CHILD_LOGGER_SCRIPT, true);
mm.loadFrameScript(CHILD_SCRIPT_API, true);
mm.loadFrameScript(CHILD_SCRIPT, true);
mm.loadFrameScript('data:,attachSpecialPowersToWindow%28content%29%3B', true);
});
container.parentNode.appendChild(popupIframe);

View File

@ -1,4 +1,3 @@
#
# 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/.
@ -887,8 +886,13 @@ class Mochitest(MochitestUtilsMixin):
# create mozrunner instance and start the system under test process
self.lastTestSeen = self.test_name
startTime = datetime.now()
runner_cls = mozrunner.runners.get(mozinfo.info.get('appname', 'firefox'),
mozrunner.Runner)
# b2g desktop requires FirefoxRunner even though appname is b2g
if mozinfo.info.get('appname') == 'b2g' and mozinfo.info.get('toolkit') != 'gonk':
runner_cls = mozrunner.FirefoxRunner
else:
runner_cls = mozrunner.runners.get(mozinfo.info.get('appname', 'firefox'),
mozrunner.Runner)
runner = runner_cls(profile=self.profile,
binary=cmd,
cmdargs=args,

View File

@ -18,7 +18,6 @@ except ImportError:
here = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, here)
from b2gautomation import B2GDesktopAutomation
from runtests import Mochitest
from runtests import MochitestUtilsMixin
from runtests import MochitestOptions
@ -225,9 +224,9 @@ class B2GDeviceMochitest(B2GMochitest):
class B2GDesktopMochitest(B2GMochitest, Mochitest):
def __init__(self, automation, marionette, profile_data_dir):
def __init__(self, marionette, profile_data_dir):
B2GMochitest.__init__(self, marionette, out_of_process=False, profile_data_dir=profile_data_dir)
Mochitest.__init__(self, automation)
Mochitest.__init__(self)
def runMarionetteScript(self, marionette, test_script, test_script_args):
assert(marionette.wait_for_port())
@ -337,8 +336,6 @@ def run_remote_mochitests(parser, options):
sys.exit(retVal)
def run_desktop_mochitests(parser, options):
automation = B2GDesktopAutomation()
# create our Marionette instance
kwargs = {}
if options.marionette:
@ -346,9 +343,7 @@ def run_desktop_mochitests(parser, options):
kwargs['host'] = host
kwargs['port'] = int(port)
marionette = Marionette.getMarionetteOrExit(**kwargs)
automation.marionette = marionette
mochitest = B2GDesktopMochitest(automation, marionette, options.profile_data_dir)
mochitest = B2GDesktopMochitest(marionette, options.profile_data_dir)
# b2g desktop builds don't always have a b2g-bin file
if options.app[-4:] == '-bin':
@ -361,10 +356,6 @@ def run_desktop_mochitests(parser, options):
if options.desktop and not options.profile:
raise Exception("must specify --profile when specifying --desktop")
automation.setServerInfo(options.webServer,
options.httpPort,
options.sslPort,
options.webSocketPort)
sys.exit(mochitest.runTests(options, onLaunch=mochitest.startTests))
def main():

View File

@ -338,8 +338,8 @@ Download.prototype = {
// While shutting down or disposing of this object, we prevent the download
// from returning to be in progress.
if (this._finalized) {
return Promise.reject(new DownloadError(Cr.NS_ERROR_FAILURE,
"Cannot start after finalization."));
return Promise.reject(new DownloadError({
message: "Cannot start after finalization."}));
}
// Initialize all the status properties for a new or restarted download.
@ -408,15 +408,12 @@ Download.prototype = {
}
}
// Disallow download if parental controls service restricts it.
if (yield DownloadIntegration.shouldBlockForParentalControls(this)) {
let error = new DownloadError(Cr.NS_ERROR_FAILURE, "Download blocked.");
error.becauseBlocked = true;
error.becauseBlockedByParentalControls = true;
throw error;
}
try {
// Disallow download if parental controls service restricts it.
if (yield DownloadIntegration.shouldBlockForParentalControls(this)) {
throw new DownloadError({ becauseBlockedByParentalControls: true });
}
// Execute the actual download through the saver object.
yield this.saver.execute(DS_setProgressBytes.bind(this),
DS_setProperties.bind(this));
@ -430,7 +427,16 @@ Download.prototype = {
// is forced to actually check the status properties to see if the
// download was canceled or failed because of other reasons.
if (this._promiseCanceled) {
throw new DownloadError(Cr.NS_ERROR_FAILURE, "Download canceled.");
throw new DownloadError({ message: "Download canceled." });
}
// An HTTP 450 error code is used by Windows to indicate that a uri is
// blocked by parental controls. This will prevent the download from
// occuring, so an error needs to be raised. This is not performed
// during the parental controls check above as it requires the request
// to start.
if (this._blockedByParentalControls) {
ex = new DownloadError({ becauseBlockedByParentalControls: true });
}
// Update the download error, unless a new attempt already started. The
@ -475,7 +481,7 @@ Download.prototype = {
// Notify the new download state before returning.
this._notifyChange();
return this._currentAttempt;
return currentAttempt;
},
/*
@ -1152,18 +1158,22 @@ DownloadTarget.fromSerializable = function (aSerializable) {
/**
* Provides detailed information about a download failure.
*
* @param aResult
* The result code associated with the error.
* @param aMessage
* The message to be displayed, or null to use the message associated
* with the result code.
* @param aInferCause
* If true, attempts to determine if the cause of the download is a
* network failure or a local file failure, based on a set of known
* values of the result code. This is useful when the error is received
* by a component that handles both aspects of the download.
* @param aProperties
* Object which may contain any of the following properties:
* {
* result: Result error code, defaulting to Cr.NS_ERROR_FAILURE
* message: String error message to be displayed, or null to use the
* message associated with the result code.
* inferCause: If true, attempts to determine if the cause of the
* download is a network failure or a local file failure,
* based on a set of known values of the result code.
* This is useful when the error is received by a
* component that handles both aspects of the download.
* }
* The properties object may also contain any of the DownloadError's
* because properties, which will be set accordingly in the error object.
*/
function DownloadError(aResult, aMessage, aInferCause)
function DownloadError(aProperties)
{
const NS_ERROR_MODULE_BASE_OFFSET = 0x45;
const NS_ERROR_MODULE_NETWORK = 6;
@ -1171,18 +1181,39 @@ function DownloadError(aResult, aMessage, aInferCause)
// Set the error name used by the Error object prototype first.
this.name = "DownloadError";
this.result = aResult || Cr.NS_ERROR_FAILURE;
if (aMessage) {
this.message = aMessage;
this.result = aProperties.result || Cr.NS_ERROR_FAILURE;
if (aProperties.message) {
this.message = aProperties.message;
} else if (aProperties.becauseBlocked ||
aProperties.becauseBlockedByParentalControls) {
this.message = "Download blocked.";
} else {
let exception = new Components.Exception("", this.result);
this.message = exception.toString();
}
if (aInferCause) {
let module = ((aResult & 0x7FFF0000) >> 16) - NS_ERROR_MODULE_BASE_OFFSET;
if (aProperties.inferCause) {
let module = ((this.result & 0x7FFF0000) >> 16) -
NS_ERROR_MODULE_BASE_OFFSET;
this.becauseSourceFailed = (module == NS_ERROR_MODULE_NETWORK);
this.becauseTargetFailed = (module == NS_ERROR_MODULE_FILES);
}
else {
if (aProperties.becauseSourceFailed) {
this.becauseSourceFailed = true;
}
if (aProperties.becauseTargetFailed) {
this.becauseTargetFailed = true;
}
}
if (aProperties.becauseBlockedByParentalControls) {
this.becauseBlocked = true;
this.becauseBlockedByParentalControls = true;
}
else if (aProperties.becauseBlocked) {
this.becauseBlocked = true;
}
this.stack = new Error().stack;
}
@ -1309,6 +1340,31 @@ DownloadSaver.prototype = {
targetUri);
},
/**
* Return true if the request's response has been blocked by Windows parental
* controls with an HTTP 450 error code.
*
* @param aRequest
* nsIRequest object
* @return True if the response is blocked.
*/
isResponseParentalBlocked: function(aRequest)
{
// If the HTTP status is 450, then Windows Parental Controls have
// blocked this download.
if (aRequest instanceof Ci.nsIHttpChannel &&
aRequest.responseStatus == 450) {
// Cancel the request, but set a flag on the download that can be
// retrieved later when handling the cancellation so that the proper
// blocked by parental controls error can be thrown.
this.download._blockedByParentalControls = true;
aRequest.cancel(Cr.NS_BINDING_ABORTED);
return true;
}
return false;
},
/**
* Returns a static representation of the current object state.
*
@ -1420,7 +1476,7 @@ DownloadCopySaver.prototype = {
// Throw a DownloadError indicating that the operation failed because of
// the target file. We cannot translate this into a specific result
// code, but we preserve the original message using the toString method.
let error = new DownloadError(Cr.NS_ERROR_FAILURE, ex.toString());
let error = new DownloadError({ message: ex.toString() });
error.becauseTargetFailed = true;
throw error;
}
@ -1431,7 +1487,7 @@ DownloadCopySaver.prototype = {
if (this._canceled) {
// Don't create the BackgroundFileSaver object if we have been
// canceled meanwhile.
throw new DownloadError(Cr.NS_ERROR_FAILURE, "Saver canceled.");
throw new DownloadError({ message: "Saver canceled." });
}
// Create the object that will save the file in a background thread.
@ -1453,8 +1509,8 @@ DownloadCopySaver.prototype = {
} else {
// Infer the origin of the error from the failure code, because
// BackgroundFileSaver does not provide more specific data.
deferSaveComplete.reject(new DownloadError(aStatus, null,
true));
let properties = { result: aStatus, inferCause: true };
deferSaveComplete.reject(new DownloadError(properties));
}
},
};
@ -1506,6 +1562,10 @@ DownloadCopySaver.prototype = {
onStartRequest: function (aRequest, aContext) {
backgroundFileSaver.onStartRequest(aRequest, aContext);
if (this.isResponseParentalBlocked(aRequest)) {
return;
}
aSetPropertiesFn({ contentType: channel.contentType });
// Ensure we report the value of "Content-Length", if available,
@ -1777,6 +1837,10 @@ DownloadLegacySaver.prototype = {
ex.result == Cr.NS_ERROR_NOT_RESUMABLE) { }
}
if (this.isResponseParentalBlocked(aRequest)) {
return;
}
// For legacy downloads, we must update the referrer at this time.
if (aRequest instanceof Ci.nsIHttpChannel && aRequest.referrer) {
this.download.source.referrer = aRequest.referrer.spec;
@ -1805,7 +1869,8 @@ DownloadLegacySaver.prototype = {
} else {
// Infer the origin of the error from the failure code, because more
// specific data is not available through the nsITransfer implementation.
this.deferExecuted.reject(new DownloadError(aStatus, null, true));
let properties = { result: aStatus, inferCause: true };
this.deferExecuted.reject(new DownloadError(properties));
}
},

View File

@ -1355,6 +1355,7 @@ add_task(function test_blocked_parental_controls()
do_throw("The download should have blocked.");
} catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) {
do_check_true(ex.becauseBlockedByParentalControls);
do_check_true(download.error.becauseBlockedByParentalControls);
}
// Now that the download stopped, the target file should not exist.
@ -1363,6 +1364,32 @@ add_task(function test_blocked_parental_controls()
cleanup();
});
/**
* Test a download that will be blocked by Windows parental controls by
* resulting in an HTTP status code of 450.
*/
add_task(function test_blocked_parental_controls_httpstatus450()
{
let download;
try {
if (!gUseLegacySaver) {
download = yield promiseNewDownload(httpUrl("parentalblocked.zip"));
yield download.start();
}
else {
download = yield promiseStartLegacyDownload(httpUrl("parentalblocked.zip"));
yield promiseDownloadStopped(download);
}
do_throw("The download should have blocked.");
} catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) {
do_check_true(ex.becauseBlockedByParentalControls);
do_check_true(download.error.becauseBlockedByParentalControls);
do_check_true(download.stopped);
}
do_check_false(yield OS.File.exists(download.target.path));
});
/**
* download.showContainingDirectory() action
*/

View File

@ -773,6 +773,13 @@ add_task(function test_common_initialize()
TEST_DATA_SHORT_GZIP_ENCODED_SECOND.length);
});
// This URL will emulate being blocked by Windows Parental controls
gHttpServer.registerPathHandler("/parentalblocked.zip",
function (aRequest, aResponse) {
aResponse.setStatusLine(aRequest.httpVersion, 450,
"Blocked by Windows Parental Controls");
});
// Disable integration with the host application requiring profile access.
DownloadIntegration.dontLoadList = true;
DownloadIntegration.dontLoadObservers = true;

View File

@ -9,6 +9,9 @@
"use strict";
XPCOMUtils.defineLazyModuleGetter(this, "DownloadError",
"resource://gre/modules/DownloadCore.jsm");
////////////////////////////////////////////////////////////////////////////////
//// Execution of common tests
@ -17,6 +20,74 @@ let gUseLegacySaver = false;
let scriptFile = do_get_file("common_test_Download.js");
Services.scriptloader.loadSubScript(NetUtil.newURI(scriptFile).spec);
////////////////////////////////////////////////////////////////////////////////
//// Tests
/**
* Tests the DownloadError object.
*/
add_task(function test_DownloadError()
{
let error = new DownloadError({ result: Cr.NS_ERROR_NOT_RESUMABLE,
message: "Not resumable."});
do_check_eq(error.result, Cr.NS_ERROR_NOT_RESUMABLE);
do_check_eq(error.message, "Not resumable.");
do_check_false(error.becauseSourceFailed);
do_check_false(error.becauseTargetFailed);
do_check_false(error.becauseBlocked);
do_check_false(error.becauseBlockedByParentalControls);
error = new DownloadError({ message: "Unknown error."});
do_check_eq(error.result, Cr.NS_ERROR_FAILURE);
do_check_eq(error.message, "Unknown error.");
error = new DownloadError({ result: Cr.NS_ERROR_NOT_RESUMABLE });
do_check_eq(error.result, Cr.NS_ERROR_NOT_RESUMABLE);
do_check_true(error.message.indexOf("Exception") > 0);
// becauseSourceFailed will be set, but not the unknown property.
error = new DownloadError({ message: "Unknown error.",
becauseSourceFailed: true,
becauseUnknown: true });
do_check_true(error.becauseSourceFailed);
do_check_false("becauseUnknown" in error);
error = new DownloadError({ result: Cr.NS_ERROR_MALFORMED_URI,
inferCause: true });
do_check_eq(error.result, Cr.NS_ERROR_MALFORMED_URI);
do_check_true(error.becauseSourceFailed);
do_check_false(error.becauseTargetFailed);
do_check_false(error.becauseBlocked);
do_check_false(error.becauseBlockedByParentalControls);
// This test does not set inferCause, so becauseSourceFailed will not be set.
error = new DownloadError({ result: Cr.NS_ERROR_MALFORMED_URI });
do_check_eq(error.result, Cr.NS_ERROR_MALFORMED_URI);
do_check_false(error.becauseSourceFailed);
error = new DownloadError({ result: Cr.NS_ERROR_FILE_INVALID_PATH,
inferCause: true });
do_check_eq(error.result, Cr.NS_ERROR_FILE_INVALID_PATH);
do_check_false(error.becauseSourceFailed);
do_check_true(error.becauseTargetFailed);
do_check_false(error.becauseBlocked);
do_check_false(error.becauseBlockedByParentalControls);
error = new DownloadError({ becauseBlocked: true });
do_check_eq(error.message, "Download blocked.");
do_check_false(error.becauseSourceFailed);
do_check_false(error.becauseTargetFailed);
do_check_true(error.becauseBlocked);
do_check_false(error.becauseBlockedByParentalControls);
error = new DownloadError({ becauseBlockedByParentalControls: true });
do_check_eq(error.message, "Download blocked.");
do_check_false(error.becauseSourceFailed);
do_check_false(error.becauseTargetFailed);
do_check_true(error.becauseBlocked);
do_check_true(error.becauseBlockedByParentalControls);
});
////////////////////////////////////////////////////////////////////////////////
//// Termination

View File

@ -202,7 +202,7 @@ Section "MaintenanceService"
; These keys are used to bypass the installation dir is a valid installation
; check from the service so that tests can be run.
WriteRegStr HKLM "${FallbackKey}\0" "name" "Mozilla Corporation"
WriteRegStr HKLM "${FallbackKey}\0" "issuer" "Thawte Code Signing CA - G2"
WriteRegStr HKLM "${FallbackKey}\0" "issuer" "DigiCert Assured ID Code Signing CA-1"
WriteRegStr HKLM "${FallbackKey}\1" "name" "Mozilla Fake SPC"
WriteRegStr HKLM "${FallbackKey}\1" "issuer" "Mozilla Fake CA"
${If} ${RunningX64}

View File

@ -934,7 +934,6 @@ var WalkerActor = protocol.ActorClass({
}
this._installHelperSheet(node);
this.layoutHelpers.scrollIntoViewIfNeeded(node.rawNode);
DOMUtils.addPseudoClassLock(node.rawNode, HIGHLIGHTED_PSEUDO_CLASS);
this._highlightTimeout = setTimeout(this._unhighlight.bind(this), HIGHLIGHTED_TIMEOUT);

View File

@ -56,7 +56,7 @@ toolbarspacer {
/* ::::: toolbarpaletteitem ::::: */
toolbarpaletteitem {
cursor: -moz-grab;
cursor: grab;
}
.toolbarpaletteitem-box[type="spacer"],

View File

@ -74,7 +74,7 @@ toolbarspacer {
/* ::::: toolbarpaletteitem ::::: */
toolbarpaletteitem {
cursor: -moz-grab;
cursor: grab;
}
.toolbarpaletteitem-box[type="spacer"],

View File

@ -41,7 +41,7 @@ toolbarseparator {
/* ::::: toolbarpaletteitem ::::: */
toolbarpaletteitem {
cursor: -moz-grab;
cursor: grab;
}
toolbar[iconsize="small"] toolbarpaletteitem[type="spacer"] {

View File

@ -65,7 +65,7 @@ toolbarspacer {
/* ::::: toolbarpaletteitem ::::: */
toolbarpaletteitem {
cursor: -moz-grab;
cursor: grab;
}
.toolbarpaletteitem-box[type="spacer"],