Home | History | Annotate | Download | only in monkey
      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.os.RemoteException;
     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 
     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 
     57     public MonkeyMotionEvent addPointer(int id, float x, float y) {
     58         return addPointer(id, x, y, 0, 0);
     59     }
     60 
     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 
     72     public MonkeyMotionEvent setIntermediateNote(boolean b) {
     73         mIntermediateNote = b;
     74         return this;
     75     }
     76 
     77     public boolean getIntermediateNote() {
     78         return mIntermediateNote;
     79     }
     80 
     81     public int getAction() {
     82         return mAction;
     83     }
     84 
     85     public long getDownTime() {
     86         return mDownTime;
     87     }
     88 
     89     public long getEventTime() {
     90         return mEventTime;
     91     }
     92 
     93     public MonkeyMotionEvent setDownTime(long downTime) {
     94         mDownTime = downTime;
     95         return this;
     96     }
     97 
     98     public MonkeyMotionEvent setEventTime(long eventTime) {
     99         mEventTime = eventTime;
    100         return this;
    101     }
    102 
    103     public MonkeyMotionEvent setMetaState(int metaState) {
    104         mMetaState = metaState;
    105         return this;
    106     }
    107 
    108     public MonkeyMotionEvent setPrecision(float xPrecision, float yPrecision) {
    109         mXPrecision = xPrecision;
    110         mYPrecision = yPrecision;
    111         return this;
    112     }
    113 
    114     public MonkeyMotionEvent setDeviceId(int deviceId) {
    115         mDeviceId = deviceId;
    116         return this;
    117     }
    118 
    119     public MonkeyMotionEvent setEdgeFlags(int edgeFlags) {
    120         mEdgeFlags = edgeFlags;
    121         return this;
    122     }
    123 
    124     /**
    125      *
    126      * @return instance of a motion event
    127      */
    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
    145     public boolean isThrottlable() {
    146         return (getAction() == MotionEvent.ACTION_UP);
    147     }
    148 
    149     @Override
    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             System.out.println(msg.toString());
    186         }
    187         try {
    188             if (!injectMotionEvent(iwm, me)) {
    189                 return MonkeyEvent.INJECT_FAIL;
    190             }
    191         } catch (RemoteException ex) {
    192             return MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION;
    193         } finally {
    194             me.recycle();
    195         }
    196         return MonkeyEvent.INJECT_SUCCESS;
    197     }
    198 
    199     protected abstract String getTypeLabel();
    200     protected abstract boolean injectMotionEvent(IWindowManager iwm, MotionEvent me)
    201             throws RemoteException;
    202 }
    203