зеркало из https://github.com/mozilla/gecko-dev.git
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:
Коммит
e523c1b047
|
@ -693,65 +693,50 @@ pref("dom.ipc.processPriorityManager.backgroundLRUPoolLevels", 5);
|
||||||
// Kernel parameters for process priorities. These affect how processes are
|
// Kernel parameters for process priorities. These affect how processes are
|
||||||
// killed on low-memory and their relative CPU priorities.
|
// 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
|
// The kernel can only accept 6 (OomScoreAdjust, KillUnderKB) pairs. But it is
|
||||||
// okay, kernel will still kill processes with larger OomScoreAdjust first even
|
// okay, kernel will still kill processes with larger OomScoreAdjust first even
|
||||||
// its OomScoreAdjust don't have a corresponding KillUnderKB.
|
// its OomScoreAdjust don't have a corresponding KillUnderKB.
|
||||||
|
|
||||||
pref("hal.processPriorityManager.gonk.MASTER.OomScoreAdjust", 0);
|
pref("hal.processPriorityManager.gonk.MASTER.OomScoreAdjust", 0);
|
||||||
pref("hal.processPriorityManager.gonk.MASTER.KillUnderKB", 4096);
|
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.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.OomScoreAdjust", 67);
|
||||||
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.KillUnderKB", 5120);
|
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.OomScoreAdjust", 134);
|
||||||
pref("hal.processPriorityManager.gonk.FOREGROUND.KillUnderKB", 6144);
|
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.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.OomScoreAdjust", 400);
|
||||||
pref("hal.processPriorityManager.gonk.BACKGROUND_PERCEIVABLE.KillUnderKB", 7168);
|
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.OomScoreAdjust", 534);
|
||||||
pref("hal.processPriorityManager.gonk.BACKGROUND_HOMESCREEN.KillUnderKB", 8192);
|
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.OomScoreAdjust", 667);
|
||||||
pref("hal.processPriorityManager.gonk.BACKGROUND.KillUnderKB", 20480);
|
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.
|
// Processes get this niceness when they have low CPU priority.
|
||||||
//
|
pref("hal.processPriorityManager.gonk.LowCPUNice", 18);
|
||||||
// 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);
|
|
||||||
|
|
||||||
// By default the compositor thread on gonk runs without real-time priority. RT
|
// 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.
|
// priority can be enabled by setting this pref to a value between 1 and 99.
|
||||||
|
|
|
@ -4,15 +4,23 @@
|
||||||
/* jshint moz: true */
|
/* jshint moz: true */
|
||||||
/* global Uint8Array, Components, dump */
|
/* 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_KEY_MAX = 32;
|
||||||
const SYSTEM_PROPERTY_VALUE_MAX = 92;
|
const SYSTEM_PROPERTY_VALUE_MAX = 92;
|
||||||
|
|
||||||
function debug(msg) {
|
function debug(msg) {
|
||||||
dump('LogCapture.jsm: ' + msg + '\n');
|
dump("LogCapture.jsm: " + msg + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
let LogCapture = {
|
let LogCapture = {
|
||||||
|
@ -24,11 +32,11 @@ let LogCapture = {
|
||||||
|
|
||||||
load: function() {
|
load: function() {
|
||||||
// load in everything on first use
|
// 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.default_abi,
|
||||||
this.ctypes.int, // bytes read (out)
|
this.ctypes.int, // bytes read (out)
|
||||||
this.ctypes.int, // file descriptor (in)
|
this.ctypes.int, // file descriptor (in)
|
||||||
|
@ -36,19 +44,24 @@ let LogCapture = {
|
||||||
this.ctypes.size_t // size_t size of buffer (in)
|
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.default_abi,
|
||||||
this.ctypes.int, // file descriptor (returned)
|
this.ctypes.int, // file descriptor (returned)
|
||||||
this.ctypes.char.ptr, // path
|
this.ctypes.char.ptr, // path
|
||||||
this.ctypes.int // flags
|
this.ctypes.int // flags
|
||||||
);
|
);
|
||||||
|
|
||||||
this.close = this.libc.declare('close',
|
this.close = this.libc.declare("close",
|
||||||
this.ctypes.default_abi,
|
this.ctypes.default_abi,
|
||||||
this.ctypes.int, // error code (returned)
|
this.ctypes.int, // error code (returned)
|
||||||
this.ctypes.int // file descriptor
|
this.ctypes.int // file descriptor
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.getpid = this.libc.declare("getpid",
|
||||||
|
this.ctypes.default_abi,
|
||||||
|
this.ctypes.int // PID
|
||||||
|
);
|
||||||
|
|
||||||
this.property_find_nth =
|
this.property_find_nth =
|
||||||
this.libc.declare("__system_property_find_nth",
|
this.libc.declare("__system_property_find_nth",
|
||||||
this.ctypes.default_abi,
|
this.ctypes.default_abi,
|
||||||
|
@ -153,6 +166,26 @@ let LogCapture = {
|
||||||
}
|
}
|
||||||
|
|
||||||
return propertyDict;
|
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,
|
/* global Services, Components, dump, LogCapture, LogParser,
|
||||||
OS, Promise, volumeService, XPCOMUtils, SystemAppProxy */
|
OS, Promise, volumeService, XPCOMUtils, SystemAppProxy */
|
||||||
|
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
const Ci = Components.interfaces;
|
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, "LogCapture", "resource://gre/modules/LogCapture.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, 'LogParser', 'resource://gre/modules/LogParser.jsm');
|
XPCOMUtils.defineLazyModuleGetter(this, "LogParser", "resource://gre/modules/LogParser.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, 'OS', 'resource://gre/modules/osfile.jsm');
|
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, 'Promise', 'resource://gre/modules/Promise.jsm');
|
XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, 'Services', 'resource://gre/modules/Services.jsm');
|
XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, 'SystemAppProxy', 'resource://gre/modules/SystemAppProxy.jsm');
|
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", "resource://gre/modules/SystemAppProxy.jsm");
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, 'powerManagerService',
|
XPCOMUtils.defineLazyServiceGetter(this, "powerManagerService",
|
||||||
'@mozilla.org/power/powermanagerservice;1',
|
"@mozilla.org/power/powermanagerservice;1",
|
||||||
'nsIPowerManagerService');
|
"nsIPowerManagerService");
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, 'volumeService',
|
XPCOMUtils.defineLazyServiceGetter(this, "volumeService",
|
||||||
'@mozilla.org/telephony/volume-service;1',
|
"@mozilla.org/telephony/volume-service;1",
|
||||||
'nsIVolumeService');
|
"nsIVolumeService");
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ['LogShake'];
|
this.EXPORTED_SYMBOLS = ["LogShake"];
|
||||||
|
|
||||||
function debug(msg) {
|
function debug(msg) {
|
||||||
dump('LogShake.jsm: '+msg+'\n');
|
dump("LogShake.jsm: "+msg+"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,11 +54,11 @@ function debug(msg) {
|
||||||
* shake
|
* shake
|
||||||
*/
|
*/
|
||||||
const EXCITEMENT_THRESHOLD = 500;
|
const EXCITEMENT_THRESHOLD = 500;
|
||||||
const DEVICE_MOTION_EVENT = 'devicemotion';
|
const DEVICE_MOTION_EVENT = "devicemotion";
|
||||||
const SCREEN_CHANGE_EVENT = 'screenchange';
|
const SCREEN_CHANGE_EVENT = "screenchange";
|
||||||
const CAPTURE_LOGS_START_EVENT = 'capture-logs-start';
|
const CAPTURE_LOGS_START_EVENT = "capture-logs-start";
|
||||||
const CAPTURE_LOGS_ERROR_EVENT = 'capture-logs-error';
|
const CAPTURE_LOGS_ERROR_EVENT = "capture-logs-error";
|
||||||
const CAPTURE_LOGS_SUCCESS_EVENT = 'capture-logs-success';
|
const CAPTURE_LOGS_SUCCESS_EVENT = "capture-logs-success";
|
||||||
|
|
||||||
let LogShake = {
|
let LogShake = {
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
|
||||||
|
@ -79,17 +79,18 @@ let LogShake = {
|
||||||
* Map of files which have log-type information to their parsers
|
* Map of files which have log-type information to their parsers
|
||||||
*/
|
*/
|
||||||
LOGS_WITH_PARSERS: {
|
LOGS_WITH_PARSERS: {
|
||||||
'/dev/log/main': LogParser.prettyPrintLogArray,
|
"/dev/log/main": LogParser.prettyPrintLogArray,
|
||||||
'/dev/log/system': LogParser.prettyPrintLogArray,
|
"/dev/log/system": LogParser.prettyPrintLogArray,
|
||||||
'/dev/log/radio': LogParser.prettyPrintLogArray,
|
"/dev/log/radio": LogParser.prettyPrintLogArray,
|
||||||
'/dev/log/events': LogParser.prettyPrintLogArray,
|
"/dev/log/events": LogParser.prettyPrintLogArray,
|
||||||
'/proc/cmdline': LogParser.prettyPrintArray,
|
"/proc/cmdline": LogParser.prettyPrintArray,
|
||||||
'/proc/kmsg': LogParser.prettyPrintArray,
|
"/proc/kmsg": LogParser.prettyPrintArray,
|
||||||
'/proc/meminfo': LogParser.prettyPrintArray,
|
"/proc/meminfo": LogParser.prettyPrintArray,
|
||||||
'/proc/uptime': LogParser.prettyPrintArray,
|
"/proc/uptime": LogParser.prettyPrintArray,
|
||||||
'/proc/version': LogParser.prettyPrintArray,
|
"/proc/version": LogParser.prettyPrintArray,
|
||||||
'/proc/vmallocinfo': LogParser.prettyPrintArray,
|
"/proc/vmallocinfo": LogParser.prettyPrintArray,
|
||||||
'/proc/vmstat': 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);
|
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
|
* Handle an observation from Services.obs
|
||||||
*/
|
*/
|
||||||
observe: function(subject, topic) {
|
observe: function(subject, topic) {
|
||||||
if (topic === 'xpcom-shutdown') {
|
if (topic === "xpcom-shutdown") {
|
||||||
this.uninit();
|
this.uninit();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -152,8 +153,8 @@ let LogShake = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a motion event, keeping track of 'excitement', the magnitude
|
* Handle a motion event, keeping track of "excitement", the magnitude
|
||||||
* of the device's acceleration.
|
* of the device"s acceleration.
|
||||||
*/
|
*/
|
||||||
handleDeviceMotionEvent: function(event) {
|
handleDeviceMotionEvent: function(event) {
|
||||||
// There is a lag between disabling the event listener and event arrival
|
// 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);
|
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) {
|
for (let loc in this.LOGS_WITH_PARSERS) {
|
||||||
let logArray;
|
let logArray;
|
||||||
try {
|
try {
|
||||||
logArray = LogCapture.readLogFile(loc);
|
logArray = LogCapture.readLogFile(loc);
|
||||||
if (!logArray) {
|
if (!logArray) {
|
||||||
|
debug("LogCapture.readLogFile() returned nothing for: " + loc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
|
@ -245,32 +268,40 @@ let LogShake = {
|
||||||
uninit: function() {
|
uninit: function() {
|
||||||
this.stopDeviceMotionListener();
|
this.stopDeviceMotionListener();
|
||||||
SystemAppProxy.removeEventListener(SCREEN_CHANGE_EVENT, this, false);
|
SystemAppProxy.removeEventListener(SCREEN_CHANGE_EVENT, this, false);
|
||||||
Services.obs.removeObserver(this, 'xpcom-shutdown');
|
Services.obs.removeObserver(this, "xpcom-shutdown");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function getLogFilename(logLocation) {
|
function getLogFilename(logLocation) {
|
||||||
// sanitize the log location
|
// sanitize the log location
|
||||||
let logName = logLocation.replace(/\//g, '-');
|
let logName = logLocation.replace(/\//g, "-");
|
||||||
if (logName[0] === '-') {
|
if (logName[0] === "-") {
|
||||||
logName = logName.substring(1);
|
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() {
|
function getSdcardPrefix() {
|
||||||
return volumeService.getVolumeByName('sdcard').mountPoint;
|
return volumeService.getVolumeByName("sdcard").mountPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLogDirectoryRoot() {
|
function getLogDirectoryRoot() {
|
||||||
return 'logs';
|
return "logs";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLogDirectory() {
|
function getLogDirectory() {
|
||||||
let d = new Date();
|
let d = new Date();
|
||||||
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000);
|
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000);
|
||||||
let timestamp = d.toISOString().slice(0, -5).replace(/[:T]/g, '-');
|
let timestamp = d.toISOString().slice(0, -5).replace(/[:T]/g, "-");
|
||||||
// return directory name of format 'logs/timestamp/'
|
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +312,7 @@ function saveLogs(logArrays) {
|
||||||
if (!logArrays || Object.keys(logArrays).length === 0) {
|
if (!logArrays || Object.keys(logArrays).length === 0) {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
logFilenames: [],
|
logFilenames: [],
|
||||||
logPrefix: ''
|
logPrefix: ""
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,19 +327,24 @@ function saveLogs(logArrays) {
|
||||||
return Promise.reject(e);
|
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);
|
let logsRoot = OS.Path.join(sdcardPrefix, dirNameRoot);
|
||||||
return OS.File.makeDir(logsRoot, {from: sdcardPrefix}).then(
|
return OS.File.makeDir(logsRoot, {from: sdcardPrefix}).then(
|
||||||
function() {
|
function() {
|
||||||
|
debug("First OS.File.makeDir done");
|
||||||
let logsDir = OS.Path.join(logsRoot, dirName);
|
let logsDir = OS.Path.join(logsRoot, dirName);
|
||||||
|
debug("Creating " + logsDir);
|
||||||
return OS.File.makeDir(logsDir, {ignoreExisting: false}).then(
|
return OS.File.makeDir(logsDir, {ignoreExisting: false}).then(
|
||||||
function() {
|
function() {
|
||||||
|
debug("Created: " + logsDir);
|
||||||
// Now the directory is guaranteed to exist, save the logs
|
// Now the directory is guaranteed to exist, save the logs
|
||||||
let logFilenames = [];
|
let logFilenames = [];
|
||||||
let saveRequests = [];
|
let saveRequests = [];
|
||||||
|
|
||||||
|
debug("Will now traverse logArrays: " + logArrays.length);
|
||||||
|
|
||||||
for (let logLocation in logArrays) {
|
for (let logLocation in logArrays) {
|
||||||
debug('requesting save of ' + logLocation);
|
debug("requesting save of " + logLocation);
|
||||||
let logArray = logArrays[logLocation];
|
let logArray = logArrays[logLocation];
|
||||||
// The filename represents the relative path within the SD card, not the
|
// The filename represents the relative path within the SD card, not the
|
||||||
// absolute path because Gaia will refer to it using the DeviceStorage
|
// absolute path because Gaia will refer to it using the DeviceStorage
|
||||||
|
@ -321,13 +357,22 @@ function saveLogs(logArrays) {
|
||||||
|
|
||||||
return Promise.all(saveRequests).then(
|
return Promise.all(saveRequests).then(
|
||||||
function() {
|
function() {
|
||||||
debug('returning logfilenames: '+logFilenames.toSource());
|
debug("returning logfilenames: "+logFilenames.toSource());
|
||||||
return {
|
return {
|
||||||
logFilenames: logFilenames,
|
logFilenames: logFilenames,
|
||||||
logPrefix: OS.Path.join(dirNameRoot, dirName)
|
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
|
* Testing non Gonk-specific code path
|
||||||
* a Uint8Array of some length, including zero. This tests a few standard
|
|
||||||
* log devices
|
|
||||||
*/
|
*/
|
||||||
function run_test() {
|
function run_test() {
|
||||||
Components.utils.import("resource:///modules/LogCapture.jsm");
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
head = head_identity.js
|
||||||
tail =
|
tail =
|
||||||
|
|
||||||
|
# testing non gonk-specific stuff
|
||||||
[test_logcapture.js]
|
[test_logcapture.js]
|
||||||
|
|
||||||
|
[test_logcapture_gonk.js]
|
||||||
# only run on b2g builds due to requiring b2g-specific log files to exist
|
# only run on b2g builds due to requiring b2g-specific log files to exist
|
||||||
skip-if = toolkit != "gonk"
|
skip-if = toolkit != "gonk"
|
||||||
|
|
||||||
[test_logparser.js]
|
[test_logparser.js]
|
||||||
|
|
||||||
[test_logshake.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">
|
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</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="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<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_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="f7d9bf71cf6693474f3f2a81a4ba62c0fc5646aa"/>
|
||||||
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="cfcef469537869947abb9aa1d656774cc2678d4c"/>
|
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="cfcef469537869947abb9aa1d656774cc2678d4c"/>
|
||||||
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
|
<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/extras" path="system/extras" revision="10e78a05252b3de785f88c2d0b9ea8a428009c50"/>
|
||||||
<project name="platform/system/media" path="system/media" revision="7ff72c2ea2496fa50b5e8a915e56e901c3ccd240"/>
|
<project name="platform/system/media" path="system/media" revision="7ff72c2ea2496fa50b5e8a915e56e901c3ccd240"/>
|
||||||
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
|
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<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="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<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="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d6a27295acb0a25926bf6290dd2532a7f9027864"/>
|
<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/sdk" path="prebuilts/sdk" revision="842e33e43a55ea44833b9e23e4d180fa17c843af"/>
|
||||||
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5db24726f0f42124304195a6bdea129039eeeaeb"/>
|
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5db24726f0f42124304195a6bdea129039eeeaeb"/>
|
||||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="930ae098543881f47eac054677726ee4b998b2f8"/>
|
<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_core" path="system/core" remote="b2g" revision="542d1f59dc331b472307e5bd043101d14d5a3a3e"/>
|
||||||
<project name="platform/system/extras" path="system/extras" revision="18c1180e848e7ab8691940481f5c1c8d22c37b3e"/>
|
<project name="platform/system/extras" path="system/extras" revision="18c1180e848e7ab8691940481f5c1c8d22c37b3e"/>
|
||||||
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
|
<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_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/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_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="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
|
||||||
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
|
<project name="darwinstreamingserver" path="system/darwinstreamingserver" remote="b2g" revision="cf85968c7f85e0ec36e72c87ceb4837a943b8af6"/>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
|
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</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="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<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_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="f7d9bf71cf6693474f3f2a81a4ba62c0fc5646aa"/>
|
||||||
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/>
|
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="b562b01c93de9578d5db537b6a602a38e1aaa0ce"/>
|
||||||
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="387f03e815f57d536dd922706db1622bddba8d81"/>
|
<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/extras" path="system/extras" revision="5356165f67f4a81c2ef28671c13697f1657590df"/>
|
||||||
<project name="platform/system/media" path="system/media" revision="be0e2fe59a8043fa5200f75697df9220a99abe9d"/>
|
<project name="platform/system/media" path="system/media" revision="be0e2fe59a8043fa5200f75697df9220a99abe9d"/>
|
||||||
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
|
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<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="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
<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">
|
<project name="platform_build" path="build" remote="b2g" revision="e06971db7acf7a35c32eb74d675a4e12e288e6be">
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</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="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<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_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="f7d9bf71cf6693474f3f2a81a4ba62c0fc5646aa"/>
|
||||||
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/>
|
<project name="platform/prebuilts/sdk" path="prebuilts/sdk" revision="69d524e80cdf3981006627c65ac85f3a871238a3"/>
|
||||||
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5a48c04c4bb5f079bc757e29864a42427378e051"/>
|
<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/extras" path="system/extras" revision="576f57b6510de59c08568b53c0fb60588be8689e"/>
|
||||||
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
|
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
|
||||||
<project name="platform/system/netd" path="system/netd" revision="a6531f7befb49b1c81bc0de7e51c5482b308e1c5"/>
|
<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/qcom/wlan" path="hardware/qcom/wlan" revision="57ee1320ed7b4a1a1274d8f3f6c177cd6b9becb2"/>
|
||||||
<project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/>
|
<project name="platform/hardware/ril" path="hardware/ril" revision="12b1977cc704b35f2e9db2bb423fa405348bc2f3"/>
|
||||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/>
|
<project name="platform/system/bluetooth" path="system/bluetooth" revision="985bf15264d865fe7b9c5b45f61c451cbaafa43d"/>
|
||||||
<project name="platform/system/core" path="system/core" revision="350eac5403124dacb2a5fd9e28ac290a59fc3b8e"/>
|
<project name="platform/system/core" path="system/core" revision="42839aedcf70bf6bc92a3b7ea4a5cc9bf9aef3f9"/>
|
||||||
<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="63e3f6f176caad587d42bba4c16b66d953fb23c2"/>
|
<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-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="d8952a42771045fca73ec600e2b42a4c7129d723"/>
|
||||||
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4c187c1f3a0dffd8e51a961735474ea703535b99"/>
|
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4c187c1f3a0dffd8e51a961735474ea703535b99"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<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="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d6a27295acb0a25926bf6290dd2532a7f9027864"/>
|
<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/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
|
||||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
|
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
|
||||||
<project name="platform/system/core" path="system/core" revision="adc485d8755af6a61641d197de7cfef667722580"/>
|
<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/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
|
||||||
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
|
<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"/>
|
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"git": {
|
"git": {
|
||||||
"git_revision": "1eedbee8f26efbaa4a113e002c46f64e9b90249d",
|
"git_revision": "1d53fb07984298253aad64bfa4236b7167ee3d4d",
|
||||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||||
"branch": ""
|
"branch": ""
|
||||||
},
|
},
|
||||||
"revision": "080bbea403be57fffcbb800eb6f7e2fcd0b4c7d2",
|
"revision": "08a288892d8f0b41a960104150fba34f113629e6",
|
||||||
"repo_path": "integration/gaia-central"
|
"repo_path": "integration/gaia-central"
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<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="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<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="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</project>
|
</project>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
<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="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d6a27295acb0a25926bf6290dd2532a7f9027864"/>
|
<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/sdk" path="prebuilts/sdk" revision="842e33e43a55ea44833b9e23e4d180fa17c843af"/>
|
||||||
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5db24726f0f42124304195a6bdea129039eeeaeb"/>
|
<project name="platform/prebuilts/tools" path="prebuilts/tools" revision="5db24726f0f42124304195a6bdea129039eeeaeb"/>
|
||||||
<project name="platform/system/bluetooth" path="system/bluetooth" revision="930ae098543881f47eac054677726ee4b998b2f8"/>
|
<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_core" path="system/core" remote="b2g" revision="542d1f59dc331b472307e5bd043101d14d5a3a3e"/>
|
||||||
<project name="platform/system/extras" path="system/extras" revision="18c1180e848e7ab8691940481f5c1c8d22c37b3e"/>
|
<project name="platform/system/extras" path="system/extras" revision="18c1180e848e7ab8691940481f5c1c8d22c37b3e"/>
|
||||||
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="8fcd25d64f0f67d1a6f7037a4c83ce6d95466770"/>
|
<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-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/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="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/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/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||||
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>
|
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||||
</project>
|
</project>
|
||||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
<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="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
|
||||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||||
|
|
|
@ -26,8 +26,6 @@ let gDataNotificationInfoBar = {
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
window.addEventListener("unload", function onUnload() {
|
window.addEventListener("unload", function onUnload() {
|
||||||
window.removeEventListener("unload", onUnload, false);
|
|
||||||
|
|
||||||
for (let o of this._OBSERVERS) {
|
for (let o of this._OBSERVERS) {
|
||||||
Services.obs.removeObserver(this, o);
|
Services.obs.removeObserver(this, o);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1012,8 +1012,8 @@ chatbox:-moz-full-screen-ancestor > .chat-titlebar {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Combobox dropdown renderer */
|
/* Combobox dropdown renderer */
|
||||||
#ContentSelectDropdown {
|
#ContentSelectDropdown > menupopup {
|
||||||
-moz-binding: url("chrome://global/content/bindings/popup.xml#popup-scrollbars");
|
max-height: 350px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contentSelectDropdown-optgroup {
|
.contentSelectDropdown-optgroup {
|
||||||
|
|
|
@ -146,8 +146,13 @@
|
||||||
<!-- for url bar autocomplete -->
|
<!-- for url bar autocomplete -->
|
||||||
<panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
|
<panel type="autocomplete-richlistbox" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
|
||||||
|
|
||||||
<!-- for select dropdowns -->
|
<!-- for select dropdowns. The menupopup is what shows the list of options,
|
||||||
<menupopup id="ContentSelectDropdown" rolluponmousewheel="true" hidden="true"/>
|
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 -->
|
<!-- for invalid form error message -->
|
||||||
<panel id="invalid-form-popup" type="arrow" orient="vertical" noautofocus="true" hidden="true" level="parent">
|
<panel id="invalid-form-popup" type="arrow" orient="vertical" noautofocus="true" hidden="true" level="parent">
|
||||||
|
@ -1169,7 +1174,7 @@
|
||||||
tabcontainer="tabbrowser-tabs"
|
tabcontainer="tabbrowser-tabs"
|
||||||
contentcontextmenu="contentAreaContextMenu"
|
contentcontextmenu="contentAreaContextMenu"
|
||||||
autocompletepopup="PopupAutoComplete"
|
autocompletepopup="PopupAutoComplete"
|
||||||
selectpopup="ContentSelectDropdown"/>
|
selectmenulist="ContentSelectDropdown"/>
|
||||||
<chatbar id="pinnedchats" layer="true" mousethrough="always" hidden="true"/>
|
<chatbar id="pinnedchats" layer="true" mousethrough="always" hidden="true"/>
|
||||||
</vbox>
|
</vbox>
|
||||||
<splitter id="social-sidebar-splitter"
|
<splitter id="social-sidebar-splitter"
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<xul:vbox flex="1" class="browserContainer">
|
<xul:vbox flex="1" class="browserContainer">
|
||||||
<xul:stack flex="1" class="browserStack" anonid="browserStack">
|
<xul:stack flex="1" class="browserStack" anonid="browserStack">
|
||||||
<xul:browser anonid="initialBrowser" type="content-primary" message="true" messagemanagergroup="browsers"
|
<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:stack>
|
||||||
</xul:vbox>
|
</xul:vbox>
|
||||||
</xul:hbox>
|
</xul:hbox>
|
||||||
|
@ -1600,8 +1600,8 @@
|
||||||
if (!isPreloadBrowser && this.hasAttribute("autocompletepopup"))
|
if (!isPreloadBrowser && this.hasAttribute("autocompletepopup"))
|
||||||
b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
|
b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
|
||||||
|
|
||||||
if (this.hasAttribute("selectpopup"))
|
if (this.hasAttribute("selectmenulist"))
|
||||||
b.setAttribute("selectpopup", this.getAttribute("selectpopup"));
|
b.setAttribute("selectmenulist", this.getAttribute("selectmenulist"));
|
||||||
|
|
||||||
b.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
|
b.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,6 @@ loop.shared.mixins = (function() {
|
||||||
publishVideo: options.publishVideo,
|
publishVideo: options.publishVideo,
|
||||||
style: {
|
style: {
|
||||||
audioLevelDisplayMode: "off",
|
audioLevelDisplayMode: "off",
|
||||||
bugDisplayMode: "off",
|
|
||||||
buttonDisplayMode: "off",
|
buttonDisplayMode: "off",
|
||||||
nameDisplayMode: "off",
|
nameDisplayMode: "off",
|
||||||
videoDisabledDisplayMode: "off"
|
videoDisabledDisplayMode: "off"
|
||||||
|
|
|
@ -118,216 +118,88 @@
|
||||||
|
|
||||||
/* Modal dialog styles */
|
/* Modal dialog styles */
|
||||||
|
|
||||||
|
.OT_dialog-centering {
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.OT_dialog-centering-child {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
.OT_dialog {
|
.OT_dialog {
|
||||||
border: none;
|
position: relative;
|
||||||
border-radius: 0;
|
|
||||||
top: 50%;
|
box-sizing: border-box;
|
||||||
left: 50%;
|
max-width: 576px;
|
||||||
position: absolute;
|
margin-right: auto;
|
||||||
position: fixed;
|
margin-left: auto;
|
||||||
padding: 0;
|
padding: 36px;
|
||||||
|
text-align: center; /* centers all the inline content */
|
||||||
|
|
||||||
background-color: #363636;
|
background-color: #363636;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
z-index: 9999;
|
|
||||||
box-shadow: 2px 4px 6px #999;
|
box-shadow: 2px 4px 6px #999;
|
||||||
font-family: 'Didact Gothic', sans-serif;
|
font-family: 'Didact Gothic', sans-serif;
|
||||||
}
|
font-size: 13px;
|
||||||
|
line-height: 1.4;
|
||||||
.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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog * {
|
.OT_dialog * {
|
||||||
font-family: 'Didact Gothic', sans-serif;
|
font-family: inherit;
|
||||||
}
|
box-sizing: inherit;
|
||||||
|
|
||||||
.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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_closeButton {
|
.OT_closeButton {
|
||||||
color: #999999;
|
color: #999999;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
line-height: 30px;
|
line-height: 36px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 15px;
|
right: 18px;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-messages {
|
.OT_dialog-messages {
|
||||||
position: absolute;
|
|
||||||
top: 32px;
|
|
||||||
left: 32px;
|
|
||||||
right: 32px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-allow-deny-firefox-maybe-denied .OT_dialog-messages {
|
|
||||||
top: 45px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.OT_dialog-messages-main {
|
.OT_dialog-messages-main {
|
||||||
|
margin-bottom: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 18pt;
|
font-size: 24px;
|
||||||
line-height: 24px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-messages-minor {
|
.OT_dialog-messages-minor {
|
||||||
font-weight: 300;
|
margin-bottom: 18px;
|
||||||
margin-top: 12px;
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
color: #A4A4A4;
|
color: #A4A4A4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-allow-deny-firefox-maybe-denied .OT_dialog-messages-minor {
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.OT_dialog-messages-minor strong {
|
.OT_dialog-messages-minor strong {
|
||||||
font-weight: 300;
|
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-hidden {
|
.OT_dialog-actions-card {
|
||||||
display: none;
|
display: inline-block;
|
||||||
}
|
|
||||||
|
|
||||||
.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-button-title {
|
.OT_dialog-button-title {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
line-height: 18px;
|
||||||
|
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 15px;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 150%;
|
|
||||||
color: #999999;
|
color: #999999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-button-title label {
|
.OT_dialog-button-title label {
|
||||||
color: #999999;
|
color: #999999;
|
||||||
}
|
}
|
||||||
|
@ -345,13 +217,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-button {
|
.OT_dialog-button {
|
||||||
font-weight: 100;
|
display: inline-block;
|
||||||
display: block;
|
|
||||||
line-height: 50px;
|
margin-bottom: 18px;
|
||||||
height: 47px;
|
padding: 0 1em;
|
||||||
|
|
||||||
background-color: #1CA3DC;
|
background-color: #1CA3DC;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 16pt;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,138 +236,67 @@
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-button.OT_dialog-button-large {
|
.OT_dialog-button-large {
|
||||||
line-height: 60px;
|
line-height: 36px;
|
||||||
height: 58px;
|
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;
|
background-color: #444444;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
font-size: 12pt;
|
font-size: 16px;
|
||||||
height: 40px;
|
|
||||||
line-height: 40px;
|
|
||||||
margin: 20px auto 0 auto;
|
|
||||||
width: 86px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-progress-bar {
|
.OT_dialog-progress-bar {
|
||||||
|
display: inline-block; /* prevents margin collapse */
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 41px;
|
||||||
|
|
||||||
border: 1px solid #4E4E4E;
|
border: 1px solid #4E4E4E;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-progress-bar-fill {
|
.OT_dialog-progress-bar-fill {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
background-color: #29A4DA;
|
background-color: #29A4DA;
|
||||||
height: 10px;
|
|
||||||
margin-top: -1px;
|
|
||||||
margin-left: -1px;
|
|
||||||
margin-right: -1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-plugin-upgrading .OT_dialog-plugin-upgrade-percentage {
|
.OT_dialog-plugin-upgrading .OT_dialog-plugin-upgrade-percentage {
|
||||||
font-size: 36pt;
|
line-height: 54px;
|
||||||
|
|
||||||
|
font-size: 48px;
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_dialog-plugin-upgrading .OT_dialog-progress-bar {
|
/* Helpers */
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.OT_centered {
|
.OT_centered {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
margin: 0;
|
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 */
|
/* Publisher and Subscriber styles */
|
||||||
|
@ -803,21 +604,14 @@
|
||||||
|
|
||||||
.OT_publisher .OT_name,
|
.OT_publisher .OT_name,
|
||||||
.OT_subscriber .OT_name {
|
.OT_subscriber .OT_name {
|
||||||
left: 24px;
|
left: 10px;
|
||||||
right: 37px;
|
right: 37px;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
}
|
|
||||||
|
|
||||||
.OT_publisher .OT_name-no-bug,
|
|
||||||
.OT_subscriber .OT_name-no-bug {
|
|
||||||
left: 10px;
|
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.OT_publisher .OT_mute,
|
.OT_publisher .OT_mute,
|
||||||
.OT_subscriber .OT_mute,
|
.OT_subscriber .OT_mute {
|
||||||
.OT_publisher .OT_opentok,
|
|
||||||
.OT_subscriber .OT_opentok {
|
|
||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -828,21 +622,6 @@
|
||||||
background-repeat: no-repeat;
|
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_publisher .OT_mute,
|
||||||
.OT_subscriber .OT_mute {
|
.OT_subscriber .OT_mute {
|
||||||
right: 0;
|
right: 0;
|
||||||
|
@ -883,21 +662,6 @@
|
||||||
background-position: 7px 7px;
|
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
|
* Styles for display modes
|
||||||
*
|
*
|
||||||
|
@ -975,23 +739,6 @@
|
||||||
opacity: 1;
|
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 */
|
/* Contains the video element, used to fix video letter-boxing */
|
||||||
.OT_video-container {
|
.OT_video-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -1095,7 +842,7 @@
|
||||||
background-image: radial-gradient(circle, rgba(151,206,0,1) 0%, rgba(151,206,0,0) 100%);
|
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;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,4 +1,5 @@
|
||||||
. "$topsrcdir/browser/config/mozconfigs/common"
|
. "$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-channel=${MOZ_UPDATE_CHANNEL}
|
||||||
ac_add_options --enable-update-packaging
|
ac_add_options --enable-update-packaging
|
||||||
|
|
|
@ -701,7 +701,7 @@ let CallsListView = Heritage.extend(WidgetMethods, {
|
||||||
let dimensionsNode = $("#screenshot-dimensions");
|
let dimensionsNode = $("#screenshot-dimensions");
|
||||||
let actualWidth = (width / scaling) | 0;
|
let actualWidth = (width / scaling) | 0;
|
||||||
let actualHeight = (height / 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);
|
window.emit(EVENTS.CALL_SCREENSHOT_DISPLAYED);
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,7 +20,7 @@ function ifTestingSupported() {
|
||||||
is($("#screenshot-container").hidden, false,
|
is($("#screenshot-container").hidden, false,
|
||||||
"The screenshot container should now be visible.");
|
"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.");
|
"The screenshot dimensions label has the expected value.");
|
||||||
|
|
||||||
is($("#screenshot-image").getAttribute("flipped"), "false",
|
is($("#screenshot-image").getAttribute("flipped"), "false",
|
||||||
|
|
|
@ -20,7 +20,7 @@ add_task(function*() {
|
||||||
tag: "DIV",
|
tag: "DIV",
|
||||||
id: "top",
|
id: "top",
|
||||||
classes: ".class1.class2",
|
classes: ".class1.class2",
|
||||||
dims: "500 x 100"
|
dims: "500" + " \u00D7 " + "100"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
selector: "#vertical",
|
selector: "#vertical",
|
||||||
|
@ -36,7 +36,7 @@ add_task(function*() {
|
||||||
tag: "DIV",
|
tag: "DIV",
|
||||||
id: "bottom",
|
id: "bottom",
|
||||||
classes: "",
|
classes: "",
|
||||||
dims: "500 x 100"
|
dims: "500" + " \u00D7 " + "100"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
selector: "body",
|
selector: "body",
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
// Expected values:
|
// Expected values:
|
||||||
let res1 = [
|
let res1 = [
|
||||||
{selector: "#element-size", value: "160x160"},
|
{selector: "#element-size", value: "160" + "\u00D7" + "160"},
|
||||||
{selector: ".size > span", value: "100x100"},
|
{selector: ".size > span", value: "100" + "\u00D7" + "100"},
|
||||||
{selector: ".margin.top > span", value: 30},
|
{selector: ".margin.top > span", value: 30},
|
||||||
{selector: ".margin.left > span", value: "auto"},
|
{selector: ".margin.left > span", value: "auto"},
|
||||||
{selector: ".margin.bottom > span", value: 30},
|
{selector: ".margin.bottom > span", value: 30},
|
||||||
|
@ -26,8 +26,8 @@ let res1 = [
|
||||||
];
|
];
|
||||||
|
|
||||||
let res2 = [
|
let res2 = [
|
||||||
{selector: "#element-size", value: "190x210"},
|
{selector: "#element-size", value: "190" + "\u00D7" + "210"},
|
||||||
{selector: ".size > span", value: "100x150"},
|
{selector: ".size > span", value: "100" + "\u00D7" + "150"},
|
||||||
{selector: ".margin.top > span", value: 30},
|
{selector: ".margin.top > span", value: 30},
|
||||||
{selector: ".margin.left > span", value: "auto"},
|
{selector: ".margin.left > span", value: "auto"},
|
||||||
{selector: ".margin.bottom > span", value: 30},
|
{selector: ".margin.bottom > span", value: 30},
|
||||||
|
|
|
@ -45,7 +45,7 @@ function*(inspector, view) {
|
||||||
|
|
||||||
info("Checking that the layout-view shows the right value");
|
info("Checking that the layout-view shows the right value");
|
||||||
let sizeElt = view.doc.querySelector(".size > span");
|
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");
|
info("Listening for layout-view changes and modifying the size");
|
||||||
let onUpdated = waitForUpdate(inspector);
|
let onUpdated = waitForUpdate(inspector);
|
||||||
|
@ -54,7 +54,7 @@ function*(inspector, view) {
|
||||||
ok(true, "Layout-view got updated");
|
ok(true, "Layout-view got updated");
|
||||||
|
|
||||||
info("Checking that the layout-view shows the right value after update");
|
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",
|
addTest("Go back to the first page",
|
||||||
|
|
|
@ -401,7 +401,7 @@ LayoutView.prototype = {
|
||||||
this._lastRequest = null;
|
this._lastRequest = null;
|
||||||
let width = layout.width;
|
let width = layout.width;
|
||||||
let height = layout.height;
|
let height = layout.height;
|
||||||
let newLabel = width + "x" + height;
|
let newLabel = width + "\u00D7" + height;
|
||||||
if (this.sizeHeadingLabel.textContent != newLabel) {
|
if (this.sizeHeadingLabel.textContent != newLabel) {
|
||||||
this.sizeHeadingLabel.textContent = newLabel;
|
this.sizeHeadingLabel.textContent = newLabel;
|
||||||
}
|
}
|
||||||
|
@ -452,7 +452,7 @@ LayoutView.prototype = {
|
||||||
height -= this.map.borderTop.value + this.map.borderBottom.value +
|
height -= this.map.borderTop.value + this.map.borderBottom.value +
|
||||||
this.map.paddingTop.value + this.map.paddingBottom.value;
|
this.map.paddingTop.value + this.map.paddingBottom.value;
|
||||||
|
|
||||||
let newValue = width + "x" + height;
|
let newValue = width + "\u00D7" + height;
|
||||||
if (this.sizeLabel.textContent != newValue) {
|
if (this.sizeLabel.textContent != newValue) {
|
||||||
this.sizeLabel.textContent = newValue;
|
this.sizeLabel.textContent = newValue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,10 @@ const PAGE_CONTENT = [
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
const TEST_NODES = [
|
const TEST_NODES = [
|
||||||
{selector: "img.local", size: "192 x 192"},
|
{selector: "img.local", size: "192" + " \u00D7 " + "192"},
|
||||||
{selector: "img.data", size: "64 x 64"},
|
{selector: "img.data", size: "64" + " \u00D7 " + "64"},
|
||||||
{selector: "img.remote", size: "22 x 23"},
|
{selector: "img.remote", size: "22" + " \u00D7 " + "23"},
|
||||||
{selector: ".canvas", size: "600 x 600"}
|
{selector: ".canvas", size: "600" + " \u00D7 " + "600"}
|
||||||
];
|
];
|
||||||
|
|
||||||
add_task(function*() {
|
add_task(function*() {
|
||||||
|
|
|
@ -1683,7 +1683,7 @@ RequestsMenuView.prototype = Heritage.extend(WidgetMethods, {
|
||||||
*/
|
*/
|
||||||
_onSecurityIconClick: function(e) {
|
_onSecurityIconClick: function(e) {
|
||||||
let state = this.selectedItem.attachment.securityState;
|
let state = this.selectedItem.attachment.securityState;
|
||||||
if (state === "broken" || state === "secure") {
|
if (state !== "insecure") {
|
||||||
// Choose the security tab.
|
// Choose the security tab.
|
||||||
NetMonitorView.NetworkDetails.widget.selectedIndex = 5;
|
NetMonitorView.NetworkDetails.widget.selectedIndex = 5;
|
||||||
}
|
}
|
||||||
|
@ -2605,7 +2605,7 @@ NetworkDetailsView.prototype = {
|
||||||
// in width and height attributes like the rest of the folk. Hack around
|
// in width and height attributes like the rest of the folk. Hack around
|
||||||
// this by getting the bounding client rect and subtracting the margins.
|
// this by getting the bounding client rect and subtracting the margins.
|
||||||
let { width, height } = e.target.getBoundingClientRect();
|
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);
|
$("#response-content-image-dimensions-value").setAttribute("value", dimensions);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2765,10 +2765,22 @@ NetworkDetailsView.prototype = {
|
||||||
let errorbox = $("#security-error");
|
let errorbox = $("#security-error");
|
||||||
let infobox = $("#security-information");
|
let infobox = $("#security-information");
|
||||||
|
|
||||||
if (securityInfo.state === "secure") {
|
if (securityInfo.state === "secure" || securityInfo.state === "weak") {
|
||||||
infobox.hidden = false;
|
infobox.hidden = false;
|
||||||
errorbox.hidden = true;
|
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 enabledLabel = L10N.getStr("netmonitor.security.enabled");
|
||||||
let disabledLabel = L10N.getStr("netmonitor.security.disabled");
|
let disabledLabel = L10N.getStr("netmonitor.security.disabled");
|
||||||
|
|
||||||
|
|
|
@ -506,6 +506,9 @@
|
||||||
class="plain tabpanel-summary-value devtools-monospace"
|
class="plain tabpanel-summary-value devtools-monospace"
|
||||||
crop="end"
|
crop="end"
|
||||||
flex="1"/>
|
flex="1"/>
|
||||||
|
<image class="security-warning-icon"
|
||||||
|
id="security-warning-sslv3"
|
||||||
|
tooltiptext="&netmonitorUI.security.warning.sslv3;" />
|
||||||
</hbox>
|
</hbox>
|
||||||
<hbox id="security-ciphersuite"
|
<hbox id="security-ciphersuite"
|
||||||
class="tabpanel-summary-container"
|
class="tabpanel-summary-container"
|
||||||
|
@ -516,6 +519,9 @@
|
||||||
class="plain tabpanel-summary-value devtools-monospace"
|
class="plain tabpanel-summary-value devtools-monospace"
|
||||||
crop="end"
|
crop="end"
|
||||||
flex="1"/>
|
flex="1"/>
|
||||||
|
<image class="security-warning-icon"
|
||||||
|
id="security-warning-cipher"
|
||||||
|
tooltiptext="&netmonitorUI.security.warning.cipher;" />
|
||||||
</hbox>
|
</hbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
|
|
@ -92,6 +92,7 @@ skip-if = e10s # Bug 1091612
|
||||||
[browser_net_security-state.js]
|
[browser_net_security-state.js]
|
||||||
[browser_net_security-tab-deselect.js]
|
[browser_net_security-tab-deselect.js]
|
||||||
[browser_net_security-tab-visibility.js]
|
[browser_net_security-tab-visibility.js]
|
||||||
|
[browser_net_security-warnings.js]
|
||||||
[browser_net_simple-init.js]
|
[browser_net_simple-init.js]
|
||||||
[browser_net_simple-request-data.js]
|
[browser_net_simple-request-data.js]
|
||||||
[browser_net_simple-request-details.js]
|
[browser_net_simple-request-details.js]
|
||||||
|
|
|
@ -208,7 +208,7 @@ function test() {
|
||||||
.getAttribute("value"), "base64",
|
.getAttribute("value"), "base64",
|
||||||
"The image encoding info isn't correct.");
|
"The image encoding info isn't correct.");
|
||||||
is(tabpanel.querySelector("#response-content-image-dimensions-value")
|
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.");
|
"The image dimensions info isn't correct.");
|
||||||
|
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
|
|
@ -13,6 +13,7 @@ add_task(function* () {
|
||||||
"test1.example.com": "security-state-insecure",
|
"test1.example.com": "security-state-insecure",
|
||||||
"example.com": "security-state-secure",
|
"example.com": "security-state-secure",
|
||||||
"nocert.example.com": "security-state-broken",
|
"nocert.example.com": "security-state-broken",
|
||||||
|
"rc4.example.com": "security-state-weak",
|
||||||
};
|
};
|
||||||
|
|
||||||
let [tab, debuggee, monitor] = yield initNetMonitor(CUSTOM_GET_URL);
|
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);
|
debuggee.performRequests(1, "https://example.com" + CORS_SJS_PATH);
|
||||||
yield done;
|
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.
|
* @param aPreset associated preset.
|
||||||
*/
|
*/
|
||||||
setMenuLabel: function RUI_setMenuLabel(aMenuitem, aPreset) {
|
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)
|
// .inputField might be not reachable yet (async XBL loading)
|
||||||
if (this.menulist.inputField) {
|
if (this.menulist.inputField) {
|
||||||
|
|
|
@ -210,7 +210,7 @@ function test() {
|
||||||
initialWidth = content.innerWidth;
|
initialWidth = content.innerWidth;
|
||||||
initialHeight = content.innerHeight;
|
initialHeight = content.innerHeight;
|
||||||
index = instance.menulist.selectedIndex;
|
index = instance.menulist.selectedIndex;
|
||||||
let expectedValue = initialWidth + "x" + initialHeight;
|
let expectedValue = initialWidth + "\u00D7" + initialHeight;
|
||||||
let expectedLabel = instance.menulist.firstChild.firstChild.getAttribute("label");
|
let expectedLabel = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||||
|
|
||||||
userInput = "I'm wrong";
|
userInput = "I'm wrong";
|
||||||
|
|
|
@ -115,7 +115,7 @@ function test() {
|
||||||
|
|
||||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||||
|
|
||||||
let customPresetIndex = getPresetIndex("456x123 (Testing preset)");
|
let customPresetIndex = getPresetIndex("456" + "\u00D7" + "123 (Testing preset)");
|
||||||
info(customPresetIndex);
|
info(customPresetIndex);
|
||||||
ok(customPresetIndex >= 0, "is the previously added preset (idx = " + customPresetIndex + ") in the list of items");
|
ok(customPresetIndex >= 0, "is the previously added preset (idx = " + customPresetIndex + ") in the list of items");
|
||||||
|
|
||||||
|
|
|
@ -726,7 +726,7 @@ Tooltip.prototype = {
|
||||||
this.content = vbox;
|
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
|
* 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");
|
let body = this.document.createElementNS(XHTML_NS, "span");
|
||||||
body.className = "message-body-wrapper message-body devtools-monospace";
|
body.className = "message-body-wrapper message-body devtools-monospace";
|
||||||
|
|
||||||
let bodyInner = this.document.createElementNS(XHTML_NS, "span");
|
let anchor, container = body;
|
||||||
body.appendChild(bodyInner);
|
|
||||||
|
|
||||||
let anchor, container = bodyInner;
|
|
||||||
if (this._link || this._linkCallback) {
|
if (this._link || this._linkCallback) {
|
||||||
container = anchor = this.document.createElementNS(XHTML_NS, "a");
|
container = anchor = this.document.createElementNS(XHTML_NS, "a");
|
||||||
anchor.href = this._link || "#";
|
anchor.href = this._link || "#";
|
||||||
anchor.draggable = false;
|
anchor.draggable = false;
|
||||||
this._addLinkCallback(anchor, this._linkCallback);
|
this._addLinkCallback(anchor, this._linkCallback);
|
||||||
bodyInner.appendChild(anchor);
|
body.appendChild(anchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof this._message == "function") {
|
if (typeof this._message == "function") {
|
||||||
|
|
|
@ -57,9 +57,7 @@ function consoleOpened(aHud) {
|
||||||
controller = top.document.commandDispatcher.getControllerForCommand("cmd_copy");
|
controller = top.document.commandDispatcher.getControllerForCommand("cmd_copy");
|
||||||
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
||||||
|
|
||||||
// Remove new lines since getSelection() includes one between message and line
|
let selection = HUD.iframeWindow.getSelection() + "";
|
||||||
// number, but the clipboard doesn't (see bug 1119503)
|
|
||||||
let selection = (HUD.iframeWindow.getSelection() + "").replace(/\r?\n|\r/g, " ");
|
|
||||||
isnot(selection.indexOf("bug587617"), -1,
|
isnot(selection.indexOf("bug587617"), -1,
|
||||||
"selection text includes 'bug587617'");
|
"selection text includes 'bug587617'");
|
||||||
|
|
||||||
|
@ -82,9 +80,7 @@ function testContextMenuCopy() {
|
||||||
let copyItem = contextMenu.querySelector("*[command='cmd_copy']");
|
let copyItem = contextMenu.querySelector("*[command='cmd_copy']");
|
||||||
ok(copyItem, "the context menu on the output node has a \"Copy\" item");
|
ok(copyItem, "the context menu on the output node has a \"Copy\" item");
|
||||||
|
|
||||||
// Remove new lines since getSelection() includes one between message and line
|
let selection = HUD.iframeWindow.getSelection() + "";
|
||||||
// number, but the clipboard doesn't (see bug 1119503)
|
|
||||||
let selection = (HUD.iframeWindow.getSelection() + "").replace(/\r?\n|\r/g, " ");
|
|
||||||
|
|
||||||
copyItem.doCommand();
|
copyItem.doCommand();
|
||||||
|
|
||||||
|
|
|
@ -69,9 +69,7 @@ function performTest(HUD, [result]) {
|
||||||
getControllerForCommand("cmd_copy");
|
getControllerForCommand("cmd_copy");
|
||||||
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
||||||
|
|
||||||
// Remove new lines since getSelection() includes one between message and line
|
let selectionText = HUD.iframeWindow.getSelection() + "";
|
||||||
// number, but the clipboard doesn't (see bug 1119503)
|
|
||||||
let selectionText = (HUD.iframeWindow.getSelection() + "").replace(/\r?\n|\r/g, " ");
|
|
||||||
isnot(selectionText.indexOf("foobarBazBug613280"), -1,
|
isnot(selectionText.indexOf("foobarBazBug613280"), -1,
|
||||||
"selection text includes 'foobarBazBug613280'");
|
"selection text includes 'foobarBazBug613280'");
|
||||||
|
|
||||||
|
|
|
@ -202,6 +202,14 @@
|
||||||
- in a "receive" state. -->
|
- in a "receive" state. -->
|
||||||
<!ENTITY netmonitorUI.timings.receive "Receiving:">
|
<!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
|
<!-- LOCALIZATION NOTE (netmonitorUI.security.error): This is the label displayed
|
||||||
- in the security tab if a security error prevented the connection. -->
|
- in the security tab if a security error prevented the connection. -->
|
||||||
<!ENTITY netmonitorUI.security.error "An error occured:">
|
<!ENTITY netmonitorUI.security.error "An error occured:">
|
||||||
|
|
|
@ -44,6 +44,10 @@ netmonitor.security.state.insecure=The connection used to fetch this resource wa
|
||||||
# issues.
|
# issues.
|
||||||
netmonitor.security.state.broken=A security error prevented the resource from being loaded.
|
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):
|
# LOCALIZATION NOTE (netmonitor.security.enabled):
|
||||||
# This string is used to indicate that a specific security feature is used by
|
# This string is used to indicate that a specific security feature is used by
|
||||||
# a connection in the security details tab.
|
# a connection in the security details tab.
|
||||||
|
|
|
@ -178,6 +178,11 @@
|
||||||
list-style-image: url(chrome://browser/skin/identity-icons-https.png);
|
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 {
|
.security-state-broken {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-active.png);
|
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;
|
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 request form */
|
||||||
|
|
||||||
#custom-pane {
|
#custom-pane {
|
||||||
|
|
|
@ -117,7 +117,7 @@ a {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-body > * {
|
.message-body {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,14 @@ treecol {
|
||||||
|
|
||||||
/* Category List */
|
/* Category List */
|
||||||
|
|
||||||
|
#categories {
|
||||||
|
max-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#categories > scrollbox {
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
.category-icon {
|
.category-icon {
|
||||||
list-style-image: url("chrome://browser/skin/preferences/in-content/icons.png");
|
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.
|
// Do the first and potentially trial encoding as preformatted and raw.
|
||||||
uint32_t flags = aFlags | nsIDocumentEncoder::OutputPreformatted
|
uint32_t flags = aFlags | nsIDocumentEncoder::OutputPreformatted
|
||||||
| nsIDocumentEncoder::OutputRaw
|
| nsIDocumentEncoder::OutputRaw;
|
||||||
| nsIDocumentEncoder::OutputForPlainTextClipboardCopy;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
|
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(aDoc);
|
||||||
NS_ASSERTION(domDoc, "Need a document");
|
NS_ASSERTION(domDoc, "Need a document");
|
||||||
|
|
|
@ -227,13 +227,6 @@ interface nsIDocumentEncoder : nsISupports
|
||||||
*/
|
*/
|
||||||
const unsigned long OutputDontRemoveLineEndingSpaces = (1 << 24);
|
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.
|
* Initialize with a pointer to the document and the mime type.
|
||||||
* @param aDocument Document to encode.
|
* @param aDocument Document to encode.
|
||||||
|
|
|
@ -91,8 +91,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
|
||||||
mPreFormatted = false;
|
mPreFormatted = false;
|
||||||
mStartedOutput = false;
|
mStartedOutput = false;
|
||||||
|
|
||||||
mPreformattedBlockBoundary = false;
|
|
||||||
|
|
||||||
// initialize the tag stack to zero:
|
// initialize the tag stack to zero:
|
||||||
// The stack only ever contains pointers to static atoms, so they don't
|
// The stack only ever contains pointers to static atoms, so they don't
|
||||||
// need refcounting.
|
// need refcounting.
|
||||||
|
@ -169,8 +167,6 @@ nsPlainTextSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
|
||||||
mLineBreakDue = false;
|
mLineBreakDue = false;
|
||||||
mFloatingLines = -1;
|
mFloatingLines = -1;
|
||||||
|
|
||||||
mPreformattedBlockBoundary = false;
|
|
||||||
|
|
||||||
if (mFlags & nsIDocumentEncoder::OutputFormatted) {
|
if (mFlags & nsIDocumentEncoder::OutputFormatted) {
|
||||||
// Get some prefs that controls how we do formatted output
|
// Get some prefs that controls how we do formatted output
|
||||||
mStructs = Preferences::GetBool(PREF_STRUCTS, mStructs);
|
mStructs = Preferences::GetBool(PREF_STRUCTS, mStructs);
|
||||||
|
@ -441,16 +437,6 @@ nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
|
||||||
return NS_OK;
|
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) {
|
if (mFlags & nsIDocumentEncoder::OutputRaw) {
|
||||||
// Raw means raw. Don't even think about doing anything fancy
|
// Raw means raw. Don't even think about doing anything fancy
|
||||||
// here like indenting, adding line breaks or any other
|
// 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,
|
// Else make sure we'll separate block level tags,
|
||||||
// even if we're about to leave, before doing any other formatting.
|
// even if we're about to leave, before doing any other formatting.
|
||||||
else if (IsElementBlock(mElement)) {
|
else if (nsContentUtils::IsHTMLBlock(aTag)) {
|
||||||
EnsureVerticalSpace(0);
|
EnsureVerticalSpace(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,14 +767,6 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
|
||||||
return NS_OK;
|
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) {
|
if (mFlags & nsIDocumentEncoder::OutputRaw) {
|
||||||
// Raw means raw. Don't even think about doing anything fancy
|
// Raw means raw. Don't even think about doing anything fancy
|
||||||
// here like indenting, adding line breaks or any other
|
// here like indenting, adding line breaks or any other
|
||||||
|
@ -909,7 +887,8 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
|
||||||
else if (aTag == nsGkAtoms::q) {
|
else if (aTag == nsGkAtoms::q) {
|
||||||
Write(NS_LITERAL_STRING("\""));
|
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
|
// All other blocks get 1 vertical space after them
|
||||||
// in formatted mode, otherwise 0.
|
// in formatted mode, otherwise 0.
|
||||||
// This is hard. Sometimes 0 is a better number, but
|
// This is hard. Sometimes 0 is a better number, but
|
||||||
|
@ -1058,8 +1037,6 @@ nsPlainTextSerializer::DoAddText(bool aIsLineBreak, const nsAString& aText)
|
||||||
nsresult
|
nsresult
|
||||||
nsPlainTextSerializer::DoAddLeaf(nsIAtom* aTag)
|
nsPlainTextSerializer::DoAddLeaf(nsIAtom* aTag)
|
||||||
{
|
{
|
||||||
mPreformattedBlockBoundary = false;
|
|
||||||
|
|
||||||
// If we don't want any output, just return
|
// If we don't want any output, just return
|
||||||
if (!DoOutput()) {
|
if (!DoOutput()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -1801,20 +1778,6 @@ nsPlainTextSerializer::IsElementPreformatted(Element* aElement)
|
||||||
return GetIdForContent(aElement) == nsGkAtoms::pre;
|
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.
|
* This method is required only to identify LI's inside OL.
|
||||||
* Returns TRUE if we are inside an OL tag and FALSE otherwise.
|
* Returns TRUE if we are inside an OL tag and FALSE otherwise.
|
||||||
|
|
|
@ -115,7 +115,6 @@ private:
|
||||||
bool ShouldReplaceContainerWithPlaceholder(nsIAtom* aTag);
|
bool ShouldReplaceContainerWithPlaceholder(nsIAtom* aTag);
|
||||||
|
|
||||||
bool IsElementPreformatted(mozilla::dom::Element* aElement);
|
bool IsElementPreformatted(mozilla::dom::Element* aElement);
|
||||||
bool IsElementBlock(mozilla::dom::Element* aElement);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsString mCurrentLine;
|
nsString mCurrentLine;
|
||||||
|
@ -170,9 +169,7 @@ private:
|
||||||
// While handling a new tag, this variable should remind if any line break
|
// 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.
|
// 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.
|
// Hence opening tags are guaranteed to start with appropriate line breaks.
|
||||||
bool mLineBreakDue;
|
bool mLineBreakDue;
|
||||||
|
|
||||||
bool mPreformattedBlockBoundary;
|
|
||||||
|
|
||||||
nsString mURL;
|
nsString mURL;
|
||||||
int32_t mHeaderStrategy; /* Header strategy (pref)
|
int32_t mHeaderStrategy; /* Header strategy (pref)
|
||||||
|
|
|
@ -137,31 +137,6 @@ TestPreElement()
|
||||||
return NS_OK;
|
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
|
nsresult
|
||||||
TestPlainTextSerializer()
|
TestPlainTextSerializer()
|
||||||
{
|
{
|
||||||
|
@ -188,9 +163,6 @@ TestPlainTextSerializer()
|
||||||
rv = TestPreElement();
|
rv = TestPreElement();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = TestBlockElement();
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Add new tests here...
|
// Add new tests here...
|
||||||
return NS_OK;
|
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-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: 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="bar baz"><span style="white-space: -moz-pre-space">bar </span>baz</div>
|
||||||
<div data-result="foo bar ! 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 bar ! 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 bar ! 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 bar ! 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 bar ! 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 bar ! 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 bar ! 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 bar ! 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=" foo bar ">foo bar</div>
|
<div data-result=" foo bar ">foo bar</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
|
|
|
@ -1600,7 +1600,7 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, nsDependentCString& aOut)
|
||||||
return NS_ERROR_ILLEGAL_VALUE; // end of PDU
|
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)) {
|
if (NS_WARN_IF(!end)) {
|
||||||
return NS_ERROR_ILLEGAL_VALUE; // no string terminator
|
return NS_ERROR_ILLEGAL_VALUE; // no string terminator
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ BroadcastSystemMessage(const nsAString& aType,
|
||||||
aData.get_nsString().Length());
|
aData.get_nsString().Length());
|
||||||
value = STRING_TO_JSVAL(jsData);
|
value = STRING_TO_JSVAL(jsData);
|
||||||
} else if (aData.type() == BluetoothValue::TArrayOfBluetoothNamedValue) {
|
} else if (aData.type() == BluetoothValue::TArrayOfBluetoothNamedValue) {
|
||||||
JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx)));
|
JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
BT_WARNING("Failed to new JSObject for system message!");
|
BT_WARNING("Failed to new JSObject for system message!");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -106,6 +106,7 @@ namespace system {
|
||||||
#define USB_FUNC_NONE "none"
|
#define USB_FUNC_NONE "none"
|
||||||
#define USB_FUNC_RNDIS "rndis"
|
#define USB_FUNC_RNDIS "rndis"
|
||||||
#define USB_FUNC_UMS "mass_storage"
|
#define USB_FUNC_UMS "mass_storage"
|
||||||
|
#define USB_FUNC_DEFAULT "default"
|
||||||
|
|
||||||
class AutoMounter;
|
class AutoMounter;
|
||||||
|
|
||||||
|
@ -552,6 +553,9 @@ SetUsbFunction(const char* aUsbFunc)
|
||||||
// We're enabling UMS. For this we make the assumption that the persisted
|
// We're enabling UMS. For this we make the assumption that the persisted
|
||||||
// property has mass_storage enabled.
|
// property has mass_storage enabled.
|
||||||
property_get(PERSIST_SYS_USB_CONFIG, newSysUsbConfig, "");
|
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 {
|
} else {
|
||||||
printf_stderr("AutoMounter::SetUsbFunction Unrecognized aUsbFunc '%s'\n", aUsbFunc);
|
printf_stderr("AutoMounter::SetUsbFunction Unrecognized aUsbFunc '%s'\n", aUsbFunc);
|
||||||
MOZ_ASSERT(0);
|
MOZ_ASSERT(0);
|
||||||
|
@ -626,6 +630,7 @@ AutoMounter::StartMtpServer()
|
||||||
|
|
||||||
sMozMtpServer = new MozMtpServer();
|
sMozMtpServer = new MozMtpServer();
|
||||||
if (!sMozMtpServer->Init()) {
|
if (!sMozMtpServer->Init()) {
|
||||||
|
sMozMtpServer = nullptr;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,9 +791,15 @@ AutoMounter::UpdateState()
|
||||||
if (StartMtpServer()) {
|
if (StartMtpServer()) {
|
||||||
SetState(STATE_MTP_STARTED);
|
SetState(STATE_MTP_STARTED);
|
||||||
} else {
|
} else {
|
||||||
// Unable to start MTP. Go back to UMS.
|
if (umsAvail) {
|
||||||
SetUsbFunction(USB_FUNC_UMS);
|
// Unable to start MTP. Go back to UMS.
|
||||||
SetState(STATE_UMS_CONFIGURING);
|
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 {
|
} else {
|
||||||
// We need to configure USB to use mtp. Wait for it to be configured
|
// We need to configure USB to use mtp. Wait for it to be configured
|
||||||
|
@ -849,6 +860,10 @@ AutoMounter::UpdateState()
|
||||||
SetState(STATE_UMS_CONFIGURING);
|
SetState(STATE_UMS_CONFIGURING);
|
||||||
break;
|
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);
|
SetState(STATE_IDLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@ MozMtpServer::Init()
|
||||||
const char *mtpUsbFilename = "/dev/mtp_usb";
|
const char *mtpUsbFilename = "/dev/mtp_usb";
|
||||||
mMtpUsbFd = open(mtpUsbFilename, O_RDWR);
|
mMtpUsbFd = open(mtpUsbFilename, O_RDWR);
|
||||||
if (mMtpUsbFd.get() < 0) {
|
if (mMtpUsbFd.get() < 0) {
|
||||||
MTP_ERR("open of '%s' failed", mtpUsbFilename);
|
MTP_ERR("open of '%s' failed((%s))", mtpUsbFilename, strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MTP_LOG("Opened '%s' fd %d", mtpUsbFilename, mMtpUsbFd.get());
|
MTP_LOG("Opened '%s' fd %d", mtpUsbFilename, mMtpUsbFd.get());
|
||||||
|
|
|
@ -19,7 +19,8 @@ enum NFCTechType {
|
||||||
"ISO-DEP", // NFCForum-TS-DigitalProtocol-1.1 ISO-DEP.
|
"ISO-DEP", // NFCForum-TS-DigitalProtocol-1.1 ISO-DEP.
|
||||||
"MIFARE-Classic", // MIFARE Classic from NXP.
|
"MIFARE-Classic", // MIFARE Classic from NXP.
|
||||||
"MIFARE-Ultralight", // MIFARE Ultralight 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 <sched.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/klog.h>
|
#include <sys/klog.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -48,7 +47,6 @@
|
||||||
#include "HalImpl.h"
|
#include "HalImpl.h"
|
||||||
#include "HalLog.h"
|
#include "HalLog.h"
|
||||||
#include "mozilla/ArrayUtils.h"
|
#include "mozilla/ArrayUtils.h"
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
|
||||||
#include "mozilla/dom/battery/Constants.h"
|
#include "mozilla/dom/battery/Constants.h"
|
||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
#include "mozilla/FileUtils.h"
|
#include "mozilla/FileUtils.h"
|
||||||
|
@ -630,6 +628,28 @@ namespace {
|
||||||
/**
|
/**
|
||||||
* RAII class to help us remember to close file descriptors.
|
* 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)
|
bool WriteToFile(const char *filename, const char *toWrite)
|
||||||
{
|
{
|
||||||
|
@ -755,9 +775,6 @@ static Monitor* sInternalLockCpuMonitor = nullptr;
|
||||||
static void
|
static void
|
||||||
UpdateCpuSleepState()
|
UpdateCpuSleepState()
|
||||||
{
|
{
|
||||||
const char *wakeLockFilename = "/sys/power/wake_lock";
|
|
||||||
const char *wakeUnlockFilename = "/sys/power/wake_unlock";
|
|
||||||
|
|
||||||
sInternalLockCpuMonitor->AssertCurrentThreadOwns();
|
sInternalLockCpuMonitor->AssertCurrentThreadOwns();
|
||||||
bool allowed = sCpuSleepAllowed && !sInternalLockCpuCount;
|
bool allowed = sCpuSleepAllowed && !sInternalLockCpuCount;
|
||||||
WriteToFile(allowed ? wakeUnlockFilename : wakeLockFilename, "gecko");
|
WriteToFile(allowed ? wakeUnlockFilename : wakeLockFilename, "gecko");
|
||||||
|
@ -1269,6 +1286,7 @@ OomVictimLogger::Observe(
|
||||||
lineTimestampFound = true;
|
lineTimestampFound = true;
|
||||||
mLastLineChecked = lineTimestamp;
|
mLastLineChecked = lineTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Log interesting lines
|
// Log interesting lines
|
||||||
for (size_t i = 0; i < regex_count; i++) {
|
for (size_t i = 0; i < regex_count; i++) {
|
||||||
|
@ -1294,347 +1312,6 @@ OomVictimLogger::Observe(
|
||||||
return NS_OK;
|
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
|
static void
|
||||||
EnsureKernelLowMemKillerParamsSet()
|
EnsureKernelLowMemKillerParamsSet()
|
||||||
{
|
{
|
||||||
|
@ -1675,12 +1352,21 @@ EnsureKernelLowMemKillerParamsSet()
|
||||||
// The system doesn't function correctly if we're missing these prefs, so
|
// The system doesn't function correctly if we're missing these prefs, so
|
||||||
// crash loudly.
|
// crash loudly.
|
||||||
|
|
||||||
PriorityClass* pc = GetPriorityClass(static_cast<ProcessPriority>(i));
|
ProcessPriority priority = static_cast<ProcessPriority>(i);
|
||||||
|
|
||||||
int32_t oomScoreAdj = pc->OomScoreAdj();
|
int32_t oomScoreAdj;
|
||||||
int32_t killUnderKB = pc->KillUnderKB();
|
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,
|
// ProcessPriority values like PROCESS_PRIORITY_FOREGROUND_KEYBOARD,
|
||||||
// which has only OomScoreAdjust but lacks KillUnderMB value, will not
|
// which has only OomScoreAdjust but lacks KillUnderMB value, will not
|
||||||
// create new LMK parameters.
|
// create new LMK parameters.
|
||||||
|
@ -1711,8 +1397,7 @@ EnsureKernelLowMemKillerParamsSet()
|
||||||
minfreeParams.Cut(minfreeParams.Length() - 1, 1);
|
minfreeParams.Cut(minfreeParams.Length() - 1, 1);
|
||||||
if (!adjParams.IsEmpty() && !minfreeParams.IsEmpty()) {
|
if (!adjParams.IsEmpty() && !minfreeParams.IsEmpty()) {
|
||||||
WriteToFile("/sys/module/lowmemorykiller/parameters/adj", adjParams.get());
|
WriteToFile("/sys/module/lowmemorykiller/parameters/adj", adjParams.get());
|
||||||
WriteToFile("/sys/module/lowmemorykiller/parameters/minfree",
|
WriteToFile("/sys/module/lowmemorykiller/parameters/minfree", minfreeParams.get());
|
||||||
minfreeParams.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the low-memory-notification threshold.
|
// 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
|
void
|
||||||
SetProcessPriority(int aPid,
|
SetProcessPriority(int aPid,
|
||||||
ProcessPriority aPriority,
|
ProcessPriority aPriority,
|
||||||
|
@ -1752,23 +1579,49 @@ SetProcessPriority(int aPid,
|
||||||
// SetProcessPriority being called early in startup.
|
// SetProcessPriority being called early in startup.
|
||||||
EnsureKernelLowMemKillerParamsSet();
|
EnsureKernelLowMemKillerParamsSet();
|
||||||
|
|
||||||
PriorityClass* pc = GetPriorityClass(aPriority);
|
static ProcessPriorityPrefs prefs = { 0 };
|
||||||
|
EnsureProcessPriorityPrefs(&prefs);
|
||||||
|
|
||||||
int oomScoreAdj = pc->OomScoreAdj();
|
int oomScoreAdj = prefs.priorities[aPriority].oomScoreAdj;
|
||||||
|
|
||||||
RoundOomScoreAdjUpWithBackroundLRU(oomScoreAdj, aBackgroundLRU);
|
RoundOomScoreAdjUpWithBackroundLRU(oomScoreAdj, aBackgroundLRU);
|
||||||
|
|
||||||
// We try the newer interface first, and fall back to the older interface
|
int clampedOomScoreAdj = clamped<int>(oomScoreAdj, OOM_SCORE_ADJ_MIN,
|
||||||
// on failure.
|
OOM_SCORE_ADJ_MAX);
|
||||||
if (!WriteToFile(nsPrintfCString("/proc/%d/oom_score_adj", aPid).get(),
|
if (clampedOomScoreAdj != oomScoreAdj) {
|
||||||
nsPrintfCString("%d", oomScoreAdj).get()))
|
HAL_LOG("Clamping OOM adjustment for pid %d to %d", aPid,
|
||||||
{
|
clampedOomScoreAdj);
|
||||||
WriteToFile(nsPrintfCString("/proc/%d/oom_adj", aPid).get(),
|
} else {
|
||||||
nsPrintfCString("%d", OomAdjOfOomScoreAdj(oomScoreAdj)).get());
|
HAL_LOG("Setting OOM adjustment for pid %d to %d", aPid,
|
||||||
|
clampedOomScoreAdj);
|
||||||
}
|
}
|
||||||
|
|
||||||
HAL_LOG("Assigning pid %d to cgroup %s", aPid, pc->CGroup().get());
|
// We try the newer interface first, and fall back to the older interface
|
||||||
pc->AddProcess(aPid);
|
// 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
|
static bool
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
Cu.import("resource://services-common/async.js");
|
Cu.import("resource://services-common/async.js");
|
||||||
Cu.import("resource://testing-common/services/common/utils.js");
|
Cu.import("resource://testing-common/services/common/utils.js");
|
||||||
|
Cu.import("resource://testing-common/PlacesTestUtils.jsm");
|
||||||
|
|
||||||
let provider = {
|
let provider = {
|
||||||
getFile: function(prop, persistent) {
|
getFile: function(prop, persistent) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
* 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/constants.js");
|
||||||
Cu.import("resource://services-sync/engines/history.js");
|
Cu.import("resource://services-sync/engines/history.js");
|
||||||
Cu.import("resource://services-sync/engines.js");
|
Cu.import("resource://services-sync/engines.js");
|
||||||
|
@ -13,13 +12,16 @@ Cu.import("resource://testing-common/services/sync/utils.js");
|
||||||
|
|
||||||
Service.engineManager.clear();
|
Service.engineManager.clear();
|
||||||
|
|
||||||
|
add_test(function test_setup() {
|
||||||
|
PlacesTestUtils.clearHistory().then(run_next_test);
|
||||||
|
});
|
||||||
|
|
||||||
add_test(function test_processIncoming_mobile_history_batched() {
|
add_test(function test_processIncoming_mobile_history_batched() {
|
||||||
_("SyncEngine._processIncoming works on history engine.");
|
_("SyncEngine._processIncoming works on history engine.");
|
||||||
|
|
||||||
let FAKE_DOWNLOAD_LIMIT = 100;
|
let FAKE_DOWNLOAD_LIMIT = 100;
|
||||||
|
|
||||||
Svc.Prefs.set("client.type", "mobile");
|
Svc.Prefs.set("client.type", "mobile");
|
||||||
PlacesUtils.history.removeAllPages();
|
|
||||||
Service.engineManager.register(HistoryEngine);
|
Service.engineManager.register(HistoryEngine);
|
||||||
|
|
||||||
// A collection that logs each GET
|
// A collection that logs each GET
|
||||||
|
@ -130,10 +132,11 @@ add_test(function test_processIncoming_mobile_history_batched() {
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
PlacesUtils.history.removeAllPages();
|
PlacesTestUtils.clearHistory().then(() => {
|
||||||
server.stop(do_test_finished);
|
server.stop(do_test_finished);
|
||||||
Svc.Prefs.resetBranch("");
|
Svc.Prefs.resetBranch("");
|
||||||
Service.recordManager.clearCache();
|
Service.recordManager.clearCache();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ function ensureThrows(func) {
|
||||||
try {
|
try {
|
||||||
func.apply(this, arguments);
|
func.apply(this, arguments);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
PlacesUtils.history.removeAllPages();
|
PlacesTestUtils.clearHistory();
|
||||||
do_throw(ex);
|
do_throw(ex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -300,6 +300,5 @@ add_test(function test_remove() {
|
||||||
|
|
||||||
add_test(function cleanup() {
|
add_test(function cleanup() {
|
||||||
_("Clean up.");
|
_("Clean up.");
|
||||||
PlacesUtils.history.removeAllPages();
|
PlacesTestUtils.clearHistory().then(run_next_test);
|
||||||
run_next_test();
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -199,6 +199,5 @@ add_test(function test_stop_tracking_twice() {
|
||||||
|
|
||||||
add_test(function cleanup() {
|
add_test(function cleanup() {
|
||||||
_("Clean up.");
|
_("Clean up.");
|
||||||
PlacesUtils.history.removeAllPages();
|
PlacesTestUtils.clearHistory().then(run_next_test);
|
||||||
run_next_test();
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -369,7 +369,7 @@ Other Measurements\n\
|
||||||
\n\
|
\n\
|
||||||
100.00 MB ── heap-allocated\n\
|
100.00 MB ── heap-allocated\n\
|
||||||
\n\
|
\n\
|
||||||
End of 5th \
|
End of 5th\n\
|
||||||
";
|
";
|
||||||
|
|
||||||
let amvExpectedText =
|
let amvExpectedText =
|
||||||
|
@ -538,7 +538,7 @@ Other Measurements\n\
|
||||||
\n\
|
\n\
|
||||||
104,857,600 B ── heap-allocated\n\
|
104,857,600 B ── heap-allocated\n\
|
||||||
\n\
|
\n\
|
||||||
End of 5th \
|
End of 5th\n\
|
||||||
";
|
";
|
||||||
|
|
||||||
function finish()
|
function finish()
|
||||||
|
|
|
@ -912,14 +912,19 @@ public:
|
||||||
mozStorageTransaction transaction(mDBConn, false,
|
mozStorageTransaction transaction(mDBConn, false,
|
||||||
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||||
|
|
||||||
VisitData* lastPlace = nullptr;
|
VisitData* lastFetchedPlace = nullptr;
|
||||||
for (nsTArray<VisitData>::size_type i = 0; i < mPlaces.Length(); i++) {
|
for (nsTArray<VisitData>::size_type i = 0; i < mPlaces.Length(); i++) {
|
||||||
VisitData& place = mPlaces.ElementAt(i);
|
VisitData& place = mPlaces.ElementAt(i);
|
||||||
VisitData& referrer = mReferrers.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
|
// We can avoid a database lookup if it's the same place as the last
|
||||||
// visit we added.
|
// visit we added.
|
||||||
bool known = lastPlace && lastPlace->IsSamePlaceAs(place);
|
bool known = lastFetchedPlace && lastFetchedPlace->IsSamePlaceAs(place);
|
||||||
if (!known) {
|
if (!known) {
|
||||||
nsresult rv = mHistory->FetchPageInfo(place, &known);
|
nsresult rv = mHistory->FetchPageInfo(place, &known);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
@ -930,6 +935,17 @@ public:
|
||||||
}
|
}
|
||||||
return NS_OK;
|
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);
|
FetchReferrerInfo(referrer, place);
|
||||||
|
@ -953,8 +969,6 @@ public:
|
||||||
rv = NS_DispatchToMainThread(event);
|
rv = NS_DispatchToMainThread(event);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastPlace = &mPlaces.ElementAt(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = transaction.Commit();
|
nsresult rv = transaction.Commit();
|
||||||
|
@ -2291,24 +2305,15 @@ History::FetchPageInfo(VisitData& _place, bool* _exists)
|
||||||
(_place.title.IsEmpty() && title.IsVoid()));
|
(_place.title.IsEmpty() && title.IsVoid()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_place.hidden) {
|
int32_t hidden;
|
||||||
// If this transition was hidden, it is possible that others were not.
|
rv = stmt->GetInt32(3, &hidden);
|
||||||
// Any one visible transition makes this location visible. If database
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
// has location as visible, reflect that in our data structure.
|
_place.hidden = !!hidden;
|
||||||
int32_t hidden;
|
|
||||||
rv = stmt->GetInt32(3, &hidden);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
_place.hidden = !!hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_place.typed) {
|
int32_t typed;
|
||||||
// If this transition wasn't typed, others might have been. If database
|
rv = stmt->GetInt32(4, &typed);
|
||||||
// has location as typed, reflect that in our data structure.
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
int32_t typed;
|
_place.typed = !!typed;
|
||||||
rv = stmt->GetInt32(4, &typed);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
_place.typed = !!typed;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = stmt->GetInt32(5, &_place.frecency);
|
rv = stmt->GetInt32(5, &_place.frecency);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
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.
|
* The time of the visit. Defaults to now if not provided.
|
||||||
*/
|
*/
|
||||||
function VisitInfo(aTransitionType,
|
function VisitInfo(aTransitionType,
|
||||||
aVisitTime)
|
aVisitTime) {
|
||||||
{
|
|
||||||
this.transitionType =
|
this.transitionType =
|
||||||
aTransitionType === undefined ? TRANSITION_LINK : aTransitionType;
|
aTransitionType === undefined ? TRANSITION_LINK : aTransitionType;
|
||||||
this.visitDate = aVisitTime || Date.now() * 1000;
|
this.visitDate = aVisitTime || Date.now() * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
function promiseUpdatePlaces(aPlaces) {
|
function promiseUpdatePlaces(aPlaces) {
|
||||||
let deferred = Promise.defer();
|
return new Promise((resolve, reject) => {
|
||||||
PlacesUtils.asyncHistory.updatePlaces(aPlaces, {
|
PlacesUtils.asyncHistory.updatePlaces(aPlaces, {
|
||||||
_errors: [],
|
_errors: [],
|
||||||
_results: [],
|
_results: [],
|
||||||
handleError: function handleError(aResultCode, aPlace) {
|
handleError(aResultCode, aPlace) {
|
||||||
this._errors.push({ resultCode: aResultCode, info: aPlace});
|
this._errors.push({ resultCode: aResultCode, info: aPlace});
|
||||||
},
|
},
|
||||||
handleResult: function handleResult(aPlace) {
|
handleResult(aPlace) {
|
||||||
this._results.push(aPlace);
|
this._results.push(aPlace);
|
||||||
},
|
},
|
||||||
handleCompletion: function handleCompletion() {
|
handleCompletion() {
|
||||||
deferred.resolve({ errors: this._errors, results: this._results });
|
resolve({ errors: this._errors, results: this._results });
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,18 +61,14 @@ function promiseUpdatePlaces(aPlaces) {
|
||||||
*/
|
*/
|
||||||
function TitleChangedObserver(aURI,
|
function TitleChangedObserver(aURI,
|
||||||
aExpectedTitle,
|
aExpectedTitle,
|
||||||
aCallback)
|
aCallback) {
|
||||||
{
|
|
||||||
this.uri = aURI;
|
this.uri = aURI;
|
||||||
this.expectedTitle = aExpectedTitle;
|
this.expectedTitle = aExpectedTitle;
|
||||||
this.callback = aCallback;
|
this.callback = aCallback;
|
||||||
}
|
}
|
||||||
TitleChangedObserver.prototype = {
|
TitleChangedObserver.prototype = {
|
||||||
__proto__: NavHistoryObserver.prototype,
|
__proto__: NavHistoryObserver.prototype,
|
||||||
onTitleChanged: function(aURI,
|
onTitleChanged(aURI, aTitle, aGUID) {
|
||||||
aTitle,
|
|
||||||
aGUID)
|
|
||||||
{
|
|
||||||
do_log_info("onTitleChanged(" + aURI.spec + ", " + aTitle + ", " + aGUID + ")");
|
do_log_info("onTitleChanged(" + aURI.spec + ", " + aTitle + ", " + aGUID + ")");
|
||||||
if (!this.uri.equals(aURI)) {
|
if (!this.uri.equals(aURI)) {
|
||||||
return;
|
return;
|
||||||
|
@ -148,14 +142,12 @@ function do_check_title_for_uri(aURI,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//// Test Functions
|
//// Test Functions
|
||||||
|
|
||||||
function test_interface_exists()
|
add_task(function* test_interface_exists() {
|
||||||
{
|
|
||||||
let history = Cc["@mozilla.org/browser/history;1"].getService(Ci.nsISupports);
|
let history = Cc["@mozilla.org/browser/history;1"].getService(Ci.nsISupports);
|
||||||
do_check_true(history instanceof Ci.mozIAsyncHistory);
|
do_check_true(history instanceof Ci.mozIAsyncHistory);
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_invalid_uri_throws()
|
add_task(function* test_invalid_uri_throws() {
|
||||||
{
|
|
||||||
// First, test passing in nothing.
|
// First, test passing in nothing.
|
||||||
let place = {
|
let place = {
|
||||||
visits: [
|
visits: [
|
||||||
|
@ -188,10 +180,9 @@ function test_invalid_uri_throws()
|
||||||
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
|
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.
|
// First, test passing in nothing.
|
||||||
try {
|
try {
|
||||||
PlacesUtils.asyncHistory.updatePlaces();
|
PlacesUtils.asyncHistory.updatePlaces();
|
||||||
|
@ -219,10 +210,9 @@ function test_invalid_places_throws()
|
||||||
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
|
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.
|
// First check invalid length guid.
|
||||||
let place = {
|
let place = {
|
||||||
guid: "BAD_GUID",
|
guid: "BAD_GUID",
|
||||||
|
@ -249,10 +239,9 @@ function test_invalid_guid_throws()
|
||||||
catch (e) {
|
catch (e) {
|
||||||
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
|
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 =
|
const TEST_URI =
|
||||||
NetUtil.newURI(TEST_DOMAIN + "test_no_id_or_guid_no_visits_throws");
|
NetUtil.newURI(TEST_DOMAIN + "test_no_id_or_guid_no_visits_throws");
|
||||||
const TEST_GUID = "_RANDOMGUID_";
|
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 = {
|
let place = {
|
||||||
uri: NetUtil.newURI(TEST_DOMAIN + "test_add_visit_no_date_throws"),
|
uri: NetUtil.newURI(TEST_DOMAIN + "test_add_visit_no_date_throws"),
|
||||||
visits: [
|
visits: [
|
||||||
|
@ -308,10 +296,9 @@ function test_add_visit_no_date_throws()
|
||||||
catch (e) {
|
catch (e) {
|
||||||
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
|
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 = {
|
let place = {
|
||||||
uri: NetUtil.newURI(TEST_DOMAIN + "test_add_visit_no_transitionType_throws"),
|
uri: NetUtil.newURI(TEST_DOMAIN + "test_add_visit_no_transitionType_throws"),
|
||||||
visits: [
|
visits: [
|
||||||
|
@ -326,10 +313,9 @@ function test_add_visit_no_transitionType_throws()
|
||||||
catch (e) {
|
catch (e) {
|
||||||
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
|
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.
|
// First, test something that has a transition type lower than the first one.
|
||||||
let place = {
|
let place = {
|
||||||
uri: NetUtil.newURI(TEST_DOMAIN +
|
uri: NetUtil.newURI(TEST_DOMAIN +
|
||||||
|
@ -355,10 +341,9 @@ function test_add_visit_invalid_transitionType_throws()
|
||||||
catch (e) {
|
catch (e) {
|
||||||
do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
|
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.
|
// Array of protocols that nsINavHistoryService::canAddURI returns false for.
|
||||||
const URLS = [
|
const URLS = [
|
||||||
"about:config",
|
"about:config",
|
||||||
|
@ -404,10 +389,9 @@ function test_non_addable_uri_errors()
|
||||||
do_check_false(yield promiseIsURIVisited(place.info.uri));
|
do_check_false(yield promiseIsURIVisited(place.info.uri));
|
||||||
}
|
}
|
||||||
yield promiseAsyncUpdates();
|
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
|
// This test ensures that trying to add a visit, with a guid already found in
|
||||||
// another visit, fails.
|
// another visit, fails.
|
||||||
let place = {
|
let place = {
|
||||||
|
@ -443,10 +427,9 @@ function test_duplicate_guid_errors()
|
||||||
do_check_false(yield promiseIsURIVisited(badPlaceInfo.info.uri));
|
do_check_false(yield promiseIsURIVisited(badPlaceInfo.info.uri));
|
||||||
|
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_invalid_referrerURI_ignored()
|
add_task(function* test_invalid_referrerURI_ignored() {
|
||||||
{
|
|
||||||
let place = {
|
let place = {
|
||||||
uri: NetUtil.newURI(TEST_DOMAIN +
|
uri: NetUtil.newURI(TEST_DOMAIN +
|
||||||
"test_invalid_referrerURI_ignored"),
|
"test_invalid_referrerURI_ignored"),
|
||||||
|
@ -480,10 +463,9 @@ function test_invalid_referrerURI_ignored()
|
||||||
stmt.finalize();
|
stmt.finalize();
|
||||||
|
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_nonnsIURI_referrerURI_ignored()
|
add_task(function* test_nonnsIURI_referrerURI_ignored() {
|
||||||
{
|
|
||||||
let place = {
|
let place = {
|
||||||
uri: NetUtil.newURI(TEST_DOMAIN +
|
uri: NetUtil.newURI(TEST_DOMAIN +
|
||||||
"test_nonnsIURI_referrerURI_ignored"),
|
"test_nonnsIURI_referrerURI_ignored"),
|
||||||
|
@ -513,10 +495,9 @@ function test_nonnsIURI_referrerURI_ignored()
|
||||||
stmt.finalize();
|
stmt.finalize();
|
||||||
|
|
||||||
yield promiseAsyncUpdates();
|
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,
|
// 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
|
// older than 15 minutes as per RECENT_EVENT_THRESHOLD) is not saved by
|
||||||
// updatePlaces.
|
// updatePlaces.
|
||||||
|
@ -573,10 +554,9 @@ function test_old_referrer_ignored()
|
||||||
stmt.finalize();
|
stmt.finalize();
|
||||||
|
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_place_id_ignored()
|
add_task(function* test_place_id_ignored() {
|
||||||
{
|
|
||||||
let place = {
|
let place = {
|
||||||
uri: NetUtil.newURI(TEST_DOMAIN + "test_place_id_ignored_first"),
|
uri: NetUtil.newURI(TEST_DOMAIN + "test_place_id_ignored_first"),
|
||||||
visits: [
|
visits: [
|
||||||
|
@ -614,10 +594,9 @@ function test_place_id_ignored()
|
||||||
do_check_true(yield promiseIsURIVisited(badPlace.uri));
|
do_check_true(yield promiseIsURIVisited(badPlace.uri));
|
||||||
|
|
||||||
yield promiseAsyncUpdates();
|
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
|
// 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*
|
// the canAddURI test to make sure that the notification happens after *all*
|
||||||
// of them have had a callback.
|
// 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(callbackCountSuccess, EXPECTED_COUNT_SUCCESS);
|
||||||
do_check_eq(callbackCountFailure, EXPECTED_COUNT_FAILURE);
|
do_check_eq(callbackCountFailure, EXPECTED_COUNT_FAILURE);
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_add_visit()
|
add_task(function* test_add_visit() {
|
||||||
{
|
|
||||||
const VISIT_TIME = Date.now() * 1000;
|
const VISIT_TIME = Date.now() * 1000;
|
||||||
let place = {
|
let place = {
|
||||||
uri: NetUtil.newURI(TEST_DOMAIN + "test_add_visit"),
|
uri: NetUtil.newURI(TEST_DOMAIN + "test_add_visit"),
|
||||||
|
@ -720,10 +698,9 @@ function test_add_visit()
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_properties_saved()
|
add_task(function* test_properties_saved() {
|
||||||
{
|
|
||||||
// Check each transition type to make sure it is saved properly.
|
// Check each transition type to make sure it is saved properly.
|
||||||
let places = [];
|
let places = [];
|
||||||
for (let transitionType = TRANSITION_LINK;
|
for (let transitionType = TRANSITION_LINK;
|
||||||
|
@ -804,10 +781,9 @@ function test_properties_saved()
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_guid_saved()
|
add_task(function* test_guid_saved() {
|
||||||
{
|
|
||||||
let place = {
|
let place = {
|
||||||
uri: NetUtil.newURI(TEST_DOMAIN + "test_guid_saved"),
|
uri: NetUtil.newURI(TEST_DOMAIN + "test_guid_saved"),
|
||||||
guid: "__TESTGUID__",
|
guid: "__TESTGUID__",
|
||||||
|
@ -828,10 +804,9 @@ function test_guid_saved()
|
||||||
do_check_eq(placeInfo.guid, place.guid);
|
do_check_eq(placeInfo.guid, place.guid);
|
||||||
do_check_guid_for_uri(uri, place.guid);
|
do_check_guid_for_uri(uri, place.guid);
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_referrer_saved()
|
add_task(function* test_referrer_saved() {
|
||||||
{
|
|
||||||
let places = [
|
let places = [
|
||||||
{ uri: NetUtil.newURI(TEST_DOMAIN + "test_referrer_saved/referrer"),
|
{ uri: NetUtil.newURI(TEST_DOMAIN + "test_referrer_saved/referrer"),
|
||||||
visits: [
|
visits: [
|
||||||
|
@ -881,10 +856,9 @@ function test_referrer_saved()
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_guid_change_saved()
|
add_task(function* test_guid_change_saved() {
|
||||||
{
|
|
||||||
// First, add a visit for it.
|
// First, add a visit for it.
|
||||||
let place = {
|
let place = {
|
||||||
uri: NetUtil.newURI(TEST_DOMAIN + "test_guid_change_saved"),
|
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);
|
do_check_guid_for_uri(place.uri, place.guid);
|
||||||
|
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_title_change_saved()
|
add_task(function* test_title_change_saved() {
|
||||||
{
|
|
||||||
// First, add a visit for it.
|
// First, add a visit for it.
|
||||||
let place = {
|
let place = {
|
||||||
uri: NetUtil.newURI(TEST_DOMAIN + "test_title_change_saved"),
|
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);
|
do_check_title_for_uri(place.uri, place.title);
|
||||||
|
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
});
|
||||||
|
|
||||||
function test_no_title_does_not_clear_title()
|
add_task(function* test_no_title_does_not_clear_title() {
|
||||||
{
|
|
||||||
const TITLE = "test title";
|
const TITLE = "test title";
|
||||||
// First, add a visit for it.
|
// First, add a visit for it.
|
||||||
let place = {
|
let place = {
|
||||||
|
@ -984,10 +956,9 @@ function test_no_title_does_not_clear_title()
|
||||||
do_check_title_for_uri(place.uri, TITLE);
|
do_check_title_for_uri(place.uri, TITLE);
|
||||||
|
|
||||||
yield promiseAsyncUpdates();
|
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
|
// 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.
|
// get notified if we do not specify a title.
|
||||||
let place = {
|
let place = {
|
||||||
|
@ -1015,36 +986,35 @@ function test_title_change_notifies()
|
||||||
place.uri = NetUtil.newURI(place.uri.spec + "/new-visit-with-title");
|
place.uri = NetUtil.newURI(place.uri.spec + "/new-visit-with-title");
|
||||||
place.title = "title 1";
|
place.title = "title 1";
|
||||||
function promiseTitleChangedObserver(aPlace) {
|
function promiseTitleChangedObserver(aPlace) {
|
||||||
let deferred = Promise.defer();
|
return new Promise((resolve, reject) => {
|
||||||
let callbackCount = 0;
|
let callbackCount = 0;
|
||||||
let observer = new TitleChangedObserver(aPlace.uri, aPlace.title, function() {
|
let observer = new TitleChangedObserver(aPlace.uri, aPlace.title, function() {
|
||||||
switch (++callbackCount) {
|
switch (++callbackCount) {
|
||||||
case 1:
|
case 1:
|
||||||
// The third case to test is to make sure we get a notification when
|
// The third case to test is to make sure we get a notification when
|
||||||
// we change an existing place.
|
// we change an existing place.
|
||||||
observer.expectedTitle = place.title = "title 2";
|
observer.expectedTitle = place.title = "title 2";
|
||||||
place.visits = [new VisitInfo()];
|
place.visits = [new VisitInfo()];
|
||||||
PlacesUtils.asyncHistory.updatePlaces(place);
|
PlacesUtils.asyncHistory.updatePlaces(place);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
PlacesUtils.history.removeObserver(silentObserver);
|
PlacesUtils.history.removeObserver(silentObserver);
|
||||||
PlacesUtils.history.removeObserver(observer);
|
PlacesUtils.history.removeObserver(observer);
|
||||||
deferred.resolve();
|
resolve();
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
PlacesUtils.history.addObserver(observer, false);
|
PlacesUtils.history.addObserver(observer, false);
|
||||||
PlacesUtils.asyncHistory.updatePlaces(aPlace);
|
PlacesUtils.asyncHistory.updatePlaces(aPlace);
|
||||||
return deferred.promise;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
yield promiseTitleChangedObserver(place);
|
yield promiseTitleChangedObserver(place);
|
||||||
yield promiseAsyncUpdates();
|
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
|
// 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.
|
// nsINavHistoryObserver and the other is the uri-visit-saved observer topic.
|
||||||
let place = {
|
let place = {
|
||||||
|
@ -1057,44 +1027,43 @@ function test_visit_notifies()
|
||||||
do_check_false(yield promiseIsURIVisited(place.uri));
|
do_check_false(yield promiseIsURIVisited(place.uri));
|
||||||
|
|
||||||
function promiseVisitObserver(aPlace) {
|
function promiseVisitObserver(aPlace) {
|
||||||
let deferred = Promise.defer();
|
return new Promise((resolve, reject) => {
|
||||||
let callbackCount = 0;
|
let callbackCount = 0;
|
||||||
let finisher = function() {
|
let finisher = function() {
|
||||||
if (++callbackCount == 2) {
|
if (++callbackCount == 2) {
|
||||||
deferred.resolve();
|
resolve();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
let visitObserver = new VisitObserver(place.uri, place.guid,
|
||||||
let visitObserver = new VisitObserver(place.uri, place.guid,
|
function(aVisitDate,
|
||||||
function(aVisitDate,
|
aTransitionType) {
|
||||||
aTransitionType) {
|
let visit = place.visits[0];
|
||||||
let visit = place.visits[0];
|
do_check_eq(visit.visitDate, aVisitDate);
|
||||||
do_check_eq(visit.visitDate, aVisitDate);
|
do_check_eq(visit.transitionType, aTransitionType);
|
||||||
do_check_eq(visit.transitionType, aTransitionType);
|
|
||||||
|
|
||||||
PlacesUtils.history.removeObserver(visitObserver);
|
PlacesUtils.history.removeObserver(visitObserver);
|
||||||
finisher();
|
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 promiseVisitObserver(place);
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
});
|
||||||
|
|
||||||
// test with empty mozIVisitInfoCallback object
|
// test with empty mozIVisitInfoCallback object
|
||||||
function test_callbacks_not_supplied()
|
add_task(function* test_callbacks_not_supplied() {
|
||||||
{
|
|
||||||
const URLS = [
|
const URLS = [
|
||||||
"imap://cyrus.andrew.cmu.edu/archive.imap", // bad URI
|
"imap://cyrus.andrew.cmu.edu/archive.imap", // bad URI
|
||||||
"http://mozilla.org/" // valid URI
|
"http://mozilla.org/" // valid URI
|
||||||
|
@ -1121,40 +1090,36 @@ function test_callbacks_not_supplied()
|
||||||
|
|
||||||
PlacesUtils.asyncHistory.updatePlaces(places, {});
|
PlacesUtils.asyncHistory.updatePlaces(places, {});
|
||||||
yield promiseAsyncUpdates();
|
yield promiseAsyncUpdates();
|
||||||
}
|
});
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
// Test that we don't wrongly overwrite typed and hidden when adding new visits.
|
||||||
//// Test Runner
|
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);
|
||||||
|
|
||||||
[
|
let db = yield PlacesUtils.promiseDBConnection();
|
||||||
test_interface_exists,
|
let rows = yield db.execute("SELECT hidden, typed FROM moz_places WHERE url = :url",
|
||||||
test_invalid_uri_throws,
|
{ url: "http://mozilla.org/" });
|
||||||
test_invalid_places_throws,
|
Assert.equal(rows[0].getResultByName("typed"), 1,
|
||||||
test_invalid_guid_throws,
|
"The page should be marked as typed");
|
||||||
test_no_visits_throws,
|
Assert.equal(rows[0].getResultByName("hidden"), 0,
|
||||||
test_add_visit_no_date_throws,
|
"The page should be marked as not hidden");
|
||||||
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);
|
|
||||||
|
|
||||||
function run_test()
|
function run_test()
|
||||||
{
|
{
|
||||||
|
|
|
@ -605,4 +605,11 @@
|
||||||
<children includes="menupopup"/>
|
<children includes="menupopup"/>
|
||||||
</content>
|
</content>
|
||||||
</binding>
|
</binding>
|
||||||
|
|
||||||
|
<binding id="menulist-popuponly" display="xul:menu"
|
||||||
|
extends="chrome://global/content/bindings/menulist.xml#menulist">
|
||||||
|
<content>
|
||||||
|
<children includes="menupopup"/>
|
||||||
|
</content>
|
||||||
|
</binding>
|
||||||
</bindings>
|
</bindings>
|
||||||
|
|
|
@ -248,7 +248,7 @@
|
||||||
this.messageManager.addMessageListener("DOMFullscreen:RequestRollback", this);
|
this.messageManager.addMessageListener("DOMFullscreen:RequestRollback", this);
|
||||||
this.messageManager.loadFrameScript("chrome://global/content/browser-child.js", true);
|
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:ShowDropDown", this);
|
||||||
this.messageManager.addMessageListener("Forms:HideDropDown", this);
|
this.messageManager.addMessageListener("Forms:HideDropDown", this);
|
||||||
this.messageManager.loadFrameScript("chrome://global/content/select-child.js", true);
|
this.messageManager.loadFrameScript("chrome://global/content/select-child.js", true);
|
||||||
|
@ -310,9 +310,9 @@
|
||||||
|
|
||||||
case "Forms:ShowDropDown": {
|
case "Forms:ShowDropDown": {
|
||||||
Cu.import("resource://gre/modules/SelectParentHelper.jsm");
|
Cu.import("resource://gre/modules/SelectParentHelper.jsm");
|
||||||
let dropdown = document.getElementById(this.getAttribute("selectpopup"));
|
let menulist = document.getElementById(this.getAttribute("selectmenulist"));
|
||||||
SelectParentHelper.populate(dropdown, data.options, data.selectedIndex);
|
SelectParentHelper.populate(menulist, data.options, data.selectedIndex);
|
||||||
SelectParentHelper.open(this, dropdown, data.rect);
|
SelectParentHelper.open(this, menulist, data.rect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,8 +345,8 @@
|
||||||
|
|
||||||
case "Forms:HideDropDown": {
|
case "Forms:HideDropDown": {
|
||||||
Cu.import("resource://gre/modules/SelectParentHelper.jsm");
|
Cu.import("resource://gre/modules/SelectParentHelper.jsm");
|
||||||
let dropdown = document.getElementById(this.getAttribute("selectpopup"));
|
let menulist = document.getElementById(this.getAttribute("selectmenulist"));
|
||||||
SelectParentHelper.hide(dropdown);
|
SelectParentHelper.hide(menulist);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -930,6 +930,14 @@ menulist {
|
||||||
-moz-binding: url("chrome://global/content/bindings/menulist.xml#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"] {
|
menulist[editable="true"] {
|
||||||
-moz-binding: url("chrome://global/content/bindings/menulist.xml#menulist-editable");
|
-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 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-";
|
let elementId = this.ID_CLASS_PREFIX + "nodeinfobar-";
|
||||||
this.markup.setTextContentForElement(elementId + "tagname", tagName);
|
this.markup.setTextContentForElement(elementId + "tagname", tagName);
|
||||||
|
|
|
@ -136,7 +136,7 @@ let MemoryActor = protocol.ActorClass({
|
||||||
if (this.state == "attached") {
|
if (this.state == "attached") {
|
||||||
if (isTopLevel && this.dbg.memory.trackingAllocationSites) {
|
if (isTopLevel && this.dbg.memory.trackingAllocationSites) {
|
||||||
this._clearDebuggees();
|
this._clearDebuggees();
|
||||||
nthis._frameCache.initFrames();
|
this._frameCache.initFrames();
|
||||||
}
|
}
|
||||||
this.dbg.addDebuggees();
|
this.dbg.addDebuggees();
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,6 +500,7 @@ let NetworkHelper = {
|
||||||
* - state: The security of the connection used to fetch this
|
* - state: The security of the connection used to fetch this
|
||||||
* request. Has one of following string values:
|
* request. Has one of following string values:
|
||||||
* * "insecure": the connection was not secure (only http)
|
* * "insecure": the connection was not secure (only http)
|
||||||
|
* * "weak": the connection has minor security issues
|
||||||
* * "broken": secure connection failed (e.g. expired cert)
|
* * "broken": secure connection failed (e.g. expired cert)
|
||||||
* * "secure": the connection was properly secured.
|
* * "secure": the connection was properly secured.
|
||||||
* If state == broken:
|
* If state == broken:
|
||||||
|
@ -511,6 +512,9 @@ let NetworkHelper = {
|
||||||
* See parseCertificateInfo for the contents.
|
* See parseCertificateInfo for the contents.
|
||||||
* - hsts: true if host uses Strict Transport Security, false otherwise
|
* - hsts: true if host uses Strict Transport Security, false otherwise
|
||||||
* - hpkp: true if host uses Public Key Pinning, 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) {
|
parseSecurityInfo: function NH_parseSecurityInfo(securityInfo, httpActivity) {
|
||||||
const info = {
|
const info = {
|
||||||
|
@ -551,7 +555,7 @@ let NetworkHelper = {
|
||||||
* => .securityState has STATE_IS_BROKEN flag
|
* => .securityState has STATE_IS_BROKEN flag
|
||||||
* => .errorCode is NOT an NSS error code
|
* => .errorCode is NOT an NSS error code
|
||||||
* => .errorMessage is not available
|
* => .errorMessage is not available
|
||||||
* => state === "insecure"
|
* => state === "weak"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
|
securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
|
||||||
|
@ -561,10 +565,26 @@ let NetworkHelper = {
|
||||||
const NSSErrorsService = Cc['@mozilla.org/nss_errors_service;1']
|
const NSSErrorsService = Cc['@mozilla.org/nss_errors_service;1']
|
||||||
.getService(Ci.nsINSSErrorsService);
|
.getService(Ci.nsINSSErrorsService);
|
||||||
const SSLStatus = securityInfo.SSLStatus;
|
const SSLStatus = securityInfo.SSLStatus;
|
||||||
|
if (!NSSErrorsService.isNSSErrorCode(securityInfo.errorCode)) {
|
||||||
|
const state = securityInfo.securityState;
|
||||||
|
|
||||||
if (securityInfo.securityState & wpl.STATE_IS_SECURE) {
|
if (state & wpl.STATE_IS_SECURE) {
|
||||||
// The connection is secure.
|
// The connection is secure.
|
||||||
info.state = "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.
|
// Cipher suite.
|
||||||
info.cipherSuite = SSLStatus.cipherName;
|
info.cipherSuite = SSLStatus.cipherName;
|
||||||
|
@ -598,14 +618,10 @@ let NetworkHelper = {
|
||||||
info.hpkp = false;
|
info.hpkp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (NSSErrorsService.isNSSErrorCode(securityInfo.errorCode)) {
|
} else {
|
||||||
// The connection failed.
|
// The connection failed.
|
||||||
info.state = "broken";
|
info.state = "broken";
|
||||||
info.errorMessage = securityInfo.errorMessage;
|
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;
|
return info;
|
||||||
|
@ -683,6 +699,46 @@ let NetworkHelper = {
|
||||||
return "Unknown";
|
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)) {
|
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() {
|
function test_brokenSecurityInfo() {
|
||||||
MockSecurityInfo.securityState = wpl.STATE_IS_BROKEN;
|
MockSecurityInfo.securityState = wpl.STATE_IS_BROKEN;
|
||||||
|
|
||||||
let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {});
|
let result = NetworkHelper.parseSecurityInfo(MockSecurityInfo, {});
|
||||||
equal(result.state, "insecure",
|
equal(result.state, "weak",
|
||||||
"state == 'insecure' if securityState contains STATE_IS_BROKEN flag");
|
"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-protocol-version.js]
|
||||||
[test_security-info-state.js]
|
[test_security-info-state.js]
|
||||||
[test_security-info-static-hpkp.js]
|
[test_security-info-static-hpkp.js]
|
||||||
|
[test_security-info-weakness-reasons.js]
|
||||||
|
|
|
@ -11,27 +11,35 @@ this.EXPORTED_SYMBOLS = [
|
||||||
let currentBrowser = null;
|
let currentBrowser = null;
|
||||||
|
|
||||||
this.SelectParentHelper = {
|
this.SelectParentHelper = {
|
||||||
populate: function(popup, items, selectedIndex) {
|
populate: function(menulist, items, selectedIndex) {
|
||||||
// Clear the current contents of the popup
|
// Clear the current contents of the popup
|
||||||
popup.textContent = "";
|
menulist.menupopup.textContent = "";
|
||||||
populateChildren(popup, items, selectedIndex);
|
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;
|
currentBrowser = browser;
|
||||||
this._registerListeners(popup);
|
this._registerListeners(menulist.menupopup);
|
||||||
popup.hidden = false;
|
|
||||||
|
|
||||||
let {x, y} = browser.mapScreenCoordinatesFromContent(rect.left, rect.top + rect.height);
|
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) {
|
hide: function(menulist) {
|
||||||
popup.hidePopup();
|
menulist.menupopup.hidePopup();
|
||||||
},
|
},
|
||||||
|
|
||||||
handleEvent: function(event) {
|
handleEvent: function(event) {
|
||||||
let popup = event.currentTarget;
|
let popup = event.currentTarget;
|
||||||
|
let menulist = popup.parentNode;
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case "command":
|
case "command":
|
||||||
|
@ -47,6 +55,7 @@ this.SelectParentHelper = {
|
||||||
currentBrowser.messageManager.sendAsyncMessage("Forms:DismissedDropDown", {});
|
currentBrowser.messageManager.sendAsyncMessage("Forms:DismissedDropDown", {});
|
||||||
currentBrowser = null;
|
currentBrowser = null;
|
||||||
this._unregisterListeners(popup);
|
this._unregisterListeners(popup);
|
||||||
|
menulist.hidden = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -69,11 +78,6 @@ function populateChildren(element, options, selectedIndex, startIndex = 0, isGro
|
||||||
for (let option of options) {
|
for (let option of options) {
|
||||||
let item = element.ownerDocument.createElement("menuitem");
|
let item = element.ownerDocument.createElement("menuitem");
|
||||||
item.setAttribute("label", option.textContent);
|
item.setAttribute("label", option.textContent);
|
||||||
item.setAttribute("type", "radio");
|
|
||||||
|
|
||||||
if (index == selectedIndex) {
|
|
||||||
item.setAttribute("checked", "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
element.appendChild(item);
|
element.appendChild(item);
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,14 @@
|
||||||
menulist {
|
menulist {
|
||||||
-moz-appearance: menulist;
|
-moz-appearance: menulist;
|
||||||
margin: 5px 2px 3px;
|
margin: 5px 2px 3px;
|
||||||
min-height: 20px !important;
|
|
||||||
color: -moz-DialogText;
|
color: -moz-DialogText;
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
menulist:not([popuponly="true"]) {
|
||||||
|
min-height: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.menulist-label-box {
|
.menulist-label-box {
|
||||||
-moz-appearance: menulist-text;
|
-moz-appearance: menulist-text;
|
||||||
-moz-box-align: center;
|
-moz-box-align: center;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче