1 /* 2 * Copyright (C) 2017 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 java.io.ByteArrayOutputStream; 19 import java.io.File; 20 import java.io.IOException; 21 22 import android.app.Instrumentation; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.os.SystemClock; 26 import android.support.test.uiautomator.By; 27 import android.support.test.uiautomator.BySelector; 28 import android.support.test.uiautomator.Direction; 29 import android.support.test.uiautomator.UiDevice; 30 import android.support.test.uiautomator.UiObject2; 31 import android.support.test.uiautomator.Until; 32 import android.widget.TextView; 33 import android.util.Log; 34 35 import junit.framework.Assert; 36 37 public class WearLauncherStrategy implements ILauncherStrategy { 38 39 private static final String LAUNCHER_PKG = "com.google.android.wearable.app"; 40 private static final String LOG_TAG = WearLauncherStrategy.class.getSimpleName(); 41 protected UiDevice mDevice; 42 protected Context mContext; 43 44 /** 45 * {@inheritDoc} 46 */ 47 @Override 48 public String getSupportedLauncherPackage() { 49 return LAUNCHER_PKG; 50 } 51 52 /** 53 * {@inheritDoc} 54 */ 55 @Override 56 public void setUiDevice(UiDevice uiDevice) { 57 mDevice = uiDevice; 58 } 59 60 /** 61 * Shows the home screen of launcher 62 */ 63 @Override 64 public void open() { 65 if (!mDevice.hasObject(getHotSeatSelector())) { 66 mDevice.pressHome(); 67 if (!mDevice.wait(Until.hasObject(getHotSeatSelector()), 5000)) { 68 dumpScreen("Return Watch face"); 69 Assert.fail("Failed to open launcher"); 70 } 71 mDevice.waitForIdle(); 72 } 73 } 74 75 /** 76 * Opens the all apps drawer of launcher 77 * @param reset if the all apps drawer should be reset to the beginning 78 * @return {@link UiObject2} representation of the all apps drawer 79 */ 80 @Override 81 public UiObject2 openAllApps(boolean reset) { 82 if (!mDevice.hasObject(getAllAppsSelector())) { 83 mDevice.pressHome(); 84 mDevice.waitForIdle(); 85 if (!mDevice.wait(Until.hasObject(getAllAppsSelector()), 5000)) { 86 dumpScreen("Open launcher"); 87 Assert.fail("Failed to open launcher"); 88 } 89 } 90 UiObject2 allAppsContainer = mDevice.wait(Until.findObject(getAllAppsSelector()), 2000); 91 if (reset) { 92 CommonLauncherHelper.getInstance(mDevice).scrollBackToBeginning( 93 allAppsContainer, Direction.reverse(getAllAppsScrollDirection())); 94 } 95 if (allAppsContainer == null) { 96 Assert.fail("Failed to find launcher"); 97 } 98 return allAppsContainer; 99 } 100 101 /** 102 * {@inheritDoc} 103 */ 104 @Override 105 public BySelector getHotSeatSelector() { 106 return By.res(getSupportedLauncherPackage(), "watchface_overlay"); 107 } 108 109 110 /** 111 * Returns a {@link BySelector} describing the all apps drawer 112 * @return 113 */ 114 @Override 115 public BySelector getAllAppsSelector() { 116 return By.res(getSupportedLauncherPackage(), "launcher_view"); 117 } 118 119 /** 120 * Retrieves the all apps drawer forward scroll direction as implemented by the launcher 121 * @return 122 */ 123 @Override 124 public Direction getAllAppsScrollDirection() { 125 return Direction.DOWN; 126 } 127 128 @Override 129 public BySelector getAllAppsButtonSelector() { 130 throw new UnsupportedOperationException( 131 "The 'All Apps' button is not available on Android Wear Launcher."); 132 } 133 134 @Override 135 public UiObject2 openAllWidgets(boolean reset) { 136 throw new UnsupportedOperationException( 137 "The 'All Widgets' button is not available on Android Wear Launcher."); 138 } 139 140 @Override 141 public BySelector getAllWidgetsSelector() { 142 throw new UnsupportedOperationException( 143 "The 'All Widgets' button is not available on Android Wear Launcher."); 144 } 145 146 @Override 147 public Direction getAllWidgetsScrollDirection() { 148 throw new UnsupportedOperationException( 149 "The 'All Widgets' button is not available on Android Wear Launcher."); 150 } 151 152 @Override 153 public BySelector getWorkspaceSelector() { 154 throw new UnsupportedOperationException( 155 "The 'Work space' is not available on Android Wear Launcher."); 156 } 157 158 @Override 159 public Direction getWorkspaceScrollDirection() { 160 throw new UnsupportedOperationException( 161 "The 'Work Space' is not available on Android Wear Launcher."); 162 } 163 164 /** 165 * Launch the named application 166 * @param appName the name of the application to launch as shown in launcher 167 * @param packageName the expected package name to verify that the application has been launched 168 * into foreground. If <code>null</code> is provided, no verification is 169 * performed. 170 * @return <code>true</code> if application is verified to be in foreground after launch, or the 171 * verification is skipped; <code>false</code> otherwise. 172 */ 173 @Override 174 public long launch(String appName, String packageName) { 175 BySelector app = By.res( 176 getSupportedLauncherPackage(), "title").clazz(TextView.class).text(appName); 177 return CommonLauncherHelper.getInstance(mDevice).launchApp(this, app, packageName); 178 } 179 180 private void dumpScreen(String description) { 181 // DEBUG: dump hierarchy to logcat 182 Log.d(LOG_TAG, "Dump Screen at " + description); 183 try (ByteArrayOutputStream baos = new ByteArrayOutputStream()){ 184 mDevice.dumpWindowHierarchy(baos); 185 baos.flush(); 186 String[] lines = baos.toString().split(System.lineSeparator()); 187 for (String line : lines) { 188 Log.d(LOG_TAG, line.trim()); 189 } 190 } catch (IOException ioe) { 191 Log.e(LOG_TAG, "error dumping XML to logcat", ioe); 192 } 193 } 194 } 195