LCOV - code coverage report
Current view: top level - xpcom/base - LogModulePrefWatcher.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 47 76 61.8 %
Date: 2017-07-14 16:53:18 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "LogModulePrefWatcher.h"
       8             : 
       9             : #include "mozilla/Logging.h"
      10             : #include "mozilla/Preferences.h"
      11             : #include "nsString.h"
      12             : #include "nsXULAppAPI.h"
      13             : #include "base/process_util.h"
      14             : 
      15             : static const char kLoggingPrefPrefix[] = "logging.";
      16             : static const char kLoggingConfigPrefPrefix[] = "logging.config";
      17             : static const int  kLoggingConfigPrefixLen = sizeof(kLoggingConfigPrefPrefix) - 1;
      18             : static const char kLoggingPrefClearOnStartup[] = "logging.config.clear_on_startup";
      19             : static const char kLoggingPrefLogFile[] = "logging.config.LOG_FILE";
      20             : static const char kLoggingPrefAddTimestamp[] = "logging.config.add_timestamp";
      21             : static const char kLoggingPrefSync[] = "logging.config.sync";
      22             : 
      23             : namespace mozilla {
      24             : 
      25          41 : NS_IMPL_ISUPPORTS(LogModulePrefWatcher, nsIObserver)
      26             : 
      27             : /**
      28             :  * Resets all the preferences in the logging. branch
      29             :  * This is needed because we may crash while logging, and this would cause us
      30             :  * to log after restarting as well.
      31             :  *
      32             :  * If logging after restart is desired, set the logging.config.clear_on_startup
      33             :  * pref to false, or use the MOZ_LOG_FILE and MOZ_LOG_MODULES env vars.
      34             :  */
      35           1 : void ResetExistingPrefs()
      36             : {
      37             :   uint32_t count;
      38             :   char** names;
      39           1 :   nsresult rv = Preferences::GetRootBranch()->
      40           1 :       GetChildList(kLoggingPrefPrefix, &count, &names);
      41           1 :   if (NS_SUCCEEDED(rv) && count) {
      42           2 :     for (size_t i = 0; i < count; i++) {
      43             :       // Clearing the pref will cause it to reload, thus resetting the log level
      44           1 :       Preferences::ClearUser(names[i]);
      45             :     }
      46           1 :     NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, names);
      47             :   }
      48           1 : }
      49             : 
      50             : /**
      51             :  * Loads the log level from the given pref and updates the corresponding
      52             :  * LogModule.
      53             :  */
      54             : static void
      55           3 : LoadPrefValue(const char* aName)
      56             : {
      57           3 :   LogLevel logLevel = LogLevel::Disabled;
      58             : 
      59             :   nsresult rv;
      60           3 :   int32_t prefLevel = 0;
      61           3 :   nsAutoCString prefValue;
      62             : 
      63           3 :   if (strncmp(aName, kLoggingConfigPrefPrefix, kLoggingConfigPrefixLen) == 0) {
      64           6 :     nsAutoCString prefName(aName);
      65             : 
      66           3 :     if (prefName.EqualsLiteral(kLoggingPrefLogFile)) {
      67           0 :       rv = Preferences::GetCString(aName, &prefValue);
      68             :       // The pref was reset. Clear the user file.
      69           0 :       if (NS_FAILED(rv) || prefValue.IsEmpty()) {
      70           0 :         LogModule::SetLogFile(nullptr);
      71           0 :         return;
      72             :       }
      73             : 
      74             :       // If the pref value doesn't have a PID placeholder, append it to the end.
      75           0 :       if (!strstr(prefValue.get(), "%PID")) {
      76           0 :         prefValue.Append("%PID");
      77             :       }
      78             : 
      79           0 :       LogModule::SetLogFile(prefValue.BeginReading());
      80           3 :     } else if (prefName.EqualsLiteral(kLoggingPrefAddTimestamp)) {
      81           0 :       bool addTimestamp = Preferences::GetBool(aName, false);
      82           0 :       LogModule::SetAddTimestamp(addTimestamp);
      83           3 :     } else if (prefName.EqualsLiteral(kLoggingPrefSync)) {
      84           0 :       bool sync = Preferences::GetBool(aName, false);
      85           0 :       LogModule::SetIsSync(sync);
      86             :     }
      87           3 :     return;
      88             :   }
      89             : 
      90           0 :   if (Preferences::GetInt(aName, &prefLevel) == NS_OK) {
      91           0 :     logLevel = ToLogLevel(prefLevel);
      92           0 :   } else if (Preferences::GetCString(aName, &prefValue) == NS_OK) {
      93           0 :     if (prefValue.LowerCaseEqualsLiteral("error")) {
      94           0 :       logLevel = LogLevel::Error;
      95           0 :     } else if (prefValue.LowerCaseEqualsLiteral("warning")) {
      96           0 :       logLevel = LogLevel::Warning;
      97           0 :     } else if (prefValue.LowerCaseEqualsLiteral("info")) {
      98           0 :       logLevel = LogLevel::Info;
      99           0 :     } else if (prefValue.LowerCaseEqualsLiteral("debug")) {
     100           0 :       logLevel = LogLevel::Debug;
     101           0 :     } else if (prefValue.LowerCaseEqualsLiteral("verbose")) {
     102           0 :       logLevel = LogLevel::Verbose;
     103             :     }
     104             :   }
     105             : 
     106           0 :   const char* moduleName = aName + strlen(kLoggingPrefPrefix);
     107           0 :   LogModule::Get(moduleName)->SetLevel(logLevel);
     108             : }
     109             : 
     110             : void
     111           3 : LoadExistingPrefs()
     112             : {
     113           3 :   nsIPrefBranch* root = Preferences::GetRootBranch();
     114           3 :   if (!root) {
     115           0 :     return;
     116             :   }
     117             : 
     118             :   uint32_t count;
     119             :   char** names;
     120           3 :   nsresult rv = root->GetChildList(kLoggingPrefPrefix, &count, &names);
     121           3 :   if (NS_SUCCEEDED(rv) && count) {
     122           6 :     for (size_t i = 0; i < count; i++) {
     123           3 :       LoadPrefValue(names[i]);
     124             :     }
     125           3 :     NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, names);
     126             :   }
     127             : }
     128             : 
     129           3 : LogModulePrefWatcher::LogModulePrefWatcher()
     130             : {
     131           3 : }
     132             : 
     133             : void
     134           3 : LogModulePrefWatcher::RegisterPrefWatcher()
     135             : {
     136           6 :   RefPtr<LogModulePrefWatcher> prefWatcher = new LogModulePrefWatcher();
     137           3 :   Preferences::AddStrongObserver(prefWatcher, kLoggingPrefPrefix);
     138             : 
     139             :   nsCOMPtr<nsIObserverService> observerService =
     140           6 :     mozilla::services::GetObserverService();
     141           3 :   if (observerService && XRE_IsParentProcess()) {
     142           1 :     observerService->AddObserver(prefWatcher, "browser-delayed-startup-finished", false);
     143             :   }
     144             : 
     145           3 :   LoadExistingPrefs();
     146           3 : }
     147             : 
     148             : NS_IMETHODIMP
     149           1 : LogModulePrefWatcher::Observe(nsISupports* aSubject, const char* aTopic,
     150             :                               const char16_t* aData)
     151             : {
     152           1 :   if (strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic) == 0) {
     153           0 :     NS_LossyConvertUTF16toASCII prefName(aData);
     154           0 :     LoadPrefValue(prefName.get());
     155           1 :   } else if (strcmp("browser-delayed-startup-finished", aTopic) == 0) {
     156           1 :     bool clear = Preferences::GetBool(kLoggingPrefClearOnStartup, true);
     157           1 :     if (clear) {
     158           1 :       ResetExistingPrefs();
     159             :     }
     160             :     nsCOMPtr<nsIObserverService> observerService =
     161           2 :       mozilla::services::GetObserverService();
     162           1 :     if (observerService) {
     163           1 :       observerService->RemoveObserver(this, "browser-delayed-startup-finished");
     164             :     }
     165             :   }
     166             : 
     167           1 :   return NS_OK;
     168             : }
     169             : 
     170             : } // namespace mozilla

Generated by: LCOV version 1.13