Commit f23c9142 authored by benwells's avatar benwells Committed by Commit bot

This exposes a way to see if there is a Service Worker controlling two URLs.

This is used for the app banner manager to determine if it should
show a banner for the current page.

BUG=452825

Review URL: https://codereview.chromium.org/893793005

Cr-Commit-Position: refs/heads/master@{#315024}
parent a01db7d4
......@@ -24,8 +24,12 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/render_messages.h"
#include "content/public/browser/android/content_view_core.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/frame_navigate_params.h"
#include "content/public/common/manifest.h"
......@@ -46,7 +50,8 @@ const char kBannerTag[] = "google-play-id";
namespace banners {
AppBannerManager::AppBannerManager(JNIEnv* env, jobject obj)
: weak_java_banner_view_manager_(env, obj) {}
: weak_java_banner_view_manager_(env, obj), weak_factory_(this) {
}
AppBannerManager::~AppBannerManager() {
}
......@@ -148,21 +153,38 @@ void AppBannerManager::OnDidGetManifest(const content::Manifest& manifest) {
return;
}
// TODO(benwells): Check triggering parameters here and if there is a meta
// tag.
// Create an infobar to promote the manifest's app.
web_app_data_ = manifest;
app_title_ = web_app_data_.name.string();
GURL icon_url =
ManifestIconSelector::FindBestMatchingIcon(
manifest.icons,
GetPreferredIconSize(),
gfx::Screen::GetScreenFor(web_contents()->GetNativeView()));
if (icon_url.is_empty())
return;
FetchIcon(icon_url);
// Check to see if there is a single service worker controlling this page
// and the manifest's start url.
Profile* profile =
Profile::FromBrowserContext(web_contents()->GetBrowserContext());
content::StoragePartition* storage_partition =
content::BrowserContext::GetStoragePartition(
profile, web_contents()->GetSiteInstance());
DCHECK(storage_partition);
storage_partition->GetServiceWorkerContext()->CheckHasServiceWorker(
validated_url_, manifest.start_url,
base::Bind(&AppBannerManager::OnDidCheckHasServiceWorker,
weak_factory_.GetWeakPtr()));
}
void AppBannerManager::OnDidCheckHasServiceWorker(bool has_service_worker) {
if (has_service_worker) {
// TODO(benwells): Check triggering parameters.
// Create an infobar to promote the manifest's app.
GURL icon_url =
ManifestIconSelector::FindBestMatchingIcon(
web_app_data_.icons,
GetPreferredIconSize(),
gfx::Screen::GetScreenFor(web_contents()->GetNativeView()));
if (icon_url.is_empty())
return;
FetchIcon(icon_url);
}
}
bool AppBannerManager::OnMessageReceived(const IPC::Message& message) {
......
......@@ -7,7 +7,9 @@
#include "base/android/jni_android.h"
#include "base/android/jni_weak_ref.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/android/banners/app_banner_infobar_delegate.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
#include "chrome/browser/ui/android/infobars/app_banner_infobar.h"
......@@ -133,6 +135,9 @@ class AppBannerManager : public chrome::BitmapFetcherDelegate,
const std::string& tag_content,
const GURL& expected_url);
// Called when the result of the CheckHasServiceWorker query has completed.
void OnDidCheckHasServiceWorker(bool has_service_worker);
// Fetches the icon for an app.
scoped_ptr<chrome::BitmapFetcher> fetcher_;
GURL validated_url_;
......@@ -149,6 +154,11 @@ class AppBannerManager : public chrome::BitmapFetcherDelegate,
// AppBannerManager on the Java side.
JavaObjectWeakGlobalRef weak_java_banner_view_manager_;
// A weak pointer is used as the lifetime of the ServiceWorkerContext is
// longer than the lifetime of this banner manager. The banner manager
// might be gone when calls sent to the ServiceWorkerContext are completed.
base::WeakPtrFactory<AppBannerManager> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AppBannerManager);
}; // class AppBannerManager
......
......@@ -21,11 +21,13 @@
#include "content/browser/service_worker/service_worker_process_manager.h"
#include "content/browser/service_worker/service_worker_quota_client.h"
#include "content/browser/service_worker/service_worker_request_handler.h"
#include "content/browser/service_worker/service_worker_utils.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/service_worker_context.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/url_request/url_request_context_getter.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/quota/quota_manager_proxy.h"
......@@ -278,6 +280,27 @@ void ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins(
callback.Run(usage_infos);
}
void ServiceWorkerContextWrapper::DidFindRegistrationForCheckHasServiceWorker(
const GURL& other_url,
const CheckHasServiceWorkerCallback& callback,
ServiceWorkerStatusCode status,
const scoped_refptr<ServiceWorkerRegistration>& registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (status != SERVICE_WORKER_OK) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(callback, false));
return;
}
DCHECK(registration);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(callback, registration->active_version() &&
ServiceWorkerUtils::ScopeMatches(
registration->pattern(), other_url)));
}
namespace {
void StatusCodeToBoolCallbackAdapter(
const ServiceWorkerContext::ResultCallback& callback,
......@@ -309,6 +332,30 @@ void ServiceWorkerContextWrapper::DeleteForOrigin(const GURL& origin_url) {
DeleteForOrigin(origin_url, base::Bind(&EmptySuccessCallback));
}
void ServiceWorkerContextWrapper::CheckHasServiceWorker(
const GURL& url,
const GURL& other_url,
const CheckHasServiceWorkerCallback& callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ServiceWorkerContextWrapper::CheckHasServiceWorker, this,
url, other_url, callback));
return;
}
if (!context_core_.get()) {
LOG(ERROR) << "ServiceWorkerContextCore is no longer alive.";
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(callback, false));
return;
}
GURL stripped_url = net::SimplifyUrlForRequest(url);
context()->storage()->FindRegistrationForDocument(
stripped_url, base::Bind(&ServiceWorkerContextWrapper::
DidFindRegistrationForCheckHasServiceWorker,
this, other_url, callback));
}
void ServiceWorkerContextWrapper::AddObserver(
ServiceWorkerContextObserver* observer) {
observer_list_->AddObserver(observer);
......
......@@ -85,6 +85,10 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
const net::CompletionCallback& callback) override;
void GetAllOriginsInfo(const GetUsageInfoCallback& callback) override;
void DeleteForOrigin(const GURL& origin_url) override;
void CheckHasServiceWorker(
const GURL& url,
const GURL& other_url,
const CheckHasServiceWorkerCallback& callback) override;
// DeleteForOrigin with completion callback. Does not exit early, and returns
// false if one or more of the deletions fail.
......@@ -129,6 +133,12 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
const GetUsageInfoCallback& callback,
const std::vector<ServiceWorkerRegistrationInfo>& registrations);
void DidFindRegistrationForCheckHasServiceWorker(
const GURL& other_url,
const CheckHasServiceWorkerCallback& callback,
ServiceWorkerStatusCode status,
const scoped_refptr<ServiceWorkerRegistration>& registration);
const scoped_refptr<ObserverListThreadSafe<ServiceWorkerContextObserver> >
observer_list_;
const scoped_ptr<ServiceWorkerProcessManager> process_manager_;
......
......@@ -32,6 +32,9 @@ class ServiceWorkerContext {
typedef base::Callback<void(const std::vector<ServiceWorkerUsageInfo>&
usage_info)> GetUsageInfoCallback;
typedef base::Callback<void(bool has_service_worker)>
CheckHasServiceWorkerCallback;
// Registers the header name which should not be passed to the ServiceWorker.
// Must be called from the IO thread.
CONTENT_EXPORT static void AddExcludedHeadersForFetchEvent(
......@@ -73,7 +76,7 @@ class ServiceWorkerContext {
// TODO(jyasskin): Provide a way to SendMessage to a Scope.
// Determines if a request for 'url' can be satisfied while offline.
// Determines if a request for |url| can be satisfied while offline.
// This method always completes asynchronously.
virtual void CanHandleMainResourceOffline(const GURL& url,
const GURL& first_party,
......@@ -84,6 +87,17 @@ class ServiceWorkerContext {
virtual void GetAllOriginsInfo(const GetUsageInfoCallback& callback) = 0;
virtual void DeleteForOrigin(const GURL& origin_url) = 0;
// Returns true if an active Service Worker registration exists that matches
// |url|, and if |other_url| falls inside the scope of the same registration.
// Note this still returns true even if there is a Service Worker registration
// which has a longer match for |other_url|.
// This function can be called from any thread, but the callback will always
// be called on the UI thread.
virtual void CheckHasServiceWorker(
const GURL& url,
const GURL& other_url,
const CheckHasServiceWorkerCallback& callback) = 0;
protected:
ServiceWorkerContext() {}
virtual ~ServiceWorkerContext() {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment