1b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes/* 2b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * Copyright (C) 2016 The Android Open Source Project 3b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * 4b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * Licensed under the Apache License, Version 2.0 (the "License"); 5b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * you may not use this file except in compliance with the License. 6b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * You may obtain a copy of the License at 7b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * 8b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * http://www.apache.org/licenses/LICENSE-2.0 9b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * Unless required by applicable law or agreed to in writing, software 10b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * distributed under the License is distributed on an "AS IS" BASIS, 11b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * See the License for the specific language governing permissions and limitations under the 13b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * License. 14b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes * 15b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes */ 16b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 17b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandespackage com.android.benchmark.ui.automation; 18b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 19b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.annotation.TargetApi; 20b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.app.Instrumentation; 21b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.os.Handler; 22b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.os.HandlerThread; 23b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.os.Looper; 24b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.os.Message; 25b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.view.FrameMetrics; 26b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.view.MotionEvent; 27b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.view.ViewTreeObserver; 28b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport android.view.Window; 29b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 30b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport com.android.benchmark.results.GlobalResultsStore; 31b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport com.android.benchmark.results.UiBenchmarkResult; 32b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 33b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport java.util.LinkedList; 34b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport java.util.List; 35b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandesimport java.util.concurrent.atomic.AtomicInteger; 36b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 37b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes@TargetApi(24) 38b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandespublic class Automator extends HandlerThread 39b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes implements ViewTreeObserver.OnGlobalLayoutListener, CollectorThread.CollectorListener { 40b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public static final long FRAME_PERIOD_MILLIS = 16; 41b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 42b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private static final int PRE_READY_STATE_COUNT = 3; 43b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private static final String TAG = "Benchmark.Automator"; 44b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private final AtomicInteger mReadyState; 45b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 46b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private AutomateCallback mCallback; 47b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private Window mWindow; 48b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private AutomatorHandler mHandler; 49b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private CollectorThread mCollectorThread; 50b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private int mRunId; 51b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private int mIteration; 52b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private String mTestName; 53b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 54b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public static class AutomateCallback { 55b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public void onAutomate() {} 56b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public void onPostInteraction(List<FrameMetrics> metrics) {} 57b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public void onPostAutomate() {} 58b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 59b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes protected final void addInteraction(Interaction interaction) { 60b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (mInteractions == null) { 61b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes return; 62b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 63b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 64b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mInteractions.add(interaction); 65b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 66b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 67b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes protected final void setInteractions(List<Interaction> interactions) { 68b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mInteractions = interactions; 69b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 70b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 71b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private List<Interaction> mInteractions; 72b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 73b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 74b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private static final class AutomatorHandler extends Handler { 75b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public static final int MSG_NEXT_INTERACTION = 0; 76b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public static final int MSG_ON_AUTOMATE = 1; 77b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public static final int MSG_ON_POST_INTERACTION = 2; 78b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private final String mTestName; 79b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private final int mRunId; 80b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private final int mIteration; 81b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 82b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private Instrumentation mInstrumentation; 83b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private volatile boolean mCancelled; 84b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private CollectorThread mCollectorThread; 85b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private AutomateCallback mCallback; 86b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private Window mWindow; 87b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 88b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes LinkedList<Interaction> mInteractions; 89b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private UiBenchmarkResult mResults; 90b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 91b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes AutomatorHandler(Looper looper, Window window, CollectorThread collectorThread, 92b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes AutomateCallback callback, String testName, int runId, int iteration) { 93b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes super(looper); 94b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 95b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mInstrumentation = new Instrumentation(); 96b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 97b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCallback = callback; 98b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mWindow = window; 99b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCollectorThread = collectorThread; 100b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mInteractions = new LinkedList<>(); 101b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mTestName = testName; 102b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mRunId = runId; 103b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mIteration = iteration; 104b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 105b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 106b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes @Override 107b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public void handleMessage(Message msg) { 108b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (mCancelled) { 109b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes return; 110b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 111b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 112b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes switch (msg.what) { 113b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes case MSG_NEXT_INTERACTION: 114b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (!nextInteraction()) { 115b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes stopCollector(); 116b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes writeResults(); 117b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCallback.onPostAutomate(); 118b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 119b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes break; 120b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes case MSG_ON_AUTOMATE: 121b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCollectorThread.attachToWindow(mWindow); 122b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCallback.setInteractions(mInteractions); 123b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCallback.onAutomate(); 124b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes postNextInteraction(); 125b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes break; 126b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes case MSG_ON_POST_INTERACTION: 127b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes List<FrameMetrics> collectedStats = (List<FrameMetrics>)msg.obj; 128b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes persistResults(collectedStats); 129b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCallback.onPostInteraction(collectedStats); 130b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes postNextInteraction(); 131b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes break; 132b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 133b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 134b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 135b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public void cancel() { 136b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCancelled = true; 137b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes stopCollector(); 138b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 139b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 140b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private void stopCollector() { 141b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCollectorThread.quitCollector(); 142b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 143b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 144b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private boolean nextInteraction() { 145b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 146b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes Interaction interaction = mInteractions.poll(); 147b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (interaction != null) { 148b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes doInteraction(interaction); 149b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes return true; 150b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 151b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes return false; 152b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 153b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 154b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private void doInteraction(Interaction interaction) { 155b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (mCancelled) { 156b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes return; 157b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 158b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 159b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCollectorThread.markInteractionStart(); 160b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 161b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (interaction.getType() == Interaction.Type.KEY_EVENT) { 162b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes for (int code : interaction.getKeyCodes()) { 163b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (!mCancelled) { 164b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mInstrumentation.sendKeyDownUpSync(code); 165b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } else { 166b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes break; 167b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 168b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 169b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } else { 170b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes for (MotionEvent event : interaction.getEvents()) { 171b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (!mCancelled) { 172b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mInstrumentation.sendPointerSync(event); 173b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } else { 174b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes break; 175b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 176b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 177b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 178b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 179b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 180b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes protected void postNextInteraction() { 181b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes final Message msg = obtainMessage(AutomatorHandler.MSG_NEXT_INTERACTION); 182b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes sendMessage(msg); 183b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 184b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 185b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private void persistResults(List<FrameMetrics> stats) { 186b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (stats.isEmpty()) { 187b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes return; 188b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 189b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 190b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (mResults == null) { 191b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mResults = new UiBenchmarkResult(stats); 192b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } else { 193b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mResults.update(stats); 194b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 195b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 196b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 197b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private void writeResults() { 198b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes GlobalResultsStore.getInstance(mWindow.getContext()) 199b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes .storeRunResults(mTestName, mRunId, mIteration, mResults); 200b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 201b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 202b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 203b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes private void initHandler() { 204b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mHandler = new AutomatorHandler(getLooper(), mWindow, mCollectorThread, mCallback, 205b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mTestName, mRunId, mIteration); 206b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mWindow = null; 207b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCallback = null; 208b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCollectorThread = null; 209b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mTestName = null; 210b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mRunId = 0; 211b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mIteration = 0; 212b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 213b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 214b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes @Override 215b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public final void onGlobalLayout() { 216b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (!mCollectorThread.isAlive()) { 217b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCollectorThread.start(); 218b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mWindow.getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(this); 219b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mReadyState.decrementAndGet(); 220b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 221b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 222b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 223b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes @Override 224b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public void onCollectorThreadReady() { 225b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (mReadyState.decrementAndGet() == 0) { 226b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes initHandler(); 227b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes postOnAutomate(); 228b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 229b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 230b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 231b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes @Override 232b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes protected void onLooperPrepared() { 233b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes if (mReadyState.decrementAndGet() == 0) { 234b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes initHandler(); 235b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes postOnAutomate(); 236b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 237b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 238b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 239b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes @Override 240b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public void onPostInteraction(List<FrameMetrics> stats) { 241b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes Message m = mHandler.obtainMessage(AutomatorHandler.MSG_ON_POST_INTERACTION, stats); 242b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mHandler.sendMessage(m); 243b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 244b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 245b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes protected void postOnAutomate() { 246b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes final Message msg = mHandler.obtainMessage(AutomatorHandler.MSG_ON_AUTOMATE); 247b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mHandler.sendMessage(msg); 248b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 249b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 250b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public void cancel() { 251b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mHandler.removeMessages(AutomatorHandler.MSG_NEXT_INTERACTION); 252b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mHandler.cancel(); 253b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mHandler = null; 254b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 255b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 256b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes public Automator(String testName, int runId, int iteration, 257b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes Window window, AutomateCallback callback) { 258b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes super("AutomatorThread"); 259b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes 260b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mTestName = testName; 261b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mRunId = runId; 262b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mIteration = iteration; 263b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCallback = callback; 264b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mWindow = window; 265b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mWindow.getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(this); 266b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mCollectorThread = new CollectorThread(this); 267b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes mReadyState = new AtomicInteger(PRE_READY_STATE_COUNT); 268b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes } 269b5fbd41b23bf309e6b420a3df4641603d55dcb68Joel Fernandes} 270