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() {
}
bool GcmApiFunction::IsGcmApiEnabled() const {
return gcm::GCMProfileService::IsGCMEnabled() &&
!GetExtension()->public_key().empty();
return gcm::GCMProfileService::IsGCMEnabled(
Profile::FromBrowserContext(context())) &&
!GetExtension()->public_key().empty();
}
gcm::GCMProfileService* GcmApiFunction::GCMProfileService() const {
......
......@@ -30,7 +30,6 @@ class GcmApiTest : public ExtensionApiTest {
const Extension* LoadTestExtension(const std::string& extension_path,
const std::string& page_name);
gcm::FakeGCMProfileService* service() const;
bool ShouldSkipTest() const;
......@@ -185,4 +184,19 @@ IN_PROC_BROWSER_TEST_F(GcmApiTest, OnSendError) {
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
......@@ -38,9 +38,13 @@ class GCMProfileService::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);
// 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.
void AddTask(const std::string& app_id, base::Closure task);
......@@ -53,6 +57,9 @@ class GCMProfileService::DelayedTaskController {
// Returns true if it is ready to perform operations for an app.
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:
struct AppTaskQueue {
AppTaskQueue();
......@@ -100,6 +107,11 @@ void GCMProfileService::DelayedTaskController::AddApp(
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(
const std::string& app_id, base::Closure task) {
DelayedTaskMap::const_iterator iter = delayed_task_map_.find(app_id);
......@@ -149,6 +161,11 @@ bool GCMProfileService::DelayedTaskController::CanRunTaskWithoutDelay(
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(
AppTaskQueue* task_queue) {
DCHECK(gcm_client_ready_ && task_queue->ready);
......@@ -415,7 +432,11 @@ bool GCMProfileService::RegistrationInfo::IsValid() const {
bool GCMProfileService::enable_gcm_for_testing_ = false;
// 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_)
return true;
......@@ -443,6 +464,7 @@ GCMProfileService::GCMProfileService(Profile* profile)
: profile_(profile),
testing_delegate_(NULL),
weak_ptr_factory_(this) {
DCHECK(!profile->IsOffTheRecord());
Init();
}
......@@ -725,6 +747,9 @@ void GCMProfileService::Unregister(const std::string& app_id) {
// Remove the persisted registration info.
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
// unregister request fails. If this occurs, it does not bring any harm since
// we simply reject the messages/events received from the server.
......@@ -887,12 +912,16 @@ void GCMProfileService::WriteRegistrationInfo(const std::string& app_id) {
}
void GCMProfileService::ReadRegistrationInfo(const std::string& app_id) {
extensions::StateStore* storage =
extensions::ExtensionSystem::Get(profile_)->state_store();
DCHECK(storage);
// This function can be called more than once when the app is allowed in
// incognito and the extension service reloads the app.
if (delayed_task_controller_->IsAppTracked(app_id))
return;
delayed_task_controller_->AddApp(app_id);
extensions::StateStore* storage =
extensions::ExtensionSystem::Get(profile_)->state_store();
DCHECK(storage);
storage->GetExtensionValue(
app_id,
kRegistrationKey,
......
......@@ -55,7 +55,7 @@ class GCMProfileService : public BrowserContextKeyedService,
};
// Returns true if the GCM support is enabled.
static bool IsGCMEnabled();
static bool IsGCMEnabled(Profile* profile);
// Register profile-specific prefs for GCM.
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
......
......@@ -13,7 +13,7 @@ namespace gcm {
// static
GCMProfileService* GCMProfileServiceFactory::GetForProfile(Profile* profile) {
if (!gcm::GCMProfileService::IsGCMEnabled())
if (!gcm::GCMProfileService::IsGCMEnabled(profile))
return NULL;
return static_cast<GCMProfileService*>(
......@@ -35,9 +35,10 @@ GCMProfileServiceFactory::~GCMProfileServiceFactory() {
}
BrowserContextKeyedService* GCMProfileServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* profile) const {
return gcm::GCMProfileService::IsGCMEnabled() ?
new GCMProfileService(static_cast<Profile*>(profile)) : NULL;
content::BrowserContext* context) const {
Profile* profile = static_cast<Profile*>(context);
return gcm::GCMProfileService::IsGCMEnabled(profile) ?
new GCMProfileService(profile) : NULL;
}
content::BrowserContext* GCMProfileServiceFactory::GetBrowserContextToUse(
......
......@@ -297,6 +297,20 @@ void GCMEventRouterMock::OnSendError(const std::string& app_id,
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) {
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