// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_LOG_PRIVATE_API_H_ #define CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_LOG_PRIVATE_API_H_ #include #include #include "base/files/scoped_file.h" #include "base/macros.h" #include "base/scoped_observer.h" #include "chrome/browser/extensions/api/log_private/filter_handler.h" #include "chrome/browser/extensions/api/log_private/log_parser.h" #include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/browser/feedback/system_logs/about_system_logs_fetcher.h" #include "chrome/common/extensions/api/log_private.h" #include "extensions/browser/api/api_resource.h" #include "extensions/browser/api/api_resource_manager.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/extension_registry_observer.h" #include "net/log/net_log.h" #include "net/log/write_to_file_net_log_observer.h" class IOThread; namespace content { class BrowserContext; } namespace extensions { class ExtensionRegistry; // Tracked log files. class FileResource : public ApiResource { public: FileResource(const std::string& owner_extension_id, const base::FilePath& path); ~FileResource() override; // ApiResource overrides. bool IsPersistent() const override; static const char kSequenceToken[]; static const base::SequencedWorkerPool::WorkerShutdown kShutdownBehavior = base::SequencedWorkerPool::BLOCK_SHUTDOWN; private: base::FilePath path_; DISALLOW_COPY_AND_ASSIGN(FileResource); }; class LogPrivateAPI : public BrowserContextKeyedAPI, public ExtensionRegistryObserver, public net::NetLog::ThreadSafeObserver { public: // Convenience method to get the LogPrivateAPI for a profile. static LogPrivateAPI* Get(content::BrowserContext* context); explicit LogPrivateAPI(content::BrowserContext* context); ~LogPrivateAPI() override; void StartNetInternalsWatch(const std::string& extension_id, api::log_private::EventSink event_sink, const base::Closure& closure); void StopNetInternalsWatch(const std::string& extension_id, const base::Closure& closure); void StopAllWatches(const std::string& extension_id, const base::Closure& closure); void RegisterTempFile(const std::string& owner_extension_id, const base::FilePath& file_path); // BrowserContextKeyedAPI implementation. static BrowserContextKeyedAPIFactory* GetFactoryInstance(); private: friend class BrowserContextKeyedAPIFactory; void Initialize(); // ExtensionRegistryObserver implementation. void OnExtensionUnloaded(content::BrowserContext* browser_context, const Extension* extension, UnloadedExtensionInfo::Reason reason) override; // NetLog::ThreadSafeObserver implementation: void OnAddEntry(const net::NetLog::Entry& entry) override; void PostPendingEntries(); void AddEntriesOnUI(scoped_ptr value); // Creates a file that will be written to by net::WriteToFileNetLogObserver. void CreateTempNetLogFile(const std::string& owner_extension_id, base::ScopedFILE* file); // Starts observing network events with a new |net_logger| instance. void StartObservingNetEvents(IOThread* io_thread, base::ScopedFILE* file); void MaybeStartNetInternalLogging(const std::string& caller_extension_id, IOThread* io_thread, api::log_private::EventSink event_sink); void MaybeStopNetInternalLogging(const base::Closure& closure); void StopNetInternalLogging(); // BrowserContextKeyedAPI implementation. static const char* service_name() { return "LogPrivateAPI"; } static const bool kServiceIsNULLWhileTesting = true; static const bool kServiceRedirectedInIncognito = true; content::BrowserContext* const browser_context_; bool logging_net_internals_; api::log_private::EventSink event_sink_; std::set net_internal_watches_; scoped_ptr pending_entries_; scoped_ptr write_to_file_observer_; // Listen to extension unloaded notifications. ScopedObserver extension_registry_observer_; ApiResourceManager > log_file_resources_; bool initialized_; DISALLOW_COPY_AND_ASSIGN(LogPrivateAPI); }; class LogPrivateGetHistoricalFunction : public AsyncExtensionFunction { public: LogPrivateGetHistoricalFunction(); DECLARE_EXTENSION_FUNCTION("logPrivate.getHistorical", LOGPRIVATE_GETHISTORICAL); protected: ~LogPrivateGetHistoricalFunction() override; bool RunAsync() override; private: void OnSystemLogsLoaded(scoped_ptr sys_info); scoped_ptr filter_handler_; DISALLOW_COPY_AND_ASSIGN(LogPrivateGetHistoricalFunction); }; class LogPrivateStartEventRecorderFunction : public AsyncExtensionFunction { public: LogPrivateStartEventRecorderFunction(); DECLARE_EXTENSION_FUNCTION("logPrivate.startEventRecorder", LOGPRIVATE_STARTEVENTRECODER); protected: ~LogPrivateStartEventRecorderFunction() override; bool RunAsync() override; private: void OnEventRecorderStarted(); DISALLOW_COPY_AND_ASSIGN(LogPrivateStartEventRecorderFunction); }; class LogPrivateStopEventRecorderFunction : public AsyncExtensionFunction { public: LogPrivateStopEventRecorderFunction(); DECLARE_EXTENSION_FUNCTION("logPrivate.stopEventRecorder", LOGPRIVATE_STOPEVENTRECODER); protected: ~LogPrivateStopEventRecorderFunction() override; // AsyncExtensionFunction overrides. bool RunAsync() override; private: void OnEventRecorderStopped(); DISALLOW_COPY_AND_ASSIGN(LogPrivateStopEventRecorderFunction); }; class LogPrivateDumpLogsFunction : public AsyncExtensionFunction { public: LogPrivateDumpLogsFunction(); DECLARE_EXTENSION_FUNCTION("logPrivate.dumpLogs", LOGPRIVATE_DUMPLOGS); protected: ~LogPrivateDumpLogsFunction() override; // AsyncExtensionFunction overrides. bool RunAsync() override; private: // Callback for DebugLogWriter::StoreLogs() call. void OnStoreLogsCompleted(const base::FilePath& log_path, bool succeeded); // Callback for LogPrivateAPI::StopAllWatches() call. void OnStopAllWatches(); DISALLOW_COPY_AND_ASSIGN(LogPrivateDumpLogsFunction); }; } // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_LOG_PRIVATE_API_H_