Commit 24754fe9 authored by jianli@chromium.org's avatar jianli@chromium.org

[GCM] Make GCM API not work in incognito mode

BUG=284553
TEST=new tests added

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244085 0039d316-1c4b-4281-b951-d872f2087c98
parent 8a154c1a
...@@ -85,8 +85,9 @@ bool GcmApiFunction::RunImpl() { ...@@ -85,8 +85,9 @@ bool GcmApiFunction::RunImpl() {
} }
bool GcmApiFunction::IsGcmApiEnabled() const { bool GcmApiFunction::IsGcmApiEnabled() const {
return gcm::GCMProfileService::IsGCMEnabled() && return gcm::GCMProfileService::IsGCMEnabled(
!GetExtension()->public_key().empty(); Profile::FromBrowserContext(context())) &&
!GetExtension()->public_key().empty();
} }
gcm::GCMProfileService* GcmApiFunction::GCMProfileService() const { gcm::GCMProfileService* GcmApiFunction::GCMProfileService() const {
......
...@@ -30,7 +30,6 @@ class GcmApiTest : public ExtensionApiTest { ...@@ -30,7 +30,6 @@ class GcmApiTest : public ExtensionApiTest {
const Extension* LoadTestExtension(const std::string& extension_path, const Extension* LoadTestExtension(const std::string& extension_path,
const std::string& page_name); const std::string& page_name);
gcm::FakeGCMProfileService* service() const; gcm::FakeGCMProfileService* service() const;
bool ShouldSkipTest() const; bool ShouldSkipTest() const;
...@@ -185,4 +184,19 @@ IN_PROC_BROWSER_TEST_F(GcmApiTest, OnSendError) { ...@@ -185,4 +184,19 @@ IN_PROC_BROWSER_TEST_F(GcmApiTest, OnSendError) {
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
} }
IN_PROC_BROWSER_TEST_F(GcmApiTest, Incognito) {
if (ShouldSkipTest())
return;
ResultCatcher catcher;
catcher.RestrictToProfile(profile());
ResultCatcher incognito_catcher;
incognito_catcher.RestrictToProfile(profile()->GetOffTheRecordProfile());
ASSERT_TRUE(RunExtensionTestIncognito("gcm/functions/incognito"));
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
EXPECT_TRUE(incognito_catcher.GetNextResult()) << incognito_catcher.message();
}
} // namespace extensions } // namespace extensions
...@@ -38,9 +38,13 @@ class GCMProfileService::DelayedTaskController { ...@@ -38,9 +38,13 @@ class GCMProfileService::DelayedTaskController {
DelayedTaskController(); DelayedTaskController();
~DelayedTaskController(); ~DelayedTaskController();
// Adds an app to non-ready list that queue all tasks to invoke until ready. // Adds an app to the tracking list. It will be first marked as not ready.
// Tasks will be queued for delay execution until the app is marked as ready.
void AddApp(const std::string& app_id); void AddApp(const std::string& app_id);
// Removes the app from the tracking list.
void RemoveApp(const std::string& app_id);
// Adds a task that will be invoked once we're ready. // Adds a task that will be invoked once we're ready.
void AddTask(const std::string& app_id, base::Closure task); void AddTask(const std::string& app_id, base::Closure task);
...@@ -53,6 +57,9 @@ class GCMProfileService::DelayedTaskController { ...@@ -53,6 +57,9 @@ class GCMProfileService::DelayedTaskController {
// Returns true if it is ready to perform operations for an app. // Returns true if it is ready to perform operations for an app.
bool CanRunTaskWithoutDelay(const std::string& app_id) const; bool CanRunTaskWithoutDelay(const std::string& app_id) const;
// Returns true if the app has been tracked for readiness.
bool IsAppTracked(const std::string& app_id) const;
private: private:
struct AppTaskQueue { struct AppTaskQueue {
AppTaskQueue(); AppTaskQueue();
...@@ -100,6 +107,11 @@ void GCMProfileService::DelayedTaskController::AddApp( ...@@ -100,6 +107,11 @@ void GCMProfileService::DelayedTaskController::AddApp(
delayed_task_map_[app_id] = new AppTaskQueue; delayed_task_map_[app_id] = new AppTaskQueue;
} }
void GCMProfileService::DelayedTaskController::RemoveApp(
const std::string& app_id) {
delayed_task_map_.erase(app_id);
}
void GCMProfileService::DelayedTaskController::AddTask( void GCMProfileService::DelayedTaskController::AddTask(
const std::string& app_id, base::Closure task) { const std::string& app_id, base::Closure task) {
DelayedTaskMap::const_iterator iter = delayed_task_map_.find(app_id); DelayedTaskMap::const_iterator iter = delayed_task_map_.find(app_id);
...@@ -149,6 +161,11 @@ bool GCMProfileService::DelayedTaskController::CanRunTaskWithoutDelay( ...@@ -149,6 +161,11 @@ bool GCMProfileService::DelayedTaskController::CanRunTaskWithoutDelay(
return iter->second->ready; return iter->second->ready;
} }
bool GCMProfileService::DelayedTaskController::IsAppTracked(
const std::string& app_id) const {
return delayed_task_map_.find(app_id) != delayed_task_map_.end();
}
void GCMProfileService::DelayedTaskController::RunTasks( void GCMProfileService::DelayedTaskController::RunTasks(
AppTaskQueue* task_queue) { AppTaskQueue* task_queue) {
DCHECK(gcm_client_ready_ && task_queue->ready); DCHECK(gcm_client_ready_ && task_queue->ready);
...@@ -415,7 +432,11 @@ bool GCMProfileService::RegistrationInfo::IsValid() const { ...@@ -415,7 +432,11 @@ bool GCMProfileService::RegistrationInfo::IsValid() const {
bool GCMProfileService::enable_gcm_for_testing_ = false; bool GCMProfileService::enable_gcm_for_testing_ = false;
// static // static
bool GCMProfileService::IsGCMEnabled() { bool GCMProfileService::IsGCMEnabled(Profile* profile) {
// GCM is not enabled in incognito mode.
if (profile->IsOffTheRecord())
return false;
if (enable_gcm_for_testing_) if (enable_gcm_for_testing_)
return true; return true;
...@@ -443,6 +464,7 @@ GCMProfileService::GCMProfileService(Profile* profile) ...@@ -443,6 +464,7 @@ GCMProfileService::GCMProfileService(Profile* profile)
: profile_(profile), : profile_(profile),
testing_delegate_(NULL), testing_delegate_(NULL),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
DCHECK(!profile->IsOffTheRecord());
Init(); Init();
} }
...@@ -725,6 +747,9 @@ void GCMProfileService::Unregister(const std::string& app_id) { ...@@ -725,6 +747,9 @@ void GCMProfileService::Unregister(const std::string& app_id) {
// Remove the persisted registration info. // Remove the persisted registration info.
DeleteRegistrationInfo(app_id); DeleteRegistrationInfo(app_id);
// No need to track the app any more.
delayed_task_controller_->RemoveApp(app_id);
// Ask the server to unregister it. There could be a small chance that the // Ask the server to unregister it. There could be a small chance that the
// unregister request fails. If this occurs, it does not bring any harm since // unregister request fails. If this occurs, it does not bring any harm since
// we simply reject the messages/events received from the server. // we simply reject the messages/events received from the server.
...@@ -887,12 +912,16 @@ void GCMProfileService::WriteRegistrationInfo(const std::string& app_id) { ...@@ -887,12 +912,16 @@ void GCMProfileService::WriteRegistrationInfo(const std::string& app_id) {
} }
void GCMProfileService::ReadRegistrationInfo(const std::string& app_id) { void GCMProfileService::ReadRegistrationInfo(const std::string& app_id) {
extensions::StateStore* storage = // This function can be called more than once when the app is allowed in
extensions::ExtensionSystem::Get(profile_)->state_store(); // incognito and the extension service reloads the app.
DCHECK(storage); if (delayed_task_controller_->IsAppTracked(app_id))
return;
delayed_task_controller_->AddApp(app_id); delayed_task_controller_->AddApp(app_id);
extensions::StateStore* storage =
extensions::ExtensionSystem::Get(profile_)->state_store();
DCHECK(storage);
storage->GetExtensionValue( storage->GetExtensionValue(
app_id, app_id,
kRegistrationKey, kRegistrationKey,
......
...@@ -55,7 +55,7 @@ class GCMProfileService : public BrowserContextKeyedService, ...@@ -55,7 +55,7 @@ class GCMProfileService : public BrowserContextKeyedService,
}; };
// Returns true if the GCM support is enabled. // Returns true if the GCM support is enabled.
static bool IsGCMEnabled(); static bool IsGCMEnabled(Profile* profile);
// Register profile-specific prefs for GCM. // Register profile-specific prefs for GCM.
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
......
...@@ -13,7 +13,7 @@ namespace gcm { ...@@ -13,7 +13,7 @@ namespace gcm {
// static // static
GCMProfileService* GCMProfileServiceFactory::GetForProfile(Profile* profile) { GCMProfileService* GCMProfileServiceFactory::GetForProfile(Profile* profile) {
if (!gcm::GCMProfileService::IsGCMEnabled()) if (!gcm::GCMProfileService::IsGCMEnabled(profile))
return NULL; return NULL;
return static_cast<GCMProfileService*>( return static_cast<GCMProfileService*>(
...@@ -35,9 +35,10 @@ GCMProfileServiceFactory::~GCMProfileServiceFactory() { ...@@ -35,9 +35,10 @@ GCMProfileServiceFactory::~GCMProfileServiceFactory() {
} }
BrowserContextKeyedService* GCMProfileServiceFactory::BuildServiceInstanceFor( BrowserContextKeyedService* GCMProfileServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* profile) const { content::BrowserContext* context) const {
return gcm::GCMProfileService::IsGCMEnabled() ? Profile* profile = static_cast<Profile*>(context);
new GCMProfileService(static_cast<Profile*>(profile)) : NULL; return gcm::GCMProfileService::IsGCMEnabled(profile) ?
new GCMProfileService(profile) : NULL;
} }
content::BrowserContext* GCMProfileServiceFactory::GetBrowserContextToUse( content::BrowserContext* GCMProfileServiceFactory::GetBrowserContextToUse(
......
...@@ -297,6 +297,20 @@ void GCMEventRouterMock::OnSendError(const std::string& app_id, ...@@ -297,6 +297,20 @@ void GCMEventRouterMock::OnSendError(const std::string& app_id,
test_->SignalCompleted(); test_->SignalCompleted();
} }
TEST_F(GCMProfileServiceTest, Incognito) {
EXPECT_TRUE(GCMProfileServiceFactory::GetForProfile(profile()));
// Create an incognito profile.
TestingProfile::Builder incognito_profile_builder;
incognito_profile_builder.SetIncognito();
scoped_ptr<TestingProfile> incognito_profile =
incognito_profile_builder.Build();
incognito_profile->SetOriginalProfile(profile());
EXPECT_FALSE(GCMProfileServiceFactory::GetForProfile(
incognito_profile.get()));
}
TEST_F(GCMProfileServiceTest, CheckIn) { TEST_F(GCMProfileServiceTest, CheckIn) {
EXPECT_TRUE(checkin_info_.IsValid()); EXPECT_TRUE(checkin_info_.IsValid());
......
{
"manifest_version": 2,
"name": "Test GCM App",
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzXCAvAUOKVNuBGWfaRY6QW1YSs+2EnmERkltllVyk9T6H/a7wkdBAKpvKsEbE9PtjmHrP/Jh/XFX1AdpTFAJ7KsQ55GdyTwUW7iB5HsR4NI6dXewK2ba+vDbtBLytR9msXFpvuVnAsEmLlHf9RGuxczvOEbGXcHkUw0AuzGu72wIDAQAB",
"version": "1.0",
"description": "Tests GCM API",
"background": {
"scripts": ["test.js"]
},
"incognito": "split",
"permissions": ["gcm"]
}
// 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.
chrome.test.runTests([
function testIncognito() {
chrome.gcm.register(["Sender"], function(registrationId) {
chrome.test.assertEq(chrome.runtime.lastError != undefined,
chrome.extension.inIncognitoContext);
chrome.test.succeed();
});
}
]);
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