• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.platform.helpers;
18 
19 import android.app.Instrumentation;
20 import android.app.UiAutomation;
21 import android.content.Context;
22 import android.media.session.MediaController;
23 import android.media.session.MediaSessionManager;
24 import android.media.session.PlaybackState;
25 import android.os.SystemClock;
26 import android.platform.helpers.exceptions.UnknownUiException;
27 import android.support.test.uiautomator.By;
28 import android.support.test.uiautomator.Direction;
29 import android.support.test.uiautomator.UiObject2;
30 import android.support.test.uiautomator.UiObject;
31 import android.support.test.uiautomator.UiObjectNotFoundException;
32 import android.support.test.uiautomator.UiScrollable;
33 import android.support.test.uiautomator.UiSelector;
34 
35 import java.util.List;
36 
37 public class MediaCenterHelperImpl extends AbstractAutoStandardAppHelper
38         implements IAutoMediaHelper {
39     // Wait Time
40     private static final int UI_RESPONSE_WAIT_MS = 5000;
41     private static final int SHORT_RESPONSE_WAIT_MS = 1000;
42 
43     private static final String MEDIA_LAUNCH_COMMAND =
44             "am start -a android.car.intent.action.MEDIA_TEMPLATE -e "
45                     + "android.car.intent.extra.MEDIA_COMPONENT ";
46 
47     private MediaSessionManager mMediaSessionManager;
48     private UiAutomation mUiAutomation;
49 
MediaCenterHelperImpl(Instrumentation instr)50     public MediaCenterHelperImpl(Instrumentation instr) {
51         super(instr);
52         mUiAutomation = instr.getUiAutomation();
53         mUiAutomation.adoptShellPermissionIdentity("android.permission.MEDIA_CONTENT_CONTROL");
54         mMediaSessionManager =
55                 (MediaSessionManager)
56                         instr.getContext().getSystemService(Context.MEDIA_SESSION_SERVICE);
57     }
58 
59     /** {@inheritDoc} */
60     @Override
getPackage()61     public String getPackage() {
62         return getApplicationConfig(AutoConfigConstants.MEDIA_CENTER_PACKAGE);
63     }
64 
65     /** {@inheritDoc} */
open()66     public void open() {
67         openMediaApp(getApplicationConfig(AutoConfigConstants.MEDIA_ACTIVITY));
68     }
69 
openMediaApp(String packagename)70     private void openMediaApp(String packagename) {
71         pressHome();
72         waitForIdle();
73         executeShellCommand(MEDIA_LAUNCH_COMMAND + packagename);
74     }
75 
76     /** {@inheritDoc} */
playMedia()77     public void playMedia() {
78         if (!isPlaying()) {
79             UiObject2 playButton =
80                     findUiObject(
81                             getResourceFromConfig(
82                                     AutoConfigConstants.MEDIA_CENTER,
83                                     AutoConfigConstants.MEDIA_CENTER_SCREEN,
84                                     AutoConfigConstants.PLAY_PAUSE_BUTTON));
85             if (playButton == null) {
86                 throw new UnknownUiException("Unable to find play/pause button");
87             }
88             clickAndWaitForIdleScreen(playButton);
89             SystemClock.sleep(UI_RESPONSE_WAIT_MS);
90         }
91     }
92 
93     /** {@inheritDoc} */
playPauseMediaFromHomeScreen()94     public void playPauseMediaFromHomeScreen() {
95         UiObject2 playButton =
96                 findUiObject(
97                         getResourceFromConfig(
98                                 AutoConfigConstants.MEDIA_CENTER,
99                                 AutoConfigConstants.MEDIA_CENTER_ON_HOME_SCREEN,
100                                 AutoConfigConstants.PLAY_PAUSE_BUTTON));
101         if (playButton == null) {
102             throw new UnknownUiException("Unable to find play button from home screen");
103         }
104         clickAndWaitForIdleScreen(playButton);
105         SystemClock.sleep(UI_RESPONSE_WAIT_MS);
106     }
107 
108     /** {@inheritDoc} */
pauseMedia()109     public void pauseMedia() {
110         if (isPlaying()) {
111             UiObject2 pauseButton =
112                     findUiObject(
113                             getResourceFromConfig(
114                                     AutoConfigConstants.MEDIA_CENTER,
115                                     AutoConfigConstants.MEDIA_CENTER_SCREEN,
116                                     AutoConfigConstants.PLAY_PAUSE_BUTTON));
117             if (pauseButton == null) {
118                 throw new UnknownUiException("Unable to find pause button");
119             }
120             clickAndWaitForIdleScreen(pauseButton);
121             SystemClock.sleep(UI_RESPONSE_WAIT_MS);
122         }
123     }
124 
125     /** {@inheritDoc} */
clickNextTrack()126     public void clickNextTrack() {
127         UiObject2 nextTrackButton =
128                 findUiObject(
129                         getResourceFromConfig(
130                                 AutoConfigConstants.MEDIA_CENTER,
131                                 AutoConfigConstants.MEDIA_CENTER_SCREEN,
132                                 AutoConfigConstants.NEXT_BUTTON));
133         if (nextTrackButton == null) {
134             throw new UnknownUiException("Unable to find next track button");
135         }
136         clickAndWaitForIdleScreen(nextTrackButton);
137         SystemClock.sleep(UI_RESPONSE_WAIT_MS);
138     }
139 
140     /** {@inheritDoc} */
clickNextTrackFromHomeScreen()141     public void clickNextTrackFromHomeScreen() {
142         UiObject2 nextTrackButton =
143                 findUiObject(
144                         getResourceFromConfig(
145                                 AutoConfigConstants.MEDIA_CENTER,
146                                 AutoConfigConstants.MEDIA_CENTER_ON_HOME_SCREEN,
147                                 AutoConfigConstants.NEXT_BUTTON));
148         if (nextTrackButton == null) {
149             throw new UnknownUiException("Unable to find next track button from home screen");
150         }
151         clickAndWaitForIdleScreen(nextTrackButton);
152         SystemClock.sleep(UI_RESPONSE_WAIT_MS);
153     }
154 
155     /** {@inheritDoc} */
clickPreviousTrack()156     public void clickPreviousTrack() {
157         UiObject2 previousTrackButton =
158                 findUiObject(
159                         getResourceFromConfig(
160                                 AutoConfigConstants.MEDIA_CENTER,
161                                 AutoConfigConstants.MEDIA_CENTER_SCREEN,
162                                 AutoConfigConstants.PREVIOUS_BUTTON));
163         if (previousTrackButton == null) {
164             throw new UnknownUiException("Unable to find previous track button");
165         }
166         clickAndWaitForIdleScreen(previousTrackButton);
167         SystemClock.sleep(UI_RESPONSE_WAIT_MS);
168     }
169 
170     /** {@inheritDoc} */
clickPreviousTrackFromHomeScreen()171     public void clickPreviousTrackFromHomeScreen() {
172         UiObject2 previousTrackButton =
173                 findUiObject(
174                         getResourceFromConfig(
175                                 AutoConfigConstants.MEDIA_CENTER,
176                                 AutoConfigConstants.MEDIA_CENTER_ON_HOME_SCREEN,
177                                 AutoConfigConstants.PREVIOUS_BUTTON));
178         if (previousTrackButton == null) {
179             throw new UnknownUiException("Unable to find previous track button");
180         }
181         clickAndWaitForIdleScreen(previousTrackButton);
182         SystemClock.sleep(UI_RESPONSE_WAIT_MS);
183     }
184 
185     /** {@inheritDoc} */
clickShuffleAll()186     public void clickShuffleAll() {
187         UiObject2 shufflePlaylistButton =
188                 findUiObject(
189                         getResourceFromConfig(
190                                 AutoConfigConstants.MEDIA_CENTER,
191                                 AutoConfigConstants.MEDIA_CENTER_SCREEN,
192                                 AutoConfigConstants.SHUFFLE_BUTTON));
193         if (shufflePlaylistButton == null) {
194             throw new UnknownUiException("Unable to find shuffle playlist button");
195         }
196         clickAndWaitForIdleScreen(shufflePlaylistButton);
197     }
198 
199     /** Click the nth instance among the visible menu items */
clickMenuItem(int instance)200     public void clickMenuItem(int instance) {
201         if (!mDevice.hasObject(By.scrollable(true))) {
202             // Menu is not open
203             return;
204         }
205         UiScrollable menuList = new UiScrollable(new UiSelector().scrollable(true));
206         menuList.setAsVerticalList();
207         try {
208             UiObject menuListItem =
209                     menuList.getChildByInstance(new UiSelector().clickable(true), instance);
210             menuListItem.clickAndWaitForNewWindow(UI_RESPONSE_WAIT_MS);
211             waitForIdle();
212         } catch (UiObjectNotFoundException e) {
213             throw new UnknownUiException("Unable to find menu item", e);
214         }
215     }
216 
217     /** {@inheritDoc} */
openMenuWith(String... menuOptions)218     public void openMenuWith(String... menuOptions) {
219         for (String menu : menuOptions) {
220             UiObject2 menuButton = findUiObject(By.text(menu));
221             if (menuButton != null) {
222                 clickAndWaitForIdleScreen(menuButton);
223                 waitForGone(By.text(menu));
224             } else {
225                 try {
226                     UiObject menuItem_object = selectByName(menu);
227                     menuItem_object.clickAndWaitForNewWindow();
228                 } catch (UiObjectNotFoundException exception) {
229                     throw new UnknownUiException("Unable to find the menu item");
230                 }
231             }
232             SystemClock.sleep(SHORT_RESPONSE_WAIT_MS);
233         }
234     }
235 
236     /** {@inheritDoc} */
openNowPlayingWith(String trackName)237     public void openNowPlayingWith(String trackName) {
238         UiObject2 nowPlayingButton =
239                 findUiObject(
240                         getResourceFromConfig(
241                                 AutoConfigConstants.MEDIA_CENTER,
242                                 AutoConfigConstants.MEDIA_CENTER_SCREEN,
243                                 AutoConfigConstants.PLAY_QUEUE_BUTTON));
244         if (nowPlayingButton == null) {
245             throw new UnknownUiException("Unable to find Now playing button");
246         }
247         clickAndWaitForIdleScreen(nowPlayingButton);
248         waitForWindowUpdate(getApplicationConfig(AutoConfigConstants.MEDIA_CENTER_PACKAGE));
249         UiObject2 playTrackName = findUiObject(By.text(trackName));
250         if (playTrackName != null) {
251             clickAndWaitForIdleScreen(playTrackName);
252         } else {
253             try {
254                 UiObject menuItem_object = selectByName(trackName);
255                 menuItem_object.clickAndWaitForNewWindow();
256             } catch (UiObjectNotFoundException exception) {
257                 throw new UnknownUiException("Unable to find the trackname from Now playing list");
258             }
259         }
260     }
261 
262     /** {@inheritDoc} */
getMediaTrackName()263     public String getMediaTrackName() {
264         String track;
265         UiObject2 mediaControl =
266                 findUiObject(
267                         getResourceFromConfig(
268                                 AutoConfigConstants.MEDIA_CENTER,
269                                 AutoConfigConstants.MEDIA_CENTER_SCREEN,
270                                 AutoConfigConstants.MINIMIZED_MEDIA_CONTROLS));
271         if (mediaControl != null) {
272             track = getMediaTrackNameFromMinimizedControl();
273         } else {
274             track = getMediaTrackNameFromPlayback();
275         }
276         return track;
277     }
278 
279     /** {@inheritDoc} */
getMediaTrackNameFromHomeScreen()280     public String getMediaTrackNameFromHomeScreen() {
281         String trackName;
282         UiObject2 trackNameText =
283                 findUiObject(
284                         getResourceFromConfig(
285                                 AutoConfigConstants.MEDIA_CENTER,
286                                 AutoConfigConstants.MEDIA_CENTER_ON_HOME_SCREEN,
287                                 AutoConfigConstants.TRACK_NAME));
288         if (trackNameText == null) {
289             throw new UnknownUiException("Unable to find track name from Home Screen");
290         }
291         trackName = trackNameText.getText();
292         return trackName;
293     }
294 
getMediaTrackNameFromMinimizedControl()295     private String getMediaTrackNameFromMinimizedControl() {
296         String trackName;
297         UiObject2 trackNameText =
298                 findUiObject(
299                         getResourceFromConfig(
300                                 AutoConfigConstants.MEDIA_CENTER,
301                                 AutoConfigConstants.MEDIA_CENTER_SCREEN,
302                                 AutoConfigConstants.TRACK_NAME_MINIMIZED_CONTROL));
303         if (trackNameText == null) {
304             throw new UnknownUiException("Unable to find track name from minimized control");
305         }
306         trackName = trackNameText.getText();
307         return trackName;
308     }
309 
getMediaTrackNameFromPlayback()310     private String getMediaTrackNameFromPlayback() {
311         String trackName;
312         waitForIdle();
313         UiObject2 trackNameText =
314                 findUiObject(
315                         getResourceFromConfig(
316                                 AutoConfigConstants.MEDIA_CENTER,
317                                 AutoConfigConstants.MEDIA_CENTER_SCREEN,
318                                 AutoConfigConstants.TRACK_NAME));
319         if (trackNameText == null) {
320             throw new UnknownUiException("Unable to find track name from now playing");
321         }
322         trackName = trackNameText.getText();
323         return trackName;
324     }
325 
326     /** {@inheritDoc} */
goBackToMediaHomePage()327     public void goBackToMediaHomePage() {
328         minimizeNowPlaying();
329         UiObject2 back_btn =
330                 findUiObject(
331                         getResourceFromConfig(
332                                 AutoConfigConstants.MEDIA_CENTER,
333                                 AutoConfigConstants.MEDIA_CENTER_SCREEN,
334                                 AutoConfigConstants.BACK_BUTTON));
335         while (back_btn != null) {
336             clickAndWaitForIdleScreen(back_btn);
337             back_btn =
338                     findUiObject(
339                             getResourceFromConfig(
340                                     AutoConfigConstants.MEDIA_CENTER,
341                                     AutoConfigConstants.MEDIA_CENTER_SCREEN,
342                                     AutoConfigConstants.BACK_BUTTON));
343         }
344     }
345 
346     /** Minimize the Now Playing window. */
minimizeNowPlaying()347     private void minimizeNowPlaying() {
348         UiObject2 trackNameText =
349                 findUiObject(
350                         getResourceFromConfig(
351                                 AutoConfigConstants.MEDIA_CENTER,
352                                 AutoConfigConstants.MEDIA_CENTER_SCREEN,
353                                 AutoConfigConstants.TRACK_NAME));
354         if (trackNameText != null) {
355             trackNameText.swipe(Direction.DOWN, 1.0f, 500);
356         }
357     }
358 
359     /**
360      * Scrolls through the list in search of the provided menu
361      *
362      * @param menu : menu to search
363      * @return UiObject found for the menu searched
364      */
selectByName(String menu)365     private UiObject selectByName(String menu) throws UiObjectNotFoundException {
366         UiObject menuListItem = null;
367         UiScrollable menuList = new UiScrollable(new UiSelector().scrollable(true));
368         menuList.setAsVerticalList();
369         menuListItem =
370                 menuList.getChildByText(
371                         new UiSelector().className(android.widget.TextView.class.getName()), menu);
372         mDevice.waitForIdle();
373         return menuListItem;
374     }
375 
376     /** {@inheritDoc} */
377     @Override
isPlaying()378     public boolean isPlaying() {
379         List<MediaController> controllers = mMediaSessionManager.getActiveSessions(null);
380         if (controllers.size() == 0) {
381             throw new RuntimeException("Unable to find Media Controller");
382         }
383         PlaybackState state = controllers.get(0).getPlaybackState();
384         return state.getState() == PlaybackState.STATE_PLAYING;
385     }
386 }
387