summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-04 19:39:11 +0000
committeroshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-04 19:39:11 +0000
commitb0f2f3b67dc744fd0ef6d7b636b97c21c25519c5 (patch)
tree5afba181d694687c62b798f54bc9eb657cabb317
parent2de17d3d9d78354614d999fa1abe70e3ddb5cdef (diff)
downloadchromium_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.cc5
-rw-r--r--chrome/browser/chromeos/offline/offline_load_service.cc108
-rw-r--r--chrome/browser/chromeos/offline/offline_load_service.h75
-rw-r--r--chrome/browser/renderer_host/offline_resource_handler.cc81
-rw-r--r--chrome/browser/renderer_host/offline_resource_handler.h12
-rw-r--r--chrome/chrome_browser.gypi2
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',