tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AndroidLog.sys.mjs (3176B)


      1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
      2 * This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 /**
      7 * Native Android logging for JavaScript, wrapped for use by Log.sys.mjs.
      8 *
      9 * // Import it as a ESM:
     10 * import { AndroidAppender } from "resource://gre/modules/AndroidLog.sys.mjs";
     11 *
     12 * // Add the appender to a Log.sys.mjs appender:
     13 * import { Log } from "resource://gre/modules/Log.sys.mjs";
     14 * let logger = Log.repository.getLogger("Example");
     15 * logger.addAppender(new AndroidAppender());
     16 *
     17 * // Log with the normal Log.sys.mjs API:
     18 * logger.info("This is an info message.");
     19 *
     20 * Note: Logger names will automatically be prepended with "Gecko" before being
     21 * logged to the system logger, if they do not already have a "Gecko" prefix.
     22 */
     23 
     24 import { ctypes } from "resource://gre/modules/ctypes.sys.mjs";
     25 import { Log } from "resource://gre/modules/Log.sys.mjs";
     26 
     27 // From <https://android.googlesource.com/platform/system/core/+/master/include/android/log.h>.
     28 const ANDROID_LOG_VERBOSE = 2;
     29 const ANDROID_LOG_DEBUG = 3;
     30 const ANDROID_LOG_INFO = 4;
     31 const ANDROID_LOG_WARN = 5;
     32 const ANDROID_LOG_ERROR = 6;
     33 
     34 var liblog = ctypes.open("liblog.so"); // /system/lib/liblog.so
     35 var __android_log_write = liblog.declare(
     36  "__android_log_write",
     37  ctypes.default_abi,
     38  ctypes.int, // return value: num bytes logged
     39  ctypes.int, // priority (ANDROID_LOG_* constant)
     40  ctypes.char.ptr, // tag
     41  ctypes.char.ptr
     42 ); // message
     43 
     44 /**
     45 * A formatter that does not prepend time/name/level information to messages,
     46 * because those fields are logged separately when using the Android logger.
     47 */
     48 class AndroidFormatter extends Log.BasicFormatter {
     49  format(message) {
     50    return this.formatText(message);
     51  }
     52 }
     53 
     54 /*
     55 * AndroidAppender
     56 * Logs to Android logcat using __android_log_write
     57 */
     58 export class AndroidAppender extends Log.Appender {
     59  constructor(aFormatter) {
     60    super(aFormatter || new AndroidFormatter());
     61    this._name = "AndroidAppender";
     62 
     63    // Map log level to __android_log_write priority
     64    this._mapping = {
     65      [Log.Level.Fatal]: ANDROID_LOG_ERROR,
     66      [Log.Level.Error]: ANDROID_LOG_ERROR,
     67      [Log.Level.Warn]: ANDROID_LOG_WARN,
     68      [Log.Level.Info]: ANDROID_LOG_INFO,
     69      [Log.Level.Config]: ANDROID_LOG_DEBUG,
     70      [Log.Level.Debug]: ANDROID_LOG_DEBUG,
     71      [Log.Level.Trace]: ANDROID_LOG_VERBOSE,
     72    };
     73  }
     74 
     75  append(aMessage) {
     76    if (!aMessage) {
     77      return;
     78    }
     79 
     80    // We'll prepend "Gecko" to the tag, so we strip any leading "Gecko" here.
     81    // Also strip dots to save space.
     82    const tag = aMessage.loggerName.replace(/^Gecko|\./g, "");
     83    const msg = this._formatter.format(aMessage);
     84 
     85    // NOTE: android.util.Log.isLoggable throws IllegalArgumentException if a
     86    // tag length exceeds 23 characters, and we prepend five characters
     87    // ("Gecko") to every tag.  However, __android_log_write itself and other
     88    // android.util.Log methods don't seem to mind longer tags.
     89    __android_log_write(this._mapping[aMessage.level], "Gecko" + tag, msg);
     90  }
     91 }