Home | History | Annotate | Download | only in cros
      1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/cros/syslogs_library.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/file_util.h"
      9 #include "base/string_util.h"
     10 #include "chrome/browser/chromeos/cros/cros_library.h"
     11 #include "chrome/common/chrome_switches.h"
     12 #include "content/browser/browser_thread.h"
     13 
     14 namespace chromeos {
     15 
     16 const char kContextFeedback[] = "feedback";
     17 const char kContextSysInfo[] = "sysinfo";
     18 
     19 
     20 class SyslogsLibraryImpl : public SyslogsLibrary {
     21  public:
     22   SyslogsLibraryImpl() {}
     23   virtual ~SyslogsLibraryImpl() {}
     24 
     25   virtual Handle RequestSyslogs(
     26       bool compress_logs, bool add_feedback_context,
     27       CancelableRequestConsumerBase* consumer,
     28       ReadCompleteCallback* callback);
     29 
     30   // Reads system logs, compresses content if requested.
     31   // Called from FILE thread.
     32   void ReadSyslogs(
     33       scoped_refptr<CancelableRequest<ReadCompleteCallback> > request,
     34       bool compress_logs, bool add_feedback_context);
     35 
     36   void LoadCompressedLogs(const FilePath& zip_file,
     37                           std::string* zip_content);
     38 
     39   DISALLOW_COPY_AND_ASSIGN(SyslogsLibraryImpl);
     40 };
     41 
     42 class SyslogsLibraryStubImpl : public SyslogsLibrary {
     43  public:
     44   SyslogsLibraryStubImpl() {}
     45   virtual ~SyslogsLibraryStubImpl() {}
     46 
     47   virtual Handle RequestSyslogs(bool compress_logs, bool add_feedback_context,
     48                                 CancelableRequestConsumerBase* consumer,
     49                                 ReadCompleteCallback* callback) {
     50     if (callback)
     51       callback->Run(Tuple2<LogDictionaryType*, std::string*>(NULL , NULL));
     52 
     53     return 0;
     54   }
     55 };
     56 
     57 // static
     58 SyslogsLibrary* SyslogsLibrary::GetImpl(bool stub) {
     59   if (stub)
     60     return new SyslogsLibraryStubImpl();
     61   else
     62     return new SyslogsLibraryImpl();
     63 }
     64 
     65 
     66 CancelableRequestProvider::Handle SyslogsLibraryImpl::RequestSyslogs(
     67     bool compress_logs, bool add_feedback_context,
     68     CancelableRequestConsumerBase* consumer,
     69     ReadCompleteCallback* callback) {
     70   // Register the callback request.
     71   scoped_refptr<CancelableRequest<ReadCompleteCallback> > request(
     72          new CancelableRequest<ReadCompleteCallback>(callback));
     73   AddRequest(request, consumer);
     74 
     75   // Schedule a task on the FILE thread which will then trigger a request
     76   // callback on the calling thread (e.g. UI) when complete.
     77   BrowserThread::PostTask(
     78       BrowserThread::FILE, FROM_HERE,
     79       NewRunnableMethod(
     80           this, &SyslogsLibraryImpl::ReadSyslogs, request,
     81           compress_logs, add_feedback_context));
     82 
     83   return request->handle();
     84 }
     85 
     86 // Called from FILE thread.
     87 void SyslogsLibraryImpl::ReadSyslogs(
     88     scoped_refptr<CancelableRequest<ReadCompleteCallback> > request,
     89     bool compress_logs, bool add_feedback_context) {
     90   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
     91 
     92   if (request->canceled())
     93     return;
     94 
     95   if (compress_logs && !CommandLine::ForCurrentProcess()->HasSwitch(
     96           switches::kCompressSystemFeedback))
     97     compress_logs = false;
     98 
     99   // Create temp file.
    100   FilePath zip_file;
    101   if (compress_logs && !file_util::CreateTemporaryFile(&zip_file)) {
    102     LOG(ERROR) << "Cannot create temp file";
    103     compress_logs = false;
    104   }
    105 
    106   LogDictionaryType* logs = NULL;
    107   if (CrosLibrary::Get()->EnsureLoaded())
    108     logs = chromeos::GetSystemLogs(
    109         compress_logs ? &zip_file : NULL,
    110         add_feedback_context ? kContextFeedback : kContextSysInfo);
    111 
    112   std::string* zip_content = NULL;
    113   if (compress_logs) {
    114     // Load compressed logs.
    115     zip_content = new std::string();
    116     LoadCompressedLogs(zip_file, zip_content);
    117     file_util::Delete(zip_file, false);
    118   }
    119 
    120   // Will call the callback on the calling thread.
    121   request->ForwardResult(Tuple2<LogDictionaryType*,
    122                                 std::string*>(logs, zip_content));
    123 }
    124 
    125 
    126 void SyslogsLibraryImpl::LoadCompressedLogs(const FilePath& zip_file,
    127                                             std::string* zip_content) {
    128   DCHECK(zip_content);
    129   if (!file_util::ReadFileToString(zip_file, zip_content)) {
    130     LOG(ERROR) << "Cannot read compressed logs file from " <<
    131         zip_file.value().c_str();
    132   }
    133 }
    134 
    135 }  // namespace chromeos
    136 
    137 // Allows InvokeLater without adding refcounting. SyslogsLibraryImpl is a
    138 // Singleton and won't be deleted until it's last InvokeLater is run.
    139 DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::SyslogsLibraryImpl);
    140