Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / apps / ephemeral_app_browsertest.cc
blobe114e3cf242741b5594e0fc40db90590ef84c010
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 "chrome/browser/apps/app_browsertest_util.h"
6 #include "chrome/browser/extensions/extension_service.h"
7 #include "chrome/browser/extensions/extension_system.h"
8 #include "chrome/browser/extensions/extension_test_message_listener.h"
9 #include "chrome/common/extensions/api/alarms.h"
10 #include "content/public/test/browser_test.h"
11 #include "content/public/test/test_utils.h"
12 #include "extensions/browser/event_router.h"
13 #include "extensions/browser/process_manager.h"
14 #include "extensions/common/switches.h"
16 using extensions::Event;
17 using extensions::EventRouter;
18 using extensions::Extension;
19 using extensions::ExtensionSystem;
20 using extensions::PlatformAppBrowserTest;
22 namespace {
24 namespace alarms = extensions::api::alarms;
26 const char kDispatchEventTestApp[] =
27 "platform_apps/ephemeral_apps/dispatch_event";
29 const char kMessagingReceiverApp[] =
30 "platform_apps/ephemeral_apps/messaging_receiver";
32 const char kMessagingReceiverAppV2[] =
33 "platform_apps/ephemeral_apps/messaging_receiver2";
35 class EphemeralAppBrowserTest : public PlatformAppBrowserTest {
36 protected:
37 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
38 // Skip PlatformAppBrowserTest, which sets different values for the switches
39 // below.
40 ExtensionBrowserTest::SetUpCommandLine(command_line);
42 // Make event pages get suspended immediately.
43 command_line->AppendSwitchASCII(
44 extensions::switches::kEventPageIdleTime, "10");
45 command_line->AppendSwitchASCII(
46 extensions::switches::kEventPageSuspendingTime, "10");
49 const Extension* InstallEphemeralApp(const char* test_path) {
50 base::FilePath path = test_data_dir_.AppendASCII(test_path);
51 const Extension* extension =
52 InstallExtensionWithSourceAndFlags(
53 path,
55 extensions::Manifest::UNPACKED,
56 Extension::IS_EPHEMERAL);
57 return extension;
60 const Extension* InstallAndLaunchEphemeralApp(const char* test_path) {
61 ExtensionTestMessageListener launched_listener("launched", false);
62 const Extension* extension = InstallEphemeralApp(test_path);
63 EXPECT_TRUE(extension);
64 if (!extension)
65 return NULL;
67 LaunchPlatformApp(extension);
68 bool wait_result = launched_listener.WaitUntilSatisfied();
69 EXPECT_TRUE(wait_result);
70 if (!wait_result)
71 return NULL;
73 return extension;
76 void CloseApp(const std::string& app_id) {
77 content::WindowedNotificationObserver event_page_destroyed_signal(
78 chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED,
79 content::Source<Profile>(browser()->profile()));
81 EXPECT_EQ(1U, GetShellWindowCountForApp(app_id));
82 apps::ShellWindow* shell_window = GetFirstShellWindowForApp(app_id);
83 ASSERT_TRUE(shell_window);
84 CloseShellWindow(shell_window);
86 event_page_destroyed_signal.Wait();
89 void VerifyAppNotLoaded(const std::string& app_id) {
90 EXPECT_FALSE(ExtensionSystem::Get(browser()->profile())->
91 process_manager()->GetBackgroundHostForExtension(app_id));
94 void DispatchAlarmEvent(EventRouter* event_router,
95 const std::string& app_id) {
96 alarms::Alarm dummy_alarm;
97 dummy_alarm.name = "test_alarm";
99 scoped_ptr<base::ListValue> args(new base::ListValue());
100 args->Append(dummy_alarm.ToValue().release());
101 scoped_ptr<Event> event(new Event(alarms::OnAlarm::kEventName,
102 args.Pass()));
104 event_router->DispatchEventToExtension(app_id, event.Pass());
108 } // namespace
110 // Verify that ephemeral apps can be launched and receive system events when
111 // they are running. Once they are inactive they should not receive system
112 // events.
113 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, EventDispatchWhenLaunched) {
114 const Extension* extension =
115 InstallAndLaunchEphemeralApp(kDispatchEventTestApp);
116 ASSERT_TRUE(extension);
118 // Send a fake alarm event to the app and verify that a response is
119 // received.
120 EventRouter* event_router =
121 ExtensionSystem::Get(browser()->profile())->event_router();
122 ASSERT_TRUE(event_router);
124 ExtensionTestMessageListener alarm_received_listener("alarm_received", false);
125 DispatchAlarmEvent(event_router, extension->id());
126 ASSERT_TRUE(alarm_received_listener.WaitUntilSatisfied());
128 CloseApp(extension->id());
130 // The app needs to be launched once in order to have the onAlarm() event
131 // registered.
132 ASSERT_TRUE(event_router->ExtensionHasEventListener(
133 extension->id(), alarms::OnAlarm::kEventName));
135 // Dispatch the alarm event again and verify that the event page did not get
136 // loaded for the app.
137 DispatchAlarmEvent(event_router, extension->id());
138 VerifyAppNotLoaded(extension->id());
141 // Verify that ephemeral apps will receive messages while they are running.
142 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, ReceiveMessagesWhenLaunched) {
143 const Extension* receiver =
144 InstallAndLaunchEphemeralApp(kMessagingReceiverApp);
145 ASSERT_TRUE(receiver);
147 // Verify that messages are received while the app is running.
148 ExtensionApiTest::ResultCatcher result_catcher;
149 LoadAndLaunchPlatformApp("ephemeral_apps/messaging_sender_success");
150 EXPECT_TRUE(result_catcher.GetNextResult());
152 CloseApp(receiver->id());
154 // Verify that messages are not received while the app is inactive.
155 LoadAndLaunchPlatformApp("ephemeral_apps/messaging_sender_fail");
156 EXPECT_TRUE(result_catcher.GetNextResult());
159 // Verify that an updated ephemeral app will still have its ephemeral flag
160 // enabled.
161 IN_PROC_BROWSER_TEST_F(EphemeralAppBrowserTest, UpdateEphemeralApp) {
162 const Extension* app_v1 = InstallEphemeralApp(kMessagingReceiverApp);
163 ASSERT_TRUE(app_v1);
164 ASSERT_TRUE(app_v1->is_ephemeral());
165 std::string app_id = app_v1->id();
166 base::Version app_original_version = *app_v1->version();
167 app_v1 = NULL; // The extension object will be destroyed during update.
169 // Pack version 2 of the app.
170 base::ScopedTempDir temp_dir;
171 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
173 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
174 if (!base::DeleteFile(crx_path, false)) {
175 ADD_FAILURE() << "Failed to delete crx: " << crx_path.value();
176 return;
179 base::FilePath app_v2_path = PackExtensionWithOptions(
180 test_data_dir_.AppendASCII(kMessagingReceiverAppV2),
181 crx_path,
182 test_data_dir_.AppendASCII(kMessagingReceiverApp).ReplaceExtension(
183 FILE_PATH_LITERAL(".pem")),
184 base::FilePath());
185 ASSERT_FALSE(app_v2_path.empty());
187 // Update the ephemeral app and wait for the update to finish.
188 extensions::CrxInstaller* crx_installer = NULL;
189 content::WindowedNotificationObserver windowed_observer(
190 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
191 content::Source<extensions::CrxInstaller>(crx_installer));
192 ExtensionService* service =
193 ExtensionSystem::Get(browser()->profile())->extension_service();
194 EXPECT_TRUE(
195 service->UpdateExtension(app_id, app_v2_path, GURL(), &crx_installer));
196 windowed_observer.Wait();
198 const Extension* app_v2 = service->GetExtensionById(app_id, false);
199 ASSERT_TRUE(app_v2);
200 EXPECT_TRUE(app_v2->version()->CompareTo(app_original_version) > 0);
201 EXPECT_TRUE(app_v2->is_ephemeral());