Commit 72a6b5e9 authored by Azeem Arshad's avatar Azeem Arshad Committed by Commit Bot

Add profile keyed service for android messages for web integration.

This adds a CrosSmsService, a profile keyed service that
manages connection and pairing for ChromeOS Android Messages for
Web integration. This also includes a basic ConnectionManager
class that's listens for service worker events and
establishes connection. Message passing between service
worker and connection manager will be included in a follow up CL.
Design docs: go/awm-cros-service go/awm-cros

Bug: 850823
Change-Id: I792fbdad6aff6bc9391e4b0055e8e84a36bbd56e
Reviewed-on: https://chromium-review.googlesource.com/1140902
Commit-Queue: Azeem Arshad <azeemarshad@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarJeremy Klein <jlklein@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583512}
parent caa8cff9
...@@ -3065,6 +3065,7 @@ jumbo_split_static_library("browser") { ...@@ -3065,6 +3065,7 @@ jumbo_split_static_library("browser") {
"//ash/components/quick_launch/public/mojom:constants", "//ash/components/quick_launch/public/mojom:constants",
"//ash/public/cpp", "//ash/public/cpp",
"//chrome/browser/chromeos", "//chrome/browser/chromeos",
"//chrome/browser/chromeos/android_sms:android_sms",
"//chromeos/services/device_sync", "//chromeos/services/device_sync",
"//chromeos/services/device_sync/public/mojom", "//chromeos/services/device_sync/public/mojom",
"//chromeos/services/multidevice_setup", "//chromeos/services/multidevice_setup",
......
...@@ -2311,6 +2311,7 @@ source_set("unit_tests") { ...@@ -2311,6 +2311,7 @@ source_set("unit_tests") {
"//ash", "//ash",
"//ash/system/message_center/arc:test_support", "//ash/system/message_center/arc:test_support",
"//base", "//base",
"//chrome/browser/chromeos/android_sms:unit_tests",
"//chrome/browser/resources/chromeos/zip_archiver:char_coding", "//chrome/browser/resources/chromeos/zip_archiver:char_coding",
"//chrome/common", "//chrome/common",
"//chromeos:login_manager_proto", "//chromeos:login_manager_proto",
......
# Copyright 2018 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.
static_library("android_sms") {
sources = [
"android_sms_service.cc",
"android_sms_service.h",
"android_sms_service_factory.cc",
"android_sms_service_factory.h",
"android_sms_switches.cc",
"android_sms_switches.h",
"android_sms_urls.cc",
"android_sms_urls.h",
"connection_establisher.h",
"connection_establisher_impl.cc",
"connection_establisher_impl.h",
"connection_manager.cc",
"connection_manager.h",
]
deps = [
"//base",
"//chrome/browser/chromeos:chromeos",
"//chromeos:chromeos",
"//components/keyed_service/content:content",
"//components/keyed_service/core:core",
"//components/session_manager/core:core",
"//content/public/browser",
]
}
static_library("test_support") {
testonly = true
sources = [
"fake_connection_establisher.cc",
"fake_connection_establisher.h",
]
deps = [
":android_sms",
"//content/public/browser",
]
}
source_set("unit_tests") {
testonly = true
sources = [
"connection_manager_unittest.cc",
]
deps = [
":android_sms",
":test_support",
"//content/public/browser",
"//content/test:test_support",
"//testing/gtest",
]
}
azeemarshad@chromium.org
jlklein@chromium.org
khorimoto@chromium.org
jonmann@chromium.org
\ No newline at end of file
// Copyright 2018 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/android_sms/android_sms_service.h"
#include "chrome/browser/chromeos/android_sms/android_sms_urls.h"
#include "chrome/browser/chromeos/android_sms/connection_establisher_impl.h"
#include "components/session_manager/core/session_manager.h"
#include "content/public/browser/storage_partition.h"
namespace chromeos {
namespace android_sms {
AndroidSmsService::AndroidSmsService(content::BrowserContext* browser_context)
: browser_context_(browser_context) {
session_manager::SessionManager::Get()->AddObserver(this);
}
AndroidSmsService::~AndroidSmsService() = default;
void AndroidSmsService::Shutdown() {
session_manager::SessionManager::Get()->RemoveObserver(this);
}
void AndroidSmsService::OnSessionStateChanged() {
// At most one ConnectionManager should be created.
if (connection_manager_)
return;
// ConnectionManager should not be created for blocked sessions.
if (session_manager::SessionManager::Get()->IsUserSessionBlocked())
return;
content::StoragePartition* storage_partition =
content::BrowserContext::GetStoragePartitionForSite(
browser_context_, GetAndroidMessagesURL());
content::ServiceWorkerContext* service_worker_context =
storage_partition->GetServiceWorkerContext();
connection_manager_ = std::make_unique<ConnectionManager>(
service_worker_context, std::make_unique<ConnectionEstablisherImpl>());
}
} // namespace android_sms
} // namespace chromeos
// Copyright 2018 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_ANDROID_SMS_ANDROID_SMS_SERVICE_H_
#define CHROME_BROWSER_CHROMEOS_ANDROID_SMS_ANDROID_SMS_SERVICE_H_
#include <memory>
#include "chrome/browser/chromeos/android_sms/connection_manager.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/session_manager/core/session_manager_observer.h"
#include "content/public/browser/browser_context.h"
namespace chromeos {
namespace android_sms {
// Profile Keyed Service responsible for maintaining connection with
// android web messages service worker and initiating pairing.
class AndroidSmsService : public KeyedService,
public session_manager::SessionManagerObserver {
public:
explicit AndroidSmsService(content::BrowserContext* context);
~AndroidSmsService() override;
private:
// KeyedService:
void Shutdown() override;
// session_manager::SessionManagerObserver
void OnSessionStateChanged() override;
content::BrowserContext* browser_context_;
std::unique_ptr<ConnectionManager> connection_manager_;
DISALLOW_COPY_AND_ASSIGN(AndroidSmsService);
};
} // namespace android_sms
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_ANDROID_SMS_ANDROID_SMS_SERVICE_H_
// Copyright 2018 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/android_sms/android_sms_service_factory.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chromeos/chromeos_features.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
namespace chromeos {
namespace android_sms {
// static
AndroidSmsServiceFactory* AndroidSmsServiceFactory::GetInstance() {
static base::NoDestructor<AndroidSmsServiceFactory> factory_instance;
return factory_instance.get();
}
// static
AndroidSmsService* AndroidSmsServiceFactory::GetForBrowserContext(
content::BrowserContext* browser_context) {
return static_cast<AndroidSmsService*>(
AndroidSmsServiceFactory::GetInstance()->GetServiceForBrowserContext(
browser_context, true));
}
AndroidSmsServiceFactory::AndroidSmsServiceFactory()
: BrowserContextKeyedServiceFactory(
"AndroidSmsService",
BrowserContextDependencyManager::GetInstance()) {}
AndroidSmsServiceFactory::~AndroidSmsServiceFactory() = default;
KeyedService* AndroidSmsServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
if (!base::FeatureList::IsEnabled(
chromeos::features::kAndroidMessagesIntegration)) {
return nullptr;
}
Profile* profile = Profile::FromBrowserContext(context);
if (ProfileHelper::Get()->GetUserByProfile(profile) == nullptr)
return nullptr;
return new AndroidSmsService(context);
}
bool AndroidSmsServiceFactory::ServiceIsCreatedWithBrowserContext() const {
return true;
}
} // namespace android_sms
} // namespace chromeos
// Copyright 2018 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_ANDROID_SMS_ANDROID_SMS_SERVICE_FACTORY_H_
#define CHROME_BROWSER_CHROMEOS_ANDROID_SMS_ANDROID_SMS_SERVICE_FACTORY_H_
#include "base/no_destructor.h"
#include "chrome/browser/chromeos/android_sms/android_sms_service.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
namespace chromeos {
namespace android_sms {
class AndroidSmsServiceFactory : public BrowserContextKeyedServiceFactory {
public:
static AndroidSmsServiceFactory* GetInstance();
static AndroidSmsService* GetForBrowserContext(
content::BrowserContext* browser_context);
private:
friend class base::NoDestructor<AndroidSmsServiceFactory>;
AndroidSmsServiceFactory();
~AndroidSmsServiceFactory() override;
// BrowserContextKeyedServiceFactory:
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
bool ServiceIsCreatedWithBrowserContext() const override;
DISALLOW_COPY_AND_ASSIGN(AndroidSmsServiceFactory);
};
} // namespace android_sms
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_ANDROID_SMS_ANDROID_SMS_SERVICE_FACTORY_H_
// Copyright 2018 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/android_sms/android_sms_switches.h"
namespace switches {
const char kAlternateAndroidMessagesUrl[] = "alternate-android-messages-url";
} // namespace switches
// Copyright 2018 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_ANDROID_SMS_ANDROID_SMS_SWITCHES_H_
#define CHROME_BROWSER_CHROMEOS_ANDROID_SMS_ANDROID_SMS_SWITCHES_H_
namespace switches {
// When specified with a url string as parameter, the given url overrides the
// Android Messages for Web url used by AndroidSmsService.
extern const char kAlternateAndroidMessagesUrl[];
} // namespace switches
#endif // CHROME_BROWSER_CHROMEOS_ANDROID_SMS_ANDROID_SMS_SWITCHES_H_
// Copyright 2018 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/android_sms/android_sms_urls.h"
#include "base/command_line.h"
#include "base/optional.h"
#include "chrome/browser/chromeos/android_sms/android_sms_switches.h"
#include "url/gurl.h"
namespace chromeos {
namespace android_sms {
namespace {
const char kDefaultAndroidMessagesUrl[] = "https://messages.android.com";
} // namespace
GURL GetAndroidMessagesURL() {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
GURL android_messages_url(command_line->GetSwitchValueASCII(
switches::kAlternateAndroidMessagesUrl));
if (android_messages_url.is_empty()) {
android_messages_url = GURL(kDefaultAndroidMessagesUrl);
}
return android_messages_url;
}
} // namespace android_sms
} // namespace chromeos
// Copyright 2018 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_ANDROID_SMS_ANDROID_SMS_URLS_H_
#define CHROME_BROWSER_CHROMEOS_ANDROID_SMS_ANDROID_SMS_URLS_H_
#include "url/gurl.h"
namespace chromeos {
namespace android_sms {
// Returns URL to Android Messages for Web page used by AndroidSmsService.
GURL GetAndroidMessagesURL();
} // namespace android_sms
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_ANDROID_SMS_ANDROID_SMS_URLS_H_
// Copyright 2018 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_ANDROID_SMS_CONNECTION_ESTABLISHER_H_
#define CHROME_BROWSER_CHROMEOS_ANDROID_SMS_CONNECTION_ESTABLISHER_H_
#include "base/macros.h"
#include "content/public/browser/service_worker_context.h"
namespace chromeos {
namespace android_sms {
// Establishes a background connection from the Android Messages for Web
// service worker to the Tachyon server.
class ConnectionEstablisher {
public:
virtual ~ConnectionEstablisher() = default;
virtual void EstablishConnection(
content::ServiceWorkerContext* service_worker_context) = 0;
protected:
ConnectionEstablisher() = default;
private:
DISALLOW_COPY_AND_ASSIGN(ConnectionEstablisher);
};
} // namespace android_sms
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_ANDROID_SMS_CONNECTION_ESTABLISHER_H_
// Copyright 2018 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/android_sms/connection_establisher_impl.h"
namespace chromeos {
namespace android_sms {
ConnectionEstablisherImpl::ConnectionEstablisherImpl() = default;
ConnectionEstablisherImpl::~ConnectionEstablisherImpl() = default;
void ConnectionEstablisherImpl::EstablishConnection(
content::ServiceWorkerContext* service_worker_context) {
// TODO(azeemarshad): Send connection message to service worker using
// ServiceWorkerContext::StartServiceWorkerAndDispatchLongRunningMessage
// when https://chromium-review.googlesource.com/c/chromium/src/+/1119580
// is ready.
return;
}
} // namespace android_sms
} // namespace chromeos
// Copyright 2018 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_ANDROID_SMS_CONNECTION_ESTABLISHER_IMPL_H_
#define CHROME_BROWSER_CHROMEOS_ANDROID_SMS_CONNECTION_ESTABLISHER_IMPL_H_
#include "chrome/browser/chromeos/android_sms/connection_establisher.h"
namespace chromeos {
namespace android_sms {
// Concrete ConnectionEstablisher implementation that initiates a background
// connection between the Android Messages for Web service worker and the
// Tachyon server by dispatching a known message string to it.
//
// To allow the service worker to continue running past it's default timeout
// this message is sent using a special long-running dispatch.
class ConnectionEstablisherImpl : public ConnectionEstablisher {
public:
ConnectionEstablisherImpl();
~ConnectionEstablisherImpl() override;
void EstablishConnection(
content::ServiceWorkerContext* service_worker_context) override;
private:
DISALLOW_COPY_AND_ASSIGN(ConnectionEstablisherImpl);
};
} // namespace android_sms
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_ANDROID_SMS_CONNECTION_ESTABLISHER_IMPL_H_
// Copyright 2018 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/android_sms/connection_manager.h"
#include "chrome/browser/chromeos/android_sms/android_sms_urls.h"
#include "components/session_manager/core/session_manager.h"
namespace chromeos {
namespace android_sms {
ConnectionManager::ConnectionManager(
content::ServiceWorkerContext* service_worker_context,
std::unique_ptr<ConnectionEstablisher> connection_establisher)
: service_worker_context_(service_worker_context),
connection_establisher_(std::move(connection_establisher)) {
service_worker_context_->AddObserver(this);
connection_establisher_->EstablishConnection(service_worker_context_);
}
ConnectionManager::~ConnectionManager() {
service_worker_context_->RemoveObserver(this);
}
void ConnectionManager::OnVersionActivated(int64_t version_id,
const GURL& scope) {
if (!scope.EqualsIgnoringRef(GetAndroidMessagesURL()))
return;
prev_active_version_id_ = active_version_id_;
active_version_id_ = version_id;
connection_establisher_->EstablishConnection(service_worker_context_);
}
void ConnectionManager::OnVersionRedundant(int64_t version_id,
const GURL& scope) {
if (!scope.EqualsIgnoringRef(GetAndroidMessagesURL()))
return;
if (active_version_id_ != version_id)
return;
// If the active version is marked redundant then it cannot handle messages
// anymore, so stop tracking it.
prev_active_version_id_ = active_version_id_;
active_version_id_.reset();
}
void ConnectionManager::OnNoControllees(int64_t version_id, const GURL& scope) {
if (!scope.EqualsIgnoringRef(GetAndroidMessagesURL()))
return;
// Set active_version_id_ in case we missed version activated.
// This is unlikely but protects against a case where a Android Messages for
// Web page may have opened before the ConnectionManager is created.
if (!active_version_id_ && prev_active_version_id_ != version_id)
active_version_id_ = version_id;
if (active_version_id_ != version_id)
return;
connection_establisher_->EstablishConnection(service_worker_context_);
}
} // namespace android_sms
} // namespace chromeos
// Copyright 2018 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_ANDROID_SMS_CONNECTION_MANAGER_H_
#define CHROME_BROWSER_CHROMEOS_ANDROID_SMS_CONNECTION_MANAGER_H_
#include "base/gtest_prod_util.h"
#include "chrome/browser/chromeos/android_sms/connection_establisher.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/service_worker_context_observer.h"
namespace chromeos {
namespace android_sms {
// ConnectionManager checks to see when the user has no Android Messages for Web
// pages open (in a web page or PWA) and notifies the corresponding
// service worker to start a background connection.
//
// This class is an observer for Android Messages for Web service worker
// lifecycle events and uses ConnectionEstablisher to initiate a background
// connection with Tachyon server when appropriate. Specifically, in the
// following cases
// 1. Startup.
// 2. Activation: This occurs on service worker update, when a new updated
// version of the service worker replaces the current active version or on
// service worker cold start.
// 3. NoControllees: When all pages controlled by the service worker are closed.
// The connection establishment may be attempted in more cases than actually
// required. It's left to the service worker to ignore or establish a background
// connection as required. E.g., The service worker will not establish a
// connection if it's is already connected to the Android Messages for Web page
// or if a connection already exists.
class ConnectionManager : public content::ServiceWorkerContextObserver {
public:
ConnectionManager(
content::ServiceWorkerContext* service_worker_context,
std::unique_ptr<ConnectionEstablisher> connection_establisher);
~ConnectionManager() override;
private:
// content::ServiceWorkerContextObserver:
void OnVersionActivated(int64_t version_id, const GURL& scope) override;
void OnVersionRedundant(int64_t version_id, const GURL& scope) override;
void OnNoControllees(int64_t version_id, const GURL& scope) override;
content::ServiceWorkerContext* service_worker_context_;
std::unique_ptr<ConnectionEstablisher> connection_establisher_;
// Version ID of the Android Messages for Web service worker that's currently
// active i.e., capable of handling messages and controlling pages.
base::Optional<int64_t> active_version_id_;
// Version ID of the previously active Android Messages for Web
// service worker.
base::Optional<int64_t> prev_active_version_id_;
DISALLOW_COPY_AND_ASSIGN(ConnectionManager);
};
} // namespace android_sms
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_ANDROID_SMS_CONNECTION_MANAGER_H_
// Copyright 2018 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/android_sms/connection_manager.h"
#include "chrome/browser/chromeos/android_sms/android_sms_urls.h"
#include "chrome/browser/chromeos/android_sms/fake_connection_establisher.h"
#include "content/public/test/fake_service_worker_context.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace android_sms {
namespace {
const int64_t kDummyVersionId = 123l;
const int64_t kDummyVersionId2 = 456l;
} // namespace
class ConnectionManagerTest : public testing::Test {
protected:
ConnectionManagerTest() = default;
~ConnectionManagerTest() override = default;
void SetUp() override {
std::unique_ptr<FakeConnectionEstablisher> fake_connection_establisher =
std::make_unique<FakeConnectionEstablisher>();
fake_connection_establisher_ = fake_connection_establisher.get();
fake_service_worker_context_ =
std::make_unique<content::FakeServiceWorkerContext>();
connection_manager_ = std::make_unique<ConnectionManager>(
fake_service_worker_context_.get(),
std::move(fake_connection_establisher));
}
void VerifyNumEstablishConnectionCalls(size_t count) {
ASSERT_EQ(
count,
fake_connection_establisher_->establish_connection_calls().size());
for (content::ServiceWorkerContext* service_worker_context :
fake_connection_establisher_->establish_connection_calls())
EXPECT_EQ(fake_service_worker_context_.get(), service_worker_context);
}
content::FakeServiceWorkerContext* fake_service_worker_context() const {
return fake_service_worker_context_.get();
}
private:
FakeConnectionEstablisher* fake_connection_establisher_;
std::unique_ptr<content::FakeServiceWorkerContext>
fake_service_worker_context_;
std::unique_ptr<ConnectionManager> connection_manager_;
DISALLOW_COPY_AND_ASSIGN(ConnectionManagerTest);
};
TEST_F(ConnectionManagerTest, ConnectOnActivate) {
fake_service_worker_context()->NotifyObserversOnVersionActivated(
kDummyVersionId, GetAndroidMessagesURL());
// Verify that connection establishing is attempted on startup and
// when a new version is activated.
// startup + activate.
VerifyNumEstablishConnectionCalls(2u);
}
TEST_F(ConnectionManagerTest, ConnectOnNoControllees) {
// Notify Activation so that Connection manager is tracking the version ID.
fake_service_worker_context()->NotifyObserversOnVersionActivated(
kDummyVersionId, GetAndroidMessagesURL());
// Verify that connection establishing is attempted when there are no
// controllees.
fake_service_worker_context()->NotifyObserversOnNoControllees(
kDummyVersionId, GetAndroidMessagesURL());
// startup + activate + no controllees.
VerifyNumEstablishConnectionCalls(3u);
}
TEST_F(ConnectionManagerTest, IgnoreRedundantVersion) {
fake_service_worker_context()->NotifyObserversOnVersionActivated(
kDummyVersionId, GetAndroidMessagesURL());
// Notify that current active version is now redundant.
fake_service_worker_context()->NotifyObserversOnVersionRedundant(
kDummyVersionId, GetAndroidMessagesURL());
// Verify that no connection establishing is attempted when there are no
// controllees for the redundant version.
fake_service_worker_context()->NotifyObserversOnNoControllees(
kDummyVersionId, GetAndroidMessagesURL());
// startup + activate only.
VerifyNumEstablishConnectionCalls(2u);
}
TEST_F(ConnectionManagerTest, ConnectOnNoControlleesWithNoActive) {
// Verify that connection establishing is attempted when there are no
// controllees for a version ID even if the activate notification was missed.
fake_service_worker_context()->NotifyObserversOnNoControllees(
kDummyVersionId, GetAndroidMessagesURL());
// startup + no controllees.
VerifyNumEstablishConnectionCalls(2u);
}
TEST_F(ConnectionManagerTest, IgnoreOnNoControlleesInvalidId) {
fake_service_worker_context()->NotifyObserversOnVersionActivated(
kDummyVersionId, GetAndroidMessagesURL());
// Verify that OnNoControllees with different version id is ignored.
fake_service_worker_context()->NotifyObserversOnNoControllees(
kDummyVersionId2, GetAndroidMessagesURL());
// startup + activate only.
VerifyNumEstablishConnectionCalls(2u);
}
TEST_F(ConnectionManagerTest, InvalidScope) {
GURL invalid_scope("https://example.com");
// Verify that OnVersionActivated and OnNoControllees with invalid scope
// are ignored
fake_service_worker_context()->NotifyObserversOnVersionActivated(
kDummyVersionId, invalid_scope);
fake_service_worker_context()->NotifyObserversOnNoControllees(kDummyVersionId,
invalid_scope);
VerifyNumEstablishConnectionCalls(1u); // startup only, ignore others.
// Verify that OnVersionRedundant with invalid scope is ignored
fake_service_worker_context()->NotifyObserversOnVersionActivated(
kDummyVersionId, GetAndroidMessagesURL());
fake_service_worker_context()->NotifyObserversOnVersionRedundant(
kDummyVersionId, invalid_scope);
fake_service_worker_context()->NotifyObserversOnNoControllees(
kDummyVersionId, GetAndroidMessagesURL());
// startup + activate + no controllees.
VerifyNumEstablishConnectionCalls(3u);
}
} // namespace android_sms
} // namespace chromeos
// Copyright 2018 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/android_sms/fake_connection_establisher.h"
namespace chromeos {
namespace android_sms {
FakeConnectionEstablisher::FakeConnectionEstablisher() = default;
FakeConnectionEstablisher::~FakeConnectionEstablisher() = default;
void FakeConnectionEstablisher::EstablishConnection(
content::ServiceWorkerContext* service_worker_context_) {
establish_connection_calls_.push_back(service_worker_context_);
}
} // namespace android_sms
} // namespace chromeos
// Copyright 2018 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_ANDROID_SMS_FAKE_CONNECTION_ESTABLISHER_H_
#define CHROME_BROWSER_CHROMEOS_ANDROID_SMS_FAKE_CONNECTION_ESTABLISHER_H_
#include "chrome/browser/chromeos/android_sms/connection_establisher.h"
namespace chromeos {
namespace android_sms {
// Test ConnectionEstablisher implementation.
class FakeConnectionEstablisher : public ConnectionEstablisher {
public:
FakeConnectionEstablisher();
~FakeConnectionEstablisher() override;
const std::vector<content::ServiceWorkerContext*>&
establish_connection_calls() const {
return establish_connection_calls_;
}
private:
// ConnectionEstablisher:
void EstablishConnection(
content::ServiceWorkerContext* service_worker_context_) override;
std::vector<content::ServiceWorkerContext*> establish_connection_calls_;
DISALLOW_COPY_AND_ASSIGN(FakeConnectionEstablisher);
};
} // namespace android_sms
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_ANDROID_SMS_FAKE_CONNECTION_ESTABLISHER_H_
...@@ -105,6 +105,7 @@ ...@@ -105,6 +105,7 @@
#endif #endif
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/android_sms/android_sms_service_factory.h"
#include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h" #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h"
#include "chrome/browser/chromeos/cryptauth/chrome_cryptauth_service_factory.h" #include "chrome/browser/chromeos/cryptauth/chrome_cryptauth_service_factory.h"
#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
...@@ -226,6 +227,7 @@ void ChromeBrowserMainExtraPartsProfiles:: ...@@ -226,6 +227,7 @@ void ChromeBrowserMainExtraPartsProfiles::
ChromeBrowsingDataRemoverDelegateFactory::GetInstance(); ChromeBrowsingDataRemoverDelegateFactory::GetInstance();
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
chromeos::ChromeCryptAuthServiceFactory::GetInstance(); chromeos::ChromeCryptAuthServiceFactory::GetInstance();
chromeos::android_sms::AndroidSmsServiceFactory::GetInstance();
#endif #endif
ChromeSigninClientFactory::GetInstance(); ChromeSigninClientFactory::GetInstance();
#if BUILDFLAG(ENABLE_PRINT_PREVIEW) && !defined(OS_CHROMEOS) #if BUILDFLAG(ENABLE_PRINT_PREVIEW) && !defined(OS_CHROMEOS)
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "content/public/test/fake_service_worker_context.h" #include "content/public/test/fake_service_worker_context.h"
#include "content/public/browser/service_worker_context_observer.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/logging.h" #include "base/logging.h"
...@@ -14,11 +15,11 @@ FakeServiceWorkerContext::~FakeServiceWorkerContext() {} ...@@ -14,11 +15,11 @@ FakeServiceWorkerContext::~FakeServiceWorkerContext() {}
void FakeServiceWorkerContext::AddObserver( void FakeServiceWorkerContext::AddObserver(
ServiceWorkerContextObserver* observer) { ServiceWorkerContextObserver* observer) {
NOTREACHED(); observers_.AddObserver(observer);
} }
void FakeServiceWorkerContext::RemoveObserver( void FakeServiceWorkerContext::RemoveObserver(
ServiceWorkerContextObserver* observer) { ServiceWorkerContextObserver* observer) {
NOTREACHED(); observers_.RemoveObserver(observer);
} }
void FakeServiceWorkerContext::RegisterServiceWorker( void FakeServiceWorkerContext::RegisterServiceWorker(
const GURL& script_url, const GURL& script_url,
...@@ -93,4 +94,25 @@ void FakeServiceWorkerContext::StopAllServiceWorkers(base::OnceClosure) { ...@@ -93,4 +94,25 @@ void FakeServiceWorkerContext::StopAllServiceWorkers(base::OnceClosure) {
NOTREACHED(); NOTREACHED();
} }
void FakeServiceWorkerContext::NotifyObserversOnVersionActivated(
int64_t version_id,
const GURL& scope) {
for (auto& observer : observers_)
observer.OnVersionActivated(version_id, scope);
}
void FakeServiceWorkerContext::NotifyObserversOnVersionRedundant(
int64_t version_id,
const GURL& scope) {
for (auto& observer : observers_)
observer.OnVersionRedundant(version_id, scope);
}
void FakeServiceWorkerContext::NotifyObserversOnNoControllees(
int64_t version_id,
const GURL& scope) {
for (auto& observer : observers_)
observer.OnNoControllees(version_id, scope);
}
} // namespace content } // namespace content
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string> #include <string>
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/observer_list.h"
#include "content/public/browser/service_worker_context.h" #include "content/public/browser/service_worker_context.h"
class GURL; class GURL;
...@@ -56,6 +57,11 @@ class FakeServiceWorkerContext : public ServiceWorkerContext { ...@@ -56,6 +57,11 @@ class FakeServiceWorkerContext : public ServiceWorkerContext {
void StopAllServiceWorkersForOrigin(const GURL& origin) override; void StopAllServiceWorkersForOrigin(const GURL& origin) override;
void StopAllServiceWorkers(base::OnceClosure callback) override; void StopAllServiceWorkers(base::OnceClosure callback) override;
// Explicitly notify ServiceWorkerContextObservers added to this context.
void NotifyObserversOnVersionActivated(int64_t version_id, const GURL& scope);
void NotifyObserversOnVersionRedundant(int64_t version_id, const GURL& scope);
void NotifyObserversOnNoControllees(int64_t version_id, const GURL& scope);
bool start_service_worker_for_navigation_hint_called() { bool start_service_worker_for_navigation_hint_called() {
return start_service_worker_for_navigation_hint_called_; return start_service_worker_for_navigation_hint_called_;
} }
...@@ -68,6 +74,8 @@ class FakeServiceWorkerContext : public ServiceWorkerContext { ...@@ -68,6 +74,8 @@ class FakeServiceWorkerContext : public ServiceWorkerContext {
private: private:
bool start_service_worker_for_navigation_hint_called_ = false; bool start_service_worker_for_navigation_hint_called_ = false;
base::ObserverList<ServiceWorkerContextObserver, true> observers_;
DISALLOW_COPY_AND_ASSIGN(FakeServiceWorkerContext); DISALLOW_COPY_AND_ASSIGN(FakeServiceWorkerContext);
}; };
......
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