1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package android.host.systemui;
16 
17 import com.android.tradefed.device.DeviceNotAvailableException;
18 import com.android.tradefed.testtype.DeviceTestCase;
19 import com.android.tradefed.util.RunUtil;
20 
21 public class BaseTileServiceTest extends DeviceTestCase {
22     // Constants for generating commands below.
23     protected static final String PACKAGE = "android.systemui.cts";
24     private static final String ACTION_SHOW_DIALOG = "android.sysui.testtile.action.SHOW_DIALOG";
25     private static final String ACTION_START_ACTIVITY_WITH_PENDING_INTENT =
26             "android.sysui.testtile.action.START_ACTIVITY_WITH_PENDING_INTENT";
27     public static final String ACTION_SET_PENDING_INTENT =
28             "android.sysui.testtile.action.SET_PENDING_INTENT";
29     public static final String ACTION_SET_NULL_PENDING_INTENT =
30             "android.sysui.testtile.action.SET_NULL_PENDING_INTENT";
31 
32     // Commands used on the device.
33     private static final String ADD_TILE = "cmd statusbar add-tile ";
34     private static final String REM_TILE = "cmd statusbar remove-tile ";
35     private static final String CLICK_TILE = "cmd statusbar click-tile ";
36 
37     private static final String OPEN_NOTIFICATIONS = "cmd statusbar expand-notifications";
38     private static final String OPEN_SETTINGS = "cmd statusbar expand-settings";
39     private static final String COLLAPSE = "cmd statusbar collapse";
40 
41     private static final String SHELL_BROADCAST_COMMAND = "am broadcast -a ";
42     private static final String SHOW_DIALOG = SHELL_BROADCAST_COMMAND + ACTION_SHOW_DIALOG;
43     private static final String START_ACTIVITY_WITH_PENDING_INTENT =
44             SHELL_BROADCAST_COMMAND + ACTION_START_ACTIVITY_WITH_PENDING_INTENT;
45     private static final String SET_PENDING_INTENT =
46             SHELL_BROADCAST_COMMAND + ACTION_SET_PENDING_INTENT;
47     private static final String SET_NULL_PENDING_INTENT =
48             SHELL_BROADCAST_COMMAND + ACTION_SET_NULL_PENDING_INTENT;
49 
50     public static final String REQUEST_SUPPORTED = "cmd statusbar check-support";
51     public static final String TEST_PREFIX = "TileTest_";
52 
53     // Time between checks for logs we expect.
54     private static final long CHECK_DELAY = 500;
55     // Number of times to check before failing.
56     private static final long CHECK_RETRIES = 30;
57 
58     private final String mService;
59     private final String mComponent;
60 
BaseTileServiceTest()61     public BaseTileServiceTest() {
62         this("");
63     }
64 
BaseTileServiceTest(String service)65     public BaseTileServiceTest(String service) {
66         mService = service;
67         mComponent = PACKAGE + "/." + mService;
68     }
69 
70     @Override
setUp()71     protected void setUp() throws Exception {
72         super.setUp();
73 
74         clearLogcat();
75     }
76 
77     @Override
tearDown()78     protected void tearDown() throws Exception {
79         super.tearDown();
80 
81         if (!supported()) return;
82         collapse();
83         remTile();
84         // Try to wait for a onTileRemoved.
85         waitFor("onTileRemoved");
86     }
87 
showDialog()88     protected void showDialog() throws Exception {
89         execute(SHOW_DIALOG);
90     }
91 
startActivityWithPendingIntent()92     protected void startActivityWithPendingIntent() throws Exception {
93         execute(START_ACTIVITY_WITH_PENDING_INTENT);
94     }
95 
setActivityForLaunch()96     protected void setActivityForLaunch() throws Exception {
97         execute(SET_PENDING_INTENT);
98     }
99 
setNullPendingIntent()100     protected void setNullPendingIntent() throws Exception {
101         execute(SET_NULL_PENDING_INTENT);
102     }
103 
addTile()104     protected void addTile() throws Exception {
105         execute(ADD_TILE + mComponent);
106     }
107 
remTile()108     protected void remTile() throws Exception {
109         execute(REM_TILE + mComponent);
110     }
111 
clickTile()112     protected void clickTile() throws Exception {
113         execute(CLICK_TILE + mComponent);
114     }
115 
openNotifications()116     protected void openNotifications() throws Exception {
117         execute(OPEN_NOTIFICATIONS);
118     }
119 
openSettings()120     protected void openSettings() throws Exception {
121         execute(OPEN_SETTINGS);
122     }
123 
collapse()124     protected void collapse() throws Exception {
125         execute(COLLAPSE);
126     }
127 
execute(String cmd)128     private void execute(String cmd) throws Exception {
129         getDevice().executeShellCommand(cmd);
130         // All of the status bar commands tend to have animations associated
131         // everything seems to be happier if you give them time to finish.
132         RunUtil.getDefault().sleep(100);
133     }
134 
waitFor(String str)135     protected boolean waitFor(String str) throws DeviceNotAvailableException, InterruptedException {
136         final String searchStr = TEST_PREFIX + str;
137         int ct = 0;
138         while (!hasLog(searchStr) && (ct++ < CHECK_RETRIES)) {
139             RunUtil.getDefault().sleep(CHECK_DELAY);
140         }
141         return hasLog(searchStr);
142     }
143 
hasLog(String str)144     protected boolean hasLog(String str) throws DeviceNotAvailableException {
145         String logs = getDevice().executeAdbCommand("logcat", "-v", "brief", "-d", mService + ":I",
146                 "*:S");
147         return logs.contains(str);
148     }
149 
clearLogcat()150     protected final void clearLogcat() throws DeviceNotAvailableException {
151         getDevice().executeAdbCommand("logcat", "-c");
152     }
153 
supported()154     protected boolean supported() throws DeviceNotAvailableException {
155         return supportedHardware() && supportedSoftware();
156     }
157 
supportedSoftware()158     private boolean supportedSoftware() throws DeviceNotAvailableException {
159         String supported = getDevice().executeShellCommand(REQUEST_SUPPORTED);
160         return Boolean.parseBoolean(supported.trim());
161     }
162 
supportedHardware()163     private boolean supportedHardware() throws DeviceNotAvailableException {
164         String features = getDevice().executeShellCommand("pm list features");
165         return !features.contains("android.hardware.type.automotive")
166                 && !features.contains("android.hardware.type.television")
167                 && !features.contains("android.hardware.type.watch");
168     }
169 }
170