1bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// found in the LICENSE file. 4bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 5bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/browser/extensions/api/log_private/log_private_api.h" 6bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 7bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include <string> 8bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include <vector> 9bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/command_line.h" 11bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/json/json_writer.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/lazy_instance.h" 13bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/logging.h" 14bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/memory/linked_ptr.h" 15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/memory/scoped_ptr.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/browser_process.h" 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/download/download_prefs.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" 19bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/browser/extensions/api/log_private/filter_handler.h" 20bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/browser/extensions/api/log_private/log_parser.h" 21bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/browser/extensions/api/log_private/syslog_parser.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/feedback/system_logs/scrubbed_system_logs_fetcher.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/io_thread.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/net/chrome_net_log.h" 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 27bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/common/extensions/api/log_private.h" 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/common/logging_chrome.h" 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/render_process_host.h" 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/event_router.h" 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/extension_function.h" 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "extensions/browser/extension_registry.h" 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/granted_file_entry.h" 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS) 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/system_logs/debug_log_writer.h" 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::BrowserThread; 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace events { 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kOnCapturedEvents[] = "logPrivate.onCapturedEvents"; 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace events 44bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 45bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace extensions { 46bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace { 47bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kAppLogsSubdir[] = "apps"; 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kLogDumpsSubdir[] = "log_dumps"; 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kLogFileNameBase[] = "net-internals"; 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kNetLogEventDelayMilliseconds = 100; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Gets sequenced task runner for file specific calls within this API. 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() { 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pool->GetSequencedTaskRunnerWithShutdownBehavior( 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pool->GetNamedSequenceToken(FileResource::kSequenceToken), 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::SequencedWorkerPool::BLOCK_SHUTDOWN); 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Checks if we are running on sequenced task runner thread. 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool IsRunningOnSequenceThread() { 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool(); 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return pool->IsRunningSequenceOnCurrentThread( 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pool->GetNamedSequenceToken(FileResource::kSequenceToken)); 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 68bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochscoped_ptr<LogParser> CreateLogParser(const std::string& log_type) { 69bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (log_type == "syslog") 70bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return scoped_ptr<LogParser>(new SyslogParser()); 71bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // TODO(shinfan): Add more parser here 72bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 73bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch NOTREACHED() << "Invalid log type: " << log_type; 74bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return scoped_ptr<LogParser>(); 75bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 76bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 77bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid CollectLogInfo( 78bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch FilterHandler* filter_handler, 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) system_logs::SystemLogsResponse* logs, 80bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch std::vector<linked_ptr<api::log_private::LogEntry> >* output) { 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (system_logs::SystemLogsResponse::const_iterator 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_it = logs->begin(); request_it != logs->end(); ++request_it) { 83bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (!filter_handler->IsValidSource(request_it->first)) { 84bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch continue; 85bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 86bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_ptr<LogParser> parser(CreateLogParser(request_it->first)); 87bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (parser) { 88bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch parser->Parse(request_it->second, output, filter_handler); 89bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 90bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 91bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 92bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Returns directory location of app-specific logs that are initiated with 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// logPrivate.startEventRecorder() calls - /home/chronos/user/log/apps 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::FilePath GetAppLogDirectory() { 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return logging::GetSessionLogDir(*CommandLine::ForCurrentProcess()) 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) .Append(kAppLogsSubdir); 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Returns directory location where logs dumps initiated with chrome.dumpLogs 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// will be stored - /home/chronos/<user_profile_dir>/Downloads/log_dumps 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::FilePath GetLogDumpDirectory(content::BrowserContext* context) { 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const DownloadPrefs* const prefs = DownloadPrefs::FromBrowserContext(context); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return prefs->DownloadPath().Append(kLogDumpsSubdir); 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Removes direcotry content of |logs_dumps| and |app_logs_dir| (only for the 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// primary profile). 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void CleanUpLeftoverLogs(bool is_primary_profile, 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::FilePath& app_logs_dir, 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::FilePath& logs_dumps) { 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(WARNING) << "Deleting " << app_logs_dir.value(); 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(WARNING) << "Deleting " << logs_dumps.value(); 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(IsRunningOnSequenceThread()); 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::DeleteFile(logs_dumps, true); 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // App-specific logs are stored in /home/chronos/user/log/apps directory that 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // is shared between all profiles in multi-profile case. We should not 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // nuke it for non-primary profiles. 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!is_primary_profile) 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::DeleteFile(app_logs_dir, true); 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 127bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} // namespace 128bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char FileResource::kSequenceToken[] = "log_api_files"; 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)FileResource::FileResource(const std::string& owner_extension_id, 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::FilePath& path) 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : ApiResource(owner_extension_id), path_(path) { 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)FileResource::~FileResource() { 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::DeleteFile(path_, true); 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool FileResource::IsPersistent() const { 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)LogPrivateAPI* LogPrivateAPI::Get(content::BrowserContext* context) { 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LogPrivateAPI* api = GetFactoryInstance()->Get(context); 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api->Initialize(); 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return api; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)LogPrivateAPI::LogPrivateAPI(content::BrowserContext* context) 1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : browser_context_(context), 1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu logging_net_internals_(false), 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_sink_(api::log_private::EVENT_SINK_CAPTURE), 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry_observer_(this), 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) log_file_resources_(context), 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) initialized_(false) { 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)LogPrivateAPI::~LogPrivateAPI() { 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateAPI::StartNetInternalsWatch( 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& extension_id, 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api::log_private::EventSink event_sink, 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Closure& closure) { 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net_internal_watches_.insert(extension_id); 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Nuke any leftover app-specific or dumped log files from previous sessions. 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserThread::PostTaskAndReply( 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserThread::IO, 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&LogPrivateAPI::MaybeStartNetInternalLogging, 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Unretained(this), 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_id, 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) g_browser_process->io_thread(), 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_sink), 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) closure); 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateAPI::StopNetInternalsWatch(const std::string& extension_id, 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Closure& closure) { 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net_internal_watches_.erase(extension_id); 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MaybeStopNetInternalLogging(closure); 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateAPI::StopAllWatches(const std::string& extension_id, 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::Closure& closure) { 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) StopNetInternalsWatch(extension_id, closure); 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateAPI::RegisterTempFile(const std::string& owner_extension_id, 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::FilePath& file_path) { 1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!IsRunningOnSequenceThread()) { 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetSequencedTaskRunner()->PostTask( 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&LogPrivateAPI::RegisterTempFile, 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Unretained(this), 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) owner_extension_id, 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) file_path)); 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) log_file_resources_.Add(new FileResource(owner_extension_id, file_path)); 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance<BrowserContextKeyedAPIFactory<LogPrivateAPI> > 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_factory = LAZY_INSTANCE_INITIALIZER; 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<LogPrivateAPI>* 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)LogPrivateAPI::GetFactoryInstance() { 2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return g_factory.Pointer(); 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void LogPrivateAPI::OnAddEntry(const net::NetLog::Entry& entry) { 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // We could receive events on whatever thread they happen to be generated, 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // since we are only interested in network events, we should ignore any 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // other thread than BrowserThread::IO. 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!pending_entries_.get()) { 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_entries_.reset(new base::ListValue()); 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostDelayedTask( 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&LogPrivateAPI::PostPendingEntries, base::Unretained(this)), 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kNetLogEventDelayMilliseconds)); 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_entries_->Append(entry.ToValue()); 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void LogPrivateAPI::PostPendingEntries() { 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask( 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&LogPrivateAPI:: AddEntriesOnUI, 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this), 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Passed(&pending_entries_))); 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void LogPrivateAPI::AddEntriesOnUI(scoped_ptr<base::ListValue> value) { 243effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::set<std::string>::iterator ix = net_internal_watches_.begin(); 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ix != net_internal_watches_.end(); ++ix) { 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Create the event's arguments value. 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::ListValue> event_args(new base::ListValue()); 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_args->Append(value->DeepCopy()); 2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<Event> event( 2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new Event(events::kOnCapturedEvents, event_args.Pass())); 2525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EventRouter::Get(browser_context_) 2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ->DispatchEventToExtension(*ix, event.Pass()); 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateAPI::InitializeNetLogger(const std::string& owner_extension_id, 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::NetLogLogger** net_log_logger) { 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(IsRunningOnSequenceThread()); 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (*net_log_logger) = NULL; 2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Create app-specific subdirectory in session logs folder. 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::FilePath app_log_dir = GetAppLogDirectory().Append(owner_extension_id); 2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!base::DirectoryExists(app_log_dir)) { 2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!base::CreateDirectory(app_log_dir)) { 2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Could not create dir " << app_log_dir.value(); 2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::FilePath file_path = app_log_dir.Append(kLogFileNameBase); 2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) file_path = logging::GenerateTimestampedName(file_path, base::Time::Now()); 2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FILE* file = NULL; 2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) file = fopen(file_path.value().c_str(), "w"); 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (file == NULL) { 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Could not open " << file_path.value(); 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RegisterTempFile(owner_extension_id, file_path); 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<base::Value> constants(net::NetLogLogger::GetConstants()); 2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *net_log_logger = new net::NetLogLogger(file, *constants); 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (*net_log_logger)->set_log_level(net::NetLog::LOG_ALL_BUT_BYTES); 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateAPI::StartObservingNetEvents( 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IOThread* io_thread, 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::NetLogLogger** net_log_logger) { 2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_CURRENTLY_ON(BrowserThread::IO); 2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!(*net_log_logger)) 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net_log_logger_.reset(*net_log_logger); 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net_log_logger_->StartObserving(io_thread->net_log()); 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateAPI::MaybeStartNetInternalLogging( 2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& caller_extension_id, 2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IOThread* io_thread, 3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api::log_private::EventSink event_sink) { 301effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!logging_net_internals_) { 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) logging_net_internals_ = true; 3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event_sink_ = event_sink; 3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (event_sink_) { 3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case api::log_private::EVENT_SINK_CAPTURE: { 3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) io_thread->net_log()->AddThreadSafeObserver( 3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, net::NetLog::LOG_ALL_BUT_BYTES); 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case api::log_private::EVENT_SINK_FILE: { 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::NetLogLogger** net_logger_ptr = new net::NetLogLogger* [1]; 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Initialize net logger on the blocking pool and start observing event 3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // with in on IO thread. 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetSequencedTaskRunner()->PostTaskAndReply( 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&LogPrivateAPI::InitializeNetLogger, 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Unretained(this), 3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) caller_extension_id, 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net_logger_ptr), 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&LogPrivateAPI::StartObservingNetEvents, 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Unretained(this), 3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) io_thread, 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Owned(net_logger_ptr))); 3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case api::log_private::EVENT_SINK_NONE: { 3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED(); 3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateAPI::MaybeStopNetInternalLogging(const base::Closure& closure) { 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (net_internal_watches_.empty()) { 3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (closure.is_null()) { 3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserThread::PostTask( 3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserThread::IO, 3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, 3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&LogPrivateAPI::StopNetInternalLogging, 3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Unretained(this))); 3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserThread::PostTaskAndReply( 3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BrowserThread::IO, 3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, 3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&LogPrivateAPI::StopNetInternalLogging, 3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Unretained(this)), 3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) closure); 3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void LogPrivateAPI::StopNetInternalLogging() { 355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (net_log() && logging_net_internals_) { 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) logging_net_internals_ = false; 3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (event_sink_) { 3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case api::log_private::EVENT_SINK_CAPTURE: 3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net_log()->RemoveThreadSafeObserver(this); 3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case api::log_private::EVENT_SINK_FILE: 3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net_log_logger_->StopObserving(); 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net_log_logger_.reset(); 3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case api::log_private::EVENT_SINK_NONE: 3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED(); 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateAPI::Initialize() { 3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (initialized_) 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Clean up temp files and folders from the previous sessions. 3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) initialized_ = true; 3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); 3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetSequencedTaskRunner()->PostTask( 3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, 3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&CleanUpLeftoverLogs, 3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Profile::FromBrowserContext(browser_context_) == 3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ProfileManager::GetPrimaryUserProfile(), 3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetAppLogDirectory(), 3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetLogDumpDirectory(browser_context_))); 3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid LogPrivateAPI::OnExtensionUnloaded( 3905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu content::BrowserContext* browser_context, 3915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const Extension* extension, 3925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UnloadedExtensionInfo::Reason reason) { 3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) StopNetInternalsWatch(extension->id(), base::Closure()); 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 396bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochLogPrivateGetHistoricalFunction::LogPrivateGetHistoricalFunction() { 397bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 398bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 399bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochLogPrivateGetHistoricalFunction::~LogPrivateGetHistoricalFunction() { 400bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 401bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 402010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool LogPrivateGetHistoricalFunction::RunAsync() { 403bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Get parameters 404bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_ptr<api::log_private::GetHistorical::Params> params( 405bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch api::log_private::GetHistorical::Params::Create(*args_)); 406bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch EXTENSION_FUNCTION_VALIDATE(params.get()); 407bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch filter_handler_.reset(new FilterHandler(params->filter)); 408bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) system_logs::SystemLogsFetcherBase* fetcher; 4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if ((params->filter).scrub) { 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher = new system_logs::ScrubbedSystemLogsFetcher(); 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher = new system_logs::AboutSystemLogsFetcher(); 4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 415bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch fetcher->Fetch( 416bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::Bind(&LogPrivateGetHistoricalFunction::OnSystemLogsLoaded, this)); 4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 418bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return true; 419bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 420bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 421bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid LogPrivateGetHistoricalFunction::OnSystemLogsLoaded( 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<system_logs::SystemLogsResponse> sys_info) { 423bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch std::vector<linked_ptr<api::log_private::LogEntry> > data; 424bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 425bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch CollectLogInfo(filter_handler_.get(), sys_info.get(), &data); 426bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 427bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Prepare result 428bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch api::log_private::Result result; 429bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch result.data = data; 430bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch api::log_private::Filter::Populate( 431bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch *((filter_handler_->GetFilter())->ToValue()), &result.filter); 432bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch SetResult(result.ToValue().release()); 433bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch SendResponse(true); 434bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 435bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)LogPrivateStartEventRecorderFunction::LogPrivateStartEventRecorderFunction() { 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)LogPrivateStartEventRecorderFunction::~LogPrivateStartEventRecorderFunction() { 4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool LogPrivateStartEventRecorderFunction::RunAsync() { 4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<api::log_private::StartEventRecorder::Params> params( 4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api::log_private::StartEventRecorder::Params::Create(*args_)); 4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (params->event_type) { 4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case api::log_private::EVENT_TYPE_NETWORK: 4485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LogPrivateAPI::Get(Profile::FromBrowserContext(browser_context())) 4495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->StartNetInternalsWatch( 4505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_id(), 4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params->sink, 4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind( 4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &LogPrivateStartEventRecorderFunction::OnEventRecorderStarted, 4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this)); 4555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 4565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case api::log_private::EVENT_TYPE_NONE: 4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED(); 4585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 4595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateStartEventRecorderFunction::OnEventRecorderStarted() { 4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SendResponse(true); 4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)LogPrivateStopEventRecorderFunction::LogPrivateStopEventRecorderFunction() { 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)LogPrivateStopEventRecorderFunction::~LogPrivateStopEventRecorderFunction() { 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool LogPrivateStopEventRecorderFunction::RunAsync() { 4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<api::log_private::StopEventRecorder::Params> params( 4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) api::log_private::StopEventRecorder::Params::Create(*args_)); 4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (params->event_type) { 4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case api::log_private::EVENT_TYPE_NETWORK: 4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LogPrivateAPI::Get(Profile::FromBrowserContext(browser_context())) 4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->StopNetInternalsWatch( 4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_id(), 4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind( 4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &LogPrivateStopEventRecorderFunction::OnEventRecorderStopped, 4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this)); 4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case api::log_private::EVENT_TYPE_NONE: 4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED(); 4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateStopEventRecorderFunction::OnEventRecorderStopped() { 4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SendResponse(true); 4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)LogPrivateDumpLogsFunction::LogPrivateDumpLogsFunction() { 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)LogPrivateDumpLogsFunction::~LogPrivateDumpLogsFunction() { 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool LogPrivateDumpLogsFunction::RunAsync() { 5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LogPrivateAPI::Get(Profile::FromBrowserContext(browser_context())) 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->StopAllWatches( 5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_id(), 5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&LogPrivateDumpLogsFunction::OnStopAllWatches, this)); 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateDumpLogsFunction::OnStopAllWatches() { 5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) chromeos::DebugLogWriter::StoreCombinedLogs( 5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetLogDumpDirectory(browser_context()).Append(extension_id()), 5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FileResource::kSequenceToken, 5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&LogPrivateDumpLogsFunction::OnStoreLogsCompleted, this)); 5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void LogPrivateDumpLogsFunction::OnStoreLogsCompleted( 5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const base::FilePath& log_path, 5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool succeeded) { 5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (succeeded) { 5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LogPrivateAPI::Get(Profile::FromBrowserContext(browser_context())) 5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->RegisterTempFile(extension_id(), log_path); 5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<base::DictionaryValue> response(new base::DictionaryValue()); 5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::GrantedFileEntry file_entry = 5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::app_file_handler_util::CreateFileEntry( 5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Profile::FromBrowserContext(browser_context()), 5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension(), 5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) render_view_host_->GetProcess()->GetID(), 5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) log_path, 5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) false); 5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::DictionaryValue* entry = new base::DictionaryValue(); 5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry->SetString("fileSystemId", file_entry.filesystem_id); 5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry->SetString("baseName", file_entry.registered_name); 5395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry->SetString("id", file_entry.id); 5405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry->SetBoolean("isDirectory", false); 5415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::ListValue* entry_list = new base::ListValue(); 5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) entry_list->Append(entry); 5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) response->Set("entries", entry_list); 5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) response->SetBoolean("multiple", false); 5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetResult(response.release()); 5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SendResponse(succeeded); 5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 549bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} // namespace extensions 550