OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 "ash/shell.h" | |
6 #include "ash/system/cast/tray_cast.h" | |
7 #include "ash/system/tray/system_tray.h" | |
8 #include "ash/system/tray/system_tray_delegate.h" | |
9 #include "ash/system/tray/system_tray_item.h" | |
10 #include "ash/test/tray_cast_test_api.h" | |
11 #include "chrome/browser/extensions/extension_browsertest.h" | |
12 #include "chrome/browser/profiles/profile_manager.h" | |
13 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
14 #include "content/public/browser/render_view_host.h" | |
15 #include "content/public/test/test_utils.h" | |
16 #include "extensions/browser/process_manager.h" | |
17 | |
18 namespace { | |
19 | |
20 // Execute JavaScript within the context of the extension. Returns the result | |
21 // of the execution. | |
22 scoped_ptr<base::Value> ExecuteJavaScript( | |
23 const extensions::Extension* extension, | |
24 const std::string& javascript) { | |
25 Profile* profile = ProfileManager::GetActiveUserProfile(); | |
26 auto pm = extensions::ProcessManager::Get(profile); | |
27 content::RenderViewHost* host = | |
28 pm->GetBackgroundHostForExtension(extension->id())->render_view_host(); | |
29 return content::ExecuteScriptAndGetValue(host->GetMainFrame(), javascript); | |
30 } | |
31 | |
32 // Returns the current value within a global JavaScript variable. | |
33 scoped_ptr<base::Value> GetJavaScriptVariable( | |
34 const extensions::Extension* extension, | |
35 const std::string& variable) { | |
36 return ExecuteJavaScript(extension, | |
37 "(function() { return " + variable + "; })()"); | |
38 } | |
oshima
2015/08/19 00:34:21
new line between 38 and 39, and 45 and 46.
jdufault
2015/08/19 18:38:28
Done.
| |
39 std::string GetJavaScriptStringVariable(const extensions::Extension* extension, | |
40 const std::string& variable) { | |
41 scoped_ptr<base::Value> value = GetJavaScriptVariable(extension, variable); | |
42 std::string result; | |
43 CHECK(value->GetAsString(&result)); | |
oshima
2015/08/19 00:34:21
Just FYI: DCHECK is effective on release build on
achuithb
2015/08/19 17:34:38
Yup, believe DCHECK works, so we should use DCHECK
jdufault
2015/08/19 18:38:28
Done.
| |
44 return result; | |
45 } | |
46 bool GetJavaScriptBooleanVariable(const extensions::Extension* extension, | |
47 const std::string& variable) { | |
48 scoped_ptr<base::Value> value = GetJavaScriptVariable(extension, variable); | |
49 bool result; | |
50 CHECK(value->GetAsBoolean(&result)); | |
achuithb
2015/08/19 17:34:38
Same
jdufault
2015/08/19 18:38:28
Done.
| |
51 return result; | |
52 } | |
53 | |
54 // Ensures that all pending JavaScript execution callbacks are invoked. | |
55 void ExecutePendingJavaScript(const extensions::Extension* extension) { | |
56 ExecuteJavaScript(extension, std::string()); | |
57 } | |
58 | |
59 // Invokes tray->StartCast(id) and returns true if launchDesktopMirroring was | |
60 // called with the same id. This automatically creates/destroys the detail view | |
61 // and notifies the tray that Chrome has begun casting. | |
62 bool StartCastWithVerification(const extensions::Extension* extension, | |
63 ash::TrayCast* tray, | |
64 const std::string& receiver_id) { | |
65 ash::SystemTrayItem* system_tray_item = tray; | |
66 ash::TrayCastTestAPI test_tray(tray); | |
67 | |
68 // We will simulate a button click in the detail view to begin the cast, so we | |
69 // need to make a detail view available. | |
70 system_tray_item->CreateDetailedView(ash::user::LoginStatus::LOGGED_IN_USER); | |
71 | |
72 // Clear out any old state and execute any pending JS calls created from the | |
73 // CreateDetailedView call. | |
74 ExecuteJavaScript(extension, "launchDesktopMirroringReceiverId = ''"); | |
75 | |
76 // Tell the tray item that Chrome has started casting. | |
77 test_tray.StartCast(receiver_id); | |
78 test_tray.OnCastingSessionStartedOrStopped(true); | |
79 | |
80 system_tray_item->DestroyDetailedView(); | |
81 | |
82 return receiver_id == GetJavaScriptStringVariable( | |
83 extension, "launchDesktopMirroringReceiverId"); | |
84 } | |
85 | |
86 // Invokes tray->StopCast() and returns true if stopMirroring('user-stop') | |
87 // was called in the extension. | |
88 bool StopCastWithVerification(const extensions::Extension* extension, | |
89 ash::TrayCastTestAPI* tray) { | |
90 // Clear out any old state so we can be sure that we set the value here. | |
91 ExecuteJavaScript(extension, "stopMirroringCalled = false"); | |
92 | |
93 // Stop casting. | |
94 tray->StopCast(); | |
95 tray->OnCastingSessionStartedOrStopped(false); | |
96 | |
97 return GetJavaScriptBooleanVariable(extension, "stopMirroringCalled"); | |
98 } | |
99 | |
100 // Returns the cast tray. The tray initializer may have launched some | |
101 // JavaScript callbacks which have not finished executing. | |
102 ash::TrayCast* GetTrayCast(const extensions::Extension* extension) { | |
103 ash::SystemTray* tray = ash::Shell::GetInstance()->GetPrimarySystemTray(); | |
104 | |
105 // Make sure we actually popup the tray, otherwise the TrayCast instance will | |
106 // not be created. | |
107 tray->ShowDefaultView(ash::BubbleCreationType::BUBBLE_CREATE_NEW); | |
108 | |
109 // Creating the tray causes some JavaScript to be executed. Let's try to make | |
110 // sure it is completed. | |
111 if (extension) | |
112 ExecutePendingJavaScript(extension); | |
113 | |
114 return tray->GetTrayCastForTesting(); | |
115 } | |
116 | |
117 class SystemTrayTrayCastChromeOSTest : public ExtensionBrowserTest { | |
118 protected: | |
119 SystemTrayTrayCastChromeOSTest() : ExtensionBrowserTest() {} | |
120 ~SystemTrayTrayCastChromeOSTest() override {} | |
121 | |
122 const extensions::Extension* LoadCastTestExtension() { | |
123 return LoadExtension(test_data_dir_.AppendASCII("tray_cast")); | |
124 } | |
125 | |
126 private: | |
127 DISALLOW_COPY_AND_ASSIGN(SystemTrayTrayCastChromeOSTest); | |
128 }; | |
129 | |
130 } // namespace | |
131 | |
132 namespace chromeos { | |
133 | |
134 // A simple sanity check to make sure that the cast config delegate actually | |
135 // recognizes the cast extension. | |
136 IN_PROC_BROWSER_TEST_F(SystemTrayTrayCastChromeOSTest, | |
137 CastTraySanityCheckTestExtensionGetsRecognized) { | |
138 ash::CastConfigDelegate* cast_config_delegate = ash::Shell::GetInstance() | |
139 ->system_tray_delegate() | |
140 ->GetCastConfigDelegate(); | |
141 | |
142 EXPECT_FALSE(cast_config_delegate->HasCastExtension()); | |
143 const extensions::Extension* extension = LoadCastTestExtension(); | |
144 EXPECT_TRUE(cast_config_delegate->HasCastExtension()); | |
145 UninstallExtension(extension->id()); | |
146 } | |
147 | |
148 // Verifies that the cast tray is hidden when there is no extension installed. | |
149 IN_PROC_BROWSER_TEST_F(SystemTrayTrayCastChromeOSTest, | |
150 CastTrayIsHiddenWhenThereIsNoExtension) { | |
151 ash::TrayCastTestAPI tray(GetTrayCast(nullptr)); | |
152 EXPECT_TRUE(tray.IsTrayInitialized()); | |
153 EXPECT_FALSE(tray.IsTrayVisible()); | |
154 } | |
155 | |
156 // Verifies that the cast tray is hidden if there are no available receivers, | |
157 // even if there is an extension installed. | |
158 IN_PROC_BROWSER_TEST_F(SystemTrayTrayCastChromeOSTest, | |
159 CastTrayIsHiddenWhenThereIsAnExtensionButNoReceivers) { | |
160 const extensions::Extension* extension = LoadCastTestExtension(); | |
161 | |
162 ash::TrayCastTestAPI tray(GetTrayCast(extension)); | |
163 EXPECT_TRUE(tray.IsTrayInitialized()); | |
164 EXPECT_FALSE(tray.IsTrayVisible()); | |
165 | |
166 UninstallExtension(extension->id()); | |
167 } | |
168 | |
169 // Verifies that the cast tray is displayed when there are receivers available. | |
170 IN_PROC_BROWSER_TEST_F(SystemTrayTrayCastChromeOSTest, | |
171 CastTrayIsDisplayedWhenThereIsAnExtensionWithReceivers) { | |
172 const extensions::Extension* extension = LoadCastTestExtension(); | |
173 ExecuteJavaScript(extension, "addReceiver('test_id', 'name')"); | |
174 | |
175 ash::TrayCastTestAPI tray(GetTrayCast(extension)); | |
176 | |
177 EXPECT_TRUE(tray.IsTrayInitialized()); | |
178 EXPECT_TRUE(tray.IsTrayVisible()); | |
179 | |
180 UninstallExtension(extension->id()); | |
181 } | |
182 | |
183 // Verifies that we can cast to a specific receiver, stop casting, and then cast | |
184 // to another receiver when there is more than one receiver | |
185 IN_PROC_BROWSER_TEST_F(SystemTrayTrayCastChromeOSTest, | |
186 CastTrayMultipleReceivers) { | |
187 const extensions::Extension* extension = LoadCastTestExtension(); | |
188 ExecuteJavaScript(extension, "addReceiver('test_id_1', 'name')"); | |
189 ExecuteJavaScript(extension, "addReceiver('not_used_0', 'name1')"); | |
190 ExecuteJavaScript(extension, "addReceiver('test_id_0', 'name')"); | |
191 ExecuteJavaScript(extension, "addReceiver('not_used_1', 'name2')"); | |
192 | |
193 ash::TrayCast* tray = GetTrayCast(extension); | |
194 ash::TrayCastTestAPI test_tray(tray); | |
195 EXPECT_TRUE(StartCastWithVerification(extension, tray, "test_id_0")); | |
196 | |
197 EXPECT_TRUE(test_tray.IsTrayCastViewVisible()); | |
198 EXPECT_TRUE(StopCastWithVerification(extension, &test_tray)); | |
199 EXPECT_TRUE(test_tray.IsTraySelectViewVisible()); | |
200 | |
201 EXPECT_TRUE(StartCastWithVerification(extension, tray, "test_id_1")); | |
202 EXPECT_TRUE(test_tray.IsTrayCastViewVisible()); | |
203 EXPECT_TRUE(StopCastWithVerification(extension, &test_tray)); | |
204 EXPECT_TRUE(test_tray.IsTraySelectViewVisible()); | |
205 | |
206 UninstallExtension(extension->id()); | |
207 } | |
208 | |
209 // Verifies the stop cast button invokes the JavaScript function | |
210 // "stopMirroring('user-stop')". | |
211 IN_PROC_BROWSER_TEST_F(SystemTrayTrayCastChromeOSTest, | |
212 CastTrayStopButtonStopsCast) { | |
213 // Add a receiver that is casting. | |
214 const extensions::Extension* extension = LoadCastTestExtension(); | |
215 ExecuteJavaScript(extension, "addReceiver('test_id', 'name', 'title', 1)"); | |
216 | |
217 ash::TrayCastTestAPI test_tray(GetTrayCast(extension)); | |
218 test_tray.OnCastingSessionStartedOrStopped(true); | |
219 ExecutePendingJavaScript(extension); | |
220 EXPECT_TRUE(test_tray.IsTrayCastViewVisible()); | |
221 | |
222 // Stop the cast using the UI. | |
223 EXPECT_TRUE(StopCastWithVerification(extension, &test_tray)); | |
224 EXPECT_TRUE(test_tray.IsTraySelectViewVisible()); | |
225 | |
226 UninstallExtension(extension->id()); | |
227 } | |
228 | |
229 // Verifies that the start cast button invokes "launchDesktopMirroring(...)". | |
230 IN_PROC_BROWSER_TEST_F(SystemTrayTrayCastChromeOSTest, | |
231 CastTrayStartButtonStartsCast) { | |
232 const extensions::Extension* extension = LoadCastTestExtension(); | |
233 ExecuteJavaScript(extension, "addReceiver('test_id', 'name')"); | |
234 ash::TrayCast* tray = GetTrayCast(extension); | |
235 EXPECT_TRUE(StartCastWithVerification(extension, tray, "test_id")); | |
236 UninstallExtension(extension->id()); | |
237 } | |
238 | |
239 // Verifies that the CastConfigDelegate opens up a tab called "options.html". | |
240 IN_PROC_BROWSER_TEST_F(SystemTrayTrayCastChromeOSTest, CastTrayOpenOptions) { | |
241 const extensions::Extension* extension = LoadCastTestExtension(); | |
242 | |
243 ash::CastConfigDelegate* cast_config_delegate = ash::Shell::GetInstance() | |
244 ->system_tray_delegate() | |
245 ->GetCastConfigDelegate(); | |
246 cast_config_delegate->LaunchCastOptions(); | |
247 | |
248 const GURL url = | |
249 browser()->tab_strip_model()->GetActiveWebContents()->GetURL(); | |
250 EXPECT_TRUE(base::StringPiece(url.GetContent()).ends_with("options.html")); | |
251 | |
252 UninstallExtension(extension->id()); | |
253 } | |
254 | |
255 } // namespace chromeos | |
OLD | NEW |