Merge m-c to inbound a=merge CLOSED TREE

--HG--
rename : xpcom/tests/TestUTF.cpp => xpcom/tests/gtest/TestUTF.cpp
rename : xpcom/tests/UTFStrings.h => xpcom/tests/gtest/UTFStrings.h
This commit is contained in:
Wes Kocher 2015-01-27 16:16:21 -08:00
Родитель 6797dfdced a092ea34c3
Коммит e523c1b047
82 изменённых файлов: 2103 добавлений и 2240 удалений

Просмотреть файл

@ -693,65 +693,50 @@ pref("dom.ipc.processPriorityManager.backgroundLRUPoolLevels", 5);
// Kernel parameters for process priorities. These affect how processes are
// killed on low-memory and their relative CPU priorities.
//
// Note: The maximum nice value on Linux is 19, but the max value you should
// use here is 18. NSPR adds 1 to some threads' nice values, to mark
// low-priority threads. If the process priority manager were to renice a
// process (and all its threads) to 19, all threads would have the same
// niceness. Then when we reniced the process to (say) 10, all threads would
// /still/ have the same niceness; we'd effectively have erased NSPR's thread
// priorities.
// The kernel can only accept 6 (OomScoreAdjust, KillUnderKB) pairs. But it is
// okay, kernel will still kill processes with larger OomScoreAdjust first even
// its OomScoreAdjust don't have a corresponding KillUnderKB.
pref("hal.processPriorityManager.gonk.MASTER.OomScoreAdjust", 0);
pref("hal.processPriorityManager.gonk.MASTER.KillUnderKB", 4096);
pref("hal.processPriorityManager.gonk.MASTER.cgroup", "");
pref("hal.processPriorityManager.gonk.MASTER.Nice", 0);
pref("hal.processPriorityManager.gonk.PREALLOC.OomScoreAdjust", 67);
pref("hal.processPriorityManager.gonk.PREALLOC.cgroup", "apps/bg_non_interactive");
pref("hal.processPriorityManager.gonk.PREALLOC.Nice", 18);
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.OomScoreAdjust", 67);
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.KillUnderKB", 5120);
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.cgroup", "apps/critical");
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.Nice", 0);
pref("hal.processPriorityManager.gonk.FOREGROUND.OomScoreAdjust", 134);
pref("hal.processPriorityManager.gonk.FOREGROUND.KillUnderKB", 6144);
pref("hal.processPriorityManager.gonk.FOREGROUND.cgroup", "apps");
pref("hal.processPriorityManager.gonk.FOREGROUND.Nice", 1);
pref("hal.processPriorityManager.gonk.FOREGROUND_KEYBOARD.OomScoreAdjust", 200);
pref("hal.processPriorityManager.gonk.FOREGROUND_KEYBOARD.cgroup", "apps");
pref("hal.processPriorityManager.gonk.FOREGROUND_KEYBOARD.Nice", 1);
pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.OomScoreAdjust", 400);
pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.KillUnderKB", 7168);
pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.cgroup", "apps/bg_perceivable");
pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.Nice", 7);
pref("hal.processPriorityManager.gonk.BACKGROUND_HOMESCREEN.OomScoreAdjust", 534);
pref("hal.processPriorityManager.gonk.BACKGROUND_HOMESCREEN.KillUnderKB", 8192);
pref("hal.processPriorityManager.gonk.BACKGROUND_HOMESCREEN.cgroup", "apps/bg_non_interactive");
pref("hal.processPriorityManager.gonk.BACKGROUND_HOMESCREEN.Nice", 18);
pref("hal.processPriorityManager.gonk.BACKGROUND.OomScoreAdjust", 667);
pref("hal.processPriorityManager.gonk.BACKGROUND.KillUnderKB", 20480);
pref("hal.processPriorityManager.gonk.BACKGROUND.cgroup", "apps/bg_non_interactive");
pref("hal.processPriorityManager.gonk.BACKGROUND.Nice", 18);
// Control group definitions (i.e., CPU priority groups) for B2G processes.
//
// memory_swappiness - 0 - The kernel will swap only to avoid an out of memory condition
// memory_swappiness - 60 - The default value.
// memory_swappiness - 100 - The kernel will swap aggressively.
// Foreground apps
pref("hal.processPriorityManager.gonk.cgroups.apps.cpu_shares", 1024);
pref("hal.processPriorityManager.gonk.cgroups.apps.cpu_notify_on_migrate", 1);
pref("hal.processPriorityManager.gonk.cgroups.apps.memory_swappiness", 10);
// Foreground apps with high priority, 16x more CPU than foreground ones
pref("hal.processPriorityManager.gonk.cgroups.apps/critical.cpu_shares", 16384);
pref("hal.processPriorityManager.gonk.cgroups.apps/critical.cpu_notify_on_migrate", 1);
pref("hal.processPriorityManager.gonk.cgroups.apps/critical.memory_swappiness", 0);
// Background perceivable apps, ~10x less CPU than foreground ones
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_perceivable.cpu_shares", 103);
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_perceivable.cpu_notify_on_migrate", 0);
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_perceivable.memory_swappiness", 60);
// Background apps, ~20x less CPU than foreground ones and ~2x less than perceivable ones
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_non_interactive.cpu_shares", 52);
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_non_interactive.cpu_notify_on_migrate", 0);
pref("hal.processPriorityManager.gonk.cgroups.apps/bg_non_interactive.memory_swappiness", 100);
// Processes get this niceness when they have low CPU priority.
pref("hal.processPriorityManager.gonk.LowCPUNice", 18);
// By default the compositor thread on gonk runs without real-time priority. RT
// priority can be enabled by setting this pref to a value between 1 and 99.

Просмотреть файл

@ -4,15 +4,23 @@
/* jshint moz: true */
/* global Uint8Array, Components, dump */
'use strict';
"use strict";
this.EXPORTED_SYMBOLS = ['LogCapture'];
const Cu = Components.utils;
const Ci = Components.interfaces;
const Cc = Components.classes;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm");
this.EXPORTED_SYMBOLS = ["LogCapture"];
const SYSTEM_PROPERTY_KEY_MAX = 32;
const SYSTEM_PROPERTY_VALUE_MAX = 92;
function debug(msg) {
dump('LogCapture.jsm: ' + msg + '\n');
dump("LogCapture.jsm: " + msg + "\n");
}
let LogCapture = {
@ -24,11 +32,11 @@ let LogCapture = {
load: function() {
// load in everything on first use
Components.utils.import('resource://gre/modules/ctypes.jsm', this);
Cu.import("resource://gre/modules/ctypes.jsm", this);
this.libc = this.ctypes.open(this.ctypes.libraryName('c'));
this.libc = this.ctypes.open(this.ctypes.libraryName("c"));
this.read = this.libc.declare('read',
this.read = this.libc.declare("read",
this.ctypes.default_abi,
this.ctypes.int, // bytes read (out)
this.ctypes.int, // file descriptor (in)
@ -36,19 +44,24 @@ let LogCapture = {
this.ctypes.size_t // size_t size of buffer (in)
);
this.open = this.libc.declare('open',
this.open = this.libc.declare("open",
this.ctypes.default_abi,
this.ctypes.int, // file descriptor (returned)
this.ctypes.char.ptr, // path
this.ctypes.int // flags
);
this.close = this.libc.declare('close',
this.close = this.libc.declare("close",
this.ctypes.default_abi,
this.ctypes.int, // error code (returned)
this.ctypes.int // file descriptor
);
this.getpid = this.libc.declare("getpid",
this.ctypes.default_abi,
this.ctypes.int // PID
);
this.property_find_nth =
this.libc.declare("__system_property_find_nth",
this.ctypes.default_abi,
@ -153,6 +166,26 @@ let LogCapture = {
}
return propertyDict;
},
/**
* Dumping about:memory to a file in /data/local/tmp/, returning a Promise.
* Will be resolved with the dumped file name.
*/
readAboutMemory: function() {
this.ensureLoaded();
let deferred = Promise.defer();
// Perform the dump
let dumper = Cc["@mozilla.org/memory-info-dumper;1"]
.getService(Ci.nsIMemoryInfoDumper);
let file = "/data/local/tmp/logshake-about_memory-" + this.getpid() + ".json.gz";
dumper.dumpMemoryReportsToNamedFile(file, function() {
deferred.resolve(file);
}, null, false);
return deferred.promise;
}
};

Просмотреть файл

@ -21,32 +21,32 @@
/* global Services, Components, dump, LogCapture, LogParser,
OS, Promise, volumeService, XPCOMUtils, SystemAppProxy */
'use strict';
"use strict";
const Cu = Components.utils;
const Ci = Components.interfaces;
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, 'LogCapture', 'resource://gre/modules/LogCapture.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'LogParser', 'resource://gre/modules/LogParser.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'OS', 'resource://gre/modules/osfile.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'Promise', 'resource://gre/modules/Promise.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'Services', 'resource://gre/modules/Services.jsm');
XPCOMUtils.defineLazyModuleGetter(this, 'SystemAppProxy', 'resource://gre/modules/SystemAppProxy.jsm');
XPCOMUtils.defineLazyModuleGetter(this, "LogCapture", "resource://gre/modules/LogCapture.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LogParser", "resource://gre/modules/LogParser.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", "resource://gre/modules/SystemAppProxy.jsm");
XPCOMUtils.defineLazyServiceGetter(this, 'powerManagerService',
'@mozilla.org/power/powermanagerservice;1',
'nsIPowerManagerService');
XPCOMUtils.defineLazyServiceGetter(this, "powerManagerService",
"@mozilla.org/power/powermanagerservice;1",
"nsIPowerManagerService");
XPCOMUtils.defineLazyServiceGetter(this, 'volumeService',
'@mozilla.org/telephony/volume-service;1',
'nsIVolumeService');
XPCOMUtils.defineLazyServiceGetter(this, "volumeService",
"@mozilla.org/telephony/volume-service;1",
"nsIVolumeService");
this.EXPORTED_SYMBOLS = ['LogShake'];
this.EXPORTED_SYMBOLS = ["LogShake"];
function debug(msg) {
dump('LogShake.jsm: '+msg+'\n');
dump("LogShake.jsm: "+msg+"\n");
}
/**
@ -54,11 +54,11 @@ function debug(msg) {
* shake
*/
const EXCITEMENT_THRESHOLD = 500;
const DEVICE_MOTION_EVENT = 'devicemotion';
const SCREEN_CHANGE_EVENT = 'screenchange';
const CAPTURE_LOGS_START_EVENT = 'capture-logs-start';
const CAPTURE_LOGS_ERROR_EVENT = 'capture-logs-error';
const CAPTURE_LOGS_SUCCESS_EVENT = 'capture-logs-success';
const DEVICE_MOTION_EVENT = "devicemotion";
const SCREEN_CHANGE_EVENT = "screenchange";
const CAPTURE_LOGS_START_EVENT = "capture-logs-start";
const CAPTURE_LOGS_ERROR_EVENT = "capture-logs-error";
const CAPTURE_LOGS_SUCCESS_EVENT = "capture-logs-success";
let LogShake = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
@ -79,17 +79,18 @@ let LogShake = {
* Map of files which have log-type information to their parsers
*/
LOGS_WITH_PARSERS: {
'/dev/log/main': LogParser.prettyPrintLogArray,
'/dev/log/system': LogParser.prettyPrintLogArray,
'/dev/log/radio': LogParser.prettyPrintLogArray,
'/dev/log/events': LogParser.prettyPrintLogArray,
'/proc/cmdline': LogParser.prettyPrintArray,
'/proc/kmsg': LogParser.prettyPrintArray,
'/proc/meminfo': LogParser.prettyPrintArray,
'/proc/uptime': LogParser.prettyPrintArray,
'/proc/version': LogParser.prettyPrintArray,
'/proc/vmallocinfo': LogParser.prettyPrintArray,
'/proc/vmstat': LogParser.prettyPrintArray
"/dev/log/main": LogParser.prettyPrintLogArray,
"/dev/log/system": LogParser.prettyPrintLogArray,
"/dev/log/radio": LogParser.prettyPrintLogArray,
"/dev/log/events": LogParser.prettyPrintLogArray,
"/proc/cmdline": LogParser.prettyPrintArray,
"/proc/kmsg": LogParser.prettyPrintArray,
"/proc/meminfo": LogParser.prettyPrintArray,
"/proc/uptime": LogParser.prettyPrintArray,
"/proc/version": LogParser.prettyPrintArray,
"/proc/vmallocinfo": LogParser.prettyPrintArray,
"/proc/vmstat": LogParser.prettyPrintArray,
"/system/b2g/application.ini": LogParser.prettyPrintArray
},
/**
@ -109,7 +110,7 @@ let LogShake = {
SystemAppProxy.addEventListener(SCREEN_CHANGE_EVENT, this, false);
Services.obs.addObserver(this, 'xpcom-shutdown', false);
Services.obs.addObserver(this, "xpcom-shutdown", false);
},
/**
@ -134,7 +135,7 @@ let LogShake = {
* Handle an observation from Services.obs
*/
observe: function(subject, topic) {
if (topic === 'xpcom-shutdown') {
if (topic === "xpcom-shutdown") {
this.uninit();
}
},
@ -152,8 +153,8 @@ let LogShake = {
},
/**
* Handle a motion event, keeping track of 'excitement', the magnitude
* of the device's acceleration.
* Handle a motion event, keeping track of "excitement", the magnitude
* of the device"s acceleration.
*/
handleDeviceMotionEvent: function(event) {
// There is a lag between disabling the event listener and event arrival
@ -217,11 +218,33 @@ let LogShake = {
Cu.reportError("Unable to get device properties: " + ex);
}
// Let Gecko perfom the dump to a file, and just collect it
try {
LogCapture.readAboutMemory().then(aboutMemory => {
let file = OS.Path.basename(aboutMemory);
let logArray;
try {
logArray = LogCapture.readLogFile(aboutMemory);
if (!logArray) {
debug("LogCapture.readLogFile() returned nothing about:memory ");
}
// We need to remove the dumped file, now that we have it in memory
OS.File.remove(aboutMemory);
} catch (ex) {
Cu.reportError("Unable to handle about:memory dump: " + ex);
}
logArrays[file] = LogParser.prettyPrintArray(logArray);
});
} catch (ex) {
Cu.reportError("Unable to get about:memory dump: " + ex);
}
for (let loc in this.LOGS_WITH_PARSERS) {
let logArray;
try {
logArray = LogCapture.readLogFile(loc);
if (!logArray) {
debug("LogCapture.readLogFile() returned nothing for: " + loc);
continue;
}
} catch (ex) {
@ -245,32 +268,40 @@ let LogShake = {
uninit: function() {
this.stopDeviceMotionListener();
SystemAppProxy.removeEventListener(SCREEN_CHANGE_EVENT, this, false);
Services.obs.removeObserver(this, 'xpcom-shutdown');
Services.obs.removeObserver(this, "xpcom-shutdown");
}
};
function getLogFilename(logLocation) {
// sanitize the log location
let logName = logLocation.replace(/\//g, '-');
if (logName[0] === '-') {
let logName = logLocation.replace(/\//g, "-");
if (logName[0] === "-") {
logName = logName.substring(1);
}
return logName + '.log';
// If no extension is provided, default to forcing .log
let extension = ".log";
let logLocationExt = logLocation.split(".");
if (logLocationExt.length > 1) {
// otherwise, just append nothing
extension = "";
}
return logName + extension;
}
function getSdcardPrefix() {
return volumeService.getVolumeByName('sdcard').mountPoint;
return volumeService.getVolumeByName("sdcard").mountPoint;
}
function getLogDirectoryRoot() {
return 'logs';
return "logs";
}
function getLogDirectory() {
let d = new Date();
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000);
let timestamp = d.toISOString().slice(0, -5).replace(/[:T]/g, '-');
// return directory name of format 'logs/timestamp/'
let timestamp = d.toISOString().slice(0, -5).replace(/[:T]/g, "-");
return timestamp;
}
@ -281,7 +312,7 @@ function saveLogs(logArrays) {
if (!logArrays || Object.keys(logArrays).length === 0) {
return Promise.resolve({
logFilenames: [],
logPrefix: ''
logPrefix: ""
});
}
@ -296,19 +327,24 @@ function saveLogs(logArrays) {
return Promise.reject(e);
}
debug('making a directory all the way from '+sdcardPrefix+' to '+(sdcardPrefix + '/' + dirNameRoot + '/' + dirName));
debug("making a directory all the way from " + sdcardPrefix + " to " + (sdcardPrefix + "/" + dirNameRoot + "/" + dirName) );
let logsRoot = OS.Path.join(sdcardPrefix, dirNameRoot);
return OS.File.makeDir(logsRoot, {from: sdcardPrefix}).then(
function() {
debug("First OS.File.makeDir done");
let logsDir = OS.Path.join(logsRoot, dirName);
debug("Creating " + logsDir);
return OS.File.makeDir(logsDir, {ignoreExisting: false}).then(
function() {
debug("Created: " + logsDir);
// Now the directory is guaranteed to exist, save the logs
let logFilenames = [];
let saveRequests = [];
debug("Will now traverse logArrays: " + logArrays.length);
for (let logLocation in logArrays) {
debug('requesting save of ' + logLocation);
debug("requesting save of " + logLocation);
let logArray = logArrays[logLocation];
// The filename represents the relative path within the SD card, not the
// absolute path because Gaia will refer to it using the DeviceStorage
@ -321,13 +357,22 @@ function saveLogs(logArrays) {
return Promise.all(saveRequests).then(
function() {
debug('returning logfilenames: '+logFilenames.toSource());
debug("returning logfilenames: "+logFilenames.toSource());
return {
logFilenames: logFilenames,
logPrefix: OS.Path.join(dirNameRoot, dirName)
};
}, function(err) {
debug("Error at some save request: " + err);
return Promise.reject(err);
});
}, function(err) {
debug("Error at OS.File.makeDir for " + logsDir + ": " + err);
return Promise.reject(err);
});
}, function(err) {
debug("Error at first OS.File.makeDir: " + err);
return Promise.reject(err);
});
}

Просмотреть файл

@ -1,30 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test that LogCapture successfully reads from the /dev/log devices, returning
* a Uint8Array of some length, including zero. This tests a few standard
* log devices
* Testing non Gonk-specific code path
*/
function run_test() {
Components.utils.import("resource:///modules/LogCapture.jsm");
function verifyLog(log) {
// log exists
notEqual(log, null);
// log has a length and it is non-negative (is probably array-like)
ok(log.length >= 0);
}
let propertiesLog = LogCapture.readProperties();
notEqual(propertiesLog, null, "Properties should not be null");
notEqual(propertiesLog, undefined, "Properties should not be undefined");
equal(propertiesLog["ro.kernel.qemu"], "1", "QEMU property should be 1");
let mainLog = LogCapture.readLogFile("/dev/log/main");
verifyLog(mainLog);
let meminfoLog = LogCapture.readLogFile("/proc/meminfo");
verifyLog(meminfoLog);
run_next_test();
}
// Trivial test just to make sure we have no syntax error
add_test(function test_logCapture_loads() {
ok(LogCapture, "LogCapture object exists");
run_next_test();
});

Просмотреть файл

@ -0,0 +1,61 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test that LogCapture successfully reads from the /dev/log devices, returning
* a Uint8Array of some length, including zero. This tests a few standard
* log devices
*/
function run_test() {
Components.utils.import("resource:///modules/LogCapture.jsm");
run_next_test();
}
function verifyLog(log) {
// log exists
notEqual(log, null);
// log has a length and it is non-negative (is probably array-like)
ok(log.length >= 0);
}
add_test(function test_readLogFile() {
let mainLog = LogCapture.readLogFile("/dev/log/main");
verifyLog(mainLog);
let meminfoLog = LogCapture.readLogFile("/proc/meminfo");
verifyLog(meminfoLog);
run_next_test();
});
add_test(function test_readProperties() {
let propertiesLog = LogCapture.readProperties();
notEqual(propertiesLog, null, "Properties should not be null");
notEqual(propertiesLog, undefined, "Properties should not be undefined");
equal(propertiesLog["ro.kernel.qemu"], "1", "QEMU property should be 1");
run_next_test();
});
add_test(function test_readAppIni() {
let appIni = LogCapture.readLogFile("/system/b2g/application.ini");
verifyLog(appIni);
run_next_test();
});
add_test(function test_get_about_memory() {
let memLog = LogCapture.readAboutMemory();
ok(memLog, "Should have returned a valid Promise object");
memLog.then(file => {
ok(file, "Should have returned a filename");
run_next_test();
}, error => {
ok(false, "Dumping about:memory promise rejected: " + error);
run_next_test();
});
});

Просмотреть файл

@ -0,0 +1,121 @@
/**
* Test the log capturing capabilities of LogShake.jsm, checking
* for Gonk-specific parts
*/
/* jshint moz: true */
/* global Components, LogCapture, LogShake, ok, add_test, run_next_test, dump */
/* exported run_test */
/* disable use strict warning */
/* jshint -W097 */
"use strict";
const Cu = Components.utils;
const Ci = Components.interfaces;
const Cc = Components.classes;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "volumeService",
"@mozilla.org/telephony/volume-service;1",
"nsIVolumeService");
let sdcard;
function run_test() {
Cu.import("resource://gre/modules/LogShake.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/osfile.jsm");
do_get_profile();
debug("Starting");
run_next_test();
}
function debug(msg) {
var timestamp = Date.now();
dump("LogShake: " + timestamp + ": " + msg + "\n");
}
add_test(function setup_fs() {
OS.File.makeDir("/data/local/tmp/sdcard/", {from: "/data"}).then(function() {
run_next_test();
});
});
add_test(function setup_sdcard() {
let volName = "sdcard";
let mountPoint = "/data/local/tmp/sdcard";
volumeService.createFakeVolume(volName, mountPoint);
let vol = volumeService.getVolumeByName(volName);
ok(vol, "volume shouldn't be null");
equal(volName, vol.name, "name");
volumeService.SetFakeVolumeState(volName, Ci.nsIVolume.STATE_MOUNTED);
equal(Ci.nsIVolume.STATE_MOUNTED, vol.state, "state");
run_next_test();
});
add_test(function test_ensure_sdcard() {
sdcard = volumeService.getVolumeByName("sdcard").mountPoint;
ok(sdcard, "Should have a valid sdcard mountpoint");
run_next_test();
});
add_test(function test_logShake_captureLogs_returns() {
// Enable LogShake
LogShake.init();
LogShake.captureLogs().then(logResults => {
LogShake.uninit();
ok(logResults.logFilenames.length > 0, "Should have filenames");
ok(logResults.logPrefix.length > 0, "Should have prefix");
run_next_test();
},
error => {
LogShake.uninit();
ok(false, "Should not have received error: " + error);
run_next_test();
});
});
add_test(function test_logShake_captureLogs_writes() {
// Enable LogShake
LogShake.init();
let expectedFiles = [];
LogShake.captureLogs().then(logResults => {
LogShake.uninit();
logResults.logFilenames.forEach(f => {
let p = OS.Path.join(sdcard, f);
ok(p, "Should have a valid result path: " + p);
let t = OS.File.exists(p).then(rv => {
ok(rv, "File exists: " + p);
});
expectedFiles.push(t);
});
Promise.all(expectedFiles).then(() => {
ok(true, "Completed all files checks");
run_next_test();
});
},
error => {
LogShake.uninit();
ok(false, "Should not have received error: " + error);
run_next_test();
});
});

Просмотреть файл

@ -14,10 +14,17 @@ support-files =
head = head_identity.js
tail =
# testing non gonk-specific stuff
[test_logcapture.js]
[test_logcapture_gonk.js]
# only run on b2g builds due to requiring b2g-specific log files to exist
skip-if = toolkit != "gonk"
[test_logparser.js]
[test_logshake.js]
[test_logshake_gonk.js]
# only run on b2g builds due to requiring b2g-specific log files to exist
skip-if = ((toolkit != "gonk") || ((toolkit == "gonk") && (debug == true))) # bug 1125989: disabled because of race condition in OS.File.makeDir

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -115,7 +115,7 @@
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="f7d9bf71cf6693474f3f2a81a4ba62c0fc5646aa"/>
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="cfcef469537869947abb9aa1d656774cc2678d4c"/>
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="dcb7c6ba2c6aec23a76d95094c4cbc17eeca5d44"/>
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="a3a900615b89cbd67acfb8b750baa43b321ef68b"/>
<project name="platform/system/extras" path="system/extras" revision="10e78a05252b3de785f88c2d0b9ea8a428009c50"/>
<project name="platform/system/media" path="system/media" revision="7ff72c2ea2496fa50b5e8a915e56e901c3ccd240"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d6a27295acb0a25926bf6290dd2532a7f9027864"/>
@ -117,7 +117,7 @@
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="842e33e43a55ea44833b9e23e4d180fa17c843af"/>
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5db24726f0f42124304195a6bdea129039eeeaeb"/>
<project name="platform/system/bluetooth" path="system/bluetooth" revision="930ae098543881f47eac054677726ee4b998b2f8"/>
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="dcb7c6ba2c6aec23a76d95094c4cbc17eeca5d44"/>
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="a3a900615b89cbd67acfb8b750baa43b321ef68b"/>
<project name="platform_system_core" path="system/core" remote="b2g" revision="542d1f59dc331b472307e5bd043101d14d5a3a3e"/>
<project name="platform/system/extras" path="system/extras" revision="18c1180e848e7ab8691940481f5c1c8d22c37b3e"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
@ -135,7 +135,7 @@
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c5f8d282efe4a4e8b1e31a37300944e338e60e4f"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9f28c4faea3b2f01db227b2467b08aeba96d9bec"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="13374490fc0c989347448f0b2d6b220adff5e630"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d19dad5844e8803d5e88d1577a2742b4f5cbc467"/>
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
</manifest>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -115,7 +115,7 @@
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="f7d9bf71cf6693474f3f2a81a4ba62c0fc5646aa"/>
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/>
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="387f03e815f57d536dd922706db1622bddba8d81"/>
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="dcb7c6ba2c6aec23a76d95094c4cbc17eeca5d44"/>
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="a3a900615b89cbd67acfb8b750baa43b321ef68b"/>
<project name="platform/system/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/>
<project name="platform/system/media" path="system/media" revision="be0e2fe59a8043fa5200f75697df9220a99abe9d"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -110,7 +110,7 @@
<project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="f7d9bf71cf6693474f3f2a81a4ba62c0fc5646aa"/>
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/>
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="dcb7c6ba2c6aec23a76d95094c4cbc17eeca5d44"/>
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="a3a900615b89cbd67acfb8b750baa43b321ef68b"/>
<project name="platform/system/extras" path="system/extras" revision="576f57b6510de59c08568b53c0fb60588be8689e"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
<project name="platform/system/netd" path="system/netd" revision="a6531f7befb49b1c81bc0de7e51c5482b308e1c5"/>
@ -145,8 +145,8 @@
<project name="platform/hardware/qcom/wlan" path="hardware/qcom/wlan" revision="57ee1320ed7b4a1a1274d8f3f6c177cd6b9becb2"/>
<project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/>
<project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/>
<project name="platform/system/core" path="system/core" revision="350eac5403124dacb2a5fd9e28ac290a59fc3b8e"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="13374490fc0c989347448f0b2d6b220adff5e630"/>
<project name="platform/system/core" path="system/core" revision="42839aedcf70bf6bc92a3b7ea4a5cc9bf9aef3f9"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d19dad5844e8803d5e88d1577a2742b4f5cbc467"/>
<project name="platform/system/qcom" path="system/qcom" revision="63e3f6f176caad587d42bba4c16b66d953fb23c2"/>
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="d8952a42771045fca73ec600e2b42a4c7129d723"/>
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4c187c1f3a0dffd8e51a961735474ea703535b99"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d6a27295acb0a25926bf6290dd2532a7f9027864"/>
@ -145,7 +145,7 @@
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
<project name="platform/system/core" path="system/core" revision="adc485d8755af6a61641d197de7cfef667722580"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="13374490fc0c989347448f0b2d6b220adff5e630"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d19dad5844e8803d5e88d1577a2742b4f5cbc467"/>
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/>

Просмотреть файл

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "1eedbee8f26efbaa4a113e002c46f64e9b90249d",
"git_revision": "1d53fb07984298253aad64bfa4236b7167ee3d4d",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "080bbea403be57fffcbb800eb6f7e2fcd0b4c7d2",
"revision": "08a288892d8f0b41a960104150fba34f113629e6",
"repo_path": "integration/gaia-central"
}

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>

Просмотреть файл

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d6a27295acb0a25926bf6290dd2532a7f9027864"/>
@ -117,7 +117,7 @@
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="842e33e43a55ea44833b9e23e4d180fa17c843af"/>
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5db24726f0f42124304195a6bdea129039eeeaeb"/>
<project name="platform/system/bluetooth" path="system/bluetooth" revision="930ae098543881f47eac054677726ee4b998b2f8"/>
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="dcb7c6ba2c6aec23a76d95094c4cbc17eeca5d44"/>
<project name="platform_system_bluetoothd" path="system/bluetoothd" remote="b2g" revision="a3a900615b89cbd67acfb8b750baa43b321ef68b"/>
<project name="platform_system_core" path="system/core" remote="b2g" revision="542d1f59dc331b472307e5bd043101d14d5a3a3e"/>
<project name="platform/system/extras" path="system/extras" revision="18c1180e848e7ab8691940481f5c1c8d22c37b3e"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
@ -130,7 +130,7 @@
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="13374490fc0c989347448f0b2d6b220adff5e630"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d19dad5844e8803d5e88d1577a2742b4f5cbc467"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>

Просмотреть файл

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1eedbee8f26efbaa4a113e002c46f64e9b90249d"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1d53fb07984298253aad64bfa4236b7167ee3d4d"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

Просмотреть файл

@ -26,8 +26,6 @@ let gDataNotificationInfoBar = {
init: function() {
window.addEventListener("unload", function onUnload() {
window.removeEventListener("unload", onUnload, false);
for (let o of this._OBSERVERS) {
Services.obs.removeObserver(this, o);
}

Просмотреть файл

@ -1012,8 +1012,8 @@ chatbox:-moz-full-screen-ancestor > .chat-titlebar {
}
/* Combobox dropdown renderer */
#ContentSelectDropdown {
-moz-binding: url("chrome://global/content/bindings/popup.xml#popup-scrollbars");
#ContentSelectDropdown > menupopup {
max-height: 350px;
}
.contentSelectDropdown-optgroup {

Просмотреть файл

@ -146,8 +146,13 @@
<!-- for url bar autocomplete -->
<panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
<!-- for select dropdowns -->
<menupopup id="ContentSelectDropdown" rolluponmousewheel="true" hidden="true"/>
<!-- for select dropdowns. The menupopup is what shows the list of options,
and the popuponly menulist makes things like the menuactive attributes
work correctly on the menupopup. ContentSelectDropdown expects the
popuponly menulist to be its immediate parent. -->
<menulist popuponly="true" id="ContentSelectDropdown" hidden="true">
<menupopup rolluponmousewheel="true"/>
</menulist>
<!-- for invalid form error message -->
<panel id="invalid-form-popup" type="arrow" orient="vertical" noautofocus="true" hidden="true" level="parent">
@ -1169,7 +1174,7 @@
tabcontainer="tabbrowser-tabs"
contentcontextmenu="contentAreaContextMenu"
autocompletepopup="PopupAutoComplete"
selectpopup="ContentSelectDropdown"/>
selectmenulist="ContentSelectDropdown"/>
<chatbar id="pinnedchats" layer="true" mousethrough="always" hidden="true"/>
</vbox>
<splitter id="social-sidebar-splitter"

Просмотреть файл

@ -30,7 +30,7 @@
<xul:vbox flex="1" class="browserContainer">
<xul:stack flex="1" class="browserStack" anonid="browserStack">
<xul:browser anonid="initialBrowser" type="content-primary" message="true" messagemanagergroup="browsers"
xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup,selectpopup"/>
xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup,selectmenulist"/>
</xul:stack>
</xul:vbox>
</xul:hbox>
@ -1600,8 +1600,8 @@
if (!isPreloadBrowser && this.hasAttribute("autocompletepopup"))
b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
if (this.hasAttribute("selectpopup"))
b.setAttribute("selectpopup", this.getAttribute("selectpopup"));
if (this.hasAttribute("selectmenulist"))
b.setAttribute("selectmenulist", this.getAttribute("selectmenulist"));
b.setAttribute("autoscrollpopup", this._autoScrollPopup.id);

Просмотреть файл

@ -203,7 +203,6 @@ loop.shared.mixins = (function() {
publishVideo: options.publishVideo,
style: {
audioLevelDisplayMode: "off",
bugDisplayMode: "off",
buttonDisplayMode: "off",
nameDisplayMode: "off",
videoDisabledDisplayMode: "off"

Просмотреть файл

@ -118,216 +118,88 @@
/* Modal dialog styles */
.OT_dialog-centering {
display: table;
width: 100%;
height: 100%;
}
.OT_dialog-centering-child {
display: table-cell;
vertical-align: middle;
}
.OT_dialog {
border: none;
border-radius: 0;
top: 50%;
left: 50%;
position: absolute;
position: fixed;
padding: 0;
position: relative;
box-sizing: border-box;
max-width: 576px;
margin-right: auto;
margin-left: auto;
padding: 36px;
text-align: center; /* centers all the inline content */
background-color: #363636;
color: #fff;
z-index: 9999;
box-shadow: 2px 4px 6px #999;
font-family: 'Didact Gothic', sans-serif;
}
.OT_dialog-blackout {
position: absolute;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: #363636;
}
.OT_dialog-blackout .OT_dialog {
box-shadow: 0 0 0 transparent;
font-size: 13px;
line-height: 1.4;
}
.OT_dialog * {
font-family: 'Didact Gothic', sans-serif;
}
.OT_dialog-plugin-prompt {
margin-left: -350px;
margin-top: -127px;
width: 650px;
height: 254px;
}
.OT_dialog-plugin-reinstall {
margin-left: -271px;
margin-top: -107px;
width: 542px;
height: 214px;
}
.OT_dialog-plugin-upgrading {
margin-left: -267px;
margin-top: -94px;
width: 514px;
height: 188px;
}
.OT_dialog-plugin-upgraded {
margin-left: -300px;
margin-top: -100px;
width: 600px;
height: 200px;
}
.OT_dialog-allow-deny-chrome-first {
margin-left: -227px;
margin-top: -122px;
width: 453px;
height: 244px;
}
.OT_dialog-allow-deny-chrome-pre-denied {
margin-left: -263px;
margin-top: -135px;
width: 526px;
height: 270px;
}
.OT_dialog-allow-deny-chrome-now-denied {
margin-left: -120px;
margin-top: -85px;
width: 256px;
height: 170px;
}
.OT_dialog-allow-deny-firefox-denied {
margin-left: -160px;
margin-top: -105px;
width: 320px;
height: 190px;
}
.OT_dialog-allow-deny-firefox-maybe-denied {
margin-left: -281px;
margin-top: -126px;
width: 562px;
height: 252px;
}
.OT_dialog-allow-highlight-chrome {
display: inline-block;
margin-top: 20px;
width: 227px;
height: 94px;
background-image: url(../images/rtc/access-prompt-chrome.png);
font-family: inherit;
box-sizing: inherit;
}
.OT_closeButton {
color: #999999;
cursor: pointer;
font-size: 32px;
line-height: 30px;
line-height: 36px;
position: absolute;
right: 15px;
right: 18px;
top: 0;
}
.OT_dialog-messages {
position: absolute;
top: 32px;
left: 32px;
right: 32px;
text-align: center;
}
.OT_dialog-allow-deny-firefox-maybe-denied .OT_dialog-messages {
top: 45px;
}
.OT_dialog-messages-main {
margin-bottom: 36px;
line-height: 36px;
font-weight: 300;
font-size: 18pt;
line-height: 24px;
font-size: 24px;
}
.OT_dialog-messages-minor {
font-weight: 300;
margin-top: 12px;
margin-bottom: 18px;
font-size: 13px;
line-height: 18px;
color: #A4A4A4;
}
.OT_dialog-allow-deny-firefox-maybe-denied .OT_dialog-messages-minor {
margin-top: 4px;
}
.OT_dialog-messages-minor strong {
font-weight: 300;
color: #ffffff;
}
.OT_dialog-hidden {
display: none;
}
.OT_dialog-single-button {
position: absolute;
bottom: 41px;
left: 50%;
margin-left: -97px;
height: 47px;
width: 193px;
}
.OT_dialog-single-button-wide {
bottom: 35px;
height: 140px;
left: 5px;
position: absolute;
right: 0;
}
.OT_dialog-single-button-with-title {
margin: 0 auto;
padding-left: 30px;
padding-right: 30px;
width: 270px;
}
.OT_dialog-button-pair {
position: absolute;
bottom: 45px;
left: 5px;
right: 0;
height: 94px;
}
.OT_dialog-button-with-title {
padding-left: 30px;
padding-right: 30px;
width: 260px;
float: left;
}
.OT_dialog-button-pair-seperator {
border-right: 1px solid #555555;
height: 112px;
width: 1px;
float: left;
.OT_dialog-actions-card {
display: inline-block;
}
.OT_dialog-button-title {
margin-bottom: 18px;
line-height: 18px;
font-weight: 300;
text-align: center;
margin-bottom: 15px;
font-size: 14px;
line-height: 150%;
color: #999999;
}
.OT_dialog-button-title label {
color: #999999;
}
@ -345,13 +217,13 @@
}
.OT_dialog-button {
font-weight: 100;
display: block;
line-height: 50px;
height: 47px;
display: inline-block;
margin-bottom: 18px;
padding: 0 1em;
background-color: #1CA3DC;
text-align: center;
font-size: 16pt;
cursor: pointer;
}
@ -364,138 +236,67 @@
opacity: 0.5;
}
.OT_dialog-button.OT_dialog-button-large {
line-height: 60px;
height: 58px;
.OT_dialog-button-large {
line-height: 36px;
padding-top: 9px;
padding-bottom: 9px;
font-weight: 100;
font-size: 24px;
}
.OT_dialog-button.OT_dialog-button-small {
.OT_dialog-button-small {
line-height: 18px;
padding-top: 9px;
padding-bottom: 9px;
background-color: #444444;
color: #999999;
font-size: 12pt;
height: 40px;
line-height: 40px;
margin: 20px auto 0 auto;
width: 86px;
font-size: 16px;
}
.OT_dialog-progress-bar {
display: inline-block; /* prevents margin collapse */
width: 100%;
margin-top: 5px;
margin-bottom: 41px;
border: 1px solid #4E4E4E;
height: 8px;
}
.OT_dialog-progress-bar-fill {
height: 100%;
background-color: #29A4DA;
height: 10px;
margin-top: -1px;
margin-left: -1px;
margin-right: -1px;
}
.OT_dialog-plugin-upgrading .OT_dialog-plugin-upgrade-percentage {
font-size: 36pt;
line-height: 54px;
font-size: 48px;
font-weight: 100;
}
.OT_dialog-plugin-upgrading .OT_dialog-progress-bar {
margin-top: 25px;
margin-bottom: 25px;
}
.OT_dialog-3steps {
margin-top: 24px;
}
.OT_dialog-allow-deny-firefox-maybe-denied .OT_dialog-3steps {
margin-top: 21px;
}
.OT_dialog-3steps-step {
float: left;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 33%;
height: 140px;
padding: 0 10px;
color: #A4A4A4;
}
.OT_dialog-3steps-seperator {
float: left;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin-top: 10px;
width: 1px;
height: 68px;
background-color: #555555;
}
.OT_dialog-allow-deny-chrome-pre-denied .OT_dialog-3steps-seperator {
margin-top: 16px;
}
.OT_dialog-3steps-step-num {
font-size: 20px;
background-color: #2AA3D8;
border-radius: 20px;
line-height: 33px;
height: 33px;
width: 33px;
margin: 0 auto 17px;
}
.OT_dialog-allow-deny-chrome-pre-denied .OT_dialog-3steps-step-num {
margin-bottom: 10px;
}
.OT_dialog-allow-camera-icon {
background-color: #000;
width: 113px;
height: 48px;
margin: 10px auto 0;
background-image: url(../images/rtc/access-predenied-chrome.png);
}
/* Publisher Deny Helpers */
.OT_publisher-denied-firefox {
background-color: #fff;
}
.OT_publisher-denied-firefox p {
width: 232px;
height: 103px;
top: 50%;
left: 50%;
display: block;
position: absolute;
margin-top: -52px;
margin-left: -116px;
background-image: url(../images/rtc/access-denied-firefox.png);
background-position: 50% 0;
background-repeat: no-repeat;
}
.OT_publisher-denied-firefox span {
display: block;
position: absolute;
bottom: 0;
right: 0;
left: 0;
margin: 0 auto;
width: 232px;
height: 31px;
background-image: url(../images/rtc/access-denied-copy-firefox.png);
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
}
/* Helpers */
.OT_centered {
position: fixed;
left: 50%;
top: 50%;
margin: 0;
position: fixed;
left: 50%;
top: 50%;
margin: 0;
}
.OT_dialog-hidden {
display: none;
}
.OT_dialog-button-block {
display: block;
}
.OT_dialog-no-natural-margin {
margin-bottom: 0;
}
/* Publisher and Subscriber styles */
@ -803,21 +604,14 @@
.OT_publisher .OT_name,
.OT_subscriber .OT_name {
left: 24px;
left: 10px;
right: 37px;
height: 34px;
}
.OT_publisher .OT_name-no-bug,
.OT_subscriber .OT_name-no-bug {
left: 10px;
padding-left: 0;
}
.OT_publisher .OT_mute,
.OT_subscriber .OT_mute,
.OT_publisher .OT_opentok,
.OT_subscriber .OT_opentok {
.OT_subscriber .OT_mute {
border: none;
cursor: pointer;
display: block;
@ -828,21 +622,6 @@
background-repeat: no-repeat;
}
.OT_publisher .OT_opentok,
.OT_subscriber .OT_opentok {
background: url(../images/rtc/buttons.png) 0 -32px no-repeat;
cursor: default;
height: 18px;
left: 8px;
line-height: 18px;
top: 8px;
width: 16px;
}
.OT_micro .OT_opentok {
display: none !important;
}
.OT_publisher .OT_mute,
.OT_subscriber .OT_mute {
right: 0;
@ -883,21 +662,6 @@
background-position: 7px 7px;
}
/* Disabling this for now - see https://jira.tokbox.com/browse/OPENTOK-8870
.OT_publisher .OT_opentok:hover:after,
.OT_subscriber .OT_opentok:hover:after {
content: 'tokbox';
color: #fff;
font-weight: bold;
font-size: 14px;
letter-spacing: -1px;
top: 20px;
opacity: 0.5;
position: absolute;
text-indent: 0;
top: 0;
}*/
/**
* Styles for display modes
*
@ -975,23 +739,6 @@
opacity: 1;
}
.OT_publisher .OT_opentok.OT_mode-off,
.OT_publisher .OT_opentok.OT_mode-auto,
.OT_subscriber .OT_opentok.OT_mode-off,
.OT_subscriber .OT_opentok.OT_mode-auto {
top: -17px;
}
.OT_publisher .OT_opentok.OT_mode-on,
.OT_publisher .OT_opentok.OT_mode-auto.OT_mode-on-hold,
.OT_publisher:hover .OT_opentok.OT_mode-auto,
.OT_subscriber .OT_opentok.OT_mode-on,
.OT_subscriber .OT_opentok.OT_mode-auto.OT_mode-on-hold,
.OT_subscriber:hover .OT_opentok.OT_mode-auto {
top: 8px;
}
/* Contains the video element, used to fix video letter-boxing */
.OT_video-container {
position: absolute;
@ -1095,7 +842,7 @@
background-image: radial-gradient(circle, rgba(151,206,0,1) 0%, rgba(151,206,0,0) 100%);
}
.OT_audio-level-meter {
.OT_audio-level-meter.OT_mode-off {
display: none;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,4 +1,5 @@
. "$topsrcdir/browser/config/mozconfigs/common"
. "$topsrcdir/browser/config/mozconfigs/win64/common-win64"
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-update-packaging

Просмотреть файл

@ -701,7 +701,7 @@ let CallsListView = Heritage.extend(WidgetMethods, {
let dimensionsNode = $("#screenshot-dimensions");
let actualWidth = (width / scaling) | 0;
let actualHeight = (height / scaling) | 0;
dimensionsNode.setAttribute("value", actualWidth + " x " + actualHeight);
dimensionsNode.setAttribute("value", actualWidth + " \u00D7 " + actualHeight);
window.emit(EVENTS.CALL_SCREENSHOT_DISPLAYED);
},

Просмотреть файл

@ -20,7 +20,7 @@ function ifTestingSupported() {
is($("#screenshot-container").hidden, false,
"The screenshot container should now be visible.");
is($("#screenshot-dimensions").getAttribute("value"), "128 x 128",
is($("#screenshot-dimensions").getAttribute("value"), "128" + " \u00D7 " + "128",
"The screenshot dimensions label has the expected value.");
is($("#screenshot-image").getAttribute("flipped"), "false",

Просмотреть файл

@ -20,7 +20,7 @@ add_task(function*() {
tag: "DIV",
id: "top",
classes: ".class1.class2",
dims: "500 x 100"
dims: "500" + " \u00D7 " + "100"
},
{
selector: "#vertical",
@ -36,7 +36,7 @@ add_task(function*() {
tag: "DIV",
id: "bottom",
classes: "",
dims: "500 x 100"
dims: "500" + " \u00D7 " + "100"
},
{
selector: "body",

Просмотреть файл

@ -9,8 +9,8 @@
// Expected values:
let res1 = [
{selector: "#element-size", value: "160x160"},
{selector: ".size > span", value: "100x100"},
{selector: "#element-size", value: "160" + "\u00D7" + "160"},
{selector: ".size > span", value: "100" + "\u00D7" + "100"},
{selector: ".margin.top > span", value: 30},
{selector: ".margin.left > span", value: "auto"},
{selector: ".margin.bottom > span", value: 30},
@ -26,8 +26,8 @@ let res1 = [
];
let res2 = [
{selector: "#element-size", value: "190x210"},
{selector: ".size > span", value: "100x150"},
{selector: "#element-size", value: "190" + "\u00D7" + "210"},
{selector: ".size > span", value: "100" + "\u00D7" + "150"},
{selector: ".margin.top > span", value: 30},
{selector: ".margin.left > span", value: "auto"},
{selector: ".margin.bottom > span", value: 30},

Просмотреть файл

@ -45,7 +45,7 @@ function*(inspector, view) {
info("Checking that the layout-view shows the right value");
let sizeElt = view.doc.querySelector(".size > span");
is(sizeElt.textContent, "100x100");
is(sizeElt.textContent, "100" + "\u00D7" + "100");
info("Listening for layout-view changes and modifying the size");
let onUpdated = waitForUpdate(inspector);
@ -54,7 +54,7 @@ function*(inspector, view) {
ok(true, "Layout-view got updated");
info("Checking that the layout-view shows the right value after update");
is(sizeElt.textContent, "200x100");
is(sizeElt.textContent, "200" + "\u00D7" + "100");
});
addTest("Go back to the first page",

Просмотреть файл

@ -401,7 +401,7 @@ LayoutView.prototype = {
this._lastRequest = null;
let width = layout.width;
let height = layout.height;
let newLabel = width + "x" + height;
let newLabel = width + "\u00D7" + height;
if (this.sizeHeadingLabel.textContent != newLabel) {
this.sizeHeadingLabel.textContent = newLabel;
}
@ -452,7 +452,7 @@ LayoutView.prototype = {
height -= this.map.borderTop.value + this.map.borderBottom.value +
this.map.paddingTop.value + this.map.paddingBottom.value;
let newValue = width + "x" + height;
let newValue = width + "\u00D7" + height;
if (this.sizeLabel.textContent != newValue) {
this.sizeLabel.textContent = newValue;
}

Просмотреть файл

@ -16,10 +16,10 @@ const PAGE_CONTENT = [
].join("\n");
const TEST_NODES = [
{selector: "img.local", size: "192 x 192"},
{selector: "img.data", size: "64 x 64"},
{selector: "img.remote", size: "22 x 23"},
{selector: ".canvas", size: "600 x 600"}
{selector: "img.local", size: "192" + " \u00D7 " + "192"},
{selector: "img.data", size: "64" + " \u00D7 " + "64"},
{selector: "img.remote", size: "22" + " \u00D7 " + "23"},
{selector: ".canvas", size: "600" + " \u00D7 " + "600"}
];
add_task(function*() {

Просмотреть файл

@ -1683,7 +1683,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
*/
_onSecurityIconClick: function(e) {
let state = this.selectedItem.attachment.securityState;
if (state === "broken" || state === "secure") {
if (state !== "insecure") {
// Choose the security tab.
NetMonitorView.NetworkDetails.widget.selectedIndex = 5;
}
@ -2605,7 +2605,7 @@ NetworkDetailsView.prototype = {
// in width and height attributes like the rest of the folk. Hack around
// this by getting the bounding client rect and subtracting the margins.
let { width, height } = e.target.getBoundingClientRect();
let dimensions = (width - 2) + " x " + (height - 2);
let dimensions = (width - 2) + " \u00D7 " + (height - 2);
$("#response-content-image-dimensions-value").setAttribute("value", dimensions);
};
}
@ -2765,10 +2765,22 @@ NetworkDetailsView.prototype = {
let errorbox = $("#security-error");
let infobox = $("#security-information");
if (securityInfo.state === "secure") {
if (securityInfo.state === "secure" || securityInfo.state === "weak") {
infobox.hidden = false;
errorbox.hidden = true;
// Warning icons
let cipher = $("#security-warning-cipher");
let sslv3 = $("#security-warning-sslv3");
if (securityInfo.state === "weak") {
cipher.hidden = securityInfo.weaknessReasons.indexOf("cipher") === -1;
sslv3.hidden = securityInfo.weaknessReasons.indexOf("sslv3") === -1;
} else {
cipher.hidden = true;
sslv3.hidden = true;
}
let enabledLabel = L10N.getStr("netmonitor.security.enabled");
let disabledLabel = L10N.getStr("netmonitor.security.disabled");

Просмотреть файл

@ -506,6 +506,9 @@
class="plain tabpanel-summary-value devtools-monospace"
crop="end"
flex="1"/>
<image class="security-warning-icon"
id="security-warning-sslv3"
tooltiptext="&netmonitorUI.security.warning.sslv3;" />
</hbox>
<hbox id="security-ciphersuite"
class="tabpanel-summary-container"
@ -516,6 +519,9 @@
class="plain tabpanel-summary-value devtools-monospace"
crop="end"
flex="1"/>
<image class="security-warning-icon"
id="security-warning-cipher"
tooltiptext="&netmonitorUI.security.warning.cipher;" />
</hbox>
</vbox>
</vbox>

Просмотреть файл

@ -92,6 +92,7 @@ skip-if = e10s # Bug 1091612
[browser_net_security-state.js]
[browser_net_security-tab-deselect.js]
[browser_net_security-tab-visibility.js]
[browser_net_security-warnings.js]
[browser_net_simple-init.js]
[browser_net_simple-request-data.js]
[browser_net_simple-request-details.js]

Просмотреть файл

@ -208,7 +208,7 @@ function test() {
.getAttribute("value"), "base64",
"The image encoding info isn't correct.");
is(tabpanel.querySelector("#response-content-image-dimensions-value")
.getAttribute("value"), "16 x 16",
.getAttribute("value"), "16" + " \u00D7 " + "16",
"The image dimensions info isn't correct.");
deferred.resolve();

Просмотреть файл

@ -13,6 +13,7 @@ add_task(function* () {
"test1.example.com": "security-state-insecure",
"example.com": "security-state-secure",
"nocert.example.com": "security-state-broken",
"rc4.example.com": "security-state-weak",
};
let [tab, debuggee, monitor] = yield initNetMonitor(CUSTOM_GET_URL);
@ -70,7 +71,12 @@ add_task(function* () {
debuggee.performRequests(1, "https://example.com" + CORS_SJS_PATH);
yield done;
is(RequestsMenu.itemCount, 3, "Three events logged.");
done = waitForNetworkEvents(monitor, 1);
info("Requesting a resource over HTTPS with RC4.");
debuggee.performRequests(1, "https://rc4.example.com" + CORS_SJS_PATH);
yield done;
is(RequestsMenu.itemCount, 4, "Four events logged.");
}
/**

Просмотреть файл

@ -0,0 +1,81 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Test that warning indicators are shown when appropriate.
*/
const TEST_CASES = [
{
desc: "no warnings",
uri: "https://example.com" + CORS_SJS_PATH,
warnCipher: false,
warnSSLv3: false,
},
{
desc: "sslv3 warning",
uri: "https://ssl3.example.com" + CORS_SJS_PATH,
warnCipher: false,
warnSSLv3: true,
},
{
desc: "cipher warning",
uri: "https://rc4.example.com" + CORS_SJS_PATH,
warnCipher: true,
warnSSLv3: false,
},
{
desc: "cipher and sslv3 warning",
uri: "https://ssl3rc4.example.com" + CORS_SJS_PATH,
warnCipher: true,
warnSSLv3: true,
},
];
add_task(function* () {
let [tab, debuggee, monitor] = yield initNetMonitor(CUSTOM_GET_URL);
let { $, EVENTS, NetMonitorView } = monitor.panelWin;
let { RequestsMenu, NetworkDetails } = NetMonitorView;
RequestsMenu.lazyUpdate = false;
info("Enabling SSLv3 for the test.");
yield new promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [["security.tls.version.min", 0]]}, resolve);
});
let cipher = $("#security-warning-cipher");
let sslv3 = $("#security-warning-sslv3");
for (let test of TEST_CASES) {
info("Testing site with " + test.desc);
info("Performing request to " + test.uri);
debuggee.performRequests(1, test.uri);
yield waitForNetworkEvents(monitor, 1);
info("Selecting the request.");
RequestsMenu.selectedIndex = 0;
info("Waiting for details pane to be updated.");
yield monitor.panelWin.once(EVENTS.TAB_UPDATED);
if (NetworkDetails.widget.selectedIndex !== 5) {
info("Selecting security tab.");
NetworkDetails.widget.selectedIndex = 5;
info("Waiting for details pane to be updated.");
yield monitor.panelWin.once(EVENTS.TAB_UPDATED);
}
is(cipher.hidden, !test.warnCipher, "Cipher suite warning is hidden.");
is(sslv3.hidden, !test.warnSSLv3, "SSLv3 warning is hidden.");
RequestsMenu.clear();
}
yield teardown(monitor);
});

Просмотреть файл

@ -604,7 +604,7 @@ ResponsiveUI.prototype = {
* @param aPreset associated preset.
*/
setMenuLabel: function RUI_setMenuLabel(aMenuitem, aPreset) {
let size = Math.round(aPreset.width) + "x" + Math.round(aPreset.height);
let size = Math.round(aPreset.width) + "\u00D7" + Math.round(aPreset.height);
// .inputField might be not reachable yet (async XBL loading)
if (this.menulist.inputField) {

Просмотреть файл

@ -210,7 +210,7 @@ function test() {
initialWidth = content.innerWidth;
initialHeight = content.innerHeight;
index = instance.menulist.selectedIndex;
let expectedValue = initialWidth + "x" + initialHeight;
let expectedValue = initialWidth + "\u00D7" + initialHeight;
let expectedLabel = instance.menulist.firstChild.firstChild.getAttribute("label");
userInput = "I'm wrong";

Просмотреть файл

@ -115,7 +115,7 @@ function test() {
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
let customPresetIndex = getPresetIndex("456x123 (Testing preset)");
let customPresetIndex = getPresetIndex("456" + "\u00D7" + "123 (Testing preset)");
info(customPresetIndex);
ok(customPresetIndex >= 0, "is the previously added preset (idx = " + customPresetIndex + ") in the list of items");

Просмотреть файл

@ -726,7 +726,7 @@ Tooltip.prototype = {
this.content = vbox;
},
_getImageDimensionLabel: (w, h) => w + " x " + h,
_getImageDimensionLabel: (w, h) => w + " \u00D7 " + h,
/**
* Fill the tooltip with a new instance of the spectrum color picker widget

Просмотреть файл

@ -896,16 +896,13 @@ Messages.Simple.prototype = Heritage.extend(Messages.BaseMessage.prototype,
let body = this.document.createElementNS(XHTML_NS, "span");
body.className = "message-body-wrapper message-body devtools-monospace";
let bodyInner = this.document.createElementNS(XHTML_NS, "span");
body.appendChild(bodyInner);
let anchor, container = bodyInner;
let anchor, container = body;
if (this._link || this._linkCallback) {
container = anchor = this.document.createElementNS(XHTML_NS, "a");
anchor.href = this._link || "#";
anchor.draggable = false;
this._addLinkCallback(anchor, this._linkCallback);
bodyInner.appendChild(anchor);
body.appendChild(anchor);
}
if (typeof this._message == "function") {

Просмотреть файл

@ -57,9 +57,7 @@ function consoleOpened(aHud) {
controller = top.document.commandDispatcher.getControllerForCommand("cmd_copy");
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
// Remove new lines since getSelection() includes one between message and line
// number, but the clipboard doesn't (see bug 1119503)
let selection = (HUD.iframeWindow.getSelection() + "").replace(/\r?\n|\r/g, " ");
let selection = HUD.iframeWindow.getSelection() + "";
isnot(selection.indexOf("bug587617"), -1,
"selection text includes 'bug587617'");
@ -82,9 +80,7 @@ function testContextMenuCopy() {
let copyItem = contextMenu.querySelector("*[command='cmd_copy']");
ok(copyItem, "the context menu on the output node has a \"Copy\" item");
// Remove new lines since getSelection() includes one between message and line
// number, but the clipboard doesn't (see bug 1119503)
let selection = (HUD.iframeWindow.getSelection() + "").replace(/\r?\n|\r/g, " ");
let selection = HUD.iframeWindow.getSelection() + "";
copyItem.doCommand();

Просмотреть файл

@ -69,9 +69,7 @@ function performTest(HUD, [result]) {
getControllerForCommand("cmd_copy");
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
// Remove new lines since getSelection() includes one between message and line
// number, but the clipboard doesn't (see bug 1119503)
let selectionText = (HUD.iframeWindow.getSelection() + "").replace(/\r?\n|\r/g, " ");
let selectionText = HUD.iframeWindow.getSelection() + "";
isnot(selectionText.indexOf("foobarBazBug613280"), -1,
"selection text includes 'foobarBazBug613280'");

Просмотреть файл

@ -202,6 +202,14 @@
- in a "receive" state. -->
<!ENTITY netmonitorUI.timings.receive "Receiving:">
<!-- LOCALIZATION NOTE (netmonitorUI.security.warning.protocol): A tooltip
- for warning icon that indicates a connection uses insecure protocol. -->
<!ENTITY netmonitorUI.security.warning.sslv3 "The protocol SSL 3.0 is deprecated and insecure.">
<!-- LOCALIZATION NOTE (netmonitorUI.security.warning.cipher): A tooltip
- for warning icon that indicates a connection uses insecure cipher suite. -->
<!ENTITY netmonitorUI.security.warning.cipher "The cipher used for encryption is deprecated and insecure.">
<!-- LOCALIZATION NOTE (netmonitorUI.security.error): This is the label displayed
- in the security tab if a security error prevented the connection. -->
<!ENTITY netmonitorUI.security.error "An error occured:">

Просмотреть файл

@ -44,6 +44,10 @@ netmonitor.security.state.insecure=The connection used to fetch this resource wa
# issues.
netmonitor.security.state.broken=A security error prevented the resource from being loaded.
# LOCALIZATION NOTE (netmonitor.security.state.weak)
# This string is used as an tooltip for request that had minor security issues
netmonitor.security.state.weak=This resource was transferred over a connection that used weak encryption.
# LOCALIZATION NOTE (netmonitor.security.enabled):
# This string is used to indicate that a specific security feature is used by
# a connection in the security details tab.

Просмотреть файл

@ -178,6 +178,11 @@
list-style-image: url(chrome://browser/skin/identity-icons-https.png);
}
.security-state-weak {
cursor: pointer;
list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-display.png);
}
.security-state-broken {
cursor: pointer;
list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-active.png);
@ -578,6 +583,21 @@ label.requests-menu-status-code {
white-space: pre-wrap;
}
.security-warning-icon {
background-image: url(alerticon-warning.png);
background-size: 13px 12px;
-moz-margin-start: 5px;
vertical-align: top;
width: 13px;
height: 12px;
}
@media (min-resolution: 2dppx) {
.security-warning-icon {
background-image: url(alerticon-warning@2x.png);
}
}
/* Custom request form */
#custom-pane {

Просмотреть файл

@ -117,7 +117,7 @@ a {
display: flex;
}
.message-body > * {
.message-body {
white-space: pre-wrap;
word-wrap: break-word;
}

Просмотреть файл

@ -25,6 +25,14 @@ treecol {
/* Category List */
#categories {
max-height: 100vh;
}
#categories > scrollbox {
overflow-x: hidden !important;
}
.category-icon {
list-style-image: url("chrome://browser/skin/preferences/in-content/icons.png");
}

Просмотреть файл

@ -97,8 +97,7 @@ SelectionCopyHelper(nsISelection *aSel, nsIDocument *aDoc,
// Do the first and potentially trial encoding as preformatted and raw.
uint32_t flags = aFlags | nsIDocumentEncoder::OutputPreformatted
| nsIDocumentEncoder::OutputRaw
| nsIDocumentEncoder::OutputForPlainTextClipboardCopy;
| nsIDocumentEncoder::OutputRaw;
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
NS_ASSERTION(domDoc, "Need a document");

Просмотреть файл

@ -227,13 +227,6 @@ interface nsIDocumentEncoder : nsISupports
*/
const unsigned long OutputDontRemoveLineEndingSpaces = (1 << 24);
/**
* Serialize in a way that is suitable for copying a plaintext version of the
* document to the clipboard. This can for example cause line endings to be
* injected at preformatted block element boundaries.
*/
const unsigned long OutputForPlainTextClipboardCopy = (1 << 25);
/**
* Initialize with a pointer to the document and the mime type.
* @param aDocument Document to encode.

Просмотреть файл

@ -91,8 +91,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
mPreFormatted = false;
mStartedOutput = false;
mPreformattedBlockBoundary = false;
// initialize the tag stack to zero:
// The stack only ever contains pointers to static atoms, so they don't
// need refcounting.
@ -169,8 +167,6 @@ nsPlainTextSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
mLineBreakDue = false;
mFloatingLines = -1;
mPreformattedBlockBoundary = false;
if (mFlags & nsIDocumentEncoder::OutputFormatted) {
// Get some prefs that controls how we do formatted output
mStructs = Preferences::GetBool(PREF_STRUCTS, mStructs);
@ -441,16 +437,6 @@ nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
return NS_OK;
}
if (mFlags & nsIDocumentEncoder::OutputForPlainTextClipboardCopy) {
if (mPreformattedBlockBoundary && DoOutput()) {
// Should always end a line, but get no more whitespace
if (mFloatingLines < 0)
mFloatingLines = 0;
mLineBreakDue = true;
}
mPreformattedBlockBoundary = false;
}
if (mFlags & nsIDocumentEncoder::OutputRaw) {
// Raw means raw. Don't even think about doing anything fancy
// here like indenting, adding line breaks or any other
@ -684,7 +670,7 @@ nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
// Else make sure we'll separate block level tags,
// even if we're about to leave, before doing any other formatting.
else if (IsElementBlock(mElement)) {
else if (nsContentUtils::IsHTMLBlock(aTag)) {
EnsureVerticalSpace(0);
}
@ -781,14 +767,6 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
return NS_OK;
}
if (mFlags & nsIDocumentEncoder::OutputForPlainTextClipboardCopy) {
if (DoOutput() && IsInPre() && IsElementBlock(mElement)) {
// If we're closing a preformatted block element, output a line break
// when we find a new container.
mPreformattedBlockBoundary = true;
}
}
if (mFlags & nsIDocumentEncoder::OutputRaw) {
// Raw means raw. Don't even think about doing anything fancy
// here like indenting, adding line breaks or any other
@ -909,7 +887,8 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
else if (aTag == nsGkAtoms::q) {
Write(NS_LITERAL_STRING("\""));
}
else if (IsElementBlock(mElement) && aTag != nsGkAtoms::script) {
else if (nsContentUtils::IsHTMLBlock(aTag)
&& aTag != nsGkAtoms::script) {
// All other blocks get 1 vertical space after them
// in formatted mode, otherwise 0.
// This is hard. Sometimes 0 is a better number, but
@ -1058,8 +1037,6 @@ nsPlainTextSerializer::DoAddText(bool aIsLineBreak, const nsAString& aText)
nsresult
nsPlainTextSerializer::DoAddLeaf(nsIAtom* aTag)
{
mPreformattedBlockBoundary = false;
// If we don't want any output, just return
if (!DoOutput()) {
return NS_OK;
@ -1801,20 +1778,6 @@ nsPlainTextSerializer::IsElementPreformatted(Element* aElement)
return GetIdForContent(aElement) == nsGkAtoms::pre;
}
bool
nsPlainTextSerializer::IsElementBlock(Element* aElement)
{
nsRefPtr<nsStyleContext> styleContext =
nsComputedDOMStyle::GetStyleContextForElementNoFlush(aElement, nullptr,
nullptr);
if (styleContext) {
const nsStyleDisplay* displayStyle = styleContext->StyleDisplay();
return displayStyle->IsBlockOutsideStyle();
}
// Fall back to looking at the tag, in case there is no style information.
return nsContentUtils::IsHTMLBlock(GetIdForContent(aElement));
}
/**
* This method is required only to identify LI's inside OL.
* Returns TRUE if we are inside an OL tag and FALSE otherwise.

Просмотреть файл

@ -115,7 +115,6 @@ private:
bool ShouldReplaceContainerWithPlaceholder(nsIAtom* aTag);
bool IsElementPreformatted(mozilla::dom::Element* aElement);
bool IsElementBlock(mozilla::dom::Element* aElement);
private:
nsString mCurrentLine;
@ -170,9 +169,7 @@ private:
// While handling a new tag, this variable should remind if any line break
// is due because of a closing tag. Setting it to "TRUE" while closing the tags.
// Hence opening tags are guaranteed to start with appropriate line breaks.
bool mLineBreakDue;
bool mPreformattedBlockBoundary;
bool mLineBreakDue;
nsString mURL;
int32_t mHeaderStrategy; /* Header strategy (pref)

Просмотреть файл

@ -137,31 +137,6 @@ TestPreElement()
return NS_OK;
}
nsresult
TestBlockElement()
{
nsString test;
test.AppendLiteral(
"<html>" NS_LINEBREAK
"<body>" NS_LINEBREAK
"<div>" NS_LINEBREAK
" first" NS_LINEBREAK
"</div>" NS_LINEBREAK
"<div>" NS_LINEBREAK
" second" NS_LINEBREAK
"</div>" NS_LINEBREAK
"</body>" NS_LINEBREAK "</html>");
ConvertBufToPlainText(test, 0);
if (!test.EqualsLiteral("first" NS_LINEBREAK "second" NS_LINEBREAK)) {
fail("Wrong prettyprinted html to text serialization");
return NS_ERROR_FAILURE;
}
passed("prettyprinted HTML to text serialization test");
return NS_OK;
}
nsresult
TestPlainTextSerializer()
{
@ -188,9 +163,6 @@ TestPlainTextSerializer()
rv = TestPreElement();
NS_ENSURE_SUCCESS(rv, rv);
rv = TestBlockElement();
NS_ENSURE_SUCCESS(rv, rv);
// Add new tests here...
return NS_OK;
}

Просмотреть файл

@ -20,14 +20,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=116083
<div data-result="bar baz"><span style="white-space: pre-wrap">bar </span>baz</div>
<div data-result="bar baz"><span style="white-space: pre-line">bar </span>baz</div>
<div data-result="bar baz"><span style="white-space: -moz-pre-space">bar </span>baz</div>
<div data-result="foo &#10; bar&#10;&#10;!&#10;&#10;&#10;baz" style="white-space: pre"><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
<div data-result="foo &#10; bar&#10;&#10;!&#10;&#10;&#10;baz" style="white-space: pre" contenteditable><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
<div data-result="foo &#10; bar&#10;&#10;!&#10;&#10;&#10;baz" style="white-space: pre-wrap"><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
<div data-result="foo &#10; bar&#10;&#10;!&#10;&#10;&#10;baz" style="white-space: pre-wrap" contenteditable><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
<div data-result="foo &#10; bar&#10;&#10;!&#10;&#10;&#10;baz" style="white-space: pre-line"><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
<div data-result="foo &#10; bar&#10;&#10;!&#10;&#10;&#10;baz" style="white-space: pre-line" contenteditable><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
<div data-result="foo &#10; bar&#10;&#10;!&#10;&#10;&#10;baz" style="white-space: -moz-pre-space"><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
<div data-result="foo &#10; bar&#10;&#10;!&#10;&#10;&#10;baz" style="white-space: -moz-pre-space" contenteditable><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
<div data-result="&#10;foo bar&#10;">foo bar</div>
</div>
<script type="application/javascript">

Просмотреть файл

@ -1600,7 +1600,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, nsDependentCString& aOut)
return NS_ERROR_ILLEGAL_VALUE; // end of PDU
}
const char* end = static_cast<char*>(memchr(str, '\0', aPDU.GetSize()));
const char* end = static_cast<char*>(memchr(str, '\0', aPDU.GetSize() + 1));
if (NS_WARN_IF(!end)) {
return NS_ERROR_ILLEGAL_VALUE; // no string terminator
}

Просмотреть файл

@ -116,7 +116,7 @@ BroadcastSystemMessage(const nsAString& aType,
aData.get_nsString().Length());
value = STRING_TO_JSVAL(jsData);
} else if (aData.type() == BluetoothValue::TArrayOfBluetoothNamedValue) {
JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx)));
JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
if (!obj) {
BT_WARNING("Failed to new JSObject for system message!");
return false;

Просмотреть файл

@ -106,6 +106,7 @@ namespace system {
#define USB_FUNC_NONE "none"
#define USB_FUNC_RNDIS "rndis"
#define USB_FUNC_UMS "mass_storage"
#define USB_FUNC_DEFAULT "default"
class AutoMounter;
@ -552,6 +553,9 @@ SetUsbFunction(const char* aUsbFunc)
// We're enabling UMS. For this we make the assumption that the persisted
// property has mass_storage enabled.
property_get(PERSIST_SYS_USB_CONFIG, newSysUsbConfig, "");
} else if (strcmp(aUsbFunc, USB_FUNC_DEFAULT) == 0) {
// Set the property as PERSIST_SYS_USB_CONFIG
property_get(PERSIST_SYS_USB_CONFIG, newSysUsbConfig, "");
} else {
printf_stderr("AutoMounter::SetUsbFunction Unrecognized aUsbFunc '%s'\n", aUsbFunc);
MOZ_ASSERT(0);
@ -626,6 +630,7 @@ AutoMounter::StartMtpServer()
sMozMtpServer = new MozMtpServer();
if (!sMozMtpServer->Init()) {
sMozMtpServer = nullptr;
return false;
}
@ -786,9 +791,15 @@ AutoMounter::UpdateState()
if (StartMtpServer()) {
SetState(STATE_MTP_STARTED);
} else {
// Unable to start MTP. Go back to UMS.
SetUsbFunction(USB_FUNC_UMS);
SetState(STATE_UMS_CONFIGURING);
if (umsAvail) {
// Unable to start MTP. Go back to UMS.
LOG("UpdateState: StartMtpServer failed, switch to UMS");
SetUsbFunction(USB_FUNC_UMS);
SetState(STATE_UMS_CONFIGURING);
} else {
LOG("UpdateState: StartMtpServer failed, keep idle state");
SetUsbFunction(USB_FUNC_DEFAULT);
}
}
} else {
// We need to configure USB to use mtp. Wait for it to be configured
@ -849,6 +860,10 @@ AutoMounter::UpdateState()
SetState(STATE_UMS_CONFIGURING);
break;
}
// if ums/rndis is not available and mtp is disable,
// restore the usb function as PERSIST_SYS_USB_CONFIG.
SetUsbFunction(USB_FUNC_DEFAULT);
SetState(STATE_IDLE);
break;

Просмотреть файл

@ -232,7 +232,7 @@ MozMtpServer::Init()
const char *mtpUsbFilename = "/dev/mtp_usb";
mMtpUsbFd = open(mtpUsbFilename, O_RDWR);
if (mMtpUsbFd.get() < 0) {
MTP_ERR("open of '%s' failed", mtpUsbFilename);
MTP_ERR("open of '%s' failed((%s))", mtpUsbFilename, strerror(errno));
return false;
}
MTP_LOG("Opened '%s' fd %d", mtpUsbFilename, mMtpUsbFd.get());

Просмотреть файл

@ -19,7 +19,8 @@ enum NFCTechType {
"ISO-DEP", // NFCForum-TS-DigitalProtocol-1.1 ISO-DEP.
"MIFARE-Classic", // MIFARE Classic from NXP.
"MIFARE-Ultralight", // MIFARE Ultralight from NXP.
"NFC-Barcode" // NFC Barcode from Kovio.
"NFC-Barcode", // NFC Barcode from Kovio.
"Unknown"
};
/**

Просмотреть файл

@ -24,7 +24,6 @@
#include <sched.h>
#include <stdio.h>
#include <sys/klog.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/resource.h>
#include <time.h>
@ -48,7 +47,6 @@
#include "HalImpl.h"
#include "HalLog.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/battery/Constants.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/FileUtils.h"
@ -630,6 +628,28 @@ namespace {
/**
* RAII class to help us remember to close file descriptors.
*/
const char *wakeLockFilename = "/sys/power/wake_lock";
const char *wakeUnlockFilename = "/sys/power/wake_unlock";
template<ssize_t n>
bool ReadFromFile(const char *filename, char (&buf)[n])
{
int fd = open(filename, O_RDONLY);
ScopedClose autoClose(fd);
if (fd < 0) {
HAL_LOG("Unable to open file %s.", filename);
return false;
}
ssize_t numRead = read(fd, buf, n);
if (numRead < 0) {
HAL_LOG("Error reading from file %s.", filename);
return false;
}
buf[std::min(numRead, n - 1)] = '\0';
return true;
}
bool WriteToFile(const char *filename, const char *toWrite)
{
@ -755,9 +775,6 @@ static Monitor* sInternalLockCpuMonitor = nullptr;
static void
UpdateCpuSleepState()
{
const char *wakeLockFilename = "/sys/power/wake_lock";
const char *wakeUnlockFilename = "/sys/power/wake_unlock";
sInternalLockCpuMonitor->AssertCurrentThreadOwns();
bool allowed = sCpuSleepAllowed && !sInternalLockCpuCount;
WriteToFile(allowed ? wakeUnlockFilename : wakeLockFilename, "gecko");
@ -1269,6 +1286,7 @@ OomVictimLogger::Observe(
lineTimestampFound = true;
mLastLineChecked = lineTimestamp;
}
// Log interesting lines
for (size_t i = 0; i < regex_count; i++) {
@ -1294,347 +1312,6 @@ OomVictimLogger::Observe(
return NS_OK;
}
/**
* Wraps a particular ProcessPriority, giving us easy access to the prefs that
* are relevant to it.
*
* Creating a PriorityClass also ensures that the control group is created.
*/
class PriorityClass
{
public:
/**
* Create a PriorityClass for the given ProcessPriority. This implicitly
* reads the relevant prefs and opens the cgroup.procs file of the relevant
* control group caching its file descriptor for later use.
*/
PriorityClass(ProcessPriority aPriority);
/**
* Closes the file descriptor for the cgroup.procs file of the associated
* control group.
*/
~PriorityClass();
PriorityClass(const PriorityClass& aOther);
PriorityClass& operator=(const PriorityClass& aOther);
ProcessPriority Priority()
{
return mPriority;
}
int32_t OomScoreAdj()
{
return clamped<int32_t>(mOomScoreAdj, OOM_SCORE_ADJ_MIN, OOM_SCORE_ADJ_MAX);
}
int32_t KillUnderKB()
{
return mKillUnderKB;
}
nsCString CGroup()
{
return mGroup;
}
/**
* Adds a process to this priority class, this moves the process' PID into
* the associated control group.
*
* @param aPid The PID of the process to be added.
*/
void AddProcess(int aPid);
private:
ProcessPriority mPriority;
int32_t mOomScoreAdj;
int32_t mKillUnderKB;
int mCpuCGroupProcsFd;
int mMemCGroupProcsFd;
nsCString mGroup;
/**
* Return a string that identifies where we can find the value of aPref
* that's specific to mPriority. For example, we might return
* "hal.processPriorityManager.gonk.FOREGROUND_HIGH.oomScoreAdjust".
*/
nsCString PriorityPrefName(const char* aPref)
{
return nsPrintfCString("hal.processPriorityManager.gonk.%s.%s",
ProcessPriorityToString(mPriority), aPref);
}
/**
* Get the full path of the cgroup.procs file associated with the group.
*/
nsCString CpuCGroupProcsFilename()
{
nsCString cgroupName = mGroup;
/* If mGroup is empty, our cgroup.procs file is the root procs file,
* located at /dev/cpuctl/cgroup.procs. Otherwise our procs file is
* /dev/cpuctl/NAME/cgroup.procs. */
if (!mGroup.IsEmpty()) {
cgroupName.AppendLiteral("/");
}
return NS_LITERAL_CSTRING("/dev/cpuctl/") + cgroupName +
NS_LITERAL_CSTRING("cgroup.procs");
}
nsCString MemCGroupProcsFilename()
{
nsCString cgroupName = mGroup;
/* If mGroup is empty, our cgroup.procs file is the root procs file,
* located at /sys/fs/cgroup/memory/cgroup.procs. Otherwise our procs
* file is /sys/fs/cgroup/memory/NAME/cgroup.procs. */
if (!mGroup.IsEmpty()) {
cgroupName.AppendLiteral("/");
}
return NS_LITERAL_CSTRING("/sys/fs/cgroup/memory/") + cgroupName +
NS_LITERAL_CSTRING("cgroup.procs");
}
int OpenCpuCGroupProcs()
{
return open(CpuCGroupProcsFilename().get(), O_WRONLY);
}
int OpenMemCGroupProcs()
{
return open(MemCGroupProcsFilename().get(), O_WRONLY);
}
};
/**
* Creates a directory and parents (essentially mkdir -p, but
* this only create the directories within the cgroup name).
*/
static bool MakeCGroupDir(const nsACString& aRootDir,
const nsACString& aGroupName)
{
NS_NAMED_LITERAL_CSTRING(kSlash, "/");
// Create directories contained within aGroupName
nsCString cgroupIter = aGroupName + kSlash;
int32_t offset = 0;
while ((offset = cgroupIter.FindChar('/', offset)) != -1) {
nsAutoCString path = aRootDir + Substring(cgroupIter, 0, offset);
int rv = mkdir(path.get(), 0744);
if (rv == -1 && errno != EEXIST) {
HAL_LOG("Could not create the %s control group.", path.get());
return false;
}
offset++;
}
return true;
}
/**
* Try to create the cgroup for the given PriorityClass, if it doesn't already
* exist. This essentially implements mkdir -p; that is, we create parent
* cgroups as necessary. The group parameters are also set according to
* the corresponding preferences.
*
* @param aGroup The name of the group.
* @return true if we successfully created the cgroup, or if it already
* exists. Otherwise, return false.
*/
static bool
EnsureCpuCGroupExists(const nsACString& aGroup)
{
NS_NAMED_LITERAL_CSTRING(kDevCpuCtl, "/dev/cpuctl/");
NS_NAMED_LITERAL_CSTRING(kSlash, "/");
nsAutoCString prefPrefix("hal.processPriorityManager.gonk.cgroups.");
/* If cgroup is not empty, append the cgroup name and a dot to obtain the
* group specific preferences. */
if (!aGroup.IsEmpty()) {
prefPrefix += aGroup + NS_LITERAL_CSTRING(".");
}
nsAutoCString cpuSharesPref(prefPrefix + NS_LITERAL_CSTRING("cpu_shares"));
int cpuShares = Preferences::GetInt(cpuSharesPref.get());
nsAutoCString cpuNotifyOnMigratePref(prefPrefix
+ NS_LITERAL_CSTRING("cpu_notify_on_migrate"));
int cpuNotifyOnMigrate = Preferences::GetInt(cpuNotifyOnMigratePref.get());
if (!MakeCGroupDir(kDevCpuCtl, aGroup)) {
return false;
}
nsAutoCString pathPrefix(kDevCpuCtl + aGroup + kSlash);
nsAutoCString cpuSharesPath(pathPrefix + NS_LITERAL_CSTRING("cpu.shares"));
if (cpuShares && !WriteToFile(cpuSharesPath.get(),
nsPrintfCString("%d", cpuShares).get())) {
HAL_LOG("Could not set the cpu share for group %s", cpuSharesPath.get());
return false;
}
nsAutoCString notifyOnMigratePath(pathPrefix
+ NS_LITERAL_CSTRING("cpu.notify_on_migrate"));
if (!WriteToFile(notifyOnMigratePath.get(),
nsPrintfCString("%d", cpuNotifyOnMigrate).get())) {
HAL_LOG("Could not set the cpu migration notification flag for group %s",
notifyOnMigratePath.get());
return false;
}
return true;
}
static bool
EnsureMemCGroupExists(const nsACString& aGroup)
{
NS_NAMED_LITERAL_CSTRING(kMemCtl, "/sys/fs/cgroup/memory/");
NS_NAMED_LITERAL_CSTRING(kSlash, "/");
nsAutoCString prefPrefix("hal.processPriorityManager.gonk.cgroups.");
/* If cgroup is not empty, append the cgroup name and a dot to obtain the
* group specific preferences. */
if (!aGroup.IsEmpty()) {
prefPrefix += aGroup + NS_LITERAL_CSTRING(".");
}
nsAutoCString memSwappinessPref(prefPrefix +
NS_LITERAL_CSTRING("memory_swappiness"));
int memSwappiness = Preferences::GetInt(memSwappinessPref.get());
if (!MakeCGroupDir(kMemCtl, aGroup)) {
return false;
}
nsAutoCString pathPrefix(kMemCtl + aGroup + kSlash);
nsAutoCString memSwappinessPath(pathPrefix +
NS_LITERAL_CSTRING("memory.swappiness"));
if (!WriteToFile(memSwappinessPath.get(),
nsPrintfCString("%d", memSwappiness).get())) {
HAL_LOG("Could not set the memory.swappiness for group %s",
memSwappinessPath.get());
return false;
}
return true;
}
PriorityClass::PriorityClass(ProcessPriority aPriority)
: mPriority(aPriority)
, mOomScoreAdj(0)
, mKillUnderKB(0)
, mCpuCGroupProcsFd(-1)
, mMemCGroupProcsFd(-1)
{
DebugOnly<nsresult> rv;
rv = Preferences::GetInt(PriorityPrefName("OomScoreAdjust").get(),
&mOomScoreAdj);
MOZ_ASSERT(NS_SUCCEEDED(rv), "Missing oom_score_adj preference");
rv = Preferences::GetInt(PriorityPrefName("KillUnderKB").get(),
&mKillUnderKB);
rv = Preferences::GetCString(PriorityPrefName("cgroup").get(), &mGroup);
MOZ_ASSERT(NS_SUCCEEDED(rv), "Missing control group preference");
if (EnsureCpuCGroupExists(mGroup)) {
mCpuCGroupProcsFd = OpenCpuCGroupProcs();
}
if (EnsureMemCGroupExists(mGroup)) {
mMemCGroupProcsFd = OpenMemCGroupProcs();
}
}
PriorityClass::~PriorityClass()
{
MOZ_TEMP_FAILURE_RETRY(close(mCpuCGroupProcsFd));
MOZ_TEMP_FAILURE_RETRY(close(mMemCGroupProcsFd));
}
PriorityClass::PriorityClass(const PriorityClass& aOther)
: mPriority(aOther.mPriority)
, mOomScoreAdj(aOther.mOomScoreAdj)
, mKillUnderKB(aOther.mKillUnderKB)
, mGroup(aOther.mGroup)
{
mCpuCGroupProcsFd = OpenCpuCGroupProcs();
mMemCGroupProcsFd = OpenMemCGroupProcs();
}
PriorityClass& PriorityClass::operator=(const PriorityClass& aOther)
{
mPriority = aOther.mPriority;
mOomScoreAdj = aOther.mOomScoreAdj;
mKillUnderKB = aOther.mKillUnderKB;
mGroup = aOther.mGroup;
mCpuCGroupProcsFd = OpenCpuCGroupProcs();
mMemCGroupProcsFd = OpenMemCGroupProcs();
return *this;
}
void PriorityClass::AddProcess(int aPid)
{
if (mCpuCGroupProcsFd >= 0) {
nsPrintfCString str("%d", aPid);
if (write(mCpuCGroupProcsFd, str.get(), str.Length()) < 0) {
HAL_ERR("Couldn't add PID %d to the %s cpu control group",
aPid, mGroup.get());
}
}
if (mMemCGroupProcsFd >= 0) {
nsPrintfCString str("%d", aPid);
if (write(mMemCGroupProcsFd, str.get(), str.Length()) < 0) {
HAL_ERR("Couldn't add PID %d to the %s memory control group",
aPid, mGroup.get());
}
}
}
/**
* Get the PriorityClass associated with the given ProcessPriority.
*
* If you pass an invalid ProcessPriority value, we return null.
*
* The pointers returned here are owned by GetPriorityClass (don't free them
* yourself). They are guaranteed to stick around until shutdown.
*/
PriorityClass*
GetPriorityClass(ProcessPriority aPriority)
{
static StaticAutoPtr<nsTArray<PriorityClass>> priorityClasses;
// Initialize priorityClasses if this is the first time we're running this
// method.
if (!priorityClasses) {
priorityClasses = new nsTArray<PriorityClass>();
ClearOnShutdown(&priorityClasses);
for (int32_t i = 0; i < NUM_PROCESS_PRIORITY; i++) {
priorityClasses->AppendElement(PriorityClass(ProcessPriority(i)));
}
}
if (aPriority < 0 ||
static_cast<uint32_t>(aPriority) >= priorityClasses->Length()) {
return nullptr;
}
return &(*priorityClasses)[aPriority];
}
static void
EnsureKernelLowMemKillerParamsSet()
{
@ -1675,12 +1352,21 @@ EnsureKernelLowMemKillerParamsSet()
// The system doesn't function correctly if we're missing these prefs, so
// crash loudly.
PriorityClass* pc = GetPriorityClass(static_cast<ProcessPriority>(i));
ProcessPriority priority = static_cast<ProcessPriority>(i);
int32_t oomScoreAdj = pc->OomScoreAdj();
int32_t killUnderKB = pc->KillUnderKB();
int32_t oomScoreAdj;
if (!NS_SUCCEEDED(Preferences::GetInt(
nsPrintfCString("hal.processPriorityManager.gonk.%s.OomScoreAdjust",
ProcessPriorityToString(priority)).get(),
&oomScoreAdj))) {
MOZ_CRASH();
}
if (killUnderKB == 0) {
int32_t killUnderKB;
if (!NS_SUCCEEDED(Preferences::GetInt(
nsPrintfCString("hal.processPriorityManager.gonk.%s.KillUnderKB",
ProcessPriorityToString(priority)).get(),
&killUnderKB))) {
// ProcessPriority values like PROCESS_PRIORITY_FOREGROUND_KEYBOARD,
// which has only OomScoreAdjust but lacks KillUnderMB value, will not
// create new LMK parameters.
@ -1711,8 +1397,7 @@ EnsureKernelLowMemKillerParamsSet()
minfreeParams.Cut(minfreeParams.Length() - 1, 1);
if (!adjParams.IsEmpty() && !minfreeParams.IsEmpty()) {
WriteToFile("/sys/module/lowmemorykiller/parameters/adj", adjParams.get());
WriteToFile("/sys/module/lowmemorykiller/parameters/minfree",
minfreeParams.get());
WriteToFile("/sys/module/lowmemorykiller/parameters/minfree", minfreeParams.get());
}
// Set the low-memory-notification threshold.
@ -1734,6 +1419,148 @@ EnsureKernelLowMemKillerParamsSet()
}
}
static void
SetNiceForPid(int aPid, int aNice)
{
errno = 0;
int origProcPriority = getpriority(PRIO_PROCESS, aPid);
if (errno) {
HAL_LOG("Unable to get nice for pid=%d; error %d. SetNiceForPid bailing.",
aPid, errno);
return;
}
int rv = setpriority(PRIO_PROCESS, aPid, aNice);
if (rv) {
HAL_LOG("Unable to set nice for pid=%d; error %d. SetNiceForPid bailing.",
aPid, errno);
return;
}
// On Linux, setpriority(aPid) modifies the priority only of the main
// thread of that process. We have to modify the priorities of all of the
// process's threads as well, so iterate over all the threads and increase
// each of their priorites by aNice - origProcPriority (and also ensure that
// none of the tasks has a lower priority than the main thread).
//
// This is horribly racy.
DIR* tasksDir = opendir(nsPrintfCString("/proc/%d/task/", aPid).get());
if (!tasksDir) {
HAL_LOG("Unable to open /proc/%d/task. SetNiceForPid bailing.", aPid);
return;
}
// Be careful not to leak tasksDir; after this point, we must call closedir().
while (struct dirent* de = readdir(tasksDir)) {
char* endptr = nullptr;
long tidlong = strtol(de->d_name, &endptr, /* base */ 10);
if (*endptr || tidlong < 0 || tidlong > INT32_MAX || tidlong == aPid) {
// if dp->d_name was not an integer, was negative (?!) or too large, or
// was the same as aPid, we're not interested.
//
// (The |tidlong == aPid| check is very important; without it, we'll
// renice aPid twice, and the second renice will be relative to the
// priority set by the first renice.)
continue;
}
int tid = static_cast<int>(tidlong);
// Do not set the priority of threads running with a real-time policy
// as part of the bulk process adjustment. These threads need to run
// at their specified priority in order to meet timing guarantees.
int schedPolicy = sched_getscheduler(tid);
if (schedPolicy == SCHED_FIFO || schedPolicy == SCHED_RR) {
continue;
}
errno = 0;
// Get and set the task's new priority.
int origtaskpriority = getpriority(PRIO_PROCESS, tid);
if (errno) {
HAL_LOG("Unable to get nice for tid=%d (pid=%d); error %d. This isn't "
"necessarily a problem; it could be a benign race condition.",
tid, aPid, errno);
continue;
}
int newtaskpriority =
std::max(origtaskpriority - origProcPriority + aNice, aNice);
// Do not reduce priority of threads already running at priorities greater
// than normal. These threads are likely special service threads that need
// elevated priorities to process audio, display composition, etc.
if (newtaskpriority > origtaskpriority &&
origtaskpriority < ANDROID_PRIORITY_NORMAL) {
continue;
}
rv = setpriority(PRIO_PROCESS, tid, newtaskpriority);
if (rv) {
HAL_LOG("Unable to set nice for tid=%d (pid=%d); error %d. This isn't "
"necessarily a problem; it could be a benign race condition.",
tid, aPid, errno);
continue;
}
}
HAL_LOG("Changed nice for pid %d from %d to %d.",
aPid, origProcPriority, aNice);
closedir(tasksDir);
}
/*
* Used to store the nice value adjustments and oom_adj values for the various
* process priority levels.
*/
struct ProcessPriorityPrefs {
bool initialized;
int lowPriorityNice;
struct {
int nice;
int oomScoreAdj;
} priorities[NUM_PROCESS_PRIORITY];
};
/*
* Reads the preferences for the various process priority levels and sets up
* watchers so that if they're dynamically changed the change is reflected on
* the appropriate variables.
*/
void
EnsureProcessPriorityPrefs(ProcessPriorityPrefs* prefs)
{
if (prefs->initialized) {
return;
}
// Read the preferences for process priority levels
for (int i = PROCESS_PRIORITY_BACKGROUND; i < NUM_PROCESS_PRIORITY; i++) {
ProcessPriority priority = static_cast<ProcessPriority>(i);
// Read the nice values
const char* processPriorityStr = ProcessPriorityToString(priority);
nsPrintfCString niceStr("hal.processPriorityManager.gonk.%s.Nice",
processPriorityStr);
Preferences::AddIntVarCache(&prefs->priorities[i].nice, niceStr.get());
// Read the oom_adj scores
nsPrintfCString oomStr("hal.processPriorityManager.gonk.%s.OomScoreAdjust",
processPriorityStr);
Preferences::AddIntVarCache(&prefs->priorities[i].oomScoreAdj,
oomStr.get());
}
Preferences::AddIntVarCache(&prefs->lowPriorityNice,
"hal.processPriorityManager.gonk.LowCPUNice");
prefs->initialized = true;
}
void
SetProcessPriority(int aPid,
ProcessPriority aPriority,
@ -1752,23 +1579,49 @@ SetProcessPriority(int aPid,
// SetProcessPriority being called early in startup.
EnsureKernelLowMemKillerParamsSet();
PriorityClass* pc = GetPriorityClass(aPriority);
static ProcessPriorityPrefs prefs = { 0 };
EnsureProcessPriorityPrefs(&prefs);
int oomScoreAdj = pc->OomScoreAdj();
int oomScoreAdj = prefs.priorities[aPriority].oomScoreAdj;
RoundOomScoreAdjUpWithBackroundLRU(oomScoreAdj, aBackgroundLRU);
// We try the newer interface first, and fall back to the older interface
// on failure.
if (!WriteToFile(nsPrintfCString("/proc/%d/oom_score_adj", aPid).get(),
nsPrintfCString("%d", oomScoreAdj).get()))
{
WriteToFile(nsPrintfCString("/proc/%d/oom_adj", aPid).get(),
nsPrintfCString("%d", OomAdjOfOomScoreAdj(oomScoreAdj)).get());
int clampedOomScoreAdj = clamped<int>(oomScoreAdj, OOM_SCORE_ADJ_MIN,
OOM_SCORE_ADJ_MAX);
if (clampedOomScoreAdj != oomScoreAdj) {
HAL_LOG("Clamping OOM adjustment for pid %d to %d", aPid,
clampedOomScoreAdj);
} else {
HAL_LOG("Setting OOM adjustment for pid %d to %d", aPid,
clampedOomScoreAdj);
}
HAL_LOG("Assigning pid %d to cgroup %s", aPid, pc->CGroup().get());
pc->AddProcess(aPid);
// We try the newer interface first, and fall back to the older interface
// on failure.
if (!WriteToFile(nsPrintfCString("/proc/%d/oom_score_adj", aPid).get(),
nsPrintfCString("%d", clampedOomScoreAdj).get()))
{
int oomAdj = OomAdjOfOomScoreAdj(clampedOomScoreAdj);
WriteToFile(nsPrintfCString("/proc/%d/oom_adj", aPid).get(),
nsPrintfCString("%d", oomAdj).get());
}
int nice = 0;
if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
nice = prefs.priorities[aPriority].nice;
} else if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
nice = prefs.lowPriorityNice;
} else {
HAL_ERR("Unknown aCPUPriority value %d", aCPUPriority);
MOZ_ASSERT(false);
return;
}
HAL_LOG("Setting nice for pid %d to %d", aPid, nice);
SetNiceForPid(aPid, nice);
}
static bool

Просмотреть файл

@ -3,6 +3,7 @@
Cu.import("resource://services-common/async.js");
Cu.import("resource://testing-common/services/common/utils.js");
Cu.import("resource://testing-common/PlacesTestUtils.jsm");
let provider = {
getFile: function(prop, persistent) {

Просмотреть файл

@ -1,7 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/PlacesUtils.jsm");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/engines/history.js");
Cu.import("resource://services-sync/engines.js");
@ -13,13 +12,16 @@ Cu.import("resource://testing-common/services/sync/utils.js");
Service.engineManager.clear();
add_test(function test_setup() {
PlacesTestUtils.clearHistory().then(run_next_test);
});
add_test(function test_processIncoming_mobile_history_batched() {
_("SyncEngine._processIncoming works on history engine.");
let FAKE_DOWNLOAD_LIMIT = 100;
Svc.Prefs.set("client.type", "mobile");
PlacesUtils.history.removeAllPages();
Service.engineManager.register(HistoryEngine);
// A collection that logs each GET
@ -130,10 +132,11 @@ add_test(function test_processIncoming_mobile_history_batched() {
}
} finally {
PlacesUtils.history.removeAllPages();
server.stop(do_test_finished);
Svc.Prefs.resetBranch("");
Service.recordManager.clearCache();
PlacesTestUtils.clearHistory().then(() => {
server.stop(do_test_finished);
Svc.Prefs.resetBranch("");
Service.recordManager.clearCache();
});
}
});

Просмотреть файл

@ -62,7 +62,7 @@ function ensureThrows(func) {
try {
func.apply(this, arguments);
} catch (ex) {
PlacesUtils.history.removeAllPages();
PlacesTestUtils.clearHistory();
do_throw(ex);
}
};
@ -300,6 +300,5 @@ add_test(function test_remove() {
add_test(function cleanup() {
_("Clean up.");
PlacesUtils.history.removeAllPages();
run_next_test();
PlacesTestUtils.clearHistory().then(run_next_test);
});

Просмотреть файл

@ -199,6 +199,5 @@ add_test(function test_stop_tracking_twice() {
add_test(function cleanup() {
_("Clean up.");
PlacesUtils.history.removeAllPages();
run_next_test();
PlacesTestUtils.clearHistory().then(run_next_test);
});

Просмотреть файл

@ -369,7 +369,7 @@ Other Measurements\n\
\n\
100.00 MB ── heap-allocated\n\
\n\
End of 5th \
End of 5th\n\
";
let amvExpectedText =
@ -538,7 +538,7 @@ Other Measurements\n\
\n\
104,857,600 B ── heap-allocated\n\
\n\
End of 5th \
End of 5th\n\
";
function finish()

Просмотреть файл

@ -912,14 +912,19 @@ public:
mozStorageTransaction transaction(mDBConn, false,
mozIStorageConnection::TRANSACTION_IMMEDIATE);
VisitData* lastPlace = nullptr;
VisitData* lastFetchedPlace = nullptr;
for (nsTArray<VisitData>::size_type i = 0; i < mPlaces.Length(); i++) {
VisitData& place = mPlaces.ElementAt(i);
VisitData& referrer = mReferrers.ElementAt(i);
// Fetching from the database can overwrite this information, so save it
// apart.
bool typed = place.typed;
bool hidden = place.hidden;
// We can avoid a database lookup if it's the same place as the last
// visit we added.
bool known = lastPlace && lastPlace->IsSamePlaceAs(place);
bool known = lastFetchedPlace && lastFetchedPlace->IsSamePlaceAs(place);
if (!known) {
nsresult rv = mHistory->FetchPageInfo(place, &known);
if (NS_FAILED(rv)) {
@ -930,6 +935,17 @@ public:
}
return NS_OK;
}
lastFetchedPlace = &mPlaces.ElementAt(i);
}
// If any transition is typed, ensure the page is marked as typed.
if (typed != lastFetchedPlace->typed) {
place.typed = true;
}
// If any transition is visible, ensure the page is marked as visible.
if (hidden != lastFetchedPlace->hidden) {
place.hidden = false;
}
FetchReferrerInfo(referrer, place);
@ -953,8 +969,6 @@ public:
rv = NS_DispatchToMainThread(event);
NS_ENSURE_SUCCESS(rv, rv);
}
lastPlace = &mPlaces.ElementAt(i);
}
nsresult rv = transaction.Commit();
@ -2291,24 +2305,15 @@ History::FetchPageInfo(VisitData& _place, bool* _exists)
(_place.title.IsEmpty() && title.IsVoid()));
}
if (_place.hidden) {
// If this transition was hidden, it is possible that others were not.
// Any one visible transition makes this location visible. If database
// has location as visible, reflect that in our data structure.
int32_t hidden;
rv = stmt->GetInt32(3, &hidden);
NS_ENSURE_SUCCESS(rv, rv);
_place.hidden = !!hidden;
}
int32_t hidden;
rv = stmt->GetInt32(3, &hidden);
NS_ENSURE_SUCCESS(rv, rv);
_place.hidden = !!hidden;
if (!_place.typed) {
// If this transition wasn't typed, others might have been. If database
// has location as typed, reflect that in our data structure.
int32_t typed;
rv = stmt->GetInt32(4, &typed);
NS_ENSURE_SUCCESS(rv, rv);
_place.typed = !!typed;
}
int32_t typed;
rv = stmt->GetInt32(4, &typed);
NS_ENSURE_SUCCESS(rv, rv);
_place.typed = !!typed;
rv = stmt->GetInt32(5, &_place.frecency);
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -24,30 +24,28 @@ const RECENT_EVENT_THRESHOLD = 15 * 60 * 1000000;
* The time of the visit. Defaults to now if not provided.
*/
function VisitInfo(aTransitionType,
aVisitTime)
{
aVisitTime) {
this.transitionType =
aTransitionType === undefined ? TRANSITION_LINK : aTransitionType;
this.visitDate = aVisitTime || Date.now() * 1000;
}
function promiseUpdatePlaces(aPlaces) {
let deferred = Promise.defer();
PlacesUtils.asyncHistory.updatePlaces(aPlaces, {
_errors: [],
_results: [],
handleError: function handleError(aResultCode, aPlace) {
this._errors.push({ resultCode: aResultCode, info: aPlace});
},
handleResult: function handleResult(aPlace) {
this._results.push(aPlace);
},
handleCompletion: function handleCompletion() {
deferred.resolve({ errors: this._errors, results: this._results });
}
return new Promise((resolve, reject) => {
PlacesUtils.asyncHistory.updatePlaces(aPlaces, {
_errors: [],
_results: [],
handleError(aResultCode, aPlace) {
this._errors.push({ resultCode: aResultCode, info: aPlace});
},
handleResult(aPlace) {
this._results.push(aPlace);
},
handleCompletion() {
resolve({ errors: this._errors, results: this._results });
}
});
});
return deferred.promise;
}
/**
@ -63,18 +61,14 @@ function promiseUpdatePlaces(aPlaces) {
*/
function TitleChangedObserver(aURI,
aExpectedTitle,
aCallback)
{
aCallback) {
this.uri = aURI;
this.expectedTitle = aExpectedTitle;
this.callback = aCallback;
}
TitleChangedObserver.prototype = {
__proto__: NavHistoryObserver.prototype,
onTitleChanged: function(aURI,
aTitle,
aGUID)
{
onTitleChanged(aURI, aTitle, aGUID) {
do_log_info("onTitleChanged(" + aURI.spec + ", " + aTitle + ", " + aGUID + ")");
if (!this.uri.equals(aURI)) {
return;
@ -148,14 +142,12 @@ function do_check_title_for_uri(aURI,
////////////////////////////////////////////////////////////////////////////////
//// Test Functions
function test_interface_exists()
{
add_task(function* test_interface_exists() {
let history = Cc["@mozilla.org/browser/history;1"].getService(Ci.nsISupports);
do_check_true(history instanceof Ci.mozIAsyncHistory);
}
});
function test_invalid_uri_throws()
{
add_task(function* test_invalid_uri_throws() {
// First, test passing in nothing.
let place = {
visits: [
@ -188,10 +180,9 @@ function test_invalid_uri_throws()
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
}
}
}
});
function test_invalid_places_throws()
{
add_task(function* test_invalid_places_throws() {
// First, test passing in nothing.
try {
PlacesUtils.asyncHistory.updatePlaces();
@ -219,10 +210,9 @@ function test_invalid_places_throws()
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
}
}
}
});
function test_invalid_guid_throws()
{
add_task(function* test_invalid_guid_throws() {
// First check invalid length guid.
let place = {
guid: "BAD_GUID",
@ -249,10 +239,9 @@ function test_invalid_guid_throws()
catch (e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
}
}
});
function test_no_visits_throws()
{
add_task(function* test_no_visits_throws() {
const TEST_URI =
NetUtil.newURI(TEST_DOMAIN + "test_no_id_or_guid_no_visits_throws");
const TEST_GUID = "_RANDOMGUID_";
@ -290,10 +279,9 @@ function test_no_visits_throws()
}
}
}
}
});
function test_add_visit_no_date_throws()
{
add_task(function* test_add_visit_no_date_throws() {
let place = {
uri: NetUtil.newURI(TEST_DOMAIN + "test_add_visit_no_date_throws"),
visits: [
@ -308,10 +296,9 @@ function test_add_visit_no_date_throws()
catch (e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
}
}
});
function test_add_visit_no_transitionType_throws()
{
add_task(function* test_add_visit_no_transitionType_throws() {
let place = {
uri: NetUtil.newURI(TEST_DOMAIN + "test_add_visit_no_transitionType_throws"),
visits: [
@ -326,10 +313,9 @@ function test_add_visit_no_transitionType_throws()
catch (e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
}
}
});
function test_add_visit_invalid_transitionType_throws()
{
add_task(function* test_add_visit_invalid_transitionType_throws() {
// First, test something that has a transition type lower than the first one.
let place = {
uri: NetUtil.newURI(TEST_DOMAIN +
@ -355,10 +341,9 @@ function test_add_visit_invalid_transitionType_throws()
catch (e) {
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
}
}
});
function test_non_addable_uri_errors()
{
add_task(function* test_non_addable_uri_errors() {
// Array of protocols that nsINavHistoryService::canAddURI returns false for.
const URLS = [
"about:config",
@ -404,10 +389,9 @@ function test_non_addable_uri_errors()
do_check_false(yield promiseIsURIVisited(place.info.uri));
}
yield promiseAsyncUpdates();
}
});
function test_duplicate_guid_errors()
{
add_task(function* test_duplicate_guid_errors() {
// This test ensures that trying to add a visit, with a guid already found in
// another visit, fails.
let place = {
@ -443,10 +427,9 @@ function test_duplicate_guid_errors()
do_check_false(yield promiseIsURIVisited(badPlaceInfo.info.uri));
yield promiseAsyncUpdates();
}
});
function test_invalid_referrerURI_ignored()
{
add_task(function* test_invalid_referrerURI_ignored() {
let place = {
uri: NetUtil.newURI(TEST_DOMAIN +
"test_invalid_referrerURI_ignored"),
@ -480,10 +463,9 @@ function test_invalid_referrerURI_ignored()
stmt.finalize();
yield promiseAsyncUpdates();
}
});
function test_nonnsIURI_referrerURI_ignored()
{
add_task(function* test_nonnsIURI_referrerURI_ignored() {
let place = {
uri: NetUtil.newURI(TEST_DOMAIN +
"test_nonnsIURI_referrerURI_ignored"),
@ -513,10 +495,9 @@ function test_nonnsIURI_referrerURI_ignored()
stmt.finalize();
yield promiseAsyncUpdates();
}
});
function test_old_referrer_ignored()
{
add_task(function* test_old_referrer_ignored() {
// This tests that a referrer for a visit which is not recent (specifically,
// older than 15 minutes as per RECENT_EVENT_THRESHOLD) is not saved by
// updatePlaces.
@ -573,10 +554,9 @@ function test_old_referrer_ignored()
stmt.finalize();
yield promiseAsyncUpdates();
}
});
function test_place_id_ignored()
{
add_task(function* test_place_id_ignored() {
let place = {
uri: NetUtil.newURI(TEST_DOMAIN + "test_place_id_ignored_first"),
visits: [
@ -614,10 +594,9 @@ function test_place_id_ignored()
do_check_true(yield promiseIsURIVisited(badPlace.uri));
yield promiseAsyncUpdates();
}
});
function test_handleCompletion_called_when_complete()
{
add_task(function* test_handleCompletion_called_when_complete() {
// We test a normal visit, and embeded visit, and a uri that would fail
// the canAddURI test to make sure that the notification happens after *all*
// of them have had a callback.
@ -656,10 +635,9 @@ function test_handleCompletion_called_when_complete()
do_check_eq(callbackCountSuccess, EXPECTED_COUNT_SUCCESS);
do_check_eq(callbackCountFailure, EXPECTED_COUNT_FAILURE);
yield promiseAsyncUpdates();
}
});
function test_add_visit()
{
add_task(function* test_add_visit() {
const VISIT_TIME = Date.now() * 1000;
let place = {
uri: NetUtil.newURI(TEST_DOMAIN + "test_add_visit"),
@ -720,10 +698,9 @@ function test_add_visit()
yield promiseAsyncUpdates();
}
}
}
});
function test_properties_saved()
{
add_task(function* test_properties_saved() {
// Check each transition type to make sure it is saved properly.
let places = [];
for (let transitionType = TRANSITION_LINK;
@ -804,10 +781,9 @@ function test_properties_saved()
yield promiseAsyncUpdates();
}
}
}
});
function test_guid_saved()
{
add_task(function* test_guid_saved() {
let place = {
uri: NetUtil.newURI(TEST_DOMAIN + "test_guid_saved"),
guid: "__TESTGUID__",
@ -828,10 +804,9 @@ function test_guid_saved()
do_check_eq(placeInfo.guid, place.guid);
do_check_guid_for_uri(uri, place.guid);
yield promiseAsyncUpdates();
}
});
function test_referrer_saved()
{
add_task(function* test_referrer_saved() {
let places = [
{ uri: NetUtil.newURI(TEST_DOMAIN + "test_referrer_saved/referrer"),
visits: [
@ -881,10 +856,9 @@ function test_referrer_saved()
yield promiseAsyncUpdates();
}
}
}
});
function test_guid_change_saved()
{
add_task(function* test_guid_change_saved() {
// First, add a visit for it.
let place = {
uri: NetUtil.newURI(TEST_DOMAIN + "test_guid_change_saved"),
@ -908,10 +882,9 @@ function test_guid_change_saved()
do_check_guid_for_uri(place.uri, place.guid);
yield promiseAsyncUpdates();
}
});
function test_title_change_saved()
{
add_task(function* test_title_change_saved() {
// First, add a visit for it.
let place = {
uri: NetUtil.newURI(TEST_DOMAIN + "test_title_change_saved"),
@ -955,10 +928,9 @@ function test_title_change_saved()
do_check_title_for_uri(place.uri, place.title);
yield promiseAsyncUpdates();
}
});
function test_no_title_does_not_clear_title()
{
add_task(function* test_no_title_does_not_clear_title() {
const TITLE = "test title";
// First, add a visit for it.
let place = {
@ -984,10 +956,9 @@ function test_no_title_does_not_clear_title()
do_check_title_for_uri(place.uri, TITLE);
yield promiseAsyncUpdates();
}
});
function test_title_change_notifies()
{
add_task(function* test_title_change_notifies() {
// There are three cases to test. The first case is to make sure we do not
// get notified if we do not specify a title.
let place = {
@ -1015,36 +986,35 @@ function test_title_change_notifies()
place.uri = NetUtil.newURI(place.uri.spec + "/new-visit-with-title");
place.title = "title 1";
function promiseTitleChangedObserver(aPlace) {
let deferred = Promise.defer();
let callbackCount = 0;
let observer = new TitleChangedObserver(aPlace.uri, aPlace.title, function() {
switch (++callbackCount) {
case 1:
// The third case to test is to make sure we get a notification when
// we change an existing place.
observer.expectedTitle = place.title = "title 2";
place.visits = [new VisitInfo()];
PlacesUtils.asyncHistory.updatePlaces(place);
break;
case 2:
PlacesUtils.history.removeObserver(silentObserver);
PlacesUtils.history.removeObserver(observer);
deferred.resolve();
break;
};
});
return new Promise((resolve, reject) => {
let callbackCount = 0;
let observer = new TitleChangedObserver(aPlace.uri, aPlace.title, function() {
switch (++callbackCount) {
case 1:
// The third case to test is to make sure we get a notification when
// we change an existing place.
observer.expectedTitle = place.title = "title 2";
place.visits = [new VisitInfo()];
PlacesUtils.asyncHistory.updatePlaces(place);
break;
case 2:
PlacesUtils.history.removeObserver(silentObserver);
PlacesUtils.history.removeObserver(observer);
resolve();
break;
};
});
PlacesUtils.history.addObserver(observer, false);
PlacesUtils.asyncHistory.updatePlaces(aPlace);
return deferred.promise;
PlacesUtils.history.addObserver(observer, false);
PlacesUtils.asyncHistory.updatePlaces(aPlace);
});
}
yield promiseTitleChangedObserver(place);
yield promiseAsyncUpdates();
}
});
function test_visit_notifies()
{
add_task(function* test_visit_notifies() {
// There are two observers we need to see for each visit. One is an
// nsINavHistoryObserver and the other is the uri-visit-saved observer topic.
let place = {
@ -1057,44 +1027,43 @@ function test_visit_notifies()
do_check_false(yield promiseIsURIVisited(place.uri));
function promiseVisitObserver(aPlace) {
let deferred = Promise.defer();
let callbackCount = 0;
let finisher = function() {
if (++callbackCount == 2) {
deferred.resolve();
return new Promise((resolve, reject) => {
let callbackCount = 0;
let finisher = function() {
if (++callbackCount == 2) {
resolve();
}
}
}
let visitObserver = new VisitObserver(place.uri, place.guid,
function(aVisitDate,
aTransitionType) {
let visit = place.visits[0];
do_check_eq(visit.visitDate, aVisitDate);
do_check_eq(visit.transitionType, aTransitionType);
let visitObserver = new VisitObserver(place.uri, place.guid,
function(aVisitDate,
aTransitionType) {
let visit = place.visits[0];
do_check_eq(visit.visitDate, aVisitDate);
do_check_eq(visit.transitionType, aTransitionType);
PlacesUtils.history.removeObserver(visitObserver);
finisher();
PlacesUtils.history.removeObserver(visitObserver);
finisher();
});
PlacesUtils.history.addObserver(visitObserver, false);
let observer = function(aSubject, aTopic, aData) {
do_log_info("observe(" + aSubject + ", " + aTopic + ", " + aData + ")");
do_check_true(aSubject instanceof Ci.nsIURI);
do_check_true(aSubject.equals(place.uri));
Services.obs.removeObserver(observer, URI_VISIT_SAVED);
finisher();
};
Services.obs.addObserver(observer, URI_VISIT_SAVED, false);
PlacesUtils.asyncHistory.updatePlaces(place);
});
PlacesUtils.history.addObserver(visitObserver, false);
let observer = function(aSubject, aTopic, aData) {
do_log_info("observe(" + aSubject + ", " + aTopic + ", " + aData + ")");
do_check_true(aSubject instanceof Ci.nsIURI);
do_check_true(aSubject.equals(place.uri));
Services.obs.removeObserver(observer, URI_VISIT_SAVED);
finisher();
};
Services.obs.addObserver(observer, URI_VISIT_SAVED, false);
PlacesUtils.asyncHistory.updatePlaces(place);
return deferred.promise;
}
yield promiseVisitObserver(place);
yield promiseAsyncUpdates();
}
});
// test with empty mozIVisitInfoCallback object
function test_callbacks_not_supplied()
{
add_task(function* test_callbacks_not_supplied() {
const URLS = [
"imap://cyrus.andrew.cmu.edu/archive.imap", // bad URI
"http://mozilla.org/" // valid URI
@ -1121,40 +1090,36 @@ function test_callbacks_not_supplied()
PlacesUtils.asyncHistory.updatePlaces(places, {});
yield promiseAsyncUpdates();
}
});
////////////////////////////////////////////////////////////////////////////////
//// Test Runner
// Test that we don't wrongly overwrite typed and hidden when adding new visits.
add_task(function* test_typed_hidden_not_overwritten() {
yield PlacesTestUtils.clearHistory();
let places = [
{ uri: NetUtil.newURI("http://mozilla.org/"),
title: "test",
visits: [
new VisitInfo(TRANSITION_TYPED),
new VisitInfo(TRANSITION_LINK)
]
},
{ uri: NetUtil.newURI("http://mozilla.org/"),
title: "test",
visits: [
new VisitInfo(TRANSITION_FRAMED_LINK)
]
},
];
yield promiseUpdatePlaces(places);
[
test_interface_exists,
test_invalid_uri_throws,
test_invalid_places_throws,
test_invalid_guid_throws,
test_no_visits_throws,
test_add_visit_no_date_throws,
test_add_visit_no_transitionType_throws,
test_add_visit_invalid_transitionType_throws,
// Note: all asynchronous tests (every test below this point) should wait for
// async updates before calling run_next_test.
test_non_addable_uri_errors,
test_duplicate_guid_errors,
test_invalid_referrerURI_ignored,
test_nonnsIURI_referrerURI_ignored,
test_old_referrer_ignored,
test_place_id_ignored,
test_handleCompletion_called_when_complete,
test_add_visit,
test_properties_saved,
test_guid_saved,
test_referrer_saved,
test_guid_change_saved,
test_title_change_saved,
test_no_title_does_not_clear_title,
test_title_change_notifies,
test_visit_notifies,
test_callbacks_not_supplied,
].forEach(add_task);
let db = yield PlacesUtils.promiseDBConnection();
let rows = yield db.execute("SELECT hidden, typed FROM moz_places WHERE url = :url",
{ url: "http://mozilla.org/" });
Assert.equal(rows[0].getResultByName("typed"), 1,
"The page should be marked as typed");
Assert.equal(rows[0].getResultByName("hidden"), 0,
"The page should be marked as not hidden");
});
function run_test()
{

Просмотреть файл

@ -605,4 +605,11 @@
<children includes="menupopup"/>
</content>
</binding>
<binding id="menulist-popuponly" display="xul:menu"
extends="chrome://global/content/bindings/menulist.xml#menulist">
<content>
<children includes="menupopup"/>
</content>
</binding>
</bindings>

Просмотреть файл

@ -248,7 +248,7 @@
this.messageManager.addMessageListener("DOMFullscreen:RequestRollback", this);
this.messageManager.loadFrameScript("chrome://global/content/browser-child.js", true);
if (this.hasAttribute("selectpopup")) {
if (this.hasAttribute("selectmenulist")) {
this.messageManager.addMessageListener("Forms:ShowDropDown", this);
this.messageManager.addMessageListener("Forms:HideDropDown", this);
this.messageManager.loadFrameScript("chrome://global/content/select-child.js", true);
@ -310,9 +310,9 @@
case "Forms:ShowDropDown": {
Cu.import("resource://gre/modules/SelectParentHelper.jsm");
let dropdown = document.getElementById(this.getAttribute("selectpopup"));
SelectParentHelper.populate(dropdown, data.options, data.selectedIndex);
SelectParentHelper.open(this, dropdown, data.rect);
let menulist = document.getElementById(this.getAttribute("selectmenulist"));
SelectParentHelper.populate(menulist, data.options, data.selectedIndex);
SelectParentHelper.open(this, menulist, data.rect);
break;
}
@ -345,8 +345,8 @@
case "Forms:HideDropDown": {
Cu.import("resource://gre/modules/SelectParentHelper.jsm");
let dropdown = document.getElementById(this.getAttribute("selectpopup"));
SelectParentHelper.hide(dropdown);
let menulist = document.getElementById(this.getAttribute("selectmenulist"));
SelectParentHelper.hide(menulist);
break;
}

Просмотреть файл

@ -930,6 +930,14 @@ menulist {
-moz-binding: url("chrome://global/content/bindings/menulist.xml#menulist");
}
menulist[popuponly="true"] {
-moz-binding: url("chrome://global/content/bindings/menulist.xml#menulist-popuponly");
-moz-appearance: none !important;
margin: 0 !important;
height: 0 !important;
border: 0 !important;
}
menulist[editable="true"] {
-moz-binding: url("chrome://global/content/bindings/menulist.xml#menulist-editable");
}

Просмотреть файл

@ -1263,7 +1263,7 @@ BoxModelHighlighter.prototype = Heritage.extend(AutoRefreshHighlighter.prototype
}
let rect = this.currentQuads.border.bounds;
let dim = Math.ceil(rect.width) + " x " + Math.ceil(rect.height);
let dim = Math.ceil(rect.width) + " \u00D7 " + Math.ceil(rect.height);
let elementId = this.ID_CLASS_PREFIX + "nodeinfobar-";
this.markup.setTextContentForElement(elementId + "tagname", tagName);

Просмотреть файл

@ -136,7 +136,7 @@ let MemoryActor = protocol.ActorClass({
if (this.state == "attached") {
if (isTopLevel && this.dbg.memory.trackingAllocationSites) {
this._clearDebuggees();
nthis._frameCache.initFrames();
this._frameCache.initFrames();
}
this.dbg.addDebuggees();
}

Просмотреть файл

@ -500,6 +500,7 @@ let NetworkHelper = {
* - state: The security of the connection used to fetch this
* request. Has one of following string values:
* * "insecure": the connection was not secure (only http)
* * "weak": the connection has minor security issues
* * "broken": secure connection failed (e.g. expired cert)
* * "secure": the connection was properly secured.
* If state == broken:
@ -511,6 +512,9 @@ let NetworkHelper = {
* See parseCertificateInfo for the contents.
* - hsts: true if host uses Strict Transport Security, false otherwise
* - hpkp: true if host uses Public Key Pinning, false otherwise
* If state == weak: Same as state == secure and
* - weaknessReasons: list of reasons that cause the request to be
* considered weak. See getReasonsForWeakness.
*/
parseSecurityInfo: function NH_parseSecurityInfo(securityInfo, httpActivity) {
const info = {
@ -551,7 +555,7 @@ let NetworkHelper = {
* => .securityState has STATE_IS_BROKEN flag
* => .errorCode is NOT an NSS error code
* => .errorMessage is not available
* => state === "insecure"
* => state === "weak"
*/
securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
@ -561,10 +565,26 @@ let NetworkHelper = {
const NSSErrorsService = Cc['@mozilla.org/nss_errors_service;1']
.getService(Ci.nsINSSErrorsService);
const SSLStatus = securityInfo.SSLStatus;
if (!NSSErrorsService.isNSSErrorCode(securityInfo.errorCode)) {
const state = securityInfo.securityState;
if (securityInfo.securityState & wpl.STATE_IS_SECURE) {
// The connection is secure.
info.state = "secure";
if (state & wpl.STATE_IS_SECURE) {
// The connection is secure.
info.state = "secure";
} else if (state & wpl.STATE_IS_BROKEN) {
// The connection is not secure, there was no error but there's some
// minor security issues.
info.state = "weak";
info.weaknessReasons = this.getReasonsForWeakness(state);
} else if (state & wpl.STATE_IS_INSECURE) {
// This was most likely an https request that was aborted before
// validation. Return info as info.state = insecure.
return info;
} else {
DevToolsUtils.reportException("NetworkHelper.parseSecurityInfo",
"Security state " + state + " has no known STATE_IS_* flags.");
return info;
}
// Cipher suite.
info.cipherSuite = SSLStatus.cipherName;
@ -598,14 +618,10 @@ let NetworkHelper = {
info.hpkp = false;
}
} else if (NSSErrorsService.isNSSErrorCode(securityInfo.errorCode)) {
} else {
// The connection failed.
info.state = "broken";
info.errorMessage = securityInfo.errorMessage;
} else {
// Connection has securityInfo, it is not secure and there's no problems
// to report. Mark the request as insecure.
return info;
}
return info;
@ -683,6 +699,46 @@ let NetworkHelper = {
return "Unknown";
}
},
/**
* Takes the securityState bitfield and returns reasons for weak connection
* as an array of strings.
*
* @param Number state
* nsITransportSecurityInfo.securityState.
*
* @return Array[String]
* List of weakness reasons. A subset of { cipher, sslv3 } where
* * cipher: The cipher suite is consireded to be weak (RC4).
* * sslv3: The protocol, SSLv3, is weak.
*/
getReasonsForWeakness: function NH_getReasonsForWeakness(state) {
const wpl = Ci.nsIWebProgressListener;
// If there's non-fatal security issues the request has STATE_IS_BROKEN
// flag set. See http://hg.mozilla.org/mozilla-central/file/44344099d119
// /security/manager/ssl/src/nsNSSCallbacks.cpp#l1233
let reasons = [];
if (state & wpl.STATE_IS_BROKEN) {
let isSSLV3 = state & wpl.STATE_USES_SSL_3;
let isCipher = state & wpl.STATE_USES_WEAK_CRYPTO;
if (isSSLV3) {
reasons.push("sslv3");
}
if (isCipher) {
reasons.push("cipher");
}
if (!isCipher && !isSSLV3) {
DevToolsUtils.reportException("NetworkHelper.getReasonsForWeakness",
"STATE_IS_BROKEN without a known reason. Full state was: " + state);
}
}
return reasons;
},
};
for (let prop of Object.getOwnPropertyNames(NetworkHelper)) {

Просмотреть файл

@ -89,12 +89,12 @@ function test_secureSecurityInfo() {
}
/**
* Test that STATE_IS_BROKEN returns "insecure"
* Test that STATE_IS_BROKEN returns "weak"
*/
function test_brokenSecurityInfo() {
MockSecurityInfo.securityState = wpl.STATE_IS_BROKEN;
let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {});
equal(result.state, "insecure",
"state == 'insecure' if securityState contains STATE_IS_BROKEN flag");
equal(result.state, "weak",
"state == 'weak' if securityState contains STATE_IS_BROKEN flag");
}

Просмотреть файл

@ -0,0 +1,55 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that NetworkHelper.getReasonsForWeakness returns correct reasons for
// weak requests.
const { devtools } = Components.utils.import("resource://gre/modules/devtools/Loader.jsm", {});
Object.defineProperty(this, "NetworkHelper", {
get: function() {
return devtools.require("devtools/toolkit/webconsole/network-helper");
},
configurable: true,
writeable: false,
enumerable: true
});
const Ci = Components.interfaces;
const wpl = Ci.nsIWebProgressListener;
const TEST_CASES = [
{
description: "weak cipher",
input: wpl.STATE_IS_BROKEN | wpl.STATE_USES_WEAK_CRYPTO,
expected: ["cipher"]
}, {
description: "weak sslv3 protocol",
input: wpl.STATE_IS_BROKEN | wpl.STATE_USES_SSL_3,
expected: ["sslv3"]
}, {
description: "weak cipher + sslv3",
input: wpl.STATE_IS_BROKEN | wpl.STATE_USES_WEAK_CRYPTO | wpl.STATE_USES_SSL_3,
expected: ["sslv3", "cipher"] // order matters for deepEqual
}, {
description: "only STATE_IS_BROKEN flag",
input: wpl.STATE_IS_BROKEN,
expected: []
}, {
description: "only STATE_IS_SECURE flag",
input: wpl.STATE_IS_SECURE,
expected: []
},
];
function run_test() {
do_print("Testing NetworkHelper.getReasonsForWeakness.");
for (let {description, input, expected} of TEST_CASES) {
do_print("Testing " + description);
deepEqual(NetworkHelper.getReasonsForWeakness(input), expected,
"Got the expected reasons for weakness.");
}
}

Просмотреть файл

@ -11,3 +11,4 @@ support-files =
[test_security-info-protocol-version.js]
[test_security-info-state.js]
[test_security-info-static-hpkp.js]
[test_security-info-weakness-reasons.js]

Просмотреть файл

@ -11,27 +11,35 @@ this.EXPORTED_SYMBOLS = [
let currentBrowser = null;
this.SelectParentHelper = {
populate: function(popup, items, selectedIndex) {
populate: function(menulist, items, selectedIndex) {
// Clear the current contents of the popup
popup.textContent = "";
populateChildren(popup, items, selectedIndex);
menulist.menupopup.textContent = "";
populateChildren(menulist.menupopup, items, selectedIndex);
// We expect the parent element of the popup to be a <xul:menulist> that
// has the popuponly attribute set to "true". This is necessary in order
// for a <xul:menupopup> to act like a proper <html:select> dropdown, as
// the <xul:menulist> does things like remember state and set the
// _moz-menuactive attribute on the selected <xul:menuitem>.
menulist.selectedIndex = selectedIndex;
},
open: function(browser, popup, rect) {
open: function(browser, menulist, rect) {
menulist.hidden = false;
currentBrowser = browser;
this._registerListeners(popup);
popup.hidden = false;
this._registerListeners(menulist.menupopup);
let {x, y} = browser.mapScreenCoordinatesFromContent(rect.left, rect.top + rect.height);
popup.openPopupAtScreen(x, y);
menulist.menupopup.openPopupAtScreen(x, y);
menulist.selectedItem.scrollIntoView();
},
hide: function(popup) {
popup.hidePopup();
hide: function(menulist) {
menulist.menupopup.hidePopup();
},
handleEvent: function(event) {
let popup = event.currentTarget;
let menulist = popup.parentNode;
switch (event.type) {
case "command":
@ -47,6 +55,7 @@ this.SelectParentHelper = {
currentBrowser.messageManager.sendAsyncMessage("Forms:DismissedDropDown", {});
currentBrowser = null;
this._unregisterListeners(popup);
menulist.hidden = true;
break;
}
},
@ -69,11 +78,6 @@ function populateChildren(element, options, selectedIndex, startIndex = 0, isGro
for (let option of options) {
let item = element.ownerDocument.createElement("menuitem");
item.setAttribute("label", option.textContent);
item.setAttribute("type", "radio");
if (index == selectedIndex) {
item.setAttribute("checked", "true");
}
element.appendChild(item);

Просмотреть файл

@ -8,11 +8,14 @@
menulist {
-moz-appearance: menulist;
margin: 5px 2px 3px;
min-height: 20px !important;
color: -moz-DialogText;
text-shadow: none;
}
menulist:not([popuponly="true"]) {
min-height: 20px !important;
}
.menulist-label-box {
-moz-appearance: menulist-text;
-moz-box-align: center;