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