diff options
author | oshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-04 19:39:11 +0000 |
---|---|---|
committer | oshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-04 19:39:11 +0000 |
commit | b0f2f3b67dc744fd0ef6d7b636b97c21c25519c5 (patch) | |
tree | 5afba181d694687c62b798f54bc9eb657cabb317 | |
parent | 2de17d3d9d78354614d999fa1abe70e3ddb5cdef (diff) | |
download | chromium_src-b0f2f3b67dc744fd0ef6d7b636b97c21c25519c5.zip chromium_src-b0f2f3b67dc744fd0ef6d7b636b97c21c25519c5.tar.gz chromium_src-b0f2f3b67dc744fd0ef6d7b636b97c21c25519c5.tar.bz2 |
Load url if appcache exists in offline mode.
Remove OfflineLoadService as it's no longer important.
BUG=chromium-os:9559, chromium-os:12370
TEST=see the bug.
Review URL: http://codereview.chromium.org/6604015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76950 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/chromeos/offline/offline_load_page.cc | 5 | ||||
-rw-r--r-- | chrome/browser/chromeos/offline/offline_load_service.cc | 108 | ||||
-rw-r--r-- | chrome/browser/chromeos/offline/offline_load_service.h | 75 | ||||
-rw-r--r-- | chrome/browser/renderer_host/offline_resource_handler.cc | 81 | ||||
-rw-r--r-- | chrome/browser/renderer_host/offline_resource_handler.h | 12 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 |
6 files changed, 76 insertions, 207 deletions
diff --git a/chrome/browser/chromeos/offline/offline_load_page.cc b/chrome/browser/chromeos/offline/offline_load_page.cc index 7bb9e74..e9457b8 100644 --- a/chrome/browser/chromeos/offline/offline_load_page.cc +++ b/chrome/browser/chromeos/offline/offline_load_page.cc @@ -53,7 +53,10 @@ void OfflineLoadPage::Show(int process_host_id, int render_view_id, } else { TabContents* tab_contents = tab_util::GetTabContentsByID(process_host_id, render_view_id); - DCHECK(tab_contents); + // There is a chance that the tab is closed after we decided to show + // offline and before we actually show the offline page. + if (!tab_contents) + return; (new OfflineLoadPage(tab_contents, url, delegate))->Show(); } } diff --git a/chrome/browser/chromeos/offline/offline_load_service.cc b/chrome/browser/chromeos/offline/offline_load_service.cc deleted file mode 100644 index a0e8c12..0000000 --- a/chrome/browser/chromeos/offline/offline_load_service.cc +++ /dev/null @@ -1,108 +0,0 @@ -// 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/tab_contents/tab_util.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_source.h" -#include "content/browser/browser_thread.h" -#include "content/browser/tab_contents/navigation_controller.h" -#include "content/browser/tab_contents/tab_contents.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>; - OfflineLoadServiceSingleton() - : offline_load_service_(new chromeos::OfflineLoadService()) {} - virtual ~OfflineLoadServiceSingleton() {} - - scoped_refptr<chromeos::OfflineLoadService> offline_load_service_; - - DISALLOW_COPY_AND_ASSIGN(OfflineLoadServiceSingleton); -}; - -static base::LazyInstance<OfflineLoadServiceSingleton> - 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<NavigationController>(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<NavigationController>( - navigation_controller)); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/offline/offline_load_service.h b/chrome/browser/chromeos/offline/offline_load_service.h deleted file mode 100644 index d052d51..0000000 --- a/chrome/browser/chromeos/offline/offline_load_service.h +++ /dev/null @@ -1,75 +0,0 @@ -// 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. - -#ifndef CHROME_BROWSER_CHROMEOS_OFFLINE_OFFLINE_LOAD_SERVICE_H_ -#define CHROME_BROWSER_CHROMEOS_OFFLINE_OFFLINE_LOAD_SERVICE_H_ -#pragma once - -#include <tr1/unordered_set> - -#include "base/ref_counted.h" -#include "chrome/common/notification_observer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_type.h" - -class GURL; -class NavigationController; -class TabContents; -template<class A> class scoped_ptr; - -namespace chromeos { - -// OfflineLoadService decides whether or not the given url in the tab -// should be loaded when the network is not available. The current -// implementation simply memorize the tab that loads offline page. -// TODO(oshima): Improve the logic so that we can automatically load -// if there is valid cache content and/or it supports offline mode. -class OfflineLoadService - : public NotificationObserver, - public base::RefCountedThreadSafe<OfflineLoadService> { - public: - // Returns the singleton instance of the offline load service. - static OfflineLoadService* Get(); - - // Returns true if the tab should proceed with loading the page even if - // it's offline. - bool ShouldProceed(int process_id, int render_view_id, - const GURL& url) const; - - // Record that the user pressed "procced" button for - // the tab_contents. - void Proceeded(int proceed_id, int render_view_id, const GURL& url); - - // NotificationObserver implementation. - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - - private: - friend class base::RefCountedThreadSafe<OfflineLoadService>; - friend class scoped_ptr<OfflineLoadService>; - friend class OfflineLoadServiceSingleton; - - OfflineLoadService() {} - virtual ~OfflineLoadService() {} - - // A method invoked in UI thread to remove |tab_contents| from |tabs_|. - void RemoveTabContents(TabContents* tab_contents); - - // A method invoked in UI thread to register TAB_CLOSED - // notification. - void RegisterNotification( - NavigationController* navigation_controller); - - NotificationRegistrar registrar_; - - // Set of tabs that should proceed - std::tr1::unordered_set<const TabContents*> tabs_; - - DISALLOW_COPY_AND_ASSIGN(OfflineLoadService); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_OFFLINE_OFFLINE_LOAD_SERVICE_H_ diff --git a/chrome/browser/renderer_host/offline_resource_handler.cc b/chrome/browser/renderer_host/offline_resource_handler.cc index 86bce00..19f5aee 100644 --- a/chrome/browser/renderer_host/offline_resource_handler.cc +++ b/chrome/browser/renderer_host/offline_resource_handler.cc @@ -12,11 +12,14 @@ #include "base/string_util.h" #include "chrome/browser/chromeos/network_state_notifier.h" #include "chrome/browser/chromeos/offline/offline_load_page.h" -#include "chrome/browser/chromeos/offline/offline_load_service.h" +#include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/common/url_constants.h" #include "content/browser/browser_thread.h" #include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" +#include "net/base/net_errors.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" OfflineResourceHandler::OfflineResourceHandler( ResourceHandler* handler, @@ -29,7 +32,12 @@ OfflineResourceHandler::OfflineResourceHandler( render_view_id_(route_id), rdh_(rdh), request_(request), - deferred_request_id_(-1) { + deferred_request_id_(-1), + offline_page_shown_(false) { +} + +OfflineResourceHandler::~OfflineResourceHandler() { + DCHECK(!appcache_completion_callback_.get()); } bool OfflineResourceHandler::OnUploadProgress(int request_id, @@ -59,9 +67,40 @@ bool OfflineResourceHandler::OnResponseCompleted( } void OfflineResourceHandler::OnRequestClosed() { + if (appcache_completion_callback_) { + appcache_completion_callback_->Cancel(); + appcache_completion_callback_.release(); + Release(); // Balanced with OnWillStart + } else if (offline_page_shown_) { + offline_page_shown_ = false; + // Interstitial page is already closed, so we need + // |Release| to balance with OnWillStart. + Release(); + } next_handler_->OnRequestClosed(); } +void OfflineResourceHandler::OnCanHandleOfflineComplete(int rv) { + CHECK(appcache_completion_callback_); + appcache_completion_callback_ = NULL; + if (deferred_request_id_ == -1) { + LOG(WARNING) << "OnCanHandleOfflineComplete called after completion: " + << " this=" << this; + NOTREACHED(); + return; + } + if (rv == net::OK) { + Resume(); + Release(); // Balanced with OnWillStart + } else { + // Skipping AddRef/Release because they're redundant. + offline_page_shown_ = true; + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + NewRunnableMethod(this, &OfflineResourceHandler::ShowOfflinePage)); + } +} + bool OfflineResourceHandler::OnWillStart(int request_id, const GURL& url, bool* defer) { @@ -69,10 +108,16 @@ bool OfflineResourceHandler::OnWillStart(int request_id, deferred_request_id_ = request_id; deferred_url_ = url; DVLOG(1) << "WillStart: this=" << this << ", request id=" << request_id; - AddRef(); // Balanced with OnBlockingPageComplete - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod(this, &OfflineResourceHandler::ShowOfflinePage)); + AddRef(); // Balanced with OnCanHandleOfflineComplete + DCHECK(!appcache_completion_callback_); + appcache_completion_callback_ = + new net::CancelableCompletionCallback<OfflineResourceHandler>( + this, &OfflineResourceHandler::OnCanHandleOfflineComplete); + ChromeURLRequestContext* url_request_context = + static_cast<ChromeURLRequestContext*>(request_->context()); + url_request_context->appcache_service()->CanHandleMainResourceOffline( + url, appcache_completion_callback_); + *defer = true; return true; } @@ -91,13 +136,6 @@ bool OfflineResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { } void OfflineResourceHandler::OnBlockingPageComplete(bool proceed) { - if (deferred_request_id_ < 0) { - LOG(WARNING) << "OnBlockingPageComplete called after completion: " - << " this=" << this << ", request_id=" - << deferred_request_id_; - NOTREACHED(); - return; - } if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, @@ -106,6 +144,15 @@ void OfflineResourceHandler::OnBlockingPageComplete(bool proceed) { proceed)); return; } + if (deferred_request_id_ == -1) { + LOG(WARNING) << "OnBlockingPageComplete called after completion: " + << " this=" << this; + NOTREACHED(); + return; + } + DCHECK(offline_page_shown_); + offline_page_shown_ = false; + if (proceed) { Resume(); } else { @@ -133,9 +180,7 @@ bool OfflineResourceHandler::ShouldShowOfflinePage(const GURL& url) const { return IsRemote(url) && !chromeos::NetworkStateNotifier::is_connected() && ResourceDispatcherHost::InfoForRequest(request_)->resource_type() - == ResourceType::MAIN_FRAME && - !chromeos::OfflineLoadService::Get()->ShouldProceed( - process_host_id_, render_view_id_, url); + == ResourceType::MAIN_FRAME; } void OfflineResourceHandler::Resume() { @@ -143,10 +188,6 @@ void OfflineResourceHandler::Resume() { int request_id = deferred_request_id_; ClearRequestInfo(); - chromeos::OfflineLoadService::Get()->Proceeded( - process_host_id_, render_view_id_, url); - - DCHECK_NE(request_id, -1); bool defer = false; DVLOG(1) << "Resume load: this=" << this << ", request id=" << request_id; next_handler_->OnWillStart(request_id, url, &defer); diff --git a/chrome/browser/renderer_host/offline_resource_handler.h b/chrome/browser/renderer_host/offline_resource_handler.h index 542ac27..33e4549 100644 --- a/chrome/browser/renderer_host/offline_resource_handler.h +++ b/chrome/browser/renderer_host/offline_resource_handler.h @@ -11,6 +11,7 @@ #include "base/ref_counted.h" #include "chrome/browser/chromeos/offline/offline_load_page.h" #include "content/browser/renderer_host/resource_handler.h" +#include "net/base/completion_callback.h" class MessageLoop; class ResourceDispatcherHost; @@ -28,7 +29,7 @@ class OfflineResourceHandler : public ResourceHandler, int render_view_id, ResourceDispatcherHost* rdh, net::URLRequest* request); - ~OfflineResourceHandler() {} + virtual ~OfflineResourceHandler(); // ResourceHandler implementation: virtual bool OnUploadProgress(int request_id, uint64 position, uint64 size); @@ -61,6 +62,9 @@ class OfflineResourceHandler : public ResourceHandler, // Shows the offline interstitinal page in UI thread. void ShowOfflinePage(); + // A callback to tell if an appcache exists. + void OnCanHandleOfflineComplete(int rv); + scoped_refptr<ResourceHandler> next_handler_; int process_host_id_; @@ -72,6 +76,12 @@ class OfflineResourceHandler : public ResourceHandler, int deferred_request_id_; GURL deferred_url_; + // If the offline page has been requested to show. + bool offline_page_shown_; + + scoped_refptr<net::CancelableCompletionCallback<OfflineResourceHandler> > + appcache_completion_callback_; + DISALLOW_COPY_AND_ASSIGN(OfflineResourceHandler); }; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 87d3c03..a5a2c12 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -621,8 +621,6 @@ 'browser/chromeos/notifications/system_notification_factory.h', 'browser/chromeos/offline/offline_load_page.cc', 'browser/chromeos/offline/offline_load_page.h', - 'browser/chromeos/offline/offline_load_service.cc', - 'browser/chromeos/offline/offline_load_service.h', 'browser/chromeos/options/network_config_view.cc', 'browser/chromeos/options/network_config_view.h', 'browser/chromeos/options/wifi_config_view.cc', |