1 /* 2 * Copyright (C) 2013 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.uiautomator.common; 18 19 import android.util.Log; 20 21 import com.android.uiautomator.core.UiDevice; 22 import com.android.uiautomator.core.UiObject; 23 import com.android.uiautomator.core.UiObjectNotFoundException; 24 import com.android.uiautomator.core.UiSelector; 25 import com.android.uiautomator.core.UiWatcher; 26 27 import java.util.ArrayList; 28 import java.util.Collections; 29 import java.util.List; 30 31 public class UiWatchers { 32 private static final String LOG_TAG = UiWatchers.class.getSimpleName(); 33 private final List<String> mErrors = new ArrayList<String>(); 34 35 /** 36 * We can use the UiDevice registerWatcher to register a small script to be executed when the 37 * framework is waiting for a control to appear. Waiting may be the cause of an unexpected 38 * dialog on the screen and it is the time when the framework runs the registered watchers. 39 * This is a sample watcher looking for ANR and crashes. it closes it and moves on. You should 40 * create your own watchers and handle error logging properly for your type of tests. 41 */ 42 public void registerAnrAndCrashWatchers() { 43 44 UiDevice.getInstance().registerWatcher("ANR", new UiWatcher() { 45 @Override 46 public boolean checkForCondition() { 47 UiObject window = new UiObject(new UiSelector().className( 48 "com.android.server.am.AppNotRespondingDialog")); 49 String errorText = null; 50 if (window.exists()) { 51 try { 52 errorText = window.getText(); 53 } catch (UiObjectNotFoundException e) { 54 Log.e(LOG_TAG, "dialog gone?", e); 55 } 56 onAnrDetected(errorText); 57 postHandler(); 58 return true; // triggered 59 } 60 return false; // no trigger 61 } 62 }); 63 64 // class names may have changed 65 UiDevice.getInstance().registerWatcher("ANR2", new UiWatcher() { 66 @Override 67 public boolean checkForCondition() { 68 UiObject window = new UiObject(new UiSelector().packageName("android") 69 .textContains("isn't responding.")); 70 if (window.exists()) { 71 String errorText = null; 72 try { 73 errorText = window.getText(); 74 } catch (UiObjectNotFoundException e) { 75 Log.e(LOG_TAG, "dialog gone?", e); 76 } 77 onAnrDetected(errorText); 78 postHandler(); 79 return true; // triggered 80 } 81 return false; // no trigger 82 } 83 }); 84 85 UiDevice.getInstance().registerWatcher("CRASH", new UiWatcher() { 86 @Override 87 public boolean checkForCondition() { 88 UiObject window = new UiObject(new UiSelector().className( 89 "com.android.server.am.AppErrorDialog")); 90 if (window.exists()) { 91 String errorText = null; 92 try { 93 errorText = window.getText(); 94 } catch (UiObjectNotFoundException e) { 95 Log.e(LOG_TAG, "dialog gone?", e); 96 } 97 onCrashDetected(errorText); 98 postHandler(); 99 return true; // triggered 100 } 101 return false; // no trigger 102 } 103 }); 104 105 UiDevice.getInstance().registerWatcher("CRASH2", new UiWatcher() { 106 @Override 107 public boolean checkForCondition() { 108 UiObject window = new UiObject(new UiSelector().packageName("android") 109 .textContains("has stopped")); 110 if (window.exists()) { 111 String errorText = null; 112 try { 113 errorText = window.getText(); 114 } catch (UiObjectNotFoundException e) { 115 Log.e(LOG_TAG, "dialog gone?", e); 116 } 117 onCrashDetected(errorText); 118 postHandler(); 119 return true; // triggered 120 } 121 return false; // no trigger 122 } 123 }); 124 125 Log.i(LOG_TAG, "Registed GUI Exception watchers"); 126 } 127 128 public void onAnrDetected(String errorText) { 129 mErrors.add(errorText); 130 } 131 132 public void onCrashDetected(String errorText) { 133 mErrors.add(errorText); 134 } 135 136 public void reset() { 137 mErrors.clear(); 138 } 139 140 public List<String> getErrors() { 141 return Collections.unmodifiableList(mErrors); 142 } 143 144 /** 145 * Current implementation ignores the exception and continues. 146 */ 147 public void postHandler() { 148 // TODO: Add custom error logging here 149 150 String formatedOutput = String.format("UI Exception Message: %-20s\n", UiDevice 151 .getInstance().getCurrentPackageName()); 152 Log.e(LOG_TAG, formatedOutput); 153 154 UiObject buttonOK = new UiObject(new UiSelector().text("OK").enabled(true)); 155 // sometimes it takes a while for the OK button to become enabled 156 buttonOK.waitForExists(5000); 157 try { 158 buttonOK.click(); 159 } catch (UiObjectNotFoundException e) { 160 Log.e(LOG_TAG, "Exception", e); 161 } 162 } 163 } 164