This source file includes following definitions.
- SetUpCommandLine
- CreateApp
- WaitForBackgroundMode
- CloseBrowser
- UnloadExtensionViaTask
- SetUpCommandLine
- extension
- LaunchTestingApp
- extension_id_
- SetGoalAndGetCallback
- Wait
- ImpulseCallback
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/background/background_contents_service.h"
#include "chrome/browser/background/background_contents_service_factory.h"
#include "chrome/browser/background/background_mode_manager.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "components/nacl/browser/nacl_process_host.h"
#include "content/public/browser/notification_service.h"
#include "content/public/test/test_notification_tracker.h"
#include "content/public/test/test_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/switches.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#if defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
#endif
using base::ASCIIToUTF16;
using extensions::Extension;
class AppBackgroundPageApiTest : public ExtensionApiTest {
public:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
ExtensionApiTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kDisablePopupBlocking);
command_line->AppendSwitch(extensions::switches::kAllowHTTPBackgroundPage);
}
bool CreateApp(const std::string& app_manifest,
base::FilePath* app_dir) {
if (!app_dir_.CreateUniqueTempDir()) {
LOG(ERROR) << "Unable to create a temporary directory.";
return false;
}
base::FilePath manifest_path = app_dir_.path().AppendASCII("manifest.json");
int bytes_written = base::WriteFile(manifest_path,
app_manifest.data(),
app_manifest.size());
if (bytes_written != static_cast<int>(app_manifest.size())) {
LOG(ERROR) << "Unable to write complete manifest to file. Return code="
<< bytes_written;
return false;
}
*app_dir = app_dir_.path();
return true;
}
bool WaitForBackgroundMode(bool expected_background_mode) {
#if defined(OS_CHROMEOS)
return true;
#else
BackgroundModeManager* manager =
g_browser_process->background_mode_manager();
if (!manager || !manager->IsBackgroundModePrefEnabled()) {
DLOG(WARNING) << "Skipping check - background mode disabled";
return true;
}
if (manager->IsBackgroundModeActive() == expected_background_mode)
return true;
content::WindowedNotificationObserver watcher(
chrome::NOTIFICATION_BACKGROUND_MODE_CHANGED,
content::NotificationService::AllSources());
watcher.Wait();
return manager->IsBackgroundModeActive() == expected_background_mode;
#endif
}
void CloseBrowser(Browser* browser) {
content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_BROWSER_CLOSED,
content::NotificationService::AllSources());
browser->window()->Close();
#if defined(OS_MACOSX)
AutoreleasePool()->Recycle();
#endif
observer.Wait();
}
void UnloadExtensionViaTask(const std::string& id) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&AppBackgroundPageApiTest::UnloadExtension, this, id));
}
private:
base::ScopedTempDir app_dir_;
};
namespace {
class AppBackgroundPageNaClTest : public AppBackgroundPageApiTest {
public:
AppBackgroundPageNaClTest()
: extension_(NULL) {}
virtual ~AppBackgroundPageNaClTest() {
}
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
AppBackgroundPageApiTest::SetUpCommandLine(command_line);
#if !defined(DISABLE_NACL)
nacl::NaClProcessHost::SetPpapiKeepAliveThrottleForTesting(50);
#endif
command_line->AppendSwitchASCII(
extensions::switches::kEventPageIdleTime, "1000");
command_line->AppendSwitchASCII(
extensions::switches::kEventPageSuspendingTime, "1000");
}
const Extension* extension() { return extension_; }
protected:
void LaunchTestingApp() {
base::FilePath app_dir;
PathService::Get(chrome::DIR_GEN_TEST_DATA, &app_dir);
app_dir = app_dir.AppendASCII(
"ppapi/tests/extensions/background_keepalive/newlib");
extension_ = LoadExtension(app_dir);
ASSERT_TRUE(extension_);
}
private:
const Extension* extension_;
};
class ImpulseCallbackCounter {
public:
explicit ImpulseCallbackCounter(extensions::ProcessManager* manager,
const std::string& extension_id)
: observed_(0),
goal_(0),
manager_(manager),
extension_id_(extension_id) {
}
extensions::ProcessManager::ImpulseCallbackForTesting
SetGoalAndGetCallback(int goal) {
observed_ = 0;
goal_ = goal;
message_loop_runner_ = new content::MessageLoopRunner();
return base::Bind(&ImpulseCallbackCounter::ImpulseCallback,
base::Unretained(this),
message_loop_runner_->QuitClosure(),
extension_id_);
}
void Wait() {
message_loop_runner_->Run();
}
private:
void ImpulseCallback(
const base::Closure& quit_callback,
const std::string& extension_id_from_test,
const std::string& extension_id_from_manager) {
if (extension_id_from_test == extension_id_from_manager) {
if (++observed_ >= goal_) {
manager_->SetKeepaliveImpulseCallbackForTesting(
extensions::ProcessManager::ImpulseCallbackForTesting());
manager_->SetKeepaliveImpulseDecrementCallbackForTesting(
extensions::ProcessManager::ImpulseCallbackForTesting());
quit_callback.Run();
}
}
}
int observed_;
int goal_;
extensions::ProcessManager* manager_;
const std::string extension_id_;
scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
};
}
#if defined(OS_MACOSX)
#define MAYBE_Basic DISABLED_Basic
#else
#define MAYBE_Basic Basic
#endif
IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, MAYBE_Basic) {
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
std::string app_manifest = base::StringPrintf(
"{"
" \"name\": \"App\","
" \"version\": \"0.1\","
" \"manifest_version\": 2,"
" \"app\": {"
" \"urls\": ["
" \"http://a.com/\""
" ],"
" \"launch\": {"
" \"web_url\": \"http://a.com:%d/\""
" }"
" },"
" \"permissions\": [\"background\"]"
"}",
embedded_test_server()->port());
base::FilePath app_dir;
ASSERT_TRUE(CreateApp(app_manifest, &app_dir));
ASSERT_TRUE(LoadExtension(app_dir));
ASSERT_TRUE(WaitForBackgroundMode(false));
ASSERT_TRUE(RunExtensionTest("app_background_page/basic")) << message_;
ASSERT_TRUE(WaitForBackgroundMode(false));
}
IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, DISABLED_LacksPermission) {
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
std::string app_manifest = base::StringPrintf(
"{"
" \"name\": \"App\","
" \"version\": \"0.1\","
" \"manifest_version\": 2,"
" \"app\": {"
" \"urls\": ["
" \"http://a.com/\""
" ],"
" \"launch\": {"
" \"web_url\": \"http://a.com:%d/\""
" }"
" }"
"}",
embedded_test_server()->port());
base::FilePath app_dir;
ASSERT_TRUE(CreateApp(app_manifest, &app_dir));
ASSERT_TRUE(LoadExtension(app_dir));
ASSERT_TRUE(RunExtensionTest("app_background_page/lacks_permission"))
<< message_;
ASSERT_TRUE(WaitForBackgroundMode(false));
}
IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, ManifestBackgroundPage) {
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
std::string app_manifest = base::StringPrintf(
"{"
" \"name\": \"App\","
" \"version\": \"0.1\","
" \"manifest_version\": 2,"
" \"app\": {"
" \"urls\": ["
" \"http://a.com/\""
" ],"
" \"launch\": {"
" \"web_url\": \"http://a.com:%d/\""
" }"
" },"
" \"permissions\": [\"background\"],"
" \"background\": {"
" \"page\": \"http://a.com:%d/test.html\""
" }"
"}",
embedded_test_server()->port(),
embedded_test_server()->port());
base::FilePath app_dir;
ASSERT_TRUE(CreateApp(app_manifest, &app_dir));
ASSERT_TRUE(LoadExtension(app_dir));
ASSERT_TRUE(WaitForBackgroundMode(true));
const Extension* extension = GetSingleLoadedExtension();
ASSERT_TRUE(
BackgroundContentsServiceFactory::GetForProfile(browser()->profile())->
GetAppBackgroundContents(ASCIIToUTF16(extension->id())));
UnloadExtension(extension->id());
}
IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, NoJsBackgroundPage) {
chrome::ShowTaskManager(browser());
content::TestNotificationTracker background_deleted_tracker;
background_deleted_tracker.ListenFor(
chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED,
content::Source<Profile>(browser()->profile()));
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
std::string app_manifest = base::StringPrintf(
"{"
" \"name\": \"App\","
" \"version\": \"0.1\","
" \"manifest_version\": 2,"
" \"app\": {"
" \"urls\": ["
" \"http://a.com/\""
" ],"
" \"launch\": {"
" \"web_url\": \"http://a.com:%d/test.html\""
" }"
" },"
" \"permissions\": [\"background\"],"
" \"background\": {"
" \"allow_js_access\": false"
" }"
"}",
embedded_test_server()->port());
base::FilePath app_dir;
ASSERT_TRUE(CreateApp(app_manifest, &app_dir));
ASSERT_TRUE(LoadExtension(app_dir));
const Extension* extension = GetSingleLoadedExtension();
ASSERT_FALSE(
BackgroundContentsServiceFactory::GetForProfile(browser()->profile())->
GetAppBackgroundContents(ASCIIToUTF16(extension->id())));
ASSERT_TRUE(RunExtensionTest("app_background_page/no_js")) << message_;
ASSERT_TRUE(
BackgroundContentsServiceFactory::GetForProfile(browser()->profile())->
GetAppBackgroundContents(ASCIIToUTF16(extension->id())));
EXPECT_EQ(0u, background_deleted_tracker.size());
UnloadExtension(extension->id());
}
IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, NoJsManifestBackgroundPage) {
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
std::string app_manifest = base::StringPrintf(
"{"
" \"name\": \"App\","
" \"version\": \"0.1\","
" \"manifest_version\": 2,"
" \"app\": {"
" \"urls\": ["
" \"http://a.com/\""
" ],"
" \"launch\": {"
" \"web_url\": \"http://a.com:%d/\""
" }"
" },"
" \"permissions\": [\"background\"],"
" \"background\": {"
" \"page\": \"http://a.com:%d/bg.html\","
" \"allow_js_access\": false"
" }"
"}",
embedded_test_server()->port(),
embedded_test_server()->port());
base::FilePath app_dir;
ASSERT_TRUE(CreateApp(app_manifest, &app_dir));
ASSERT_TRUE(LoadExtension(app_dir));
const Extension* extension = GetSingleLoadedExtension();
ASSERT_TRUE(
BackgroundContentsServiceFactory::GetForProfile(browser()->profile())->
GetAppBackgroundContents(ASCIIToUTF16(extension->id())));
ASSERT_TRUE(RunExtensionTest("app_background_page/no_js_manifest")) <<
message_;
UnloadExtension(extension->id());
}
IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, OpenTwoBackgroundPages) {
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
std::string app_manifest = base::StringPrintf(
"{"
" \"name\": \"App\","
" \"version\": \"0.1\","
" \"manifest_version\": 2,"
" \"app\": {"
" \"urls\": ["
" \"http://a.com/\""
" ],"
" \"launch\": {"
" \"web_url\": \"http://a.com:%d/\""
" }"
" },"
" \"permissions\": [\"background\"]"
"}",
embedded_test_server()->port());
base::FilePath app_dir;
ASSERT_TRUE(CreateApp(app_manifest, &app_dir));
ASSERT_TRUE(LoadExtension(app_dir));
const Extension* extension = GetSingleLoadedExtension();
ASSERT_TRUE(RunExtensionTest("app_background_page/two_pages")) << message_;
UnloadExtension(extension->id());
}
IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, OpenTwoPagesWithManifest) {
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
std::string app_manifest = base::StringPrintf(
"{"
" \"name\": \"App\","
" \"version\": \"0.1\","
" \"manifest_version\": 2,"
" \"app\": {"
" \"urls\": ["
" \"http://a.com/\""
" ],"
" \"launch\": {"
" \"web_url\": \"http://a.com:%d/\""
" }"
" },"
" \"background\": {"
" \"page\": \"http://a.com:%d/bg.html\""
" },"
" \"permissions\": [\"background\"]"
"}",
embedded_test_server()->port(),
embedded_test_server()->port());
base::FilePath app_dir;
ASSERT_TRUE(CreateApp(app_manifest, &app_dir));
ASSERT_TRUE(LoadExtension(app_dir));
const Extension* extension = GetSingleLoadedExtension();
ASSERT_TRUE(RunExtensionTest("app_background_page/two_with_manifest")) <<
message_;
UnloadExtension(extension->id());
}
IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, DISABLED_OpenPopupFromBGPage) {
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
std::string app_manifest = base::StringPrintf(
"{"
" \"name\": \"App\","
" \"version\": \"0.1\","
" \"manifest_version\": 2,"
" \"app\": {"
" \"urls\": ["
" \"http://a.com/\""
" ],"
" \"launch\": {"
" \"web_url\": \"http://a.com:%d/\""
" }"
" },"
" \"background\": { \"page\": \"http://a.com:%d/extensions/api_test/"
"app_background_page/bg_open/bg_open_bg.html\" },"
" \"permissions\": [\"background\"]"
"}",
embedded_test_server()->port(),
embedded_test_server()->port());
base::FilePath app_dir;
ASSERT_TRUE(CreateApp(app_manifest, &app_dir));
ASSERT_TRUE(LoadExtension(app_dir));
ASSERT_TRUE(RunExtensionTest("app_background_page/bg_open")) << message_;
}
IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, DISABLED_OpenThenClose) {
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
std::string app_manifest = base::StringPrintf(
"{"
" \"name\": \"App\","
" \"version\": \"0.1\","
" \"manifest_version\": 2,"
" \"app\": {"
" \"urls\": ["
" \"http://a.com/\""
" ],"
" \"launch\": {"
" \"web_url\": \"http://a.com:%d/\""
" }"
" },"
" \"permissions\": [\"background\"]"
"}",
embedded_test_server()->port());
base::FilePath app_dir;
ASSERT_TRUE(CreateApp(app_manifest, &app_dir));
ASSERT_TRUE(LoadExtension(app_dir));
const Extension* extension = GetSingleLoadedExtension();
ASSERT_FALSE(
BackgroundContentsServiceFactory::GetForProfile(browser()->profile())->
GetAppBackgroundContents(ASCIIToUTF16(extension->id())));
ASSERT_TRUE(WaitForBackgroundMode(false));
ASSERT_TRUE(RunExtensionTest("app_background_page/basic_open")) << message_;
ASSERT_TRUE(WaitForBackgroundMode(true));
ASSERT_TRUE(
BackgroundContentsServiceFactory::GetForProfile(browser()->profile())->
GetAppBackgroundContents(ASCIIToUTF16(extension->id())));
ASSERT_TRUE(RunExtensionTest("app_background_page/basic_close")) << message_;
ASSERT_TRUE(WaitForBackgroundMode(false));
ASSERT_FALSE(
BackgroundContentsServiceFactory::GetForProfile(browser()->profile())->
GetAppBackgroundContents(ASCIIToUTF16(extension->id())));
}
IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, UnloadExtensionWhileHidden) {
host_resolver()->AddRule("a.com", "127.0.0.1");
ASSERT_TRUE(StartEmbeddedTestServer());
std::string app_manifest = base::StringPrintf(
"{"
" \"name\": \"App\","
" \"version\": \"0.1\","
" \"manifest_version\": 2,"
" \"app\": {"
" \"urls\": ["
" \"http://a.com/\""
" ],"
" \"launch\": {"
" \"web_url\": \"http://a.com:%d/\""
" }"
" },"
" \"permissions\": [\"background\"],"
" \"background\": {"
" \"page\": \"http://a.com:%d/test.html\""
" }"
"}",
embedded_test_server()->port(),
embedded_test_server()->port());
base::FilePath app_dir;
ASSERT_TRUE(CreateApp(app_manifest, &app_dir));
ASSERT_TRUE(LoadExtension(app_dir));
ASSERT_TRUE(WaitForBackgroundMode(true));
const Extension* extension = GetSingleLoadedExtension();
ASSERT_TRUE(
BackgroundContentsServiceFactory::GetForProfile(browser()->profile())->
GetAppBackgroundContents(ASCIIToUTF16(extension->id())));
set_exit_when_last_browser_closes(false);
CloseBrowser(browser());
UnloadExtensionViaTask(extension->id());
content::RunAllPendingInMessageLoop();
ASSERT_TRUE(WaitForBackgroundMode(false));
}
#if defined(OS_WIN)
#define MAYBE_BackgroundKeepaliveActive DISABLED_BackgroundKeepaliveActive
#else
#define MAYBE_BackgroundKeepaliveActive BackgroundKeepaliveActive
#endif
IN_PROC_BROWSER_TEST_F(AppBackgroundPageNaClTest,
MAYBE_BackgroundKeepaliveActive) {
#if !defined(DISABLE_NACL)
ExtensionTestMessageListener nacl_modules_loaded("nacl_modules_loaded", true);
LaunchTestingApp();
extensions::ProcessManager* manager =
extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
ImpulseCallbackCounter active_impulse_counter(manager, extension()->id());
EXPECT_TRUE(nacl_modules_loaded.WaitUntilSatisfied());
manager->SetKeepaliveImpulseCallbackForTesting(
active_impulse_counter.SetGoalAndGetCallback(20));
active_impulse_counter.Wait();
#endif
}
#if defined(OS_WIN)
#define MAYBE_BackgroundKeepaliveIdle DISABLED_BackgroundKeepaliveIdle
#else
#define MAYBE_BackgroundKeepaliveIdle DISABLED_BackgroundKeepaliveIdle
#endif
IN_PROC_BROWSER_TEST_F(AppBackgroundPageNaClTest,
MAYBE_BackgroundKeepaliveIdle) {
#if !defined(DISABLE_NACL)
ExtensionTestMessageListener nacl_modules_loaded("nacl_modules_loaded", true);
LaunchTestingApp();
extensions::ProcessManager* manager =
extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
ImpulseCallbackCounter idle_impulse_counter(manager, extension()->id());
EXPECT_TRUE(nacl_modules_loaded.WaitUntilSatisfied());
manager->SetKeepaliveImpulseDecrementCallbackForTesting(
idle_impulse_counter.SetGoalAndGetCallback(1));
nacl_modules_loaded.Reply("be idle");
idle_impulse_counter.Wait();
#endif
}