blob: 8779cefc3a2f2c95a7aa7c38bc246e9c034535b6 [file] [log] [blame]
[email protected]f7240212013-10-27 03:39:121// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]9fe42042013-10-29 21:13:335#include "extensions/browser/lazy_background_task_queue.h"
[email protected]f7240212013-10-27 03:39:126
dchengf5d241082016-04-21 03:43:117#include <memory>
8
[email protected]f7240212013-10-27 03:39:129#include "base/bind.h"
avic9cec102015-12-23 00:39:2610#include "base/macros.h"
dchengf5d241082016-04-21 03:43:1111#include "base/memory/ptr_util.h"
[email protected]9fc5bdc82014-08-03 23:49:2612#include "components/keyed_service/content/browser_context_dependency_manager.h"
krasin3bc9c19c2015-07-29 20:12:4513#include "components/pref_registry/testing_pref_service_syncable.h"
brettw066508682016-02-03 08:22:0214#include "components/prefs/testing_pref_service.h"
reillyg0ea3fa902014-10-28 15:30:2315#include "components/user_prefs/user_prefs.h"
[email protected]9fc5bdc82014-08-03 23:49:2616#include "content/public/test/test_browser_context.h"
[email protected]6b54fda2014-07-22 02:13:4717#include "extensions/browser/extension_registry.h"
[email protected]9fc5bdc82014-08-03 23:49:2618#include "extensions/browser/extension_registry_factory.h"
[email protected]9fc5bdc82014-08-03 23:49:2619#include "extensions/browser/extensions_test.h"
[email protected]98b6d942013-11-10 00:34:0720#include "extensions/browser/process_manager.h"
reillyg0ea3fa902014-10-28 15:30:2321#include "extensions/browser/process_manager_factory.h"
[email protected]9fc5bdc82014-08-03 23:49:2622#include "extensions/browser/test_extensions_browser_client.h"
[email protected]e4452d32013-11-15 23:07:4123#include "extensions/common/extension.h"
[email protected]22b7b2c2013-11-05 22:52:4224#include "extensions/common/extension_builder.h"
[email protected]f7240212013-10-27 03:39:1225#include "testing/gtest/include/gtest/gtest.h"
26
[email protected]9fc5bdc82014-08-03 23:49:2627using content::BrowserContext;
28
[email protected]f7240212013-10-27 03:39:1229namespace extensions {
[email protected]9fc5bdc82014-08-03 23:49:2630namespace {
[email protected]f7240212013-10-27 03:39:1231
[email protected]98b6d942013-11-10 00:34:0732// A ProcessManager that doesn't create background host pages.
33class TestProcessManager : public ProcessManager {
[email protected]f7240212013-10-27 03:39:1234 public:
[email protected]9fc5bdc82014-08-03 23:49:2635 explicit TestProcessManager(BrowserContext* context)
36 : ProcessManager(context, context, ExtensionRegistry::Get(context)),
37 create_count_(0) {
38 // ProcessManager constructor above assumes non-incognito.
39 DCHECK(!context->IsOffTheRecord());
40 }
dcheng9168b2f2014-10-21 12:38:2441 ~TestProcessManager() override {}
[email protected]f7240212013-10-27 03:39:1242
43 int create_count() { return create_count_; }
44
[email protected]98b6d942013-11-10 00:34:0745 // ProcessManager overrides:
dcheng9168b2f2014-10-21 12:38:2446 bool CreateBackgroundHost(const Extension* extension,
47 const GURL& url) override {
[email protected]f7240212013-10-27 03:39:1248 // Don't actually try to create a web contents.
49 create_count_++;
[email protected]6ad9cdf72014-02-27 13:12:4150 return false;
[email protected]f7240212013-10-27 03:39:1251 }
52
53 private:
54 int create_count_;
55
[email protected]98b6d942013-11-10 00:34:0756 DISALLOW_COPY_AND_ASSIGN(TestProcessManager);
[email protected]f7240212013-10-27 03:39:1257};
58
dchengf5d241082016-04-21 03:43:1159std::unique_ptr<KeyedService> CreateTestProcessManager(
60 BrowserContext* context) {
ricea5e273372016-08-22 02:51:0361 return base::MakeUnique<TestProcessManager>(context);
reillyg0ea3fa902014-10-28 15:30:2362}
[email protected]9fc5bdc82014-08-03 23:49:2663
64} // namespace
65
66// Derives from ExtensionsTest to provide content module and keyed service
67// initialization.
68class LazyBackgroundTaskQueueTest : public ExtensionsTest {
69 public:
rockot8cba0362016-08-09 21:43:4370 LazyBackgroundTaskQueueTest() : task_run_count_(0) {}
dchengf9afb372014-10-27 21:43:1471 ~LazyBackgroundTaskQueueTest() override {}
[email protected]f7240212013-10-27 03:39:1272
73 int task_run_count() { return task_run_count_; }
74
75 // A simple callback for AddPendingTask.
76 void RunPendingTask(ExtensionHost* host) {
77 task_run_count_++;
78 }
79
80 // Creates and registers an extension without a background page.
81 scoped_refptr<Extension> CreateSimpleExtension() {
limasdf21d67e62015-12-19 12:04:4982 scoped_refptr<Extension> extension =
83 ExtensionBuilder()
dcheng794d2bd2016-02-27 03:51:3284 .SetManifest(DictionaryBuilder()
85 .Set("name", "No background")
86 .Set("version", "1")
87 .Set("manifest_version", 2)
88 .Build())
limasdf21d67e62015-12-19 12:04:4989 .SetID("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
90 .Build();
[email protected]9fc5bdc82014-08-03 23:49:2691 ExtensionRegistry::Get(browser_context())->AddEnabled(extension);
[email protected]f7240212013-10-27 03:39:1292 return extension;
93 }
94
95 // Creates and registers an extension with a lazy background page.
96 scoped_refptr<Extension> CreateLazyBackgroundExtension() {
limasdf21d67e62015-12-19 12:04:4997 scoped_refptr<Extension> extension =
98 ExtensionBuilder()
dcheng794d2bd2016-02-27 03:51:3299 .SetManifest(
limasdf21d67e62015-12-19 12:04:49100 DictionaryBuilder()
101 .Set("name", "Lazy background")
102 .Set("version", "1")
103 .Set("manifest_version", 2)
dcheng794d2bd2016-02-27 03:51:32104 .Set("background", DictionaryBuilder()
105 .Set("page", "background.html")
106 .SetBoolean("persistent", false)
107 .Build())
108 .Build())
limasdf21d67e62015-12-19 12:04:49109 .SetID("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
110 .Build();
[email protected]9fc5bdc82014-08-03 23:49:26111 ExtensionRegistry::Get(browser_context())->AddEnabled(extension);
[email protected]f7240212013-10-27 03:39:12112 return extension;
113 }
114
reillyg0ea3fa902014-10-28 15:30:23115 protected:
dchengafa76022014-12-28 20:31:56116 void SetUp() override {
reillyg0ea3fa902014-10-28 15:30:23117 user_prefs::UserPrefs::Set(browser_context(), &testing_pref_service_);
118 }
119
[email protected]f7240212013-10-27 03:39:12120 private:
krasin3bc9c19c2015-07-29 20:12:45121 user_prefs::TestingPrefServiceSyncable testing_pref_service_;
[email protected]9fc5bdc82014-08-03 23:49:26122
[email protected]f7240212013-10-27 03:39:12123 // The total number of pending tasks that have been executed.
124 int task_run_count_;
125
126 DISALLOW_COPY_AND_ASSIGN(LazyBackgroundTaskQueueTest);
127};
128
129// Tests that only extensions with background pages should have tasks queued.
130TEST_F(LazyBackgroundTaskQueueTest, ShouldEnqueueTask) {
[email protected]9fc5bdc82014-08-03 23:49:26131 LazyBackgroundTaskQueue queue(browser_context());
[email protected]f7240212013-10-27 03:39:12132
133 // Build a simple extension with no background page.
134 scoped_refptr<Extension> no_background = CreateSimpleExtension();
[email protected]9fc5bdc82014-08-03 23:49:26135 EXPECT_FALSE(queue.ShouldEnqueueTask(browser_context(), no_background.get()));
[email protected]f7240212013-10-27 03:39:12136
137 // Build another extension with a background page.
138 scoped_refptr<Extension> with_background = CreateLazyBackgroundExtension();
[email protected]9fc5bdc82014-08-03 23:49:26139 EXPECT_TRUE(
140 queue.ShouldEnqueueTask(browser_context(), with_background.get()));
[email protected]f7240212013-10-27 03:39:12141}
142
143// Tests that adding tasks actually increases the pending task count, and that
144// multiple extensions can have pending tasks.
145TEST_F(LazyBackgroundTaskQueueTest, AddPendingTask) {
[email protected]9fc5bdc82014-08-03 23:49:26146 // Get our TestProcessManager.
reillyg0ea3fa902014-10-28 15:30:23147 TestProcessManager* process_manager = static_cast<TestProcessManager*>(
148 ProcessManagerFactory::GetInstance()->SetTestingFactoryAndUse(
149 browser_context(), CreateTestProcessManager));
[email protected]f7240212013-10-27 03:39:12150
[email protected]9fc5bdc82014-08-03 23:49:26151 LazyBackgroundTaskQueue queue(browser_context());
[email protected]f7240212013-10-27 03:39:12152
153 // Build a simple extension with no background page.
154 scoped_refptr<Extension> no_background = CreateSimpleExtension();
155
156 // Adding a pending task increases the number of extensions with tasks, but
157 // doesn't run the task.
[email protected]9fc5bdc82014-08-03 23:49:26158 queue.AddPendingTask(browser_context(),
[email protected]f7240212013-10-27 03:39:12159 no_background->id(),
160 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
161 base::Unretained(this)));
162 EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
163 EXPECT_EQ(0, task_run_count());
164
165 // Another task on the same extension doesn't increase the number of
166 // extensions that have tasks and doesn't run any tasks.
[email protected]9fc5bdc82014-08-03 23:49:26167 queue.AddPendingTask(browser_context(),
[email protected]f7240212013-10-27 03:39:12168 no_background->id(),
169 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
170 base::Unretained(this)));
171 EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
172 EXPECT_EQ(0, task_run_count());
173
174 // Adding a task on an extension with a lazy background page tries to create
175 // a background host, and if that fails, runs the task immediately.
176 scoped_refptr<Extension> lazy_background = CreateLazyBackgroundExtension();
[email protected]9fc5bdc82014-08-03 23:49:26177 queue.AddPendingTask(browser_context(),
[email protected]f7240212013-10-27 03:39:12178 lazy_background->id(),
179 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
180 base::Unretained(this)));
181 EXPECT_EQ(2u, queue.extensions_with_pending_tasks());
182 // The process manager tried to create a background host.
183 EXPECT_EQ(1, process_manager->create_count());
184 // The task ran immediately because the creation failed.
185 EXPECT_EQ(1, task_run_count());
186}
187
188// Tests that pending tasks are actually run.
189TEST_F(LazyBackgroundTaskQueueTest, ProcessPendingTasks) {
[email protected]9fc5bdc82014-08-03 23:49:26190 LazyBackgroundTaskQueue queue(browser_context());
[email protected]f7240212013-10-27 03:39:12191
192 // ProcessPendingTasks is a no-op if there are no tasks.
193 scoped_refptr<Extension> extension = CreateSimpleExtension();
dcheng7921e3f2014-08-25 22:20:01194 queue.ProcessPendingTasks(NULL, browser_context(), extension.get());
[email protected]f7240212013-10-27 03:39:12195 EXPECT_EQ(0, task_run_count());
196
197 // Schedule a task to run.
[email protected]9fc5bdc82014-08-03 23:49:26198 queue.AddPendingTask(browser_context(),
[email protected]f7240212013-10-27 03:39:12199 extension->id(),
200 base::Bind(&LazyBackgroundTaskQueueTest::RunPendingTask,
201 base::Unretained(this)));
202 EXPECT_EQ(0, task_run_count());
203 EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
204
[email protected]9fc5bdc82014-08-03 23:49:26205 // Trying to run tasks for an unrelated BrowserContext should do nothing.
206 content::TestBrowserContext unrelated_context;
dcheng7921e3f2014-08-25 22:20:01207 queue.ProcessPendingTasks(NULL, &unrelated_context, extension.get());
[email protected]9fe42042013-10-29 21:13:33208 EXPECT_EQ(0, task_run_count());
209 EXPECT_EQ(1u, queue.extensions_with_pending_tasks());
210
[email protected]f7240212013-10-27 03:39:12211 // Processing tasks when there is one pending runs the task and removes the
212 // extension from the list of extensions with pending tasks.
dcheng7921e3f2014-08-25 22:20:01213 queue.ProcessPendingTasks(NULL, browser_context(), extension.get());
[email protected]f7240212013-10-27 03:39:12214 EXPECT_EQ(1, task_run_count());
215 EXPECT_EQ(0u, queue.extensions_with_pending_tasks());
216}
217
218} // namespace extensions