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.platform.helpers.ScrollUtility.ScrollActions;
21 import android.platform.helpers.ScrollUtility.ScrollDirection;
22 
23 import androidx.test.uiautomator.By;
24 import androidx.test.uiautomator.BySelector;
25 import androidx.test.uiautomator.UiObject2;
26 
27 import java.util.List;
28 
29 /**
30  * Helper for Notifications on Automotive device openNotification() for swipeDown is removed- Not
31  * supported in UDC- bug b/285387870
32  */
33 public class AutoNotificationHelperImpl extends AbstractStandardAppHelper
34         implements IAutoNotificationHelper {
35 
36     private ScrollUtility mScrollUtility;
37     private ScrollActions mScrollAction;
38     private BySelector mBackwardButtonSelector;
39     private BySelector mForwardButtonSelector;
40     private BySelector mScrollableElementSelector;
41     private ScrollDirection mScrollDirection;
42 
AutoNotificationHelperImpl(Instrumentation instr)43     public AutoNotificationHelperImpl(Instrumentation instr) {
44         super(instr);
45         mScrollUtility = ScrollUtility.getInstance(getSpectatioUiUtil());
46         mScrollAction =
47                 ScrollActions.valueOf(
48                         getActionFromConfig(
49                                 AutomotiveConfigConstants.NOTIFICATION_LIST_SCROLL_ACTION));
50         mBackwardButtonSelector =
51                 getUiElementFromConfig(
52                         AutomotiveConfigConstants.NOTIFICATION_LIST_SCROLL_BACKWARD_BUTTON);
53         mForwardButtonSelector =
54                 getUiElementFromConfig(
55                         AutomotiveConfigConstants.NOTIFICATION_LIST_SCROLL_FORWARD_BUTTON);
56         mScrollableElementSelector =
57                 getUiElementFromConfig(AutomotiveConfigConstants.NOTIFICATION_LIST);
58         mScrollDirection =
59                 ScrollDirection.valueOf(
60                         getActionFromConfig(
61                                 AutomotiveConfigConstants.NOTIFICATION_LIST_SCROLL_DIRECTION));
62     }
63 
64     /** {@inheritDoc} */
65     @Override
exit()66     public void exit() {
67         getSpectatioUiUtil().pressHome();
68         getSpectatioUiUtil().wait1Second();
69     }
70 
71     /** {@inheritDoc} */
72     @Override
getLauncherName()73     public String getLauncherName() {
74         throw new UnsupportedOperationException("Operation not supported.");
75     }
76 
77     /** {@inheritDoc} */
78     @Override
getPackage()79     public String getPackage() {
80         throw new UnsupportedOperationException("Operation not supported.");
81     }
82 
83     /** {@inheritDoc} */
84     @Override
dismissInitialDialogs()85     public void dismissInitialDialogs() {
86         // Nothing to dismiss
87     }
88     /**
89      * Setup expectation: None.
90      *
91      * <p>Open notification, do nothing if notification is already open.
92      */
93     @Override
open()94     public void open() {
95         if (!isAppInForeground()) {
96             getSpectatioUiUtil()
97                     .executeShellCommand(
98                             getCommandFromConfig(
99                                     AutomotiveConfigConstants.OPEN_NOTIFICATIONS_COMMAND));
100             getSpectatioUiUtil().wait1Second();
101         }
102     }
103 
104     /**
105      * Setup expectations: None
106      *
107      * <p>Check if notification app is in foreground by checking if the notification list exists.
108      */
109     @Override
isAppInForeground()110     public boolean isAppInForeground() {
111         BySelector notificationViewSelector =
112                 getUiElementFromConfig(AutomotiveConfigConstants.NOTIFICATION_VIEW);
113         return getSpectatioUiUtil().hasUiElement(notificationViewSelector);
114     }
115 
116     /** {@inheritDoc} */
117     @Override
tapClearAllBtn()118     public void tapClearAllBtn() {
119         open();
120         getSpectatioUiUtil().wait5Seconds();
121         UiObject2 empty_notification =
122                 getSpectatioUiUtil()
123                         .findUiObject(
124                                 getUiElementFromConfig(
125                                         AutomotiveConfigConstants.NOTIFICATION_LIST_EMPTY));
126         if (empty_notification == null) {
127             BySelector clearButtonSelector =
128                     getUiElementFromConfig(AutomotiveConfigConstants.CLEAR_ALL_BUTTON);
129             if (checkIfClearAllButtonExist(clearButtonSelector)) {
130                 UiObject2 clear_all_btn = getSpectatioUiUtil().findUiObject(clearButtonSelector);
131                 getSpectatioUiUtil().clickAndWait(clear_all_btn);
132             } else {
133                 throw new RuntimeException("Cannot find Clear All button");
134             }
135         }
136 
137     }
138 
139     /** {@inheritDoc} */
140     @Override
clickManageBtn()141     public void clickManageBtn() {
142         open();
143         getSpectatioUiUtil().wait5Seconds();
144         UiObject2 empty_notification =
145                 getSpectatioUiUtil()
146                         .findUiObject(
147                                 getUiElementFromConfig(
148                                         AutomotiveConfigConstants.NOTIFICATION_LIST_EMPTY));
149         if (empty_notification == null) {
150             BySelector manageButtonSelector =
151                     getUiElementFromConfig(AutomotiveConfigConstants.MANAGE_BUTTON);
152             if (checkIfManageButtonExist(manageButtonSelector)) {
153                 UiObject2 manage_btn = getSpectatioUiUtil().findUiObject(manageButtonSelector);
154                 getSpectatioUiUtil().clickAndWait(manage_btn);
155             } else {
156                 throw new RuntimeException("Cannot find Manage button");
157             }
158         }
159     }
160 
161     /** {@inheritDoc} */
162     @Override
checkNotificationExists(String title)163     public boolean checkNotificationExists(String title) {
164         open();
165         BySelector selector = By.text(title);
166         UiObject2 postedNotification = findInNotificationList(selector);
167         return postedNotification != null;
168     }
169 
170     @Override
checkAppPermissionsExists(String title)171     public boolean checkAppPermissionsExists(String title) {
172         return getSpectatioUiUtil().hasUiElement(title);
173     }
174 
175     @Override
clickOnCheckRecentPermissions(String title)176     public void clickOnCheckRecentPermissions(String title) {
177         BySelector notificationSelector = By.text(title);
178         UiObject2 notification = getSpectatioUiUtil().findUiObject(notificationSelector);
179         getSpectatioUiUtil().clickAndWait(notification);
180     }
181 
182     /** {@inheritDoc} */
183     @Override
removeNotification(String title)184     public void removeNotification(String title) {
185         getSpectatioUiUtil().wait5Seconds();
186         open();
187         UiObject2 postedNotification = getSpectatioUiUtil().findUiObject(By.text(title));
188         getSpectatioUiUtil()
189                 .validateUiObject(
190                         postedNotification,
191                         String.format("Unable to get the posted notification."));
192         getSpectatioUiUtil().swipeLeft(postedNotification);
193         getSpectatioUiUtil().wait5Seconds();
194     }
195 
checkIfClearAllButtonExist(BySelector selector)196     private boolean checkIfClearAllButtonExist(BySelector selector) {
197         open();
198         UiObject2 clr_btn = findInNotificationList(selector);
199         return clr_btn != null;
200     }
201 
checkIfManageButtonExist(BySelector selector)202     private boolean checkIfManageButtonExist(BySelector selector) {
203         open();
204         UiObject2 manage_btn = findInNotificationList(selector);
205         return manage_btn != null;
206     }
207 
208     /** {@inheritDoc} */
209     @Override
isNotificationSettingsOpened()210     public boolean isNotificationSettingsOpened() {
211         BySelector notificationLayoutSelector =
212                 getUiElementFromConfig(AutomotiveConfigConstants.NOTIFICATION_SETTINGS_LAYOUT);
213         List<UiObject2> notificationLayoutList =
214                 getSpectatioUiUtil().findUiObjects(notificationLayoutSelector);
215         getSpectatioUiUtil()
216                 .validateUiObjects(
217                         notificationLayoutList,
218                         AutomotiveConfigConstants.NOTIFICATION_SETTINGS_LAYOUT);
219 
220         BySelector notificationSettingsSelector =
221                 getUiElementFromConfig(AutomotiveConfigConstants.NOTIFICATION_SETTINGS_TITLE);
222         UiObject2 notificationPageObj = null;
223         for (int i = 0; i < notificationLayoutList.size(); i++) {
224             notificationPageObj =
225                     getSpectatioUiUtil()
226                             .findUiObjectInGivenElement(
227                                     notificationLayoutList.get(i), notificationSettingsSelector);
228             if (notificationPageObj != null) {
229                 break;
230             }
231         }
232 
233         getSpectatioUiUtil()
234                 .validateUiObject(notificationPageObj, String.format("notification page"));
235         return notificationPageObj != null;
236     }
237 
238     @Override
scrollDownOnePage()239     public boolean scrollDownOnePage() {
240         UiObject2 notification_list = getSpectatioUiUtil().findUiObject(mScrollableElementSelector);
241         boolean swipeResult = false;
242         if (notification_list != null && notification_list.isScrollable()) {
243             swipeResult =
244                     mScrollUtility.scrollForward(
245                             mScrollAction,
246                             mScrollDirection,
247                             mForwardButtonSelector,
248                             mScrollableElementSelector,
249                             String.format("Scroll down one page on notification list"));
250         }
251         return swipeResult;
252     }
253 
254     @Override
scrollUpOnePage()255     public boolean scrollUpOnePage() {
256         UiObject2 notification_list = getSpectatioUiUtil().findUiObject(mScrollableElementSelector);
257         boolean swipeResult = false;
258         if (notification_list != null && notification_list.isScrollable()) {
259             swipeResult =
260                     mScrollUtility.scrollBackward(
261                             mScrollAction,
262                             mScrollDirection,
263                             mBackwardButtonSelector,
264                             mScrollableElementSelector,
265                             String.format("Scroll up one page on notification list"));
266         }
267         return swipeResult;
268     }
269 
findInNotificationList(BySelector selector)270     private UiObject2 findInNotificationList(BySelector selector) {
271         UiObject2 notification_list = getSpectatioUiUtil().findUiObject(mScrollableElementSelector);
272         UiObject2 object = null;
273         if (isAppInForeground() && notification_list != null) {
274             object = getSpectatioUiUtil().findUiObject(selector);
275             if (object != null) return object;
276             if (notification_list.isScrollable()) {
277                 object =
278                         mScrollUtility.scrollAndFindUiObject(
279                                 mScrollAction,
280                                 mScrollDirection,
281                                 mForwardButtonSelector,
282                                 mBackwardButtonSelector,
283                                 mScrollableElementSelector,
284                                 selector,
285                                 String.format("Scroll on notification list to find %s", selector));
286             }
287         }
288         return object;
289     }
290 
291     @Override
isRecentNotification()292     public boolean isRecentNotification() {
293         BySelector recentNotificationsPanel =
294                 getUiElementFromConfig(AutomotiveConfigConstants.RECENT_NOTIFICATIONS);
295         UiObject2 recentNotificationLayOut =
296                 getSpectatioUiUtil().findUiObject(recentNotificationsPanel);
297         getSpectatioUiUtil()
298                 .validateUiObject(
299                         recentNotificationLayOut, AutomotiveConfigConstants.RECENT_NOTIFICATIONS);
300         BySelector testNotification =
301                 getUiElementFromConfig(AutomotiveConfigConstants.TEST_NOTIFICATION);
302         UiObject2 testNotificationLayout =
303                 getSpectatioUiUtil()
304                         .findUiObjectInGivenElement(recentNotificationLayOut, testNotification);
305         return testNotificationLayout != null;
306     }
307 
308     @Override
isOlderNotification()309     public boolean isOlderNotification() {
310         BySelector olderNotificationsPanel =
311                 getUiElementFromConfig(AutomotiveConfigConstants.OLDER_NOTIFICATIONS);
312         UiObject2 olderNotificationLayOut =
313                 getSpectatioUiUtil().findUiObject(olderNotificationsPanel);
314         getSpectatioUiUtil()
315                 .validateUiObject(
316                         olderNotificationLayOut, AutomotiveConfigConstants.OLDER_NOTIFICATIONS);
317         BySelector testNotification =
318                 getUiElementFromConfig(AutomotiveConfigConstants.TEST_NOTIFICATION);
319         UiObject2 testNotificationLayout =
320                 getSpectatioUiUtil()
321                         .findUiObjectInGivenElement(olderNotificationLayOut, testNotification);
322         return testNotificationLayout != null;
323     }
324 
325 }
326