LCOV - code coverage report
Current view: top level - xpcom/base - nsStatusReporterManager.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 141 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 29 0.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 "nsStatusReporterManager.h"
       8             : #include "nsCOMPtr.h"
       9             : #include "nsDirectoryServiceDefs.h"
      10             : #include "nsArrayEnumerator.h"
      11             : #include "nsISimpleEnumerator.h"
      12             : #include "nsIFile.h"
      13             : #include "nsDumpUtils.h"
      14             : #include "nsIFileStreams.h"
      15             : #include "nsPrintfCString.h"
      16             : 
      17             : #ifdef XP_WIN
      18             : #include <process.h>
      19             : #define getpid _getpid
      20             : #else
      21             : #include <unistd.h>
      22             : #endif
      23             : 
      24             : #ifdef XP_UNIX
      25             : #define DO_STATUS_REPORT 1
      26             : #endif
      27             : 
      28             : #ifdef DO_STATUS_REPORT // {
      29             : namespace {
      30             : 
      31           0 : class DumpStatusInfoToTempDirRunnable : public mozilla::Runnable
      32             : {
      33             : public:
      34           0 :   DumpStatusInfoToTempDirRunnable()
      35           0 :     : mozilla::Runnable("DumpStatusInfoToTempDirRunnable")
      36             :   {
      37           0 :   }
      38             : 
      39           0 :   NS_IMETHOD Run() override
      40             :   {
      41             :     nsCOMPtr<nsIStatusReporterManager> mgr =
      42           0 :       do_GetService("@mozilla.org/status-reporter-manager;1");
      43           0 :     mgr->DumpReports();
      44           0 :     return NS_OK;
      45             :   }
      46             : };
      47             : 
      48             : void
      49           0 : doStatusReport(const nsCString& aInputStr)
      50             : {
      51             :   LOG("FifoWatcher(%s) dispatching status report runnable.", aInputStr.get());
      52             :   RefPtr<DumpStatusInfoToTempDirRunnable> runnable =
      53           0 :     new DumpStatusInfoToTempDirRunnable();
      54           0 :   NS_DispatchToMainThread(runnable);
      55           0 : }
      56             : 
      57             : } //anonymous namespace
      58             : #endif // DO_STATUS_REPORT }
      59             : 
      60             : static bool gStatusReportProgress = 0;
      61             : static int gNumReporters = 0;
      62             : 
      63             : nsresult
      64           0 : getStatus(nsACString& aDesc)
      65             : {
      66           0 :   if (!gStatusReportProgress) {
      67           0 :     aDesc.AssignLiteral("Init");
      68             :   } else {
      69           0 :     aDesc.AssignLiteral("Running: There are ");
      70           0 :     aDesc.AppendInt(gNumReporters);
      71           0 :     aDesc.AppendLiteral(" reporters");
      72             :   }
      73           0 :   return NS_OK;
      74             : }
      75             : 
      76           0 : NS_STATUS_REPORTER_IMPLEMENT(StatusReporter, "StatusReporter State", getStatus)
      77             : 
      78             : #define DUMP(o, s) \
      79             :   do { \
      80             :     const char* s2 = (s); \
      81             :     uint32_t dummy; \
      82             :     nsresult rvDump = (o)->Write((s2), strlen(s2), &dummy); \
      83             :     if (NS_WARN_IF(NS_FAILED(rvDump))) \
      84             :       return rvDump; \
      85             :   } while (0)
      86             : 
      87             : static nsresult
      88           0 : DumpReport(nsIFileOutputStream* aOStream, const nsCString& aProcess,
      89             :            const nsCString& aName, const nsCString& aDescription)
      90             : {
      91           0 :   if (aProcess.IsEmpty()) {
      92           0 :     int pid = getpid();
      93           0 :     nsPrintfCString pidStr("PID %u", pid);
      94           0 :     DUMP(aOStream, "\n  {\n  \"Process\": \"");
      95           0 :     DUMP(aOStream, pidStr.get());
      96             :   } else {
      97           0 :     DUMP(aOStream, "\n  {  \"Unknown Process\": \"");
      98             :   }
      99             : 
     100           0 :   DUMP(aOStream, "\",\n  \"Reporter name\": \"");
     101           0 :   DUMP(aOStream, aName.get());
     102             : 
     103           0 :   DUMP(aOStream, "\",\n  \"Status Description\": [\"");
     104           0 :   nsCString desc = aDescription;
     105           0 :   desc.ReplaceSubstring("|", "\",\"");
     106           0 :   DUMP(aOStream, desc.get());
     107             : 
     108           0 :   DUMP(aOStream, "\"]\n  }");
     109             : 
     110           0 :   return NS_OK;
     111             : }
     112             : 
     113             : /**
     114             :  ** nsStatusReporterManager implementation
     115             :  **/
     116             : 
     117           0 : NS_IMPL_ISUPPORTS(nsStatusReporterManager, nsIStatusReporterManager)
     118             : 
     119           0 : nsStatusReporterManager::nsStatusReporterManager()
     120             : {
     121           0 : }
     122             : 
     123           0 : nsStatusReporterManager::~nsStatusReporterManager()
     124             : {
     125           0 : }
     126             : 
     127             : NS_IMETHODIMP
     128           0 : nsStatusReporterManager::Init()
     129             : {
     130           0 :   RegisterReporter(new NS_STATUS_REPORTER_NAME(StatusReporter));
     131           0 :   gStatusReportProgress = 1;
     132             : 
     133             : #ifdef DO_STATUS_REPORT
     134           0 :   if (FifoWatcher::MaybeCreate()) {
     135           0 :     FifoWatcher* fw = FifoWatcher::GetSingleton();
     136           0 :     fw->RegisterCallback(NS_LITERAL_CSTRING("status report"), doStatusReport);
     137             :   }
     138             : #endif
     139             : 
     140           0 :   return NS_OK;
     141             : }
     142             : 
     143             : NS_IMETHODIMP
     144           0 : nsStatusReporterManager::DumpReports()
     145             : {
     146             :   static unsigned number = 1;
     147             :   nsresult rv;
     148             : 
     149           0 :   nsCString filename("status-reports-");
     150           0 :   filename.AppendInt((uint32_t)getpid());
     151           0 :   filename.Append('-');
     152           0 :   filename.AppendInt(number++);
     153           0 :   filename.AppendLiteral(".json");
     154             : 
     155             :   // Open a file in NS_OS_TEMP_DIR for writing.
     156             :   // The file is initialized as "incomplete-status-reports-pid-number.json" in the
     157             :   // begining, it will be rename as "status-reports-pid-number.json" in the end.
     158           0 :   nsCOMPtr<nsIFile> tmpFile;
     159           0 :   rv = nsDumpUtils::OpenTempFile(NS_LITERAL_CSTRING("incomplete-") +
     160           0 :                                  filename,
     161           0 :                                  getter_AddRefs(tmpFile),
     162           0 :                                  NS_LITERAL_CSTRING("status-reports"));
     163           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     164           0 :     return rv;
     165             :   }
     166             : 
     167             :   nsCOMPtr<nsIFileOutputStream> ostream =
     168           0 :     do_CreateInstance("@mozilla.org/network/file-output-stream;1");
     169           0 :   rv = ostream->Init(tmpFile, -1, -1, 0);
     170           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     171           0 :     return rv;
     172             :   }
     173             : 
     174             :   //Write the reports to the file
     175             : 
     176           0 :   DUMP(ostream, "{\n\"subject\":\"about:service reports\",\n");
     177           0 :   DUMP(ostream, "\"reporters\": [ ");
     178             : 
     179           0 :   nsCOMPtr<nsISimpleEnumerator> e;
     180           0 :   bool more, first = true;
     181           0 :   EnumerateReporters(getter_AddRefs(e));
     182           0 :   while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
     183           0 :     nsCOMPtr<nsISupports> supports;
     184           0 :     e->GetNext(getter_AddRefs(supports));
     185           0 :     nsCOMPtr<nsIStatusReporter> r = do_QueryInterface(supports);
     186             : 
     187           0 :     nsCString process;
     188           0 :     rv = r->GetProcess(process);
     189           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     190           0 :       return rv;
     191             :     }
     192             : 
     193           0 :     nsCString name;
     194           0 :     rv = r->GetName(name);
     195           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     196           0 :       return rv;
     197             :     }
     198             : 
     199           0 :     nsCString description;
     200           0 :     rv = r->GetDescription(description);
     201           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     202           0 :       return rv;
     203             :     }
     204             : 
     205           0 :     if (first) {
     206           0 :       first = false;
     207             :     } else {
     208           0 :       DUMP(ostream, ",");
     209             :     }
     210             : 
     211           0 :     rv = DumpReport(ostream, process, name, description);
     212           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     213           0 :       return rv;
     214             :     }
     215             :   }
     216           0 :   DUMP(ostream, "\n]\n}\n");
     217             : 
     218           0 :   rv = ostream->Close();
     219           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     220           0 :     return rv;
     221             :   }
     222             : 
     223             :   // Rename the status reports file
     224           0 :   nsCOMPtr<nsIFile> srFinalFile;
     225           0 :   rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(srFinalFile));
     226           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     227           0 :     return rv;
     228             :   }
     229             : 
     230             : #ifdef ANDROID
     231             :   rv = srFinalFile->AppendNative(NS_LITERAL_CSTRING("status-reports"));
     232             :   if (NS_WARN_IF(NS_FAILED(rv))) {
     233             :     return rv;
     234             :   }
     235             : #endif
     236             : 
     237           0 :   rv = srFinalFile->AppendNative(filename);
     238           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     239           0 :     return rv;
     240             :   }
     241             : 
     242           0 :   rv = srFinalFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
     243           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     244           0 :     return rv;
     245             :   }
     246             : 
     247           0 :   nsAutoString srActualFinalFilename;
     248           0 :   rv = srFinalFile->GetLeafName(srActualFinalFilename);
     249           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     250           0 :     return rv;
     251             :   }
     252             : 
     253           0 :   rv = tmpFile->MoveTo(/* directory */ nullptr, srActualFinalFilename);
     254             : 
     255           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     256           0 :     return rv;
     257             :   }
     258             : 
     259           0 :   return NS_OK;
     260             : }
     261             : 
     262             : NS_IMETHODIMP
     263           0 : nsStatusReporterManager::EnumerateReporters(nsISimpleEnumerator** aResult)
     264             : {
     265           0 :   return NS_NewArrayEnumerator(aResult, mReporters);
     266             : }
     267             : 
     268             : NS_IMETHODIMP
     269           0 : nsStatusReporterManager::RegisterReporter(nsIStatusReporter* aReporter)
     270             : {
     271           0 :   if (mReporters.IndexOf(aReporter) != -1) {
     272           0 :     return NS_ERROR_FAILURE;
     273             :   }
     274             : 
     275           0 :   mReporters.AppendObject(aReporter);
     276           0 :   gNumReporters++;
     277           0 :   return NS_OK;
     278             : }
     279             : 
     280             : NS_IMETHODIMP
     281           0 : nsStatusReporterManager::UnregisterReporter(nsIStatusReporter* aReporter)
     282             : {
     283           0 :   if (!mReporters.RemoveObject(aReporter)) {
     284           0 :     return NS_ERROR_FAILURE;
     285             :   }
     286           0 :   gNumReporters--;
     287           0 :   return NS_OK;
     288             : }
     289             : 
     290             : nsresult
     291           0 : NS_RegisterStatusReporter(nsIStatusReporter* aReporter)
     292             : {
     293             :   nsCOMPtr<nsIStatusReporterManager> mgr =
     294           0 :     do_GetService("@mozilla.org/status-reporter-manager;1");
     295           0 :   if (!mgr) {
     296           0 :     return NS_ERROR_FAILURE;
     297             :   }
     298           0 :   return mgr->RegisterReporter(aReporter);
     299             : }
     300             : 
     301             : nsresult
     302           0 : NS_UnregisterStatusReporter(nsIStatusReporter* aReporter)
     303             : {
     304             :   nsCOMPtr<nsIStatusReporterManager> mgr =
     305           0 :     do_GetService("@mozilla.org/status-reporter-manager;1");
     306           0 :   if (!mgr) {
     307           0 :     return NS_ERROR_FAILURE;
     308             :   }
     309           0 :   return mgr->UnregisterReporter(aReporter);
     310             : }
     311             : 
     312             : nsresult
     313           0 : NS_DumpStatusReporter()
     314             : {
     315             :   nsCOMPtr<nsIStatusReporterManager> mgr =
     316           0 :     do_GetService("@mozilla.org/status-reporter-manager;1");
     317           0 :   if (!mgr) {
     318           0 :     return NS_ERROR_FAILURE;
     319             :   }
     320           0 :   return mgr->DumpReports();
     321             : }

Generated by: LCOV version 1.13