1#!/usr/bin/env python3 2# 3# Copyright 2016 - Google 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17# Utilities that can be used for testing media related usecases. 18 19# Events dispatched from the RPC Server 20EVENT_PLAY_RECEIVED = "playReceived" 21EVENT_PAUSE_RECEIVED = "pauseReceived" 22EVENT_SKIP_NEXT_RECEIVED = "skipNextReceived" 23EVENT_SKIP_PREV_RECEIVED = "skipPrevReceived" 24 25# Passthrough Commands sent to the RPC Server 26CMD_MEDIA_PLAY = "play" 27CMD_MEDIA_PAUSE = "pause" 28CMD_MEDIA_SKIP_NEXT = "skipNext" 29CMD_MEDIA_SKIP_PREV = "skipPrev" 30 31# MediaMetaData keys. Keep them the same as in BluetoothMediaFacade. 32MEDIA_KEY_TITLE = "keyTitle" 33MEDIA_KEY_ALBUM = "keyAlbum" 34MEDIA_KEY_ARTIST = "keyArtist" 35MEDIA_KEY_DURATION = "keyDuration" 36MEDIA_KEY_NUM_TRACKS = "keyNumTracks" 37 38class PlaybackState: 39 PAUSE = 2 40 PLAY = 3 41 42def verifyEventReceived(log, device, event, timeout): 43 """ 44 Verify if the event was received from the given device. 45 When a fromDevice talks to a toDevice and expects an event back, 46 this util function can be used to see if the toDevice posted it. 47 Args: 48 log: The logging object 49 device: The device to pop the event from 50 event: The event we are interested in. 51 timeout: The time in seconds before we timeout 52 Returns: 53 True if the event was received 54 False if we timed out waiting for the event 55 """ 56 try: 57 device.ed.pop_event(event, timeout) 58 except Exception: 59 log.info(" {} Event Not received".format(event)) 60 return False 61 log.info("Event Received : {}".format(event)) 62 return True 63 64 65def send_media_passthrough_cmd(log, 66 fromDevice, 67 toDevice, 68 cmd, 69 expctEvent, 70 timeout=1.0): 71 """ 72 Send a media passthrough command from one device to another 73 via bluetooth. 74 Args: 75 log: The logging object 76 fromDevice: The device to send the command from 77 toDevice: The device the command is sent to 78 cmd: The passthrough command to send 79 expctEvent: The expected event 80 timeout: The time in seconds before we timeout, deafult = 1sec 81 Returns: 82 True if the event was received 83 False if we timed out waiting for the event 84 """ 85 log.info("Sending passthru : {}".format(cmd)) 86 fromDevice.droid.bluetoothMediaPassthrough(cmd) 87 return verifyEventReceived(log, toDevice, expctEvent, timeout) 88 89 90def log_metadata(log, metadata): 91 """ 92 Log the Metadata to the console. 93 Args: 94 log: The logging object 95 metadata: Dictionary of the song's metadata 96 """ 97 title = metadata[MEDIA_KEY_TITLE] 98 album = metadata[MEDIA_KEY_ALBUM] 99 artist = metadata[MEDIA_KEY_ARTIST] 100 duration = metadata[MEDIA_KEY_DURATION] 101 numTracks = metadata[MEDIA_KEY_NUM_TRACKS] 102 log.info("Playing Artist: {}, Album: {}, Title: {}".format(artist, album, 103 title)) 104 log.info("Duration: {}, NumTracks: {}".format(duration, numTracks)) 105 106 107def compare_metadata(log, metadata1, metadata2): 108 """ 109 Compares the Metadata between the two devices 110 Args: 111 log: The logging object 112 metadata1 Media Metadata of device1 113 metadata2 Media Metadata of device2 114 Returns: 115 True if the Metadata matches 116 False if the Metadata do not match 117 """ 118 log.info("Device1 metadata:") 119 log_metadata(log, metadata1) 120 log.info("Device2 metadata:") 121 log_metadata(log, metadata2) 122 123 if not (metadata1[MEDIA_KEY_TITLE] == metadata2[MEDIA_KEY_TITLE]): 124 log.info("Song Titles do not match") 125 return False 126 127 if not (metadata1[MEDIA_KEY_ALBUM] == metadata2[MEDIA_KEY_ALBUM]): 128 log.info("Song Albums do not match") 129 return False 130 131 if not (metadata1[MEDIA_KEY_ARTIST] == metadata2[MEDIA_KEY_ARTIST]): 132 log.info("Song Artists do not match") 133 return False 134 135 if not (metadata1[MEDIA_KEY_DURATION] == metadata2[MEDIA_KEY_DURATION]): 136 log.info("Song Duration do not match") 137 return False 138 139 if not (metadata1[MEDIA_KEY_NUM_TRACKS] == metadata2[MEDIA_KEY_NUM_TRACKS] 140 ): 141 log.info("Song Num Tracks do not match") 142 return False 143 144 return True 145 146 147def check_metadata(log, device1, device2): 148 """ 149 Gets the now playing metadata from 2 devices and checks if they are the same 150 Args: 151 log: The logging object 152 device1 Device 1 153 device2 Device 2 154 Returns: 155 True if the Metadata matches 156 False if the Metadata do not match 157 """ 158 metadata1 = device1.droid.bluetoothMediaGetCurrentMediaMetaData() 159 if metadata1 is None: 160 return False 161 162 metadata2 = device2.droid.bluetoothMediaGetCurrentMediaMetaData() 163 if metadata2 is None: 164 return False 165 return compare_metadata(log, metadata1, metadata2) 166 167 168def isMediaSessionActive(log, device, mediaSession): 169 """ 170 Checks if the passed mediaSession is active. 171 Used to see if the device is playing music. 172 Args: 173 log: The logging object 174 device Device to check 175 mediaSession MediaSession to check if it is active 176 Returns: 177 True if the given mediaSession is active 178 False if the given mediaSession is not active 179 """ 180 # Get a list of MediaSession tags (String) that is currently active 181 activeSessions = device.droid.bluetoothMediaGetActiveMediaSessions() 182 if len(activeSessions) > 0: 183 for session in activeSessions: 184 log.info(session) 185 if (session == mediaSession): 186 return True 187 log.info("No Media Sessions") 188 return False 189