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