Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / apps / ephemeral_app_browsertest.cc
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.
4
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"
15
16 using extensions::Event;
17 using extensions::EventRouter;
18 using extensions::Extension;
19 using extensions::ExtensionSystem;
20 using extensions::PlatformAppBrowserTest;
21
22 namespace {
23
24 namespace alarms = extensions::api::alarms;
25
26 const char kDispatchEventTestApp[] =
27     "platform_apps/ephemeral_apps/dispatch_event";
28
29 const char kMessagingReceiverApp[] =
30     "platform_apps/ephemeral_apps/messaging_receiver";
31
32 const char kMessagingReceiverAppV2[] =
33     "platform_apps/ephemeral_apps/messaging_receiver2";
34
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);
41
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");
47   }
48
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,
54             1,
55             extensions::Manifest::UNPACKED,
56             Extension::IS_EPHEMERAL);
57     return extension;
58   }
59
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;
66
67     LaunchPlatformApp(extension);
68     bool wait_result = launched_listener.WaitUntilSatisfied();
69     EXPECT_TRUE(wait_result);
70     if (!wait_result)
71       return NULL;
72
73     return extension;
74   }
75
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()));
80
81     EXPECT_EQ(1U, GetShellWindowCountForApp(app_id));
82     apps::ShellWindow* shell_window = GetFirstShellWindowForApp(app_id);
83     ASSERT_TRUE(shell_window);
84     CloseShellWindow(shell_window);
85
86     event_page_destroyed_signal.Wait();
87   }
88
89   void VerifyAppNotLoaded(const std::string& app_id) {
90     EXPECT_FALSE(ExtensionSystem::Get(browser()->profile())->
91         process_manager()->GetBackgroundHostForExtension(app_id));
92   }
93
94   void DispatchAlarmEvent(EventRouter* event_router,
95                           const std::string& app_id) {
96     alarms::Alarm dummy_alarm;
97     dummy_alarm.name = "test_alarm";
98
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()));
103
104     event_router->DispatchEventToExtension(app_id, event.Pass());
105   }
106 };
107
108 }  // namespace
109
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);
117
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);
123
124   ExtensionTestMessageListener alarm_received_listener("alarm_received", false);
125   DispatchAlarmEvent(event_router, extension->id());
126   ASSERT_TRUE(alarm_received_listener.WaitUntilSatisfied());
127
128   CloseApp(extension->id());
129
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));
134
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());
139 }
140
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);
146
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());
151
152   CloseApp(receiver->id());
153
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());
157 }
158
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.
168
169   // Pack version 2 of the app.
170   base::ScopedTempDir temp_dir;
171   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
172
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;
177   }
178
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());
186
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(service->UpdateExtension(app_id, app_v2_path, true, GURL(),
195                                        &crx_installer));
196   windowed_observer.Wait();
197
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());
202 }