// Copyright (c) 2010 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. #include "chrome/browser/chromeos/offline/offline_load_service.h" #include "base/lazy_instance.h" #include "base/ref_counted.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_source.h" namespace chromeos { // A utility class that serves a singleton instance of OfflineLoadService. // OfflineLoadSerivce itself cannot be a singleton as it implements // RefCount interface. class OfflineLoadServiceSingleton { public: chromeos::OfflineLoadService* offline_load_service() { return offline_load_service_.get(); } private: friend struct base::DefaultLazyInstanceTraits; OfflineLoadServiceSingleton() : offline_load_service_(new chromeos::OfflineLoadService()) {} virtual ~OfflineLoadServiceSingleton() {} scoped_refptr offline_load_service_; DISALLOW_COPY_AND_ASSIGN(OfflineLoadServiceSingleton); }; static base::LazyInstance g_offline_load_service_singleton(base::LINKER_INITIALIZED); // static OfflineLoadService* OfflineLoadService::Get() { return g_offline_load_service_singleton.Get().offline_load_service(); } void OfflineLoadService::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (type.value == NotificationType::TAB_CLOSED) { registrar_.Remove(this, NotificationType::TAB_CLOSED, source); NavigationController* tab = Source(source).ptr(); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, NewRunnableMethod(this, &OfflineLoadService::RemoveTabContents, tab->tab_contents())); } } bool OfflineLoadService::ShouldProceed(int process_host_id, int render_view_id, const GURL& url) const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); TabContents* tab_contents = tab_util::GetTabContentsByID( process_host_id, render_view_id); DCHECK(tab_contents); bool proceed = tabs_.find(tab_contents) != tabs_.end(); DVLOG(1) << "ShouldProceed:" << proceed << ", url=" << url.spec() << ", tab_contents=" << tab_contents; return proceed; } void OfflineLoadService::Proceeded(int process_host_id, int render_view_id, const GURL& url) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); TabContents* tab_contents = tab_util::GetTabContentsByID( process_host_id, render_view_id); DCHECK(tab_contents); if (tabs_.find(tab_contents) == tabs_.end()) { DVLOG(1) << "Proceeded: url=" << url.spec() << ", tab_contents=" << tab_contents; tabs_.insert(tab_contents); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, NewRunnableMethod(this, &OfflineLoadService::RegisterNotification, &tab_contents->controller())); } else { DLOG(WARNING) << "Proceeded: ignoring duplicate"; } } void OfflineLoadService::RemoveTabContents(TabContents* tab_contents) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); tabs_.erase(tabs_.find(tab_contents)); } void OfflineLoadService::RegisterNotification( NavigationController* navigation_controller) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); registrar_.Add(this, NotificationType::TAB_CLOSED, Source( navigation_controller)); } } // namespace chromeos