Home | History | Annotate | Download | only in janktests
      1 /*
      2  * Copyright (C) 2016 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 com.android.wearable.ime.janktests;
     18 
     19 import android.app.Instrumentation;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.os.SystemClock;
     23 import android.support.test.uiautomator.By;
     24 import android.support.test.uiautomator.UiDevice;
     25 import android.support.test.uiautomator.UiObject2;
     26 import android.support.test.uiautomator.Until;
     27 import android.util.Log;
     28 
     29 import junit.framework.Assert;
     30 
     31 import java.io.IOException;
     32 
     33 /**
     34  * Helpers for Wear IME Jank Tests
     35  */
     36 
     37 public class IMEJankTestsHelper {
     38 
     39     public static final int LONG_TIMEOUT = 5000;
     40     public static final int SHORT_TIMEOUT = 1500;
     41     public static final int WFM_EXPECTED_FRAMES = 10;
     42     public static final int GFX_EXPECTED_FRAMES = 10;
     43     public static final String IME_PACKAGE_NAME = "com.google.android.inputmethod.latin";
     44     private static final String LOG_TAG = IMEJankTestsHelper.class.getSimpleName();
     45     private static final String HOME_INDICATOR = "charging_icon";
     46     private static final String LAUNCHER_VIEW_NAME = "launcher_view";
     47     private static final String CARD_TITLE_NAME = "title";
     48     private static final String IME_BUTTON_NAME = "ime_choice";
     49     private static final String REPLY_BUTTON_TEXT = "Reply";
     50     private static final String REMOTE_INPUT_TEXT = "Quick reply";
     51     private static final String REMOTE_INPUT_PACKAGE_NAME =
     52             "com.google.android.wearable.app";
     53     private static final String RELOAD_NOTIFICATION_CARD_INTENT = "com.google.android.wearable."
     54             + "support.wearnotificationgenerator.SHOW_NOTIFICATION";
     55     private static final String KEYBOARD_ID =
     56             "com.google.android.inputmethod.latin/com.google.android.apps.inputmethod.wear.WearIME";
     57     private static final String HANDWRITING_ID = "com.google.android.apps.handwriting.ime/"
     58             + "com.google.android.wearable.input.handwriting.HandwriterInputMethodService";
     59     private static final String SET_IME_CMD = "ime set %s";
     60     private static final String ENABLE_IME_CMD = "ime enable %s";
     61     private static final String INPUT_BOX_PACKAGE_NAME =
     62             "com.google.android.wearable.input.latin.activity";
     63     private static IMEJankTestsHelper mInstance;
     64     private UiDevice mDevice;
     65     private Instrumentation mInstrumentation;
     66 
     67     private IMEJankTestsHelper(UiDevice device, Instrumentation instrumentation) {
     68         mDevice = device;
     69         mInstrumentation = instrumentation;
     70     }
     71 
     72     public static IMEJankTestsHelper getInstance(UiDevice device, Instrumentation instrumentation) {
     73         if (mInstance == null) {
     74             mInstance = new IMEJankTestsHelper(device, instrumentation);
     75         }
     76         return mInstance;
     77     }
     78 
     79     public void swipeUp() {
     80         mDevice.swipe(mDevice.getDisplayWidth() / 2, mDevice.getDisplayHeight() / 2 + 50,
     81                 mDevice.getDisplayWidth() / 2, 0, 30); // slow speed
     82         SystemClock.sleep(SHORT_TIMEOUT);
     83     }
     84 
     85     public void swipeRight(int heightOffset) {
     86         mDevice.swipe(50,
     87                 mDevice.getDisplayHeight() / 2 + heightOffset, mDevice.getDisplayWidth() - 25,
     88                 mDevice.getDisplayHeight() / 2 + heightOffset, 30); // slow speed
     89         SystemClock.sleep(SHORT_TIMEOUT);
     90     }
     91 
     92     // Helper function to go back to home screen
     93     public void goBackHome() {
     94         String launcherPackage = mDevice.getLauncherPackageName();
     95         UiObject2 homeScreen = mDevice.findObject(By.res(launcherPackage, HOME_INDICATOR));
     96         int count = 0;
     97         while (homeScreen == null && count < 5) {
     98             mDevice.pressBack();
     99             Log.d(LOG_TAG, "Pressed back");
    100             homeScreen = mDevice.findObject(By.res(launcherPackage, HOME_INDICATOR));
    101             count++;
    102         }
    103 
    104         // TODO (yuanlang@) Delete the following hacky codes after charging icon issue fixed
    105         // App launcher still draw changing icon. Make sure we're not in the launcher
    106         homeScreen = mDevice.findObject(By.res(launcherPackage, LAUNCHER_VIEW_NAME));
    107         if (homeScreen != null) {
    108             mDevice.pressBack();
    109         }
    110 
    111         SystemClock.sleep(SHORT_TIMEOUT);
    112     }
    113 
    114     public void launchRemoteInputActivity() {
    115         String launcherPackage = mDevice.getLauncherPackageName();
    116         // Swipe up 5 times to bring up demo cards
    117         // in case there are some real cards on top
    118         reloadDemoCards();
    119         int i = 0;
    120         UiObject2 cardTitle = null;
    121         while (i < 5) {
    122             swipeUp();
    123             cardTitle = mDevice.wait(
    124                     Until.findObject(By.text("Clockwork Notifications-10")), SHORT_TIMEOUT);
    125             if (cardTitle != null) {
    126                 cardTitle.click();
    127                 break;
    128             }
    129             i ++;
    130         }
    131         Assert.assertNotNull("Cannot find demo card with remote input", cardTitle);
    132         // Click on reply action button
    133         UiObject2 replyButton = mDevice
    134                 .wait(Until.findObject(By.text(REPLY_BUTTON_TEXT)), LONG_TIMEOUT);
    135         Assert.assertNotNull(replyButton);
    136         replyButton.click();
    137 
    138         // Make sure remote input activity launched
    139         UiObject2 replyText = mDevice
    140                 .wait(Until.findObject(By.text(REMOTE_INPUT_TEXT)), LONG_TIMEOUT);
    141         Assert.assertNotNull(replyText);
    142     }
    143 
    144     public void launchInputBoxActivity() {
    145         Context context = mInstrumentation.getContext();
    146         Intent intent = context.getPackageManager()
    147                 .getLaunchIntentForPackage(INPUT_BOX_PACKAGE_NAME);
    148         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
    149         context.startActivity(intent);
    150         Assert.assertTrue("Input box activity not started",
    151                 mDevice.wait(Until.hasObject(By.pkg(INPUT_BOX_PACKAGE_NAME).depth(0)),
    152                         LONG_TIMEOUT));
    153     }
    154 
    155     public void tapIMEButton() {
    156         UiObject2 imeButton = mDevice.wait(
    157                 Until.findObject(By.res(REMOTE_INPUT_PACKAGE_NAME, IME_BUTTON_NAME)), LONG_TIMEOUT);
    158         Assert.assertNotNull(imeButton);
    159         imeButton.click();
    160         SystemClock.sleep(SHORT_TIMEOUT);
    161     }
    162 
    163     // This will ensure to reload notification cards by launching NotificationsGeneratorWear app
    164     // when there are insufficient cards.
    165     private void reloadDemoCards() {
    166         Intent intent = new Intent();
    167         intent.setAction(RELOAD_NOTIFICATION_CARD_INTENT);
    168         mInstrumentation.getContext().sendBroadcast(intent);
    169         Log.d(LOG_TAG, "Demo cards have been reloaded");
    170         SystemClock.sleep(LONG_TIMEOUT);
    171     }
    172 
    173     public void activateIMEKeyboard() {
    174         try {
    175             mDevice.executeShellCommand(String.format(ENABLE_IME_CMD, KEYBOARD_ID));
    176             mDevice.executeShellCommand(String.format(SET_IME_CMD, KEYBOARD_ID));
    177         } catch (IOException e) {
    178             Log.e(LOG_TAG, e.toString());
    179         }
    180         Log.d(LOG_TAG, "Keyboard activated");
    181     }
    182 
    183     public void activateIMEHandwriting() {
    184         try {
    185             mDevice.executeShellCommand(String.format(ENABLE_IME_CMD, HANDWRITING_ID));
    186             mDevice.executeShellCommand(String.format(SET_IME_CMD, HANDWRITING_ID));
    187         } catch (IOException e) {
    188             Log.e(LOG_TAG, e.toString());
    189         }
    190         Log.d(LOG_TAG, "Handwriting activated");
    191     }
    192 
    193     public void pressBack() {
    194         mDevice.pressBack();
    195         SystemClock.sleep(SHORT_TIMEOUT);
    196     }
    197 
    198     public void tapOnScreen() {
    199         mDevice.click(mDevice.getDisplayHeight() / 2, mDevice.getDisplayWidth() / 2);
    200         SystemClock.sleep(SHORT_TIMEOUT);
    201     }
    202 
    203     public void clickSoftKey(String softKeyDescription) {
    204         UiObject2 softKey = mDevice.wait(
    205                 Until.findObject(By.res(IME_PACKAGE_NAME, keyPosIdByDesc(softKeyDescription))),
    206                 SHORT_TIMEOUT);
    207         Assert.assertNotNull("Soft Key " + softKeyDescription + " not found in UI", softKey);
    208         softKey.click();
    209     }
    210 
    211     private String keyPosIdByDesc(String desc) {
    212         return String.format("key_pos_%s", desc);
    213     }
    214 }