1 /* 2 * Copyright (C) 2008 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.commands.monkey; 18 19 import android.app.IActivityManager; 20 import android.hardware.input.InputManager; 21 import android.hardware.input.InputManagerGlobal; 22 import android.os.SystemClock; 23 import android.util.SparseArray; 24 import android.view.IWindowManager; 25 import android.view.MotionEvent; 26 27 28 /** 29 * monkey motion event 30 */ 31 public abstract class MonkeyMotionEvent extends MonkeyEvent { 32 private long mDownTime; 33 private long mEventTime; 34 private int mAction; 35 private SparseArray<MotionEvent.PointerCoords> mPointers; 36 private int mMetaState; 37 private float mXPrecision; 38 private float mYPrecision; 39 private int mDeviceId; 40 private int mSource; 41 private int mFlags; 42 private int mEdgeFlags; 43 44 //If true, this is an intermediate step (more verbose logging, only) 45 private boolean mIntermediateNote; 46 MonkeyMotionEvent(int type, int source, int action)47 protected MonkeyMotionEvent(int type, int source, int action) { 48 super(type); 49 mSource = source; 50 mDownTime = -1; 51 mEventTime = -1; 52 mAction = action; 53 mPointers = new SparseArray<MotionEvent.PointerCoords>(); 54 mXPrecision = 1; 55 mYPrecision = 1; 56 } 57 addPointer(int id, float x, float y)58 public MonkeyMotionEvent addPointer(int id, float x, float y) { 59 return addPointer(id, x, y, 0, 0); 60 } 61 addPointer(int id, float x, float y, float pressure, float size)62 public MonkeyMotionEvent addPointer(int id, float x, float y, 63 float pressure, float size) { 64 MotionEvent.PointerCoords c = new MotionEvent.PointerCoords(); 65 c.x = x; 66 c.y = y; 67 c.pressure = pressure; 68 c.size = size; 69 mPointers.append(id, c); 70 return this; 71 } 72 setIntermediateNote(boolean b)73 public MonkeyMotionEvent setIntermediateNote(boolean b) { 74 mIntermediateNote = b; 75 return this; 76 } 77 getIntermediateNote()78 public boolean getIntermediateNote() { 79 return mIntermediateNote; 80 } 81 getAction()82 public int getAction() { 83 return mAction; 84 } 85 getDownTime()86 public long getDownTime() { 87 return mDownTime; 88 } 89 getEventTime()90 public long getEventTime() { 91 return mEventTime; 92 } 93 setDownTime(long downTime)94 public MonkeyMotionEvent setDownTime(long downTime) { 95 mDownTime = downTime; 96 return this; 97 } 98 setEventTime(long eventTime)99 public MonkeyMotionEvent setEventTime(long eventTime) { 100 mEventTime = eventTime; 101 return this; 102 } 103 setMetaState(int metaState)104 public MonkeyMotionEvent setMetaState(int metaState) { 105 mMetaState = metaState; 106 return this; 107 } 108 setPrecision(float xPrecision, float yPrecision)109 public MonkeyMotionEvent setPrecision(float xPrecision, float yPrecision) { 110 mXPrecision = xPrecision; 111 mYPrecision = yPrecision; 112 return this; 113 } 114 setDeviceId(int deviceId)115 public MonkeyMotionEvent setDeviceId(int deviceId) { 116 mDeviceId = deviceId; 117 return this; 118 } 119 setEdgeFlags(int edgeFlags)120 public MonkeyMotionEvent setEdgeFlags(int edgeFlags) { 121 mEdgeFlags = edgeFlags; 122 return this; 123 } 124 125 /** 126 * 127 * @return instance of a motion event 128 */ getEvent()129 private MotionEvent getEvent() { 130 int pointerCount = mPointers.size(); 131 int[] pointerIds = new int[pointerCount]; 132 MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[pointerCount]; 133 for (int i = 0; i < pointerCount; i++) { 134 pointerIds[i] = mPointers.keyAt(i); 135 pointerCoords[i] = mPointers.valueAt(i); 136 } 137 138 MotionEvent ev = MotionEvent.obtain(mDownTime, 139 mEventTime < 0 ? SystemClock.uptimeMillis() : mEventTime, 140 mAction, pointerCount, pointerIds, pointerCoords, 141 mMetaState, mXPrecision, mYPrecision, mDeviceId, mEdgeFlags, mSource, mFlags); 142 return ev; 143 } 144 145 @Override isThrottlable()146 public boolean isThrottlable() { 147 return (getAction() == MotionEvent.ACTION_UP); 148 } 149 150 @Override injectEvent(IWindowManager iwm, IActivityManager iam, int verbose)151 public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) { 152 MotionEvent me = getEvent(); 153 if ((verbose > 0 && !mIntermediateNote) || verbose > 1) { 154 StringBuilder msg = new StringBuilder(":Sending "); 155 msg.append(getTypeLabel()).append(" ("); 156 switch (me.getActionMasked()) { 157 case MotionEvent.ACTION_DOWN: 158 msg.append("ACTION_DOWN"); 159 break; 160 case MotionEvent.ACTION_MOVE: 161 msg.append("ACTION_MOVE"); 162 break; 163 case MotionEvent.ACTION_UP: 164 msg.append("ACTION_UP"); 165 break; 166 case MotionEvent.ACTION_CANCEL: 167 msg.append("ACTION_CANCEL"); 168 break; 169 case MotionEvent.ACTION_POINTER_DOWN: 170 msg.append("ACTION_POINTER_DOWN ").append(me.getPointerId(me.getActionIndex())); 171 break; 172 case MotionEvent.ACTION_POINTER_UP: 173 msg.append("ACTION_POINTER_UP ").append(me.getPointerId(me.getActionIndex())); 174 break; 175 default: 176 msg.append(me.getAction()); 177 break; 178 } 179 msg.append("):"); 180 181 int pointerCount = me.getPointerCount(); 182 for (int i = 0; i < pointerCount; i++) { 183 msg.append(" ").append(me.getPointerId(i)); 184 msg.append(":(").append(me.getX(i)).append(",").append(me.getY(i)).append(")"); 185 } 186 Logger.out.println(msg.toString()); 187 } 188 try { 189 if (!InputManagerGlobal.getInstance().injectInputEvent(me, 190 InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT)) { 191 return MonkeyEvent.INJECT_FAIL; 192 } 193 } finally { 194 me.recycle(); 195 } 196 return MonkeyEvent.INJECT_SUCCESS; 197 } 198 getTypeLabel()199 protected abstract String getTypeLabel(); 200 } 201