bug 1004825 - prioritized, tagged Android logging in JS; r=mfinkle, marco

This commit is contained in:
Myk Melez 2014-05-09 13:15:54 -07:00
parent dcb7d3c560
commit ce063f2025
9 changed files with 145 additions and 16 deletions

View File

@ -71,11 +71,20 @@ XPCOMUtils.defineLazyGetter(this, "libcutils", function() {
});
#endif
#ifdef MOZ_WIDGET_ANDROID
// On Android, define the "debug" function as a binding of the "d" function
// from the AndroidLog module so it gets the "debug" priority and a log tag.
// We always report debug messages on Android because it's hard to use a debug
// build on Android and unnecessary to restrict reporting, per bug 1003469.
let debug = Cu.import("resource://gre/modules/AndroidLog.jsm", {})
.AndroidLog.d.bind(null, "Webapps");
#else
function debug(aMsg) {
#ifdef DEBUG
dump("-*- Webapps.jsm : " + aMsg + "\n");
#endif
}
#endif
function getNSPRErrorCode(err) {
return -1 * ((err) & 0xffff);

View File

@ -111,6 +111,7 @@ skip-if = android_version == "10"
# Using JavascriptTest
[testAccounts]
[testAndroidLog]
[testBrowserDiscovery]
[testDeviceSearchEngine]
[testJNI]

View File

@ -0,0 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.tests;
public class testAndroidLog extends JavascriptTest {
public testAndroidLog() {
super("testAndroidLog.js");
}
@Override
public void testJavascript() throws Exception {
super.testJavascript();
}
}

View File

@ -0,0 +1,38 @@
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
add_task(function test_AndroidLog() {
Components.utils.import("resource://gre/modules/AndroidLog.jsm");
do_check_true(!!AndroidLog);
do_check_true("v" in AndroidLog && typeof AndroidLog.v == "function");
do_check_true("d" in AndroidLog && typeof AndroidLog.d == "function");
do_check_true("i" in AndroidLog && typeof AndroidLog.i == "function");
do_check_true("w" in AndroidLog && typeof AndroidLog.w == "function");
do_check_true("e" in AndroidLog && typeof AndroidLog.e == "function");
// I don't know how to check that these messages actually make it to the log,
// but at least we can ensure that they don't cause the test process to crash
// (because of some change to the native object being accessed via ctypes)
// and return the right values (the number of bytes--not characters--logged).
do_check_eq(48, AndroidLog.v("AndroidLogTest", "This is a verbose message."));
do_check_eq(46, AndroidLog.d("AndroidLogTest", "This is a debug message."));
do_check_eq(46, AndroidLog.i("AndroidLogTest", "This is an info message."));
do_check_eq(48, AndroidLog.w("AndroidLogTest", "This is a warning message."));
do_check_eq(47, AndroidLog.e("AndroidLogTest", "This is an error message."));
// Ensure the functions work when bound with null value for thisArg parameter.
do_check_eq(48, AndroidLog.v.bind(null, "AndroidLogTest")("This is a verbose message."));
do_check_eq(46, AndroidLog.d.bind(null, "AndroidLogTest")("This is a debug message."));
do_check_eq(46, AndroidLog.i.bind(null, "AndroidLogTest")("This is an info message."));
do_check_eq(48, AndroidLog.w.bind(null, "AndroidLogTest")("This is a warning message."));
do_check_eq(47, AndroidLog.e.bind(null, "AndroidLogTest")("This is an error message."));
// We should also ensure that the module is accessible from a ChromeWorker,
// but there doesn't seem to be a way to load a ChromeWorker from this test.
});
run_next_test();

View File

@ -173,9 +173,11 @@ const kDoNotTrackPrefState = Object.freeze({
ALLOW_TRACKING: "2",
});
function dump(a) {
Services.console.logStringMessage(a);
}
let Log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog;
// Define the "dump" function as a binding of the Log.d function so it specifies
// the "debug" priority and a log tag.
let dump = Log.d.bind(null, "Browser");
function doChangeMaxLineBoxWidth(aWidth) {
gReflowPending = null;

View File

@ -0,0 +1,67 @@
/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Native Android logging for JavaScript. Lets you specify a priority and tag
* in addition to the message being logged. Resembles the android.util.Log API
* <http://developer.android.com/reference/android/util/Log.html>.
*
* // Import it as a JSM:
* let Log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog;
*
* // Or require it in a chrome worker:
* importScripts("resource://gre/modules/workers/require.js");
* let Log = require("resource://gre/modules/AndroidLog.jsm");
*
* // Use Log.i, Log.v, Log.d, Log.w, and Log.e to log verbose, debug, info,
* // warning, and error messages, respectively.
* Log.v("MyModule", "This is a verbose message.");
* Log.d("MyModule", "This is a debug message.");
* Log.i("MyModule", "This is an info message.");
* Log.w("MyModule", "This is a warning message.");
* Log.e("MyModule", "This is an error message.");
*
* // Bind a function with a tag to replace a bespoke dump/log/debug function:
* let debug = Log.d.bind(null, "MyModule");
* debug("This is a debug message.");
*
* Note: the module automatically prepends "Gecko" to the tag you specify,
* since all tags used by Fennec code should start with that string.
*/
if (typeof Components != "undefined") {
// Specify exported symbols for JSM module loader.
this.EXPORTED_SYMBOLS = ["AndroidLog"];
Components.utils.import("resource://gre/modules/ctypes.jsm");
}
// From <https://android.googlesource.com/platform/system/core/+/master/include/android/log.h>.
const ANDROID_LOG_VERBOSE = 2;
const ANDROID_LOG_DEBUG = 3;
const ANDROID_LOG_INFO = 4;
const ANDROID_LOG_WARN = 5;
const ANDROID_LOG_ERROR = 6;
let liblog = ctypes.open("liblog.so"); // /system/lib/liblog.so
let __android_log_write = liblog.declare("__android_log_write",
ctypes.default_abi,
ctypes.int, // return value: num bytes logged
ctypes.int, // priority (ANDROID_LOG_* constant)
ctypes.char.ptr, // tag
ctypes.char.ptr); // message
let AndroidLog = {
v: (tag, msg) => __android_log_write(ANDROID_LOG_VERBOSE, "Gecko" + tag, msg),
d: (tag, msg) => __android_log_write(ANDROID_LOG_DEBUG, "Gecko" + tag, msg),
i: (tag, msg) => __android_log_write(ANDROID_LOG_INFO, "Gecko" + tag, msg),
w: (tag, msg) => __android_log_write(ANDROID_LOG_WARN, "Gecko" + tag, msg),
e: (tag, msg) => __android_log_write(ANDROID_LOG_ERROR, "Gecko" + tag, msg),
};
if (typeof Components == "undefined") {
// Specify exported symbols for require.js module loader.
module.exports = AndroidLog;
}

View File

@ -29,16 +29,8 @@ XPCOMUtils.defineLazyGetter(this, "Strings", function() {
return Services.strings.createBundle("chrome://browser/locale/webapp.properties");
});
function debug(aMessage) {
// We use *dump* instead of Services.console.logStringMessage so the messages
// have the INFO level of severity instead of the ERROR level. And we don't
// append a newline character to the end of the message because *dump* spills
// into the Android native logging system, which strips newlines from messages
// and breaks messages into lines automatically at display time (i.e. logcat).
#ifdef DEBUG
dump(aMessage);
#endif
}
let Log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog;
let debug = Log.d.bind(null, "WebappManager");
this.WebappManager = {
__proto__: DOMRequestIpcHelper.prototype,

View File

@ -3,10 +3,12 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
importScripts("resource://gre/modules/osfile.jsm");
importScripts("resource://gre/modules/workers/require.js");
let Log = require("resource://gre/modules/AndroidLog.jsm");
function log(message) {
dump("WebManagerWorker " + message + "\n");
}
// Define the "log" function as a binding of the Log.d function so it specifies
// the "debug" priority and a log tag.
let log = Log.d.bind(null, "WebappManagerWorker");
onmessage = function(event) {
let { url, path } = event.data;

View File

@ -6,6 +6,7 @@
EXTRA_JS_MODULES += [
'Accounts.jsm',
'AndroidLog.jsm',
'ContactService.jsm',
'DownloadNotifications.jsm',
'HelperApps.jsm',