diff options
Diffstat (limited to 'chromium/chrome/browser/gcm')
10 files changed, 700 insertions, 0 deletions
diff --git a/chromium/chrome/browser/gcm/COMMON_METADATA b/chromium/chrome/browser/gcm/COMMON_METADATA new file mode 100644 index 00000000000..777cdb6a192 --- /dev/null +++ b/chromium/chrome/browser/gcm/COMMON_METADATA @@ -0,0 +1,4 @@ +monorail: { + component: "Services>CloudMessaging" +} +team_email: "platform-capabilities@chromium.org" diff --git a/chromium/chrome/browser/gcm/DIR_METADATA b/chromium/chrome/browser/gcm/DIR_METADATA new file mode 100644 index 00000000000..66fe8683773 --- /dev/null +++ b/chromium/chrome/browser/gcm/DIR_METADATA @@ -0,0 +1 @@ +mixins: "//chrome/browser/gcm/COMMON_METADATA" diff --git a/chromium/chrome/browser/gcm/OWNERS b/chromium/chrome/browser/gcm/OWNERS new file mode 100644 index 00000000000..06f7d3cbe88 --- /dev/null +++ b/chromium/chrome/browser/gcm/OWNERS @@ -0,0 +1,4 @@ +dimich@chromium.org +fgorski@chromium.org +jianli@chromium.org +peter@chromium.org diff --git a/chromium/chrome/browser/gcm/gcm_product_util.cc b/chromium/chrome/browser/gcm/gcm_product_util.cc new file mode 100644 index 00000000000..cb2fa486c11 --- /dev/null +++ b/chromium/chrome/browser/gcm/gcm_product_util.cc @@ -0,0 +1,57 @@ +// Copyright 2016 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/gcm/gcm_product_util.h" + +#include "base/strings/string_piece.h" +#include "base/strings/string_util.h" +#include "chrome/common/chrome_version.h" +#include "chrome/common/pref_names.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/version_info/version_info.h" + +namespace gcm { + +namespace { + +std::string ToLowerAlphaNum(base::StringPiece in) { + std::string out; + out.reserve(in.size()); + for (char ch : in) { + if (base::IsAsciiAlpha(ch) || base::IsAsciiDigit(ch)) + out.push_back(base::ToLowerASCII(ch)); + } + return out; +} + +} // namespace + +std::string GetProductCategoryForSubtypes(PrefService* prefs) { + std::string product_category_for_subtypes = + prefs->GetString(prefs::kGCMProductCategoryForSubtypes); + if (!product_category_for_subtypes.empty()) + return product_category_for_subtypes; + + std::string product = ToLowerAlphaNum(PRODUCT_SHORTNAME_STRING); + std::string ns = product == "chromium" ? "org" : "com"; + std::string platform = ToLowerAlphaNum(version_info::GetOSType()); + product_category_for_subtypes = ns + '.' + product + '.' + platform; + + prefs->SetString(prefs::kGCMProductCategoryForSubtypes, + product_category_for_subtypes); + return product_category_for_subtypes; +} + +void RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterStringPref(prefs::kGCMProductCategoryForSubtypes, + std::string() /* default_value */); +} + +void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { + RegisterPrefs(registry); +} + +} // namespace gcm diff --git a/chromium/chrome/browser/gcm/gcm_product_util.h b/chromium/chrome/browser/gcm/gcm_product_util.h new file mode 100644 index 00000000000..f91c869b310 --- /dev/null +++ b/chromium/chrome/browser/gcm/gcm_product_util.h @@ -0,0 +1,30 @@ +// Copyright 2016 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_GCM_GCM_PRODUCT_UTIL_H_ +#define CHROME_BROWSER_GCM_GCM_PRODUCT_UTIL_H_ + +#include <string> + +class PrefRegistrySimple; +class PrefService; + +namespace user_prefs { +class PrefRegistrySyncable; +} + +namespace gcm { + +// Returns a string like "com.chrome.macosx" that should be used as the GCM +// category when an app_id is sent as a subtype instead of as a category. This +// is generated once, then remains fixed forever (even if the product name +// changes), since it must match existing Instance ID tokens. +std::string GetProductCategoryForSubtypes(PrefService* prefs); + +void RegisterPrefs(PrefRegistrySimple* registry); +void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + +} // namespace gcm + +#endif // CHROME_BROWSER_GCM_GCM_PRODUCT_UTIL_H_ diff --git a/chromium/chrome/browser/gcm/gcm_profile_service_factory.cc b/chromium/chrome/browser/gcm/gcm_profile_service_factory.cc new file mode 100644 index 00000000000..b3207963fdb --- /dev/null +++ b/chromium/chrome/browser/gcm/gcm_profile_service_factory.cc @@ -0,0 +1,174 @@ +// Copyright (c) 2013 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/gcm/gcm_profile_service_factory.h" +#include <memory> + +#include "base/bind.h" +#include "base/no_destructor.h" +#include "base/task/sequenced_task_runner.h" +#include "base/task/thread_pool.h" +#include "build/build_config.h" +#include "chrome/browser/profiles/incognito_helpers.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_key.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "components/gcm_driver/gcm_profile_service.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/offline_pages/buildflags/buildflags.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/network_service_instance.h" +#include "content/public/browser/storage_partition.h" +#include "services/network/public/mojom/network_context.mojom.h" + +#if !defined(OS_ANDROID) +#include "chrome/browser/gcm/gcm_product_util.h" +#include "chrome/common/channel_info.h" +#include "components/gcm_driver/gcm_client_factory.h" +#include "content/public/browser/browser_context.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#endif + +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) +#include "chrome/browser/offline_pages/prefetch/prefetch_service_factory.h" +#include "components/gcm_driver/gcm_driver.h" +#include "components/offline_pages/core/offline_page_feature.h" +#include "components/offline_pages/core/prefetch/prefetch_gcm_app_handler.h" +#include "components/offline_pages/core/prefetch/prefetch_service.h" +#endif + +namespace gcm { + +namespace { + +#if !defined(OS_ANDROID) +// Requests a ProxyResolvingSocketFactory on the UI thread. Note that a WeakPtr +// of GCMProfileService is needed to detect when the KeyedService shuts down, +// and avoid calling into |profile| which might have also been destroyed. +void RequestProxyResolvingSocketFactoryOnUIThread( + Profile* profile, + base::WeakPtr<GCMProfileService> service, + mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory> + receiver) { + if (!service) + return; + network::mojom::NetworkContext* network_context = + profile->GetDefaultStoragePartition()->GetNetworkContext(); + network_context->CreateProxyResolvingSocketFactory(std::move(receiver)); +} + +// A thread-safe wrapper to request a ProxyResolvingSocketFactory. +void RequestProxyResolvingSocketFactory( + Profile* profile, + base::WeakPtr<GCMProfileService> service, + mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory> + receiver) { + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce(&RequestProxyResolvingSocketFactoryOnUIThread, profile, + std::move(service), std::move(receiver))); +} +#endif + +BrowserContextKeyedServiceFactory::TestingFactory& GetTestingFactory() { + static base::NoDestructor<BrowserContextKeyedServiceFactory::TestingFactory> + testing_factory; + return *testing_factory; +} + +} // namespace + +GCMProfileServiceFactory::ScopedTestingFactoryInstaller:: + ScopedTestingFactoryInstaller(TestingFactory testing_factory) { + DCHECK(!GetTestingFactory()); + GetTestingFactory() = std::move(testing_factory); +} + +GCMProfileServiceFactory::ScopedTestingFactoryInstaller:: + ~ScopedTestingFactoryInstaller() { + GetTestingFactory() = BrowserContextKeyedServiceFactory::TestingFactory(); +} + +// static +GCMProfileService* GCMProfileServiceFactory::GetForProfile( + content::BrowserContext* profile) { + // GCM is not supported in incognito mode. + if (profile->IsOffTheRecord()) + return NULL; + + return static_cast<GCMProfileService*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + +// static +GCMProfileServiceFactory* GCMProfileServiceFactory::GetInstance() { + static base::NoDestructor<GCMProfileServiceFactory> instance; + return instance.get(); +} + +GCMProfileServiceFactory::GCMProfileServiceFactory() + : BrowserContextKeyedServiceFactory( + "GCMProfileService", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(IdentityManagerFactory::GetInstance()); +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + DependsOn(offline_pages::PrefetchServiceFactory::GetInstance()); +#endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) +} + +GCMProfileServiceFactory::~GCMProfileServiceFactory() { +} + +KeyedService* GCMProfileServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + Profile* profile = Profile::FromBrowserContext(context); + DCHECK(!profile->IsOffTheRecord()); + + TestingFactory& testing_factory = GetTestingFactory(); + if (testing_factory) + return testing_factory.Run(context).release(); + + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner( + base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})); + std::unique_ptr<GCMProfileService> service; +#if defined(OS_ANDROID) + service = std::make_unique<GCMProfileService>(profile->GetPath(), + blocking_task_runner); +#else + service = std::make_unique<GCMProfileService>( + profile->GetPrefs(), profile->GetPath(), + base::BindRepeating(&RequestProxyResolvingSocketFactory, profile), + profile->GetDefaultStoragePartition() + ->GetURLLoaderFactoryForBrowserProcess(), + content::GetNetworkConnectionTracker(), chrome::GetChannel(), + gcm::GetProductCategoryForSubtypes(profile->GetPrefs()), + IdentityManagerFactory::GetForProfile(profile), + std::make_unique<GCMClientFactory>(), content::GetUIThreadTaskRunner({}), + content::GetIOThreadTaskRunner({}), blocking_task_runner); +#endif +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + offline_pages::PrefetchService* prefetch_service = + offline_pages::PrefetchServiceFactory::GetForKey( + profile->GetProfileKey()); + if (prefetch_service != nullptr) { + offline_pages::PrefetchGCMHandler* prefetch_gcm_handler = + prefetch_service->GetPrefetchGCMHandler(); + service->driver()->AddAppHandler(prefetch_gcm_handler->GetAppId(), + prefetch_gcm_handler->AsGCMAppHandler()); + } +#endif // BUILDFLAG(ENABLE_OFFLINE_PAGES) + + return service.release(); +} + +content::BrowserContext* GCMProfileServiceFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return chrome::GetBrowserContextOwnInstanceInIncognito(context); +} + +} // namespace gcm diff --git a/chromium/chrome/browser/gcm/gcm_profile_service_factory.h b/chromium/chrome/browser/gcm/gcm_profile_service_factory.h new file mode 100644 index 00000000000..13511e84611 --- /dev/null +++ b/chromium/chrome/browser/gcm/gcm_profile_service_factory.h @@ -0,0 +1,57 @@ +// Copyright (c) 2013 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_GCM_GCM_PROFILE_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_GCM_GCM_PROFILE_SERVICE_FACTORY_H_ + +#include "base/no_destructor.h" +#include "components/gcm_driver/system_encryptor.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace gcm { + +class GCMProfileService; + +// Singleton that owns all GCMProfileService and associates them with +// Profiles. +class GCMProfileServiceFactory : public BrowserContextKeyedServiceFactory { + public: + static GCMProfileService* GetForProfile(content::BrowserContext* profile); + static GCMProfileServiceFactory* GetInstance(); + + // Helper registering a testing factory. Needs to be instantiated before the + // factory is accessed in your test, and deallocated after the last access. + // Usually this is achieved by putting this object as the first member in + // your test fixture. + class ScopedTestingFactoryInstaller { + public: + explicit ScopedTestingFactoryInstaller(TestingFactory testing_factory); + + ScopedTestingFactoryInstaller(const ScopedTestingFactoryInstaller&) = + delete; + ScopedTestingFactoryInstaller& operator=( + const ScopedTestingFactoryInstaller&) = delete; + + ~ScopedTestingFactoryInstaller(); + }; + + GCMProfileServiceFactory(const GCMProfileServiceFactory&) = delete; + GCMProfileServiceFactory& operator=(const GCMProfileServiceFactory&) = delete; + + private: + friend base::NoDestructor<GCMProfileServiceFactory>; + + GCMProfileServiceFactory(); + ~GCMProfileServiceFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* profile) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; +}; + +} // namespace gcm + +#endif // CHROME_BROWSER_GCM_GCM_PROFILE_SERVICE_FACTORY_H_ diff --git a/chromium/chrome/browser/gcm/gcm_profile_service_unittest.cc b/chromium/chrome/browser/gcm/gcm_profile_service_unittest.cc new file mode 100644 index 00000000000..2a13932a454 --- /dev/null +++ b/chromium/chrome/browser/gcm/gcm_profile_service_unittest.cc @@ -0,0 +1,269 @@ +// Copyright 2014 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 <memory> +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/callback_helpers.h" +#include "base/memory/raw_ptr.h" +#include "base/run_loop.h" +#include "base/task/sequenced_task_runner.h" +#include "base/task/thread_pool.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "chrome/browser/gcm/gcm_product_util.h" +#include "chrome/browser/gcm/gcm_profile_service_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "chrome/common/channel_info.h" +#include "chrome/test/base/testing_profile.h" +#include "components/gcm_driver/fake_gcm_app_handler.h" +#include "components/gcm_driver/fake_gcm_client.h" +#include "components/gcm_driver/fake_gcm_client_factory.h" +#include "components/gcm_driver/gcm_client.h" +#include "components/gcm_driver/gcm_client_factory.h" +#include "components/gcm_driver/gcm_driver.h" +#include "components/gcm_driver/gcm_profile_service.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/test/browser_task_environment.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "services/network/test/test_network_connection_tracker.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chromeos/dbus/concierge/concierge_client.h" +#endif + +namespace gcm { + +namespace { + +const char kTestAppID[] = "TestApp"; +const char kUserID[] = "user"; + +void RequestProxyResolvingSocketFactoryOnUIThread( + Profile* profile, + base::WeakPtr<gcm::GCMProfileService> service, + mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory> + receiver) { + if (!service) + return; + return profile->GetDefaultStoragePartition() + ->GetNetworkContext() + ->CreateProxyResolvingSocketFactory(std::move(receiver)); +} + +void RequestProxyResolvingSocketFactory( + Profile* profile, + base::WeakPtr<gcm::GCMProfileService> service, + mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory> + receiver) { + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&RequestProxyResolvingSocketFactoryOnUIThread, + profile, service, std::move(receiver))); +} + +std::unique_ptr<KeyedService> BuildGCMProfileService( + content::BrowserContext* context) { + Profile* profile = Profile::FromBrowserContext(context); + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner( + base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})); + return std::make_unique<gcm::GCMProfileService>( + profile->GetPrefs(), profile->GetPath(), + base::BindRepeating(&RequestProxyResolvingSocketFactory, profile), + profile->GetDefaultStoragePartition() + ->GetURLLoaderFactoryForBrowserProcess(), + network::TestNetworkConnectionTracker::GetInstance(), + chrome::GetChannel(), + gcm::GetProductCategoryForSubtypes(profile->GetPrefs()), + IdentityManagerFactory::GetForProfile(profile), + std::unique_ptr<gcm::GCMClientFactory>( + new gcm::FakeGCMClientFactory(content::GetUIThreadTaskRunner({}), + content::GetIOThreadTaskRunner({}))), + content::GetUIThreadTaskRunner({}), content::GetIOThreadTaskRunner({}), + blocking_task_runner); +} + +} // namespace + +class GCMProfileServiceTest : public testing::Test { + public: + GCMProfileServiceTest(const GCMProfileServiceTest&) = delete; + GCMProfileServiceTest& operator=(const GCMProfileServiceTest&) = delete; + + protected: + GCMProfileServiceTest(); + ~GCMProfileServiceTest() override; + + // testing::Test: + void SetUp() override; + void TearDown() override; + + FakeGCMClient* GetGCMClient() const; + + void CreateGCMProfileService(); + + void RegisterAndWaitForCompletion(const std::vector<std::string>& sender_ids); + void UnregisterAndWaitForCompletion(); + void SendAndWaitForCompletion(const OutgoingMessage& message); + + void RegisterCompleted(base::OnceClosure callback, + const std::string& registration_id, + GCMClient::Result result); + void UnregisterCompleted(base::OnceClosure callback, + GCMClient::Result result); + void SendCompleted(base::OnceClosure callback, + const std::string& message_id, + GCMClient::Result result); + + GCMDriver* driver() const { return gcm_profile_service_->driver(); } + std::string registration_id() const { return registration_id_; } + GCMClient::Result registration_result() const { return registration_result_; } + GCMClient::Result unregistration_result() const { + return unregistration_result_; + } + std::string send_message_id() const { return send_message_id_; } + GCMClient::Result send_result() const { return send_result_; } + + private: + content::BrowserTaskEnvironment task_environment_; + std::unique_ptr<TestingProfile> profile_; + raw_ptr<GCMProfileService> gcm_profile_service_; + std::unique_ptr<FakeGCMAppHandler> gcm_app_handler_; + + std::string registration_id_; + GCMClient::Result registration_result_; + GCMClient::Result unregistration_result_; + std::string send_message_id_; + GCMClient::Result send_result_; +}; + +GCMProfileServiceTest::GCMProfileServiceTest() + : gcm_profile_service_(nullptr), + gcm_app_handler_(new FakeGCMAppHandler), + registration_result_(GCMClient::UNKNOWN_ERROR), + send_result_(GCMClient::UNKNOWN_ERROR) {} + +GCMProfileServiceTest::~GCMProfileServiceTest() { +} + +FakeGCMClient* GCMProfileServiceTest::GetGCMClient() const { + return static_cast<FakeGCMClient*>( + gcm_profile_service_->driver()->GetGCMClientForTesting()); +} + +void GCMProfileServiceTest::SetUp() { +#if BUILDFLAG(IS_CHROMEOS_ASH) + chromeos::ConciergeClient::InitializeFake(/*fake_cicerone_client=*/nullptr); +#endif + TestingProfile::Builder builder; + profile_ = builder.Build(); +} + +void GCMProfileServiceTest::TearDown() { + gcm_profile_service_->driver()->RemoveAppHandler(kTestAppID); +#if BUILDFLAG(IS_CHROMEOS_ASH) + profile_.reset(); + chromeos::ConciergeClient::Shutdown(); +#endif +} + +void GCMProfileServiceTest::CreateGCMProfileService() { + gcm_profile_service_ = static_cast<GCMProfileService*>( + GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse( + profile_.get(), base::BindRepeating(&BuildGCMProfileService))); + gcm_profile_service_->driver()->AddAppHandler( + kTestAppID, gcm_app_handler_.get()); +} + +void GCMProfileServiceTest::RegisterAndWaitForCompletion( + const std::vector<std::string>& sender_ids) { + base::RunLoop run_loop; + gcm_profile_service_->driver()->Register( + kTestAppID, sender_ids, + base::BindOnce(&GCMProfileServiceTest::RegisterCompleted, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); +} + +void GCMProfileServiceTest::UnregisterAndWaitForCompletion() { + base::RunLoop run_loop; + gcm_profile_service_->driver()->Unregister( + kTestAppID, + base::BindOnce(&GCMProfileServiceTest::UnregisterCompleted, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); +} + +void GCMProfileServiceTest::SendAndWaitForCompletion( + const OutgoingMessage& message) { + base::RunLoop run_loop; + gcm_profile_service_->driver()->Send( + kTestAppID, kUserID, message, + base::BindOnce(&GCMProfileServiceTest::SendCompleted, + base::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); +} + +void GCMProfileServiceTest::RegisterCompleted( + base::OnceClosure callback, + const std::string& registration_id, + GCMClient::Result result) { + registration_id_ = registration_id; + registration_result_ = result; + std::move(callback).Run(); +} + +void GCMProfileServiceTest::UnregisterCompleted(base::OnceClosure callback, + GCMClient::Result result) { + unregistration_result_ = result; + std::move(callback).Run(); +} + +void GCMProfileServiceTest::SendCompleted(base::OnceClosure callback, + const std::string& message_id, + GCMClient::Result result) { + send_message_id_ = message_id; + send_result_ = result; + std::move(callback).Run(); +} + +TEST_F(GCMProfileServiceTest, RegisterAndUnregister) { + CreateGCMProfileService(); + + std::vector<std::string> sender_ids; + sender_ids.push_back("sender"); + RegisterAndWaitForCompletion(sender_ids); + + std::string expected_registration_id = + FakeGCMClient::GenerateGCMRegistrationID(sender_ids); + EXPECT_EQ(expected_registration_id, registration_id()); + EXPECT_EQ(GCMClient::SUCCESS, registration_result()); + + UnregisterAndWaitForCompletion(); + EXPECT_EQ(GCMClient::SUCCESS, unregistration_result()); +} + +TEST_F(GCMProfileServiceTest, Send) { + CreateGCMProfileService(); + + OutgoingMessage message; + message.id = "1"; + message.data["key1"] = "value1"; + SendAndWaitForCompletion(message); + + EXPECT_EQ(message.id, send_message_id()); + EXPECT_EQ(GCMClient::SUCCESS, send_result()); +} + +} // namespace gcm diff --git a/chromium/chrome/browser/gcm/instance_id/instance_id_profile_service_factory.cc b/chromium/chrome/browser/gcm/instance_id/instance_id_profile_service_factory.cc new file mode 100644 index 00000000000..8123d8f04c6 --- /dev/null +++ b/chromium/chrome/browser/gcm/instance_id/instance_id_profile_service_factory.cc @@ -0,0 +1,60 @@ +// Copyright (c) 2015 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/gcm/instance_id/instance_id_profile_service_factory.h" + +#include <memory> + +#include "chrome/browser/gcm/gcm_profile_service_factory.h" +#include "chrome/browser/profiles/incognito_helpers.h" +#include "chrome/browser/profiles/profile.h" +#include "components/gcm_driver/gcm_profile_service.h" +#include "components/gcm_driver/instance_id/instance_id_profile_service.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" + +namespace instance_id { + +// static +InstanceIDProfileService* InstanceIDProfileServiceFactory::GetForProfile( + content::BrowserContext* profile) { + // Instance ID is not supported in incognito mode. + if (profile->IsOffTheRecord()) + return NULL; + + return static_cast<InstanceIDProfileService*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + +// static +InstanceIDProfileServiceFactory* +InstanceIDProfileServiceFactory::GetInstance() { + return base::Singleton<InstanceIDProfileServiceFactory>::get(); +} + +InstanceIDProfileServiceFactory::InstanceIDProfileServiceFactory() + : BrowserContextKeyedServiceFactory( + "InstanceIDProfileService", + BrowserContextDependencyManager::GetInstance()) { + // GCM is needed for device ID. + DependsOn(gcm::GCMProfileServiceFactory::GetInstance()); +} + +InstanceIDProfileServiceFactory::~InstanceIDProfileServiceFactory() { +} + +KeyedService* InstanceIDProfileServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + Profile* profile = Profile::FromBrowserContext(context); + return new InstanceIDProfileService( + gcm::GCMProfileServiceFactory::GetForProfile(profile)->driver(), + profile->IsOffTheRecord()); +} + +content::BrowserContext* +InstanceIDProfileServiceFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return chrome::GetBrowserContextOwnInstanceInIncognito(context); +} + +} // namespace instance_id diff --git a/chromium/chrome/browser/gcm/instance_id/instance_id_profile_service_factory.h b/chromium/chrome/browser/gcm/instance_id/instance_id_profile_service_factory.h new file mode 100644 index 00000000000..c4505760a3d --- /dev/null +++ b/chromium/chrome/browser/gcm/instance_id/instance_id_profile_service_factory.h @@ -0,0 +1,44 @@ +// Copyright (c) 2015 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_GCM_INSTANCE_ID_INSTANCE_ID_PROFILE_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_GCM_INSTANCE_ID_INSTANCE_ID_PROFILE_SERVICE_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace instance_id { + +class InstanceIDProfileService; + +// Singleton that owns all InstanceIDProfileService and associates them with +// profiles. +class InstanceIDProfileServiceFactory : + public BrowserContextKeyedServiceFactory { + public: + static InstanceIDProfileService* GetForProfile( + content::BrowserContext* profile); + static InstanceIDProfileServiceFactory* GetInstance(); + + InstanceIDProfileServiceFactory(const InstanceIDProfileServiceFactory&) = + delete; + InstanceIDProfileServiceFactory& operator=( + const InstanceIDProfileServiceFactory&) = delete; + + private: + friend struct base::DefaultSingletonTraits<InstanceIDProfileServiceFactory>; + + InstanceIDProfileServiceFactory(); + ~InstanceIDProfileServiceFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* profile) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; +}; + +} // namespace instance_id + +#endif // CHROME_BROWSER_GCM_INSTANCE_ID_INSTANCE_ID_PROFILE_SERVICE_FACTORY_H_ |