Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / search / hotword_service_unittest.cc
blob7244abf0305ecd3782c6a663a517c7c62e969c87
1 // Copyright 2014 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.
5 #include "base/command_line.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/metrics/field_trial.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/test/test_simple_task_runner.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/extensions/extension_service_test_base.h"
12 #include "chrome/browser/extensions/test_extension_service.h"
13 #include "chrome/browser/search/hotword_audio_history_handler.h"
14 #include "chrome/browser/search/hotword_service.h"
15 #include "chrome/browser/search/hotword_service_factory.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/common/extensions/extension_constants.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "components/history/core/browser/web_history_service.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "extensions/browser/extension_system.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_builder.h"
25 #include "extensions/common/manifest.h"
26 #include "extensions/common/one_shot_event.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 #if defined(OS_CHROMEOS)
30 #include "chromeos/audio/cras_audio_handler.h"
31 #endif
33 namespace {
35 class MockAudioHistoryHandler : public HotwordAudioHistoryHandler {
36 public:
37 MockAudioHistoryHandler(
38 content::BrowserContext* context,
39 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
40 history::WebHistoryService* web_history)
41 : HotwordAudioHistoryHandler(context, task_runner),
42 get_audio_history_calls_(0),
43 web_history_(web_history) {
45 ~MockAudioHistoryHandler() override {}
47 void GetAudioHistoryEnabled(
48 const HotwordAudioHistoryCallback& callback) override {
49 get_audio_history_calls_++;
50 callback.Run(true, true);
53 history::WebHistoryService* GetWebHistory() override {
54 return web_history_.get();
57 int GetAudioHistoryCalls() {
58 return get_audio_history_calls_;
61 private:
62 int get_audio_history_calls_;
63 scoped_ptr<history::WebHistoryService> web_history_;
66 class MockHotwordService : public HotwordService {
67 public:
68 explicit MockHotwordService(Profile* profile)
69 : HotwordService(profile),
70 uninstall_count_(0) {
73 bool UninstallHotwordExtension(ExtensionService* extension_service) override {
74 uninstall_count_++;
75 return HotwordService::UninstallHotwordExtension(extension_service);
78 void InstallHotwordExtensionFromWebstore(int num_tries) override {
79 scoped_ptr<base::DictionaryValue> manifest =
80 extensions::DictionaryBuilder()
81 .Set("name", "Hotword Test Extension")
82 .Set("version", "1.0")
83 .Set("manifest_version", 2)
84 .Build();
85 scoped_refptr<extensions::Extension> extension =
86 extensions::ExtensionBuilder().SetManifest(manifest.Pass())
87 .AddFlags(extensions::Extension::FROM_WEBSTORE
88 | extensions::Extension::WAS_INSTALLED_BY_DEFAULT)
89 .SetID(extension_id_)
90 .SetLocation(extensions::Manifest::EXTERNAL_COMPONENT)
91 .Build();
92 ASSERT_TRUE(extension.get());
93 service_->OnExtensionInstalled(extension.get(), syncer::StringOrdinal());
97 int uninstall_count() { return uninstall_count_; }
99 void SetExtensionService(ExtensionService* service) { service_ = service; }
100 void SetExtensionId(const std::string& extension_id) {
101 extension_id_ = extension_id;
104 ExtensionService* extension_service() { return service_; }
106 private:
107 ExtensionService* service_;
108 int uninstall_count_;
109 std::string extension_id_;
112 KeyedService* BuildMockHotwordService(content::BrowserContext* context) {
113 return new MockHotwordService(static_cast<Profile*>(context));
116 } // namespace
118 class HotwordServiceTest :
119 public extensions::ExtensionServiceTestBase,
120 public ::testing::WithParamInterface<const char*> {
121 protected:
122 HotwordServiceTest() : field_trial_list_(NULL) {}
123 virtual ~HotwordServiceTest() {}
125 void SetApplicationLocale(Profile* profile, const std::string& new_locale) {
126 #if defined(OS_CHROMEOS)
127 // On ChromeOS locale is per-profile.
128 profile->GetPrefs()->SetString(prefs::kApplicationLocale, new_locale);
129 #else
130 g_browser_process->SetApplicationLocale(new_locale);
131 #endif
134 void SetUp() override {
135 extension_id_ = GetParam();
136 #if defined(OS_CHROMEOS)
137 // Tests on chromeos need to have the handler initialized.
138 chromeos::CrasAudioHandler::InitializeForTesting();
139 #endif
141 extensions::ExtensionServiceTestBase::SetUp();
144 void TearDown() override {
145 #if defined(OS_CHROMEOS)
146 DCHECK(chromeos::CrasAudioHandler::IsInitialized());
147 chromeos::CrasAudioHandler::Shutdown();
148 #endif
151 base::FieldTrialList field_trial_list_;
152 std::string extension_id_;
155 INSTANTIATE_TEST_CASE_P(HotwordServiceTests,
156 HotwordServiceTest,
157 ::testing::Values(
158 extension_misc::kHotwordSharedModuleId));
160 TEST_P(HotwordServiceTest, IsHotwordAllowedDisabledFieldTrial) {
161 TestingProfile::Builder profile_builder;
162 scoped_ptr<TestingProfile> profile = profile_builder.Build();
164 // Check that the service exists so that a NULL service be ruled out in
165 // following tests.
166 HotwordService* hotword_service =
167 HotwordServiceFactory::GetForProfile(profile.get());
168 EXPECT_TRUE(hotword_service != NULL);
170 // When the field trial is empty, it should be allowed.
171 std::string group = base::FieldTrialList::FindFullName(
172 hotword_internal::kHotwordFieldTrialName);
173 EXPECT_TRUE(group.empty());
174 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
176 // When the field trial is 'Disabled', it should not be allowed.
177 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
178 hotword_internal::kHotwordFieldTrialName,
179 hotword_internal::kHotwordFieldTrialDisabledGroupName));
180 group = base::FieldTrialList::FindFullName(
181 hotword_internal::kHotwordFieldTrialName);
182 EXPECT_TRUE(group == hotword_internal::kHotwordFieldTrialDisabledGroupName);
183 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
185 // Set a valid locale with invalid field trial to be sure it is
186 // still false.
187 SetApplicationLocale(static_cast<Profile*>(profile.get()), "en");
188 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
190 // Test that incognito returns false as well.
191 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(
192 profile->GetOffTheRecordProfile()));
195 TEST_P(HotwordServiceTest, IsHotwordAllowedInvalidFieldTrial) {
196 TestingProfile::Builder profile_builder;
197 scoped_ptr<TestingProfile> profile = profile_builder.Build();
199 // Check that the service exists so that a NULL service be ruled out in
200 // following tests.
201 HotwordService* hotword_service =
202 HotwordServiceFactory::GetForProfile(profile.get());
203 EXPECT_TRUE(hotword_service != NULL);
205 // When the field trial is set, but not 'Disabled', it should be allowed.
206 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
207 hotword_internal::kHotwordFieldTrialName, "foo"));
208 std::string group = base::FieldTrialList::FindFullName(
209 hotword_internal::kHotwordFieldTrialName);
210 EXPECT_TRUE(group == "foo");
211 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
213 // Test that incognito returns false as well.
214 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(
215 profile->GetOffTheRecordProfile()));
218 TEST_P(HotwordServiceTest, IsHotwordAllowedLocale) {
219 TestingProfile::Builder profile_builder;
220 scoped_ptr<TestingProfile> profile = profile_builder.Build();
222 // Check that the service exists so that a NULL service be ruled out in
223 // following tests.
224 HotwordService* hotword_service =
225 HotwordServiceFactory::GetForProfile(profile.get());
226 EXPECT_TRUE(hotword_service != NULL);
228 // Set the language to an invalid one.
229 SetApplicationLocale(static_cast<Profile*>(profile.get()), "non-valid");
230 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
232 // Now with valid locales it should be fine.
233 SetApplicationLocale(static_cast<Profile*>(profile.get()), "en");
234 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
235 SetApplicationLocale(static_cast<Profile*>(profile.get()), "en-US");
236 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
237 SetApplicationLocale(static_cast<Profile*>(profile.get()), "en_us");
238 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
239 SetApplicationLocale(static_cast<Profile*>(profile.get()), "de_DE");
240 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
241 SetApplicationLocale(static_cast<Profile*>(profile.get()), "fr_fr");
242 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
244 // Test that incognito even with a valid locale and valid field trial
245 // still returns false.
246 Profile* otr_profile = profile->GetOffTheRecordProfile();
247 SetApplicationLocale(otr_profile, "en");
248 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(otr_profile));
251 TEST_P(HotwordServiceTest, ShouldReinstallExtension) {
252 InitializeEmptyExtensionService();
254 HotwordServiceFactory* hotword_service_factory =
255 HotwordServiceFactory::GetInstance();
257 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
258 hotword_service_factory->SetTestingFactoryAndUse(
259 profile(), BuildMockHotwordService));
260 ASSERT_TRUE(hotword_service != NULL);
261 hotword_service->SetExtensionId(extension_id_);
263 // If no locale has been set, no reason to uninstall.
264 EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
266 SetApplicationLocale(profile(), "en");
267 hotword_service->SetPreviousLanguagePref();
269 // Now a locale is set, but it hasn't changed.
270 EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
272 SetApplicationLocale(profile(), "fr_fr");
274 // Now it's a different locale so it should uninstall.
275 EXPECT_TRUE(hotword_service->ShouldReinstallHotwordExtension());
278 TEST_P(HotwordServiceTest, PreviousLanguageSetOnInstall) {
279 InitializeEmptyExtensionService();
280 service_->Init();
282 HotwordServiceFactory* hotword_service_factory =
283 HotwordServiceFactory::GetInstance();
285 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
286 hotword_service_factory->SetTestingFactoryAndUse(
287 profile(), BuildMockHotwordService));
288 ASSERT_TRUE(hotword_service != NULL);
289 hotword_service->SetExtensionService(service());
290 hotword_service->SetExtensionId(extension_id_);
292 // If no locale has been set, no reason to uninstall.
293 EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
295 SetApplicationLocale(profile(), "test_locale");
297 hotword_service->InstallHotwordExtensionFromWebstore(1);
298 base::MessageLoop::current()->RunUntilIdle();
300 EXPECT_EQ("test_locale",
301 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
304 TEST_P(HotwordServiceTest, UninstallReinstallTriggeredCorrectly) {
305 InitializeEmptyExtensionService();
306 service_->Init();
308 HotwordServiceFactory* hotword_service_factory =
309 HotwordServiceFactory::GetInstance();
311 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
312 hotword_service_factory->SetTestingFactoryAndUse(
313 profile(), BuildMockHotwordService));
314 ASSERT_TRUE(hotword_service != NULL);
315 hotword_service->SetExtensionService(service());
316 hotword_service->SetExtensionId(extension_id_);
318 // Initialize the locale to "en".
319 SetApplicationLocale(profile(), "en");
321 // The previous locale should not be set. No reason to uninstall.
322 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
324 // Do an initial installation.
325 hotword_service->InstallHotwordExtensionFromWebstore(1);
326 base::MessageLoop::current()->RunUntilIdle();
327 EXPECT_EQ("en",
328 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
330 if (extension_id_ == extension_misc::kHotwordSharedModuleId) {
331 // Shared module is installed and enabled.
332 EXPECT_EQ(0U, registry()->disabled_extensions().size());
333 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id_));
334 } else {
335 // Verify the extension is installed but disabled.
336 EXPECT_EQ(1U, registry()->disabled_extensions().size());
337 EXPECT_TRUE(registry()->disabled_extensions().Contains(extension_id_));
340 // The previous locale should be set but should match the current
341 // locale. No reason to uninstall.
342 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
344 // Switch the locale to a valid but different one.
345 SetApplicationLocale(profile(), "fr_fr");
346 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
348 // Different but valid locale so expect uninstall.
349 EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension());
350 EXPECT_EQ(1, hotword_service->uninstall_count());
351 EXPECT_EQ("fr_fr",
352 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
354 if (extension_id_ == extension_misc::kHotwordSharedModuleId) {
355 // Shared module is installed and enabled.
356 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id_));
357 } else {
358 // Verify the extension is installed. It's still disabled.
359 EXPECT_TRUE(registry()->disabled_extensions().Contains(extension_id_));
362 // Switch the locale to an invalid one.
363 SetApplicationLocale(profile(), "invalid");
364 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile()));
365 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
366 EXPECT_EQ("fr_fr",
367 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
369 // If the locale is set back to the last valid one, then an uninstall-install
370 // shouldn't be needed.
371 SetApplicationLocale(profile(), "fr_fr");
372 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
373 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
374 EXPECT_EQ(1, hotword_service->uninstall_count()); // no change
377 TEST_P(HotwordServiceTest, DisableAlwaysOnOnLanguageChange) {
378 // Bypass test for old hotwording.
379 if (extension_id_ != extension_misc::kHotwordSharedModuleId)
380 return;
382 // Turn on Always On
383 base::CommandLine::ForCurrentProcess()->AppendSwitch(
384 switches::kEnableExperimentalHotwordHardware);
386 InitializeEmptyExtensionService();
387 service_->Init();
389 // Enable always-on.
390 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
392 HotwordServiceFactory* hotword_service_factory =
393 HotwordServiceFactory::GetInstance();
395 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
396 hotword_service_factory->SetTestingFactoryAndUse(
397 profile(), BuildMockHotwordService));
398 ASSERT_TRUE(hotword_service != NULL);
399 hotword_service->SetExtensionService(service());
400 hotword_service->SetExtensionId(extension_id_);
402 // Initialize the locale to "en".
403 SetApplicationLocale(profile(), "en");
405 // The previous locale should not be set. No reason to uninstall.
406 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
407 EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
409 // Do an initial installation.
410 hotword_service->InstallHotwordExtensionFromWebstore(1);
411 base::MessageLoop::current()->RunUntilIdle();
413 // The previous locale should be set but should match the current
414 // locale. No reason to uninstall.
415 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
416 EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
418 // Switch the locale to a valid but different one.
419 SetApplicationLocale(profile(), "fr_fr");
420 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
422 // Different but valid locale so expect uninstall.
423 EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension());
424 EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
426 // Re-enable always-on.
427 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
429 // Switch the locale to an invalid one.
430 SetApplicationLocale(profile(), "invalid");
431 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile()));
432 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
433 EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
435 // If the locale is set back to the last valid one, then an uninstall-install
436 // shouldn't be needed.
437 SetApplicationLocale(profile(), "fr_fr");
438 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
439 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
440 EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
443 TEST_P(HotwordServiceTest, IsAlwaysOnEnabled) {
444 // Bypass test for old hotwording.
445 if (extension_id_ != extension_misc::kHotwordSharedModuleId)
446 return;
448 InitializeEmptyExtensionService();
449 service_->Init();
450 HotwordServiceFactory* hotword_service_factory =
451 HotwordServiceFactory::GetInstance();
453 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
454 hotword_service_factory->SetTestingFactoryAndUse(
455 profile(), BuildMockHotwordService));
456 ASSERT_TRUE(hotword_service != NULL);
457 hotword_service->SetExtensionService(service());
458 hotword_service->SetExtensionId(extension_id_);
460 // No hardware available. Should never be true.
461 EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
463 // Enable always-on, still not available.
464 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
465 EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
467 // Enable regular hotwording, still not available.
468 profile()->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, true);
469 EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
471 // Bypass hardware check.
472 base::CommandLine::ForCurrentProcess()->AppendSwitch(
473 switches::kEnableExperimentalHotwordHardware);
474 EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
476 // Disable.
477 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled,
478 false);
479 EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
482 TEST_P(HotwordServiceTest, IsSometimesOnEnabled) {
483 InitializeEmptyExtensionService();
484 service_->Init();
485 HotwordServiceFactory* hotword_service_factory =
486 HotwordServiceFactory::GetInstance();
488 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
489 hotword_service_factory->SetTestingFactoryAndUse(
490 profile(), BuildMockHotwordService));
491 ASSERT_TRUE(hotword_service != NULL);
492 hotword_service->SetExtensionService(service());
493 hotword_service->SetExtensionId(extension_id_);
495 // No pref set.
496 EXPECT_FALSE(hotword_service->IsSometimesOnEnabled());
498 // Set pref.
499 profile()->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, true);
500 EXPECT_TRUE(hotword_service->IsSometimesOnEnabled());
502 // Turn on always-on pref. Should have no effect.
503 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
504 EXPECT_TRUE(hotword_service->IsSometimesOnEnabled());
506 // Disable.
507 profile()->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, false);
508 EXPECT_FALSE(hotword_service->IsSometimesOnEnabled());
510 // Bypass rest of test for old hotwording.
511 if (extension_id_ != extension_misc::kHotwordSharedModuleId)
512 return;
514 // Bypass hardware check.
515 base::CommandLine::ForCurrentProcess()->AppendSwitch(
516 switches::kEnableExperimentalHotwordHardware);
518 // With hardware, only always-on is allowed.
519 EXPECT_FALSE(hotword_service->IsSometimesOnEnabled());
521 // Set pref.
522 profile()->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, true);
523 EXPECT_FALSE(hotword_service->IsSometimesOnEnabled());
525 // Disable always-on.
526 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled,
527 false);
528 EXPECT_FALSE(hotword_service->IsSometimesOnEnabled());
531 TEST_P(HotwordServiceTest, AudioHistorySyncOccurs) {
532 InitializeEmptyExtensionService();
533 service_->Init();
535 HotwordServiceFactory* hotword_service_factory =
536 HotwordServiceFactory::GetInstance();
538 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
539 hotword_service_factory->SetTestingFactoryAndUse(
540 profile(), BuildMockHotwordService));
541 ASSERT_TRUE(hotword_service != NULL);
542 hotword_service->SetExtensionService(service());
543 hotword_service->SetExtensionId(extension_id_);
545 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner(
546 new base::TestSimpleTaskRunner());
547 MockAudioHistoryHandler* audio_history_handler =
548 new MockAudioHistoryHandler(profile(), test_task_runner, nullptr);
549 hotword_service->SetAudioHistoryHandler(audio_history_handler);
550 EXPECT_EQ(1, audio_history_handler->GetAudioHistoryCalls());
551 // We expect the next check for audio history to be in the queue.
552 EXPECT_EQ(base::TimeDelta::FromDays(1),
553 test_task_runner->NextPendingTaskDelay());
554 EXPECT_TRUE(test_task_runner->HasPendingTask());
555 test_task_runner->RunPendingTasks();
556 EXPECT_EQ(2, audio_history_handler->GetAudioHistoryCalls());
557 EXPECT_TRUE(test_task_runner->HasPendingTask());
558 test_task_runner->ClearPendingTasks();