diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
commit | 09911bf300f1a419907a9412154760efd0b7abc3 (patch) | |
tree | f131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/browser/browser_process_impl.cc | |
parent | 586acc5fe142f498261f52c66862fa417c3d52d2 (diff) | |
download | chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2 |
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/browser_process_impl.cc')
-rw-r--r-- | chrome/browser/browser_process_impl.cc | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc new file mode 100644 index 0000000..3d5bd99 --- /dev/null +++ b/chrome/browser/browser_process_impl.cc @@ -0,0 +1,368 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "chrome/browser/browser_process_impl.h" + +#include "base/command_line.h" +#include "base/thread.h" +#include "base/path_service.h" +#include "chrome/browser/automation/automation_provider_list.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/download_file.h" +#include "chrome/browser/google_url_tracker.h" +#include "chrome/browser/icon_manager.h" +#include "chrome/browser/metrics_service.h" +#include "chrome/browser/plugin_service.h" +#include "chrome/browser/printing/print_job_manager.h" +#include "chrome/browser/profile_manager.h" +#include "chrome/browser/render_process_host.h" +#include "chrome/browser/resource_dispatcher_host.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "chrome/browser/save_file_manager.h" +#include "chrome/browser/debugger/debugger_wrapper.h" +#include "chrome/browser/suspend_controller.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/clipboard_service.h" +#include "chrome/common/l10n_util.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "chrome/views/accelerator_handler.h" +#include "chrome/views/view_storage.h" + +namespace { + +// ---------------------------------------------------------------------------- +// BrowserProcessSubThread +// +// This simple thread object is used for the specialized threads that the +// BrowserProcess spins up. +// +// Applications must initialize the COM library before they can call +// COM library functions other than CoGetMalloc and memory allocation +// functions, so this class initializes COM for those users. +class BrowserProcessSubThread : public ChromeThread { + public: + explicit BrowserProcessSubThread(ChromeThread::ID identifier) + : ChromeThread(identifier) { + } + + ~BrowserProcessSubThread() { + // We cannot rely on our base class to stop the thread since we want our + // CleanUp function to run. + Stop(); + } + + protected: + virtual void Init() { + // Initializes the COM library on the current thread. + CoInitialize(NULL); + + notification_service_ = new NotificationService; + } + + virtual void CleanUp() { + delete notification_service_; + notification_service_ = NULL; + + // Closes the COM library on the current thread. CoInitialize must + // be balanced by a corresponding call to CoUninitialize. + CoUninitialize(); + } + + private: + // Each specialized thread has its own notification service. + // Note: We don't use scoped_ptr because the destructor runs on the wrong + // thread. + NotificationService* notification_service_; +}; + +} // namespace + +BrowserProcessImpl::BrowserProcessImpl(CommandLine& command_line) + : created_resource_dispatcher_host_(false), + created_metrics_service_(false), + created_io_thread_(false), + created_file_thread_(false), + created_db_thread_(false), + created_profile_manager_(false), + created_local_state_(false), + created_icon_manager_(false), + initialized_broker_services_(false), + created_debugger_wrapper_(false), + broker_services_(NULL), + module_ref_count_(0), + memory_model_(MEDIUM_MEMORY_MODEL) { + g_browser_process = this; + clipboard_service_.reset(new ClipboardService); + main_notification_service_.reset(new NotificationService); + + // Must be created after the NotificationService. + print_job_manager_.reset(new printing::PrintJobManager); + + // Configure the browser memory model. + if (command_line.HasSwitch(switches::kMemoryModel)) { + std::wstring model = command_line.GetSwitchValue(switches::kMemoryModel); + if (!model.empty()) { + if (model == L"high") + memory_model_ = HIGH_MEMORY_MODEL; + else if (model == L"low") + memory_model_ = LOW_MEMORY_MODEL; + else if (model == L"medium") + memory_model_ = MEDIUM_MEMORY_MODEL; + } + } + + suspend_controller_ = new SuspendController(); +} + +BrowserProcessImpl::~BrowserProcessImpl() { + // Delete the AutomationProviderList before NotificationService, + // since it may try to unregister notifications + // Both NotificationService and AutomationProvider are singleton instances in + // the BrowserProcess. Since AutomationProvider may have some active + // notification observers, it is essential that it gets destroyed before the + // NotificationService. NotificationService won't be destroyed until after + // this destructor is run. + automation_provider_list_.reset(); + + // We need to destroy the MetricsService and GoogleURLTracker before the + // io_thread_ gets destroyed, since both destructors can call the URLFetcher + // destructor, which does an InvokeLater operation on the IO thread. (The IO + // thread will handle that URLFetcher operation before going away.) + metrics_service_.reset(); + google_url_tracker_.reset(); + + // Need to clear profiles (download managers) before the io_thread_. + profile_manager_.reset(); + + // Debugger must be cleaned up before IO thread and NotificationService. + debugger_wrapper_ = NULL; + + if (resource_dispatcher_host_.get()) { + // Need to tell Safe Browsing Service that the IO thread is going away + // since it cached a pointer to it. + if (resource_dispatcher_host()->safe_browsing_service()) + resource_dispatcher_host()->safe_browsing_service()->ShutDown(); + + // Cancel pending requests and prevent new requests. + resource_dispatcher_host()->Shutdown(); + } + + // Need to stop io_thread_ before resource_dispatcher_host_, since + // io_thread_ may still deref ResourceDispatcherHost and handle resource + // request before going away. + io_thread_.reset(); + + // Clean up state that lives on the file_thread_ before it goes away. + if (resource_dispatcher_host_.get()) { + resource_dispatcher_host()->download_file_manager()->Shutdown(); + resource_dispatcher_host()->save_file_manager()->Shutdown(); + } + + // Need to stop the file_thread_ here to force it to process messages in its + // message loop from the previous call to shutdown the DownloadFileManager, + // SaveFileManager and SessionService. + file_thread_.reset(); + + // With the file_thread_ flushed, we can release any icon resources. + icon_manager_.reset(); + + // Need to destroy ResourceDispatcherHost before PluginService and + // SafeBrowsingService, since it caches a pointer to it. + resource_dispatcher_host_.reset(); + + // Wait for the pending print jobs to finish. + print_job_manager_->OnQuit(); + print_job_manager_.reset(); + + // The ViewStorage needs to go before the NotificationService. + ChromeViews::ViewStorage::DeleteSharedInstance(); + + // Now OK to destroy NotificationService. + main_notification_service_.reset(); + + g_browser_process = NULL; +} + +// Need to define this so InvokeLater on the MessageLoop works. It's ok +// not to addref/release the MessageLoop here as we *know* the main thread +// isn't going to go away on us. +template <> +struct RunnableMethodTraits<MessageLoop> { + static void RetainCallee(MessageLoop* obj) { } + static void ReleaseCallee(MessageLoop* obj) { } +}; + +void BrowserProcessImpl::EndSession() { + // Mark all the profiles as clean. + ProfileManager* pm = profile_manager(); + for (ProfileManager::const_iterator i = pm->begin(); i != pm->end(); ++i) + (*i)->MarkAsCleanShutdown(); + + // Tell the metrics service it was cleanly shutdown. + MetricsService* metrics = g_browser_process->metrics_service(); + if (metrics && local_state()) { + metrics->RecordCleanShutdown(); + + metrics->RecordStartOfSessionEnd(); + + // MetricsService lazily writes to prefs, force it to write now. + local_state()->SavePersistentPrefs(file_thread()); + } + + // We must write that the profile and metrics service shutdown cleanly, + // otherwise on startup we'll think we crashed. So we block until done and + // then proceed with normal shutdown. + g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(MessageLoop::current(), &MessageLoop::Quit)); + MessageLoop::current()->Run(); +} + +printing::PrintJobManager* BrowserProcessImpl::print_job_manager() { + // TODO(abarth): DCHECK(CalledOnValidThread()); + // See <http://b/1287209>. + // print_job_manager_ is initialized in the constructor and destroyed in the + // destructor, so it should always be valid. + DCHECK(print_job_manager_.get()); + return print_job_manager_.get(); +} + +const std::wstring& BrowserProcessImpl::GetApplicationLocale() { + DCHECK(CalledOnValidThread()); + if (locale_.empty()) { + locale_ = l10n_util::GetApplicationLocale(local_state()->GetString( + prefs::kApplicationLocale)); + } + return locale_; +} + +void BrowserProcessImpl::CreateResourceDispatcherHost() { + DCHECK(!created_resource_dispatcher_host_ && + resource_dispatcher_host_.get() == NULL); + created_resource_dispatcher_host_ = true; + + resource_dispatcher_host_.reset( + new ResourceDispatcherHost(io_thread()->message_loop())); + resource_dispatcher_host_->Initialize(); +} + +void BrowserProcessImpl::CreateMetricsService() { + DCHECK(!created_metrics_service_ && metrics_service_.get() == NULL); + created_metrics_service_ = true; + + metrics_service_.reset(new MetricsService); +} + +void BrowserProcessImpl::CreateIOThread() { + DCHECK(!created_io_thread_ && io_thread_.get() == NULL); + created_io_thread_ = true; + + // Prior to starting the io thread, we create the plugin service as + // it is predominantly used from the io thread, but must be created + // on the main thread. The service ctor is inexpensive and does not + // invoke the io_thread() accessor. + PluginService::GetInstance(); + + scoped_ptr<Thread> thread(new BrowserProcessSubThread(ChromeThread::IO)); + if (!thread->Start()) + return; + io_thread_.swap(thread); +} + +void BrowserProcessImpl::CreateFileThread() { + DCHECK(!created_file_thread_ && file_thread_.get() == NULL); + created_file_thread_ = true; + + scoped_ptr<Thread> thread(new BrowserProcessSubThread(ChromeThread::FILE)); + if (!thread->Start()) + return; + file_thread_.swap(thread); +} + +void BrowserProcessImpl::CreateDBThread() { + DCHECK(!created_db_thread_ && db_thread_.get() == NULL); + created_db_thread_ = true; + + scoped_ptr<Thread> thread(new BrowserProcessSubThread(ChromeThread::DB)); + if (!thread->Start()) + return; + db_thread_.swap(thread); +} + +void BrowserProcessImpl::CreateProfileManager() { + DCHECK(!created_profile_manager_ && profile_manager_.get() == NULL); + created_profile_manager_ = true; + + profile_manager_.reset(new ProfileManager()); +} + +void BrowserProcessImpl::CreateLocalState() { + DCHECK(!created_local_state_ && local_state_.get() == NULL); + created_local_state_ = true; + + std::wstring local_state_path; + PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path); + local_state_.reset(new PrefService(local_state_path)); +} + +void BrowserProcessImpl::InitBrokerServices( + sandbox::BrokerServices* broker_services) { + DCHECK(!initialized_broker_services_ && broker_services_ == NULL); + broker_services->Init(); + initialized_broker_services_ = true; + broker_services_ = broker_services; +} + +void BrowserProcessImpl::CreateIconManager() { + DCHECK(!created_icon_manager_ && icon_manager_.get() == NULL); + created_icon_manager_ = true; + icon_manager_.reset(new IconManager); +} + +void BrowserProcessImpl::CreateDebuggerWrapper(int port) { + DCHECK(debugger_wrapper_.get() == NULL); + created_debugger_wrapper_ = true; + + debugger_wrapper_ = new DebuggerWrapper(port); +} + +void BrowserProcessImpl::CreateAcceleratorHandler() { + DCHECK(accelerator_handler_.get() == NULL); + scoped_ptr<ChromeViews::AcceleratorHandler> accelerator_handler( + new ChromeViews::AcceleratorHandler); + accelerator_handler_.swap(accelerator_handler); +} + +void BrowserProcessImpl::CreateGoogleURLTracker() { + DCHECK(google_url_tracker_.get() == NULL); + scoped_ptr<GoogleURLTracker> google_url_tracker(new GoogleURLTracker); + google_url_tracker_.swap(google_url_tracker); +} |