This commit is contained in:
Wes Kocher 2014-09-05 17:52:51 -07:00
Родитель cc9189e5b1 40c14fa70b
Коммит 9ee1078d65
6 изменённых файлов: 178 добавлений и 58 удалений

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

@ -67,6 +67,8 @@ window.busy-determined #action-busy-undetermined {
#project-panel-button {
-moz-box-pack: start;
width: 150px;
max-width: 150px;
}
#project-panel-button > .panel-button-image {
@ -86,6 +88,7 @@ window.busy-determined #action-busy-undetermined {
}
#project-panel-button > .panel-button-label {
width: 150px;
max-width: 150px;
}

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

@ -79,6 +79,32 @@ public class BrowserLocaleManager implements LocaleManager {
return AppConstants.MOZ_LOCALE_SWITCHER;
}
/**
* Sometimes we want just the language for a locale, not the entire
* language tag. But Java's .getLanguage method is wrong.
*
* This method is equivalent to the first part of {@link #getLanguageTag(Locale)}.
*
* @return a language string, such as "he" for the Hebrew locales.
*/
public static String getLanguage(final Locale locale) {
final String language = locale.getLanguage(); // Can, but should never be, an empty string.
// Modernize certain language codes.
if (language.equals("iw")) {
return "he";
}
if (language.equals("in")) {
return "id";
}
if (language.equals("ji")) {
return "yi";
}
return language;
}
/**
* Gecko uses locale codes like "es-ES", whereas a Java {@link Locale}
* stringifies as "es_ES".
@ -91,17 +117,8 @@ public class BrowserLocaleManager implements LocaleManager {
// If this were Java 7:
// return locale.toLanguageTag();
String language = locale.getLanguage(); // Can, but should never be, an empty string.
// Modernize certain language codes.
if (language.equals("iw")) {
language = "he";
} else if (language.equals("in")) {
language = "id";
} else if (language.equals("ji")) {
language = "yi";
}
String country = locale.getCountry(); // Can be an empty string.
final String language = getLanguage(locale);
final String country = locale.getCountry(); // Can be an empty string.
if (country.equals("")) {
return language;
}

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

@ -758,6 +758,36 @@ ActivePluginsMeasurement.prototype = Object.freeze({
},
});
function ActiveGMPluginsMeasurement() {
Metrics.Measurement.call(this);
this._serializers = {};
this._serializers[this.SERIALIZE_JSON] = {
singular: this._serializeJSONSingular.bind(this),
};
}
ActiveGMPluginsMeasurement.prototype = Object.freeze({
__proto__: Metrics.Measurement.prototype,
name: "gm-plugins",
version: 1,
fields: {
"gm-plugins": LAST_TEXT_FIELD,
},
_serializeJSONSingular: function (data) {
if (!data.has("gm-plugins")) {
this._log.warn("Don't have GM plugins info. Weird.");
return null;
}
let result = JSON.parse(data.get("gm-plugins")[1]);
result._v = this.version;
return result;
},
});
function AddonCountsMeasurement() {
Metrics.Measurement.call(this);
@ -834,6 +864,7 @@ AddonsProvider.prototype = Object.freeze({
measurementTypes: [
ActiveAddonsMeasurement,
ActivePluginsMeasurement,
ActiveGMPluginsMeasurement,
AddonCountsMeasurement1,
AddonCountsMeasurement,
],
@ -869,10 +900,12 @@ AddonsProvider.prototype = Object.freeze({
let data;
let addonsField;
let pluginsField;
let gmPluginsField;
try {
data = this._createDataStructure(allAddons);
addonsField = JSON.stringify(data.addons);
pluginsField = JSON.stringify(data.plugins);
gmPluginsField = JSON.stringify(data.gmPlugins);
} catch (ex) {
this._log.warn("Exception when populating add-ons data structure: " +
CommonUtils.exceptionStr(ex));
@ -883,6 +916,7 @@ AddonsProvider.prototype = Object.freeze({
let now = new Date();
let addons = this.getMeasurement("addons", 2);
let plugins = this.getMeasurement("plugins", 1);
let gmPlugins = this.getMeasurement("gm-plugins", 1);
let counts = this.getMeasurement(AddonCountsMeasurement.prototype.name,
AddonCountsMeasurement.prototype.version);
@ -901,7 +935,15 @@ AddonsProvider.prototype = Object.freeze({
return addons.setLastText("addons", addonsField).then(
function onSuccess() {
return plugins.setLastText("plugins", pluginsField).then(
function onSuccess() { deferred.resolve(); },
function onSuccess() {
return gmPlugins.setLastText("gm-plugins", gmPluginsField).then(
function onSuccess() {
deferred.resolve();
},
function onError(error) {
deferred.reject(error);
});
},
function onError(error) { deferred.reject(error); }
);
},
@ -938,6 +980,7 @@ AddonsProvider.prototype = Object.freeze({
let data = {
addons: {},
plugins: {},
gmPlugins: {},
counts: {}
};
@ -945,8 +988,16 @@ AddonsProvider.prototype = Object.freeze({
let type = addon.type;
// We count plugins separately below.
if (addon.type == "plugin")
if (addon.type == "plugin") {
if (addon.gmPlugin) {
data.gmPlugins[addon.id] = {
version: addon.version,
userDisabled: addon.userDisabled,
applyBackgroundUpdates: addon.applyBackgroundUpdates,
};
}
continue;
}
data.counts[type] = (data.counts[type] || 0) + 1;

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

@ -116,6 +116,21 @@ add_task(function test_collect() {
updateDate: now,
description: "addon3 description"
},
{
// Should be excluded from the report completely
id: "pluginfake",
type: "plugin",
userDisabled: false,
appDisabled: false,
},
{
// Should be in gm-plugins
id: "gmp-testgmp",
type: "plugin",
userDisabled: false,
version: "7.2",
gmPlugin: true,
},
];
monkeypatchAddons(provider, testAddons);
@ -186,6 +201,8 @@ add_task(function test_collect() {
do_check_true(!("addon1" in value));
do_check_true(!("addon2" in value));
do_check_true("addon3" in value);
do_check_true(!("pluginfake" in value));
do_check_true(!("gmp-testgmp" in value));
let serializer = addons.serializer(addons.SERIALIZE_JSON);
let serialized = serializer.singular(data.singular);
@ -237,6 +254,30 @@ add_task(function test_collect() {
}
do_check_eq(serialized._v, 1);
// Test GMP plugins measurement.
let gmPlugins = provider.getMeasurement("gm-plugins", 1);
data = yield gmPlugins.getValues();
do_check_eq(data.days.size, 0);
do_check_eq(data.singular.size, 1);
do_check_true(data.singular.has("gm-plugins"));
json = data.singular.get("gm-plugins")[1];
value = JSON.parse(json);
do_print("value: " + json);
do_check_eq(typeof(value), "object");
do_check_eq(Object.keys(value).length, 1);
do_check_eq(value["gmp-testgmp"].version, "7.2");
do_check_eq(value["gmp-testgmp"].userDisabled, false);
serializer = gmPlugins.serializer(plugins.SERIALIZE_JSON);
serialized = serializer.singular(data.singular);
do_check_eq(typeof(serialized), "object");
do_check_eq(serialized["gmp-testgmp"].version, "7.2");
do_check_eq(serialized._v, 1);
// Test counts measurement.
let counts = provider.getMeasurement("counts", 2);

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

@ -23,12 +23,12 @@ Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
* # ConnectionManager
*
* Methods:
* Connection createConnection(host, port)
* void destroyConnection(connection)
* Number getFreeTCPPort()
* . Connection createConnection(host, port)
* . void destroyConnection(connection)
* . Number getFreeTCPPort()
*
* Properties:
* Array connections
* . Array connections
*
* # Connection
*
@ -38,33 +38,34 @@ Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
* will re-create a debugger client.
*
* Methods:
* connect() Connect to host:port. Expect a "connecting" event. If
* host is not specified, a local pipe is used
* disconnect() Disconnect if connected. Expect a "disconnecting" event
* . connect() Connect to host:port. Expect a "connecting" event.
* If no host is not specified, a local pipe is used
* . connect(transport) Connect via transport. Expect a "connecting" event.
* . disconnect() Disconnect if connected. Expect a "disconnecting" event
*
* Properties:
* host IP address or hostname
* port Port
* logs Current logs. "newlog" event notifies new available logs
* store Reference to a local data store (see below)
* keepConnecting Should the connection keep trying connecting
* status Connection status:
* Connection.Status.CONNECTED
* Connection.Status.DISCONNECTED
* Connection.Status.CONNECTING
* Connection.Status.DISCONNECTING
* Connection.Status.DESTROYED
* . host IP address or hostname
* . port Port
* . logs Current logs. "newlog" event notifies new available logs
* . store Reference to a local data store (see below)
* . keepConnecting Should the connection keep trying connecting
* . status Connection status:
* Connection.Status.CONNECTED
* Connection.Status.DISCONNECTED
* Connection.Status.CONNECTING
* Connection.Status.DISCONNECTING
* Connection.Status.DESTROYED
*
* Events (as in event-emitter.js):
* Connection.Events.CONNECTING Trying to connect to host:port
* Connection.Events.CONNECTED Connection is successful
* Connection.Events.DISCONNECTING Trying to disconnect from server
* Connection.Events.DISCONNECTED Disconnected (at client request, or because of a timeout or connection error)
* Connection.Events.STATUS_CHANGED The connection status (connection.status) has changed
* Connection.Events.TIMEOUT Connection timeout
* Connection.Events.HOST_CHANGED Host has changed
* Connection.Events.PORT_CHANGED Port has changed
* Connection.Events.NEW_LOG A new log line is available
* . Connection.Events.CONNECTING Trying to connect to host:port
* . Connection.Events.CONNECTED Connection is successful
* . Connection.Events.DISCONNECTING Trying to disconnect from server
* . Connection.Events.DISCONNECTED Disconnected (at client request, or because of a timeout or connection error)
* . Connection.Events.STATUS_CHANGED The connection status (connection.status) has changed
* . Connection.Events.TIMEOUT Connection timeout
* . Connection.Events.HOST_CHANGED Host has changed
* . Connection.Events.PORT_CHANGED Port has changed
* . Connection.Events.NEW_LOG A new log line is available
*
*/
@ -187,16 +188,21 @@ Connection.prototype = {
}
},
connect: function() {
connect: function(transport) {
if (this.status == Connection.Status.DESTROYED) {
return;
}
if (!this._client) {
this.log("connecting to " + this.host + ":" + this.port);
this._transport = transport;
if (this._transport) {
this.log("connecting (custom transport)");
} else {
this.log("connecting to " + this.host + ":" + this.port);
}
this._setStatus(Connection.Status.CONNECTING);
let delay = Services.prefs.getIntPref("devtools.debugger.remote-timeout");
this._timeoutID = setTimeout(this._onTimeout, delay);
this._clientConnect();
} else {
let msg = "Can't connect. Client is not fully disconnected";
@ -217,23 +223,24 @@ Connection.prototype = {
},
_clientConnect: function () {
let transport;
if (!this.host) {
transport = DebuggerServer.connectPipe();
} else {
try {
transport = debuggerSocketConnect(this.host, this.port);
} catch (e) {
// In some cases, especially on Mac, the openOutputStream call in
// debuggerSocketConnect may throw NS_ERROR_NOT_INITIALIZED.
// It occurs when we connect agressively to the simulator,
// and keep trying to open a socket to the server being started in
// the simulator.
this._onDisconnected();
return;
if (!this._transport) {
if (!this.host) {
this._transport = DebuggerServer.connectPipe();
} else {
try {
this._transport = debuggerSocketConnect(this.host, this.port);
} catch (e) {
// In some cases, especially on Mac, the openOutputStream call in
// debuggerSocketConnect may throw NS_ERROR_NOT_INITIALIZED.
// It occurs when we connect agressively to the simulator,
// and keep trying to open a socket to the server being started in
// the simulator.
this._onDisconnected();
return;
}
}
}
this._client = new DebuggerClient(transport);
this._client = new DebuggerClient(this._transport);
this._client.addOneTimeListener("closed", this._onDisconnected);
this._client.connect(this._onConnected);
},

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

@ -87,6 +87,7 @@ let OpenH264Wrapper = {
get id() { return OPENH264_PLUGIN_ID; },
get type() { return "plugin"; },
get isGMPlugin() { return true; },
get name() { return pluginsBundle.GetStringFromName("openH264_name"); },
get creator() { return null; },
get homepageURL() { return OPENH264_HOMEPAGE_URL; },