1# Copyright 2016 The Chromium OS 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
5import logging
6
7from autotest_lib.client.bin import utils
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.common_lib.cros import chrome
10
11DEFAULT_TIMEOUT = 30
12DIAGNOSTIC_RUN_TIMEOUT = 180
13
14def get_cfm_webview_context(browser, ext_id):
15    """Get context for CFM webview.
16
17    @param broswer: Telemetry broswer object.
18    @param ext_id: Extension id of the hangouts app.
19    @return webview context.
20    """
21    ext_contexts = wait_for_kiosk_ext(browser, ext_id)
22
23    for context in ext_contexts:
24        context.WaitForDocumentReadyStateToBeInteractiveOrBetter()
25        tagName = context.EvaluateJavaScript(
26            "document.querySelector('webview') ? 'WEBVIEW' : 'NOWEBVIEW'")
27
28        if tagName == "WEBVIEW":
29            def _webview_context():
30                try:
31                    wb_contexts = context.GetWebviewContexts()
32                    if len(wb_contexts) == 1:
33                        return wb_contexts[0]
34                except (KeyError, chrome.Error):
35                    pass
36                return None
37            return utils.poll_for_condition(
38                    _webview_context,
39                    exception=error.TestFail('Hangouts webview not available.'),
40                    timeout=DEFAULT_TIMEOUT,
41                    sleep_interval=1)
42
43
44def wait_for_kiosk_ext(browser, ext_id):
45    """Wait for kiosk extension launch.
46
47    @param browser: Telemetry browser object.
48    @param ext_id: Extension id of the hangouts app.
49    @return extension contexts.
50    """
51    def _kiosk_ext_contexts():
52        try:
53            ext_contexts = browser.extensions.GetByExtensionId(ext_id)
54            if len(ext_contexts) > 1:
55                return ext_contexts
56        except (KeyError, chrome.Error):
57            pass
58        return []
59    return utils.poll_for_condition(
60            _kiosk_ext_contexts,
61            exception=error.TestFail('Kiosk app failed to launch'),
62            timeout=DEFAULT_TIMEOUT,
63            sleep_interval=1)
64
65
66def wait_for_telemetry_commands(webview_context):
67    """Wait for hotrod app to load and telemetry commands to be available.
68
69    @param webview_context: Context for hangouts webview.
70    """
71    webview_context.WaitForJavaScriptCondition(
72            "typeof window.hrOobIsStartPageForTest == 'function'",
73            timeout=DEFAULT_TIMEOUT)
74    logging.info('Hotrod telemetry commands available for testing.')
75
76
77# UI commands/functions
78def wait_for_oobe_start_page(webview_context):
79    """Wait for oobe start screen to launch.
80
81    @param webview_context: Context for hangouts webview.
82    """
83    webview_context.WaitForJavaScriptCondition(
84            "window.hrOobIsStartPageForTest() === true;",
85            timeout=DEFAULT_TIMEOUT)
86    logging.info('Reached oobe start page')
87
88
89def skip_oobe_screen(webview_context):
90    """Skip Chromebox for Meetings oobe screen.
91
92    @param webview_context: Context for hangouts webview.
93    """
94    webview_context.ExecuteJavaScript("window.hrOobSkipForTest()")
95    utils.poll_for_condition(lambda: not webview_context.EvaluateJavaScript(
96            "window.hrOobIsStartPageForTest()"),
97            exception=error.TestFail('Not able to skip oobe screen.'),
98            timeout=DEFAULT_TIMEOUT,
99            sleep_interval=1)
100    logging.info('Skipped oobe screen.')
101
102
103def is_oobe_start_page(webview_context):
104    """Check if device is on CFM oobe start screen.
105
106    @param webview_context: Context for hangouts webview.
107    """
108    if webview_context.EvaluateJavaScript("window.hrOobIsStartPageForTest()"):
109        logging.info('Is on oobe start page.')
110        return True
111    logging.info('Is not on oobe start page.')
112    return False
113
114
115# Hangouts commands/functions
116def start_new_hangout_session(webview_context, hangout_name):
117    """Start a new hangout session.
118
119    @param webview_context: Context for hangouts webview.
120    @param hangout_name: Name of the hangout session.
121    """
122    if not is_ready_to_start_hangout_session(webview_context):
123        if is_in_hangout_session(webview_context):
124            end_hangout_session(webview_context)
125        utils.poll_for_condition(lambda: webview_context.EvaluateJavaScript(
126                "window.hrIsReadyToStartHangoutForTest()"),
127                exception=error.TestFail('Not ready to start hangout session.'),
128                timeout=DEFAULT_TIMEOUT,
129                sleep_interval=1)
130
131    webview_context.ExecuteJavaScript("window.hrStartCallForTest('" +
132                                  hangout_name + "')")
133    utils.poll_for_condition(lambda: webview_context.EvaluateJavaScript(
134            "window.hrIsInHangoutForTest()"),
135            exception=error.TestFail('Not able to start session.'),
136            timeout=DEFAULT_TIMEOUT,
137            sleep_interval=1)
138    logging.info('Started hangout session: %s', hangout_name)
139
140
141def end_hangout_session(webview_context):
142    """End current hangout session.
143
144    @param webview_context: Context for hangouts webview.
145    """
146    webview_context.ExecuteJavaScript("window.hrHangupCallForTest()")
147    utils.poll_for_condition(lambda: not webview_context.EvaluateJavaScript(
148            "window.hrIsInHangoutForTest()"),
149            exception=error.TestFail('Not able to end session.'),
150            timeout=DEFAULT_TIMEOUT,
151            sleep_interval=1)
152
153    logging.info('Ended hangout session.')
154
155
156def is_in_hangout_session(webview_context):
157    """Check if device is in hangout session.
158
159    @param webview_context: Context for hangouts webview.
160    """
161    if webview_context.EvaluateJavaScript("window.hrIsInHangoutForTest()"):
162        logging.info('Is in hangout session.')
163        return True
164    logging.info('Is not in hangout session.')
165    return False
166
167
168def is_ready_to_start_hangout_session(webview_context):
169    """Check if device is ready to start a new hangout session.
170
171    @param webview_context: Context for hangouts webview.
172    """
173    if (webview_context.EvaluateJavaScript(
174            "window.hrIsReadyToStartHangoutForTest()")):
175        logging.info('Is ready to start hangout session.')
176        return True
177    logging.info('Is not ready to start hangout session.')
178    return False
179
180
181# Diagnostics commands/functions
182def is_diagnostic_run_in_progress(webview_context):
183    """Check if hotrod diagnostics is running.
184
185    @param webview_context: Context for hangouts webview.
186    """
187    if (webview_context.EvaluateJavaScript(
188            "window.hrIsDiagnosticRunInProgressForTest()")):
189        logging.info('Diagnostic run is in progress.')
190        return True
191    logging.info('Diagnostic run is not in progress.')
192    return False
193
194
195def wait_for_diagnostic_run_to_complete(webview_context):
196    """Wait for hotrod diagnostics to complete.
197
198    @param webview_context: Context for hangouts webview.
199    """
200    utils.poll_for_condition(lambda: not webview_context.EvaluateJavaScript(
201            "window.hrIsDiagnosticRunInProgressForTest()"),
202            exception=error.TestError('Diagnostic run still in progress after '
203                                      '3 minutes.'),
204            timeout=DIAGNOSTIC_RUN_TIMEOUT,
205            sleep_interval=1)
206
207
208def run_diagnostics(webview_context):
209    """Run hotrod diagnostics.
210
211    @param webview_context: Context for hangouts webview.
212    """
213    if is_diagnostic_run_in_progress(webview_context):
214        wait_for_diagnostic_run_to_complete(webview_context)
215    webview_context.ExecuteJavaScript("window.hrRunDiagnosticsForTest()")
216    logging.info('Started diagnostics run.')
217
218
219def get_last_diagnostics_results(webview_context):
220    """Get latest hotrod diagnostics results.
221
222    @param webview_context: Context for hangouts webview.
223    """
224    if is_diagnostic_run_in_progress(webview_context):
225        wait_for_diagnostic_run_to_complete(webview_context)
226    return webview_context.EvaluateJavaScript(
227            "window.hrGetLastDiagnosticsResultForTest()")
228
229
230# Mic audio commands/functions
231def is_mic_muted(webview_context):
232    """Check if mic is muted.
233
234    @param webview_context: Context for hangouts webview.
235    """
236    if webview_context.EvaluateJavaScript("window.hrGetAudioInMutedForTest()"):
237        logging.info('Mic is muted.')
238        return True
239    logging.info('Mic is not muted.')
240    return False
241
242def mute_mic(webview_context):
243    """Local mic mute from toolbar.
244
245    @param webview_context: Context for hangouts webview.
246    """
247    webview_context.ExecuteJavaScript("window.hrSetAudioInMutedForTest(true)")
248    logging.info('Locally muted mic.')
249
250
251def unmute_mic(webview_context):
252    """Local mic unmute from toolbar.
253
254    @param webview_context: Context for hangouts webview.
255    """
256    webview_context.ExecuteJavaScript("window.hrSetAudioInMutedForTest(false)")
257    logging.info('Locally unmuted mic.')
258
259
260def remote_mute_mic(webview_context):
261    """Remote mic mute request from cPanel.
262
263    @param webview_context: Context for hangouts webview.
264    """
265    webview_context.ExecuteJavaScript("window.hrMuteAudioForTest()")
266    logging.info('Remotely muted mic.')
267
268
269def remote_unmute_mic(webview_context):
270    """Remote mic unmute request from cPanel.
271
272    @param webview_context: Context for hangouts webview.
273    """
274    webview_context.ExecuteJavaScript("window.hrUnmuteAudioForTest()")
275    logging.info('Remotely unmuted mic.')
276
277
278def get_mic_devices(webview_context):
279    """Get all mic devices detected by hotrod.
280
281    @param webview_context: Context for hangouts webview.
282    """
283    return webview_context.EvaluateJavaScript(
284            "window.hrGetAudioInDevicesForTest()")
285
286
287def get_preferred_mic(webview_context):
288    """Get mic preferred for hotrod.
289
290    @param webview_context: Context for hangouts webview.
291    """
292    return webview_context.EvaluateJavaScript(
293            "window.hrGetAudioInPrefForTest()")
294
295
296def set_preferred_mic(webview_context, mic):
297    """Set preferred mic for hotrod.
298
299    @param webview_context: Context for hangouts webview.
300    @param mic: String with mic name.
301    """
302    webview_context.ExecuteJavaScript(
303            "window.hrSetAudioInPrefForTest('" + mic + "')")
304    logging.info('Setting preferred mic to %s.', mic)
305
306
307# Speaker commands/functions
308def get_speaker_devices(webview_context):
309    """Get all speaker devices detected by hotrod.
310
311    @param webview_context: Context for hangouts webview.
312    """
313    return webview_context.EvaluateJavaScript(
314            "window.hrGetAudioOutDevicesForTest()")
315
316
317def get_preferred_speaker(webview_context):
318    """Get speaker preferred for hotrod.
319
320    @param webview_context: Context for hangouts webview.
321    """
322    return webview_context.EvaluateJavaScript(
323            "window.hrGetAudioOutPrefForTest()")
324
325
326def set_preferred_speaker(webview_context, speaker):
327    """Set preferred speaker for hotrod.
328
329    @param webview_context: Context for hangouts webview.
330    @param mic: String with speaker name.
331    """
332    webview_context.ExecuteJavaScript(
333            "window.hrSetAudioOutPrefForTest('" + speaker + "')")
334    logging.info('Set preferred speaker to %s.', speaker)
335
336
337def set_speaker_volume(webview_context, volume_level):
338    """Set speaker volume.
339
340    @param webview_context: Context for hangouts webview.
341    @param volume_level: String value ranging from 0-100 to set volume to.
342    """
343    webview_context.ExecuteJavaScript(
344            "window.hrSetAudioOutVolumeLevelForTest('" + volume_level + "')")
345    logging.info('Set speaker volume to %s', volume_level)
346
347
348def get_speaker_volume(webview_context):
349    """Get current speaker volume.
350
351    @param webview_context: Context for hangouts webview.
352    """
353    return webview_context.EvaluateJavaScript(
354            "window.hrGetAudioOutVolumeLevelForTest()")
355
356
357def play_test_sound(webview_context):
358    """Play test sound.
359
360    @param webview_context: Context for hangouts webview.
361    """
362    webview_context.ExecuteJavaScript("window.hrPlayTestSoundForTest()")
363    logging.info('Playing test sound.')
364
365
366# Camera commands/functions
367def get_camera_devices(webview_context):
368    """Get all camera devices detected by hotrod.
369
370    @param webview_context: Context for hangouts webview.
371    """
372    return webview_context.EvaluateJavaScript(
373            "window.hrGetVideoCaptureDevicesForTest()")
374
375
376def get_preferred_camera(webview_context):
377    """Get camera preferred for hotrod.
378
379    @param webview_context: Context for hangouts webview.
380    """
381    return webview_context.EvaluateJavaScript(
382            "window.hrGetVideoCapturePrefForTest()")
383
384
385def set_preferred_camera(webview_context, camera):
386    """Set preferred camera for hotrod.
387
388    @param webview_context: Context for hangouts webview.
389    @param mic: String with camera name.
390    """
391    webview_context.ExecuteJavaScript(
392            "window.hrSetVideoCapturePrefForTest('" + camera + "')")
393    logging.info('Set preferred camera to %s.', camera)
394
395
396def is_camera_muted(webview_context):
397    """Check if camera is muted (turned off).
398
399    @param webview_context: Context for hangouts webview.
400    """
401    if webview_context.EvaluateJavaScript("window.hrGetVideoCaptureMutedForTest()"):
402        logging.info('Camera is muted.')
403        return True
404    logging.info('Camera is not muted.')
405    return False
406
407
408def mute_camera(webview_context):
409    """Turned camera off.
410
411    @param webview_context: Context for hangouts webview.
412    """
413    webview_context.ExecuteJavaScript(
414            "window.hrSetVideoCaptureMutedForTest(true)")
415    logging.info('Camera muted.')
416
417
418def unmute_camera(webview_context):
419    """Turned camera on.
420
421    @param webview_context: Context for hangouts webview.
422    """
423    webview_context.ExecuteJavaScript(
424            "window.hrSetVideoCaptureMutedForTest(false)")
425    logging.info('Camera unmuted.')
426