• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2017 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 urlparse import urlparse
8
9from autotest_lib.client.bin import utils
10from autotest_lib.client.common_lib import error
11
12
13DEFAULT_TIMEOUT = 30
14TELEMETRY_API = 'hrTelemetryApi'
15
16
17class CfmMeetingsAPI(object):
18    """Utility class for interacting with CfMs."""
19
20    def __init__(self, webview_context):
21        self._webview_context = webview_context
22
23    def _execute_telemetry_command(self, command):
24        self._webview_context.ExecuteJavaScript(
25            'window.%s.%s' % (TELEMETRY_API, command))
26
27    def _evaluate_telemetry_command(self, command):
28        return self._webview_context.EvaluateJavaScript(
29            'window.%s.%s' % (TELEMETRY_API, command))
30
31    # UI commands/functions
32    def wait_for_meetings_landing_page(self):
33        """Waits for the landing page screen."""
34        self._webview_context.WaitForJavaScriptCondition(
35            'window.hasOwnProperty("%s") '
36            '&& !window.%s.isInMeeting()' % (TELEMETRY_API, TELEMETRY_API),
37            timeout=DEFAULT_TIMEOUT)
38        logging.info('Reached meetings landing page.')
39
40    def wait_for_meetings_in_call_page(self):
41        """Waits for the in-call page to launch."""
42        self._webview_context.WaitForJavaScriptCondition(
43            'window.hasOwnProperty("%s") '
44            '&& window.%s.isInMeeting()' % (TELEMETRY_API, TELEMETRY_API),
45            timeout=DEFAULT_TIMEOUT)
46        logging.info('Reached meetings in-call page.')
47
48    def wait_for_oobe_start_page(self):
49        """Wait for oobe start screen to launch."""
50        self._webview_context.WaitForJavaScriptCondition(
51            'window.hasOwnProperty("%s") '
52            '&& typeof window.%s.skipOobe === "function"' % (
53                TELEMETRY_API, TELEMETRY_API),
54            timeout=DEFAULT_TIMEOUT)
55        logging.info('Reached oobe page.')
56
57    def skip_oobe_screen(self):
58        """Skip Chromebox for Meetings oobe screen."""
59        self._execute_telemetry_command('skipOobe()')
60        utils.poll_for_condition(
61                lambda: not self.is_oobe_start_page(),
62                exception=error.TestFail('Not able to skip oobe screen.'),
63                timeout=DEFAULT_TIMEOUT,
64                sleep_interval=1)
65        logging.info('Skipped oobe screen.')
66
67    def is_oobe_start_page(self):
68        """Check if device is on CFM oobe start screen."""
69        if self._webview_context.EvaluateJavaScript(
70                'window.hasOwnProperty("%s") '
71                '&& typeof window.%s.skipOobe === "function"' % (
72                    TELEMETRY_API, TELEMETRY_API)):
73            logging.info('Is on oobe start page.')
74            return True
75        logging.info('Is not on oobe start page.')
76        return False
77
78    # Hangouts commands/functions
79    def start_meeting_session(self):
80        """Start a meeting.
81
82        @return code for the started meeting
83        """
84        if self.is_in_meeting_session():
85            self.end_meeting_session()
86
87        self._execute_telemetry_command('startMeeting()')
88        self.wait_for_meetings_in_call_page()
89        meeting_code = self._get_meeting_code()
90        logging.info('Started meeting session %s', meeting_code)
91        return meeting_code
92
93    def _get_meeting_code(self):
94        path = urlparse(self._webview_context.GetUrl()).path
95        # The meeting code is the last part of the path.
96        return path.split('/')[-1]
97
98    def join_meeting_session(self, meeting_name):
99        """Joins a meeting.
100
101        @param meeting_name: Name of the meeting session.
102        """
103        if self.is_in_meeting_session():
104            self.end_meeting_session()
105
106        self._execute_telemetry_command('joinMeeting("%s")' % meeting_name)
107        self.wait_for_meetings_in_call_page()
108        logging.info('Started meeting session: %s', meeting_name)
109
110    def end_meeting_session(self):
111        """End current meeting session."""
112        self._execute_telemetry_command('endCall()')
113        self.wait_for_meetings_landing_page()
114        logging.info('Ended meeting session.')
115
116    def is_in_meeting_session(self):
117        """Check if device is in meeting session."""
118        if self._evaluate_telemetry_command('isInMeeting()'):
119            logging.info('Is in meeting session.')
120            return True
121        logging.info('Is not in meeting session.')
122        return False
123
124    def start_new_hangout_session(self, hangout_name):
125        """Start a new hangout session.
126
127        @param hangout_name: Name of the hangout session.
128        """
129        raise NotImplementedError
130
131    def end_hangout_session(self):
132        """End current hangout session."""
133        raise NotImplementedError
134
135    def is_in_hangout_session(self):
136        """Check if device is in hangout session."""
137        raise NotImplementedError
138
139    def is_ready_to_start_hangout_session(self):
140        """Check if device is ready to start a new hangout session."""
141        raise NotImplementedError
142
143    def get_participant_count(self):
144        """Returns the total number of participants in a meeting."""
145        return self._evaluate_telemetry_command('getParticipantCount()')
146
147    # Diagnostics commands/functions
148    def is_diagnostic_run_in_progress(self):
149        """Check if hotrod diagnostics is running."""
150        raise NotImplementedError
151
152    def wait_for_diagnostic_run_to_complete(self):
153        """Wait for hotrod diagnostics to complete."""
154        raise NotImplementedError
155
156    def run_diagnostics(self):
157        """Run hotrod diagnostics."""
158        raise NotImplementedError
159
160    def get_last_diagnostics_results(self):
161        """Get latest hotrod diagnostics results."""
162        raise NotImplementedError
163
164    # Mic audio commands/functions
165    def is_mic_muted(self):
166        """Check if mic is muted."""
167        if self._evaluate_telemetry_command('isMicMuted()'):
168            logging.info('Mic is muted.')
169            return True
170        logging.info('Mic is not muted.')
171        return False
172
173    def mute_mic(self):
174        """Local mic mute from toolbar."""
175        self._execute_telemetry_command('setMicMuted(true)')
176        logging.info('Locally muted mic.')
177
178    def unmute_mic(self):
179        """Local mic unmute from toolbar."""
180        self._execute_telemetry_command('setMicMuted(false)')
181        logging.info('Locally unmuted mic.')
182
183    def get_mic_devices(self):
184        """Get all mic devices detected by hotrod."""
185        return self._evaluate_telemetry_command('getAudioInDevices()')
186
187    def get_preferred_mic(self):
188        """Get preferred microphone for hotrod."""
189        return self._evaluate_telemetry_command('getPreferredAudioInDevice()')
190
191    def set_preferred_mic(self, mic_name):
192        """Set preferred mic for hotrod.
193
194        @param mic_name: String with mic name.
195        """
196        self._execute_telemetry_command('setPreferredAudioInDevice(%s)'
197                                        % mic_name)
198        logging.info('Setting preferred mic to %s.', mic_name)
199
200    def remote_mute_mic(self):
201        """Remote mic mute request from cPanel."""
202        raise NotImplementedError
203
204    def remote_unmute_mic(self):
205        """Remote mic unmute request from cPanel."""
206        raise NotImplementedError
207
208    # Speaker commands/functions
209    def get_speaker_devices(self):
210        """Get all speaker devices detected by hotrod."""
211        return self._evaluate_telemetry_command('getAudioOutDevices()')
212
213    def get_preferred_speaker(self):
214        """Get speaker preferred for hotrod."""
215        return self._evaluate_telemetry_command('getPreferredAudioOutDevice()')
216
217    def set_preferred_speaker(self, speaker_name):
218        """Set preferred speaker for hotrod.
219
220        @param speaker_name: String with speaker name.
221        """
222        self._execute_telemetry_command('setPreferredAudioOutDevice(%s)'
223                                        % speaker_name)
224        logging.info('Set preferred speaker to %s.', speaker_name)
225
226    def set_speaker_volume(self, volume_level):
227        """Set speaker volume.
228
229        @param volume_level: Number value ranging from 0-100 to set volume to.
230        """
231        self._execute_telemetry_command('setAudioOutVolume(%d)' % volume_level)
232        logging.info('Set speaker volume to %d', volume_level)
233
234    def get_speaker_volume(self):
235        """Get current speaker volume."""
236        return self._evaluate_telemetry_command('getAudioOutVolume()')
237
238    def play_test_sound(self):
239        """Play test sound."""
240        raise NotImplementedError
241
242    # Camera commands/functions
243    def get_camera_devices(self):
244        """Get all camera devices detected by hotrod.
245
246        @return List of camera devices.
247        """
248        return self._evaluate_telemetry_command('getVideoInDevices()')
249
250    def get_preferred_camera(self):
251        """Get camera preferred for hotrod."""
252        return self._evaluate_telemetry_command('getPreferredVideoInDevice()')
253
254    def set_preferred_camera(self, camera_name):
255        """Set preferred camera for hotrod.
256
257        @param camera_name: String with camera name.
258        """
259        self._execute_telemetry_command('setPreferredVideoInDevice(%s)'
260                                        % camera_name)
261        logging.info('Set preferred camera to %s.', camera_name)
262
263    def is_camera_muted(self):
264        """Check if camera is muted (turned off)."""
265        if self._evaluate_telemetry_command('isCameraMuted()'):
266            logging.info('Camera is muted.')
267            return True
268        logging.info('Camera is not muted.')
269        return False
270
271    def mute_camera(self):
272        """Mute (turn off) camera."""
273        self._execute_telemetry_command('setCameraMuted(true)')
274        logging.info('Camera muted.')
275
276    def unmute_camera(self):
277        """Unmute (turn on) camera."""
278        self._execute_telemetry_command('setCameraMuted(false)')
279        logging.info('Camera unmuted.')
280
281    def move_camera(self, camera_motion):
282        """Move camera(PTZ functions).
283
284        @param camera_motion: String of the desired camera motion.
285        """
286        ptz_motions = ['panLeft','panRight','panStop',
287                       'tiltUp','tiltDown','tiltStop',
288                       'zoomIn','zoomOut','resetPosition']
289
290        if camera_motion in ptz_motions:
291            self._execute_telemetry_command('ptz.%s()' % camera_motion)
292        else:
293            raise ValueError('Unsupported PTZ camera action: "%s"'
294                             % camera_motion)
295