1 /* 2 * Copyright (C) 2019 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 package android.support.test.launcherhelper; 17 18 import android.app.Instrumentation; 19 import android.support.test.uiautomator.By; 20 import android.support.test.uiautomator.BySelector; 21 import android.support.test.uiautomator.Direction; 22 import android.support.test.uiautomator.UiDevice; 23 import android.support.test.uiautomator.UiObject2; 24 import android.support.test.uiautomator.Until; 25 import android.system.helpers.CommandsHelper; 26 27 import junit.framework.Assert; 28 29 public class AutoLauncherStrategy implements IAutoLauncherStrategy { 30 31 private static final String LOG_TAG = AutoLauncherStrategy.class.getSimpleName(); 32 private static final String CAR_LENSPICKER = "com.android.car.carlauncher"; 33 private static final String OPEN_APP_GRID_COMMAND = 34 "am start -n com.android.car.carlauncher/.AppGridActivity"; 35 36 private static final long APP_INIT_WAIT = 10000; 37 private static final int UI_WAIT_TIME = 5000; 38 private static final int OPEN_FACET_RETRY_TIME = 5; 39 40 //todo: Remove x and y axis and use resource ID's. 41 private static final int FACET_APPS = 560; 42 private static final int MAP_FACET = 250; 43 44 private static final BySelector UP_BTN = By.res(CAR_LENSPICKER, "page_up"); 45 private static final BySelector DOWN_BTN = By.res(CAR_LENSPICKER, "page_down"); 46 47 protected UiDevice mDevice; 48 private Instrumentation mInstrumentation; 49 50 @Override getSupportedLauncherPackage()51 public String getSupportedLauncherPackage() { 52 return CAR_LENSPICKER; 53 } 54 55 @Override setUiDevice(UiDevice uiDevice)56 public void setUiDevice(UiDevice uiDevice) { 57 mDevice = uiDevice; 58 } 59 60 @Override setInstrumentation(Instrumentation instrumentation)61 public void setInstrumentation(Instrumentation instrumentation) { 62 mInstrumentation = instrumentation; 63 } 64 65 @Override open()66 public void open() { 67 68 } 69 70 @Override openDialFacet()71 public void openDialFacet() { 72 throw new UnsupportedOperationException( 73 "The feature not supported on Auto"); 74 } 75 76 @Override openMediaFacet(String appName)77 public void openMediaFacet(String appName) { 78 BySelector button = By.clickable(true).hasDescendant(By.text(appName)); 79 for (int tries = 3; tries >= 0; tries--) { 80 // TODO: Switch this to intents. It doesn't appear to work via intents on my system. 81 CommandsHelper.getInstance(mInstrumentation).executeShellCommand( 82 "am start -n com.android.support.car.lenspicker/.LensPickerActivity" 83 + " --esa categories android.intent.category.APP_MUSIC"); 84 mDevice.wait(Until.findObject(button), APP_INIT_WAIT); 85 if (mDevice.hasObject(button)) { 86 break; 87 } 88 } 89 UiObject2 choice = mDevice.findObject(button); 90 Assert.assertNotNull("Unable to find application " + appName, choice); 91 choice.click(); 92 mDevice.wait(Until.gone(button), APP_INIT_WAIT); 93 Assert.assertFalse("Failed to exit media menu.", mDevice.hasObject(button)); 94 mDevice.waitForIdle(APP_INIT_WAIT); 95 } 96 97 @Override openSettingsFacet(String appName)98 public void openSettingsFacet(String appName) { 99 throw new UnsupportedOperationException( 100 "The feature not supported on Auto"); 101 } 102 103 @Override openMapsFacet(String appName)104 public void openMapsFacet(String appName) { 105 CommandsHelper.getInstance(mInstrumentation).executeShellCommand( 106 "input tap " + MAP_FACET + " " + FACET_APPS); 107 } 108 109 @Override openHomeFacet()110 public void openHomeFacet() { 111 UiDevice.getInstance(mInstrumentation).pressHome(); 112 } 113 114 @Override openAssistantFacet()115 public void openAssistantFacet() { 116 CommandsHelper.getInstance(mInstrumentation).executeShellCommand( 117 "am start -n com.google.android.googlequicksearchbox/" 118 + "com.google.android.apps.gsa.binaries.auto.app.voiceplate" 119 + ".VoicePlateActivity"); 120 } 121 122 @Override checkApplicationExists(String appName)123 public boolean checkApplicationExists(String appName) { 124 CommandsHelper.getInstance(mInstrumentation).executeShellCommand( 125 OPEN_APP_GRID_COMMAND); 126 UiObject2 up = mDevice.wait(Until.findObject(UP_BTN), APP_INIT_WAIT); 127 UiObject2 down = mDevice.wait(Until.findObject(DOWN_BTN), APP_INIT_WAIT); 128 while (up.isEnabled()) { 129 up.click(); 130 up = mDevice.wait(Until.findObject(UP_BTN), UI_WAIT_TIME); 131 } 132 UiObject2 object = mDevice.wait(Until.findObject(By.text(appName)), UI_WAIT_TIME); 133 while (down.isEnabled() && object == null) { 134 down.click(); 135 object = mDevice.wait( 136 Until.findObject(By.text(appName)), UI_WAIT_TIME); 137 down = mDevice.wait(Until.findObject(DOWN_BTN), UI_WAIT_TIME); 138 } 139 return object != null; 140 } 141 142 @Override openApp(String appName)143 public void openApp(String appName) { 144 if (checkApplicationExists(appName)) { 145 UiObject2 app = mDevice.wait( 146 Until.findObject(By.text(appName)), APP_INIT_WAIT); 147 app.click(); 148 mDevice.waitForIdle(); 149 } else { 150 throw new RuntimeException(String.format("Application %s not found", appName)); 151 } 152 } 153 154 @SuppressWarnings("unused") 155 @Override openAllApps(boolean reset)156 public UiObject2 openAllApps(boolean reset) { 157 throw new UnsupportedOperationException( 158 "The feature not supported on Auto"); 159 } 160 161 @SuppressWarnings("unused") 162 @Override getAllAppsButtonSelector()163 public BySelector getAllAppsButtonSelector() { 164 throw new UnsupportedOperationException( 165 "The feature not supported on Auto"); 166 } 167 168 @SuppressWarnings("unused") 169 @Override getAllAppsSelector()170 public BySelector getAllAppsSelector() { 171 throw new UnsupportedOperationException( 172 "The feature not supported on Auto"); 173 } 174 175 @SuppressWarnings("unused") 176 @Override getAllAppsScrollDirection()177 public Direction getAllAppsScrollDirection() { 178 throw new UnsupportedOperationException( 179 "The feature not supported on Auto"); 180 } 181 182 @SuppressWarnings("unused") 183 @Override openAllWidgets(boolean reset)184 public UiObject2 openAllWidgets(boolean reset) { 185 throw new UnsupportedOperationException( 186 "The feature not supported on Auto"); 187 } 188 189 @SuppressWarnings("unused") 190 @Override getAllWidgetsSelector()191 public BySelector getAllWidgetsSelector() { 192 throw new UnsupportedOperationException( 193 "The feature not supported on Auto"); 194 } 195 196 @SuppressWarnings("unused") 197 @Override getAllWidgetsScrollDirection()198 public Direction getAllWidgetsScrollDirection() { 199 throw new UnsupportedOperationException( 200 "The feature not supported on Auto"); 201 } 202 203 @SuppressWarnings("unused") 204 @Override getWorkspaceSelector()205 public BySelector getWorkspaceSelector() { 206 throw new UnsupportedOperationException( 207 "The feature not supported on Auto"); 208 } 209 210 @SuppressWarnings("unused") 211 @Override getHotSeatSelector()212 public BySelector getHotSeatSelector() { 213 throw new UnsupportedOperationException( 214 "The feature not supported on Auto"); 215 } 216 217 @SuppressWarnings("unused") 218 @Override getWorkspaceScrollDirection()219 public Direction getWorkspaceScrollDirection() { 220 throw new UnsupportedOperationException( 221 "The feature not supported on Auto"); 222 } 223 224 @SuppressWarnings("unused") 225 @Override launch(String appName, String packageName)226 public long launch(String appName, String packageName) { 227 openApp(appName); 228 return 0; 229 } 230 } 231