• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
SyslogsLibraryImpl()22   SyslogsLibraryImpl() {}
~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:
SyslogsLibraryStubImpl()44   SyslogsLibraryStubImpl() {}
~SyslogsLibraryStubImpl()45   virtual ~SyslogsLibraryStubImpl() {}
46 
RequestSyslogs(bool compress_logs,bool add_feedback_context,CancelableRequestConsumerBase * consumer,ReadCompleteCallback * callback)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
GetImpl(bool stub)58 SyslogsLibrary* SyslogsLibrary::GetImpl(bool stub) {
59   if (stub)
60     return new SyslogsLibraryStubImpl();
61   else
62     return new SyslogsLibraryImpl();
63 }
64 
65 
RequestSyslogs(bool compress_logs,bool add_feedback_context,CancelableRequestConsumerBase * consumer,ReadCompleteCallback * callback)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.
ReadSyslogs(scoped_refptr<CancelableRequest<ReadCompleteCallback>> request,bool compress_logs,bool add_feedback_context)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 
LoadCompressedLogs(const FilePath & zip_file,std::string * zip_content)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