美文网首页
MonkeySourceScript.java 源码

MonkeySourceScript.java 源码

作者: 浪花三朵 | 来源:发表于2019-11-25 10:17 被阅读0次
    /*
     * Copyright (C) 2008 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package com.android.commands.monkey;
    
    import android.content.ComponentName;
    import android.os.SystemClock;
    import android.view.KeyEvent;
    import android.view.MotionEvent;
    import android.view.Surface;
    
    import java.io.BufferedReader;
    import java.io.DataInputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.NoSuchElementException;
    import java.util.Random;
    
    /**
     * monkey event queue. It takes a script to produce events sample script format:
     *
     * <pre>
     * type= raw events
     * count= 10
     * speed= 1.0
     * start data >>
     * captureDispatchPointer(5109520,5109520,0,230.75429,458.1814,0.20784314,0.06666667,0,0.0,0.0,65539,0)
     * captureDispatchKey(5113146,5113146,0,20,0,0,0,0)
     * captureDispatchFlip(true)
     * ...
     * </pre>
     */
    public class MonkeySourceScript implements MonkeyEventSource {
        private int mEventCountInScript = 0; // total number of events in the file
    
        private int mVerbose = 0;
    
        private double mSpeed = 1.0;
    
        private String mScriptFileName;
    
        private MonkeyEventQueue mQ;
    
        private static final String HEADER_COUNT = "count=";
    
        private static final String HEADER_SPEED = "speed=";
    
        private long mLastRecordedDownTimeKey = 0;
    
        private long mLastRecordedDownTimeMotion = 0;
    
        private long mLastExportDownTimeKey = 0;
    
        private long mLastExportDownTimeMotion = 0;
    
        private long mLastExportEventTime = -1;
    
        private long mLastRecordedEventTime = -1;
    
        // process scripts in line-by-line mode (true) or batch processing mode (false)
        private boolean mReadScriptLineByLine = false;
    
        private static final boolean THIS_DEBUG = false;
    
        // a parameter that compensates the difference of real elapsed time and
        // time in theory
        private static final long SLEEP_COMPENSATE_DIFF = 16;
    
        // if this header is present, scripts are read and processed in line-by-line mode
        private static final String HEADER_LINE_BY_LINE = "linebyline";
    
        // maximum number of events that we read at one time
        private static final int MAX_ONE_TIME_READS = 100;
    
        // event key word in the capture log
        private static final String EVENT_KEYWORD_POINTER = "DispatchPointer";
    
        private static final String EVENT_KEYWORD_TRACKBALL = "DispatchTrackball";
    
        private static final String EVENT_KEYWORD_ROTATION = "RotateScreen";
    
        private static final String EVENT_KEYWORD_KEY = "DispatchKey";
    
        private static final String EVENT_KEYWORD_FLIP = "DispatchFlip";
    
        private static final String EVENT_KEYWORD_KEYPRESS = "DispatchPress";
    
        private static final String EVENT_KEYWORD_ACTIVITY = "LaunchActivity";
    
        private static final String EVENT_KEYWORD_INSTRUMENTATION = "LaunchInstrumentation";
    
        private static final String EVENT_KEYWORD_WAIT = "UserWait";
    
        private static final String EVENT_KEYWORD_LONGPRESS = "LongPress";
    
        private static final String EVENT_KEYWORD_POWERLOG = "PowerLog";
    
        private static final String EVENT_KEYWORD_WRITEPOWERLOG = "WriteLog";
    
        private static final String EVENT_KEYWORD_RUNCMD = "RunCmd";
    
        private static final String EVENT_KEYWORD_TAP = "Tap";
    
        private static final String EVENT_KEYWORD_PROFILE_WAIT = "ProfileWait";
    
        private static final String EVENT_KEYWORD_DEVICE_WAKEUP = "DeviceWakeUp";
    
        private static final String EVENT_KEYWORD_INPUT_STRING = "DispatchString";
    
        private static final String EVENT_KEYWORD_PRESSANDHOLD = "PressAndHold";
    
        private static final String EVENT_KEYWORD_DRAG = "Drag";
    
        private static final String EVENT_KEYWORD_PINCH_ZOOM = "PinchZoom";
    
        private static final String EVENT_KEYWORD_START_FRAMERATE_CAPTURE = "StartCaptureFramerate";
    
        private static final String EVENT_KEYWORD_END_FRAMERATE_CAPTURE = "EndCaptureFramerate";
    
        private static final String EVENT_KEYWORD_START_APP_FRAMERATE_CAPTURE =
                "StartCaptureAppFramerate";
    
        private static final String EVENT_KEYWORD_END_APP_FRAMERATE_CAPTURE = "EndCaptureAppFramerate";
    
        // a line at the end of the header
        private static final String STARTING_DATA_LINE = "start data >>";
    
        private boolean mFileOpened = false;
    
        private static int LONGPRESS_WAIT_TIME = 2000; // wait time for the long
    
        private long mProfileWaitTime = 5000; //Wait time for each user profile
    
        private long mDeviceSleepTime = 30000; //Device sleep time
    
        FileInputStream mFStream;
    
        DataInputStream mInputStream;
    
        BufferedReader mBufferedReader;
    
        // X and Y coordincates of last touch event. Array Index is the pointerId
        private float mLastX[] = new float[2];
    
        private float mLastY[] = new float[2];
    
        private long mScriptStartTime = -1;
    
        private long mMonkeyStartTime = -1;
    
        /**
         * Creates a MonkeySourceScript instance.
         *
         * @param filename The filename of the script (on the device).
         * @param throttle The amount of time in ms to sleep between events.
         */
        public MonkeySourceScript(Random random, String filename, long throttle,
                boolean randomizeThrottle, long profileWaitTime, long deviceSleepTime) {
            mScriptFileName = filename;
            mQ = new MonkeyEventQueue(random, throttle, randomizeThrottle);
            mProfileWaitTime = profileWaitTime;
            mDeviceSleepTime = deviceSleepTime;
        }
    
        /**
         * Resets the globals used to timeshift events.
         */
        private void resetValue() {
            mLastRecordedDownTimeKey = 0;
            mLastRecordedDownTimeMotion = 0;
            mLastRecordedEventTime = -1;
            mLastExportDownTimeKey = 0;
            mLastExportDownTimeMotion = 0;
            mLastExportEventTime = -1;
        }
    
        /**
         * Reads the header of the script file.
         *
         * @return True if the file header could be parsed, and false otherwise.
         * @throws IOException If there was an error reading the file.
         */
        private boolean readHeader() throws IOException {
            mFileOpened = true;
    
            mFStream = new FileInputStream(mScriptFileName);
            mInputStream = new DataInputStream(mFStream);
            mBufferedReader = new BufferedReader(new InputStreamReader(mInputStream));
    
            String line;
    
            while ((line = mBufferedReader.readLine()) != null) {
                line = line.trim();
    
                if (line.indexOf(HEADER_COUNT) >= 0) {
                    try {
                        String value = line.substring(HEADER_COUNT.length() + 1).trim();
                        mEventCountInScript = Integer.parseInt(value);
                    } catch (NumberFormatException e) {
                        System.err.println(e);
                        return false;
                    }
                } else if (line.indexOf(HEADER_SPEED) >= 0) {
                    try {
                        String value = line.substring(HEADER_COUNT.length() + 1).trim();
                        mSpeed = Double.parseDouble(value);
                    } catch (NumberFormatException e) {
                        System.err.println(e);
                        return false;
                    }
                } else if (line.indexOf(HEADER_LINE_BY_LINE) >= 0) {
                    mReadScriptLineByLine = true;
                } else if (line.indexOf(STARTING_DATA_LINE) >= 0) {
                    return true;
                }
            }
    
            return false;
        }
    
        /**
         * Reads a number of lines and passes the lines to be processed.
         *
         * @return The number of lines read.
         * @throws IOException If there was an error reading the file.
         */
        private int readLines() throws IOException {
            String line;
            for (int i = 0; i < MAX_ONE_TIME_READS; i++) {
                line = mBufferedReader.readLine();
                if (line == null) {
                    return i;
                }
                line.trim();
                processLine(line);
            }
            return MAX_ONE_TIME_READS;
        }
    
         /**
          * Reads one line and processes it.
          *
          * @return the number of lines read
          * @throws IOException If there was an error reading the file.
          */
        private int readOneLine() throws IOException {
            String line = mBufferedReader.readLine();
            if (line == null) {
                return 0;
            }
            line.trim();
            processLine(line);
            return 1;
        }
    
    
    
        /**
         * Creates an event and adds it to the event queue. If the parameters are
         * not understood, they are ignored and no events are added.
         *
         * @param s The entire string from the script file.
         * @param args An array of arguments extracted from the script file line.
         */
        private void handleEvent(String s, String[] args) {
            // Handle key event
            if (s.indexOf(EVENT_KEYWORD_KEY) >= 0 && args.length == 8) {
                try {
                    System.out.println(" old key\n");
                    long downTime = Long.parseLong(args[0]);
                    long eventTime = Long.parseLong(args[1]);
                    int action = Integer.parseInt(args[2]);
                    int code = Integer.parseInt(args[3]);
                    int repeat = Integer.parseInt(args[4]);
                    int metaState = Integer.parseInt(args[5]);
                    int device = Integer.parseInt(args[6]);
                    int scancode = Integer.parseInt(args[7]);
    
                    MonkeyKeyEvent e = new MonkeyKeyEvent(downTime, eventTime, action, code, repeat,
                            metaState, device, scancode);
                    System.out.println(" Key code " + code + "\n");
    
                    mQ.addLast(e);
                    System.out.println("Added key up \n");
                } catch (NumberFormatException e) {
                }
                return;
            }
    
            // Handle trackball or pointer events
            if ((s.indexOf(EVENT_KEYWORD_POINTER) >= 0 || s.indexOf(EVENT_KEYWORD_TRACKBALL) >= 0)
                    && args.length == 12) {
                try {
                    long downTime = Long.parseLong(args[0]);
                    long eventTime = Long.parseLong(args[1]);
                    int action = Integer.parseInt(args[2]);
                    float x = Float.parseFloat(args[3]);
                    float y = Float.parseFloat(args[4]);
                    float pressure = Float.parseFloat(args[5]);
                    float size = Float.parseFloat(args[6]);
                    int metaState = Integer.parseInt(args[7]);
                    float xPrecision = Float.parseFloat(args[8]);
                    float yPrecision = Float.parseFloat(args[9]);
                    int device = Integer.parseInt(args[10]);
                    int edgeFlags = Integer.parseInt(args[11]);
    
                    MonkeyMotionEvent e;
                    if (s.indexOf("Pointer") > 0) {
                        e = new MonkeyTouchEvent(action);
                    } else {
                        e = new MonkeyTrackballEvent(action);
                    }
    
                    e.setDownTime(downTime)
                            .setEventTime(eventTime)
                            .setMetaState(metaState)
                            .setPrecision(xPrecision, yPrecision)
                            .setDeviceId(device)
                            .setEdgeFlags(edgeFlags)
                            .addPointer(0, x, y, pressure, size);
                    mQ.addLast(e);
                } catch (NumberFormatException e) {
                }
                return;
            }
    
            // Handle trackball or multi-touch  pointer events. pointer ID is the 13th parameter
            if ((s.indexOf(EVENT_KEYWORD_POINTER) >= 0 || s.indexOf(EVENT_KEYWORD_TRACKBALL) >= 0)
                    && args.length == 13) {
                try {
                    long downTime = Long.parseLong(args[0]);
                    long eventTime = Long.parseLong(args[1]);
                    int action = Integer.parseInt(args[2]);
                    float x = Float.parseFloat(args[3]);
                    float y = Float.parseFloat(args[4]);
                    float pressure = Float.parseFloat(args[5]);
                    float size = Float.parseFloat(args[6]);
                    int metaState = Integer.parseInt(args[7]);
                    float xPrecision = Float.parseFloat(args[8]);
                    float yPrecision = Float.parseFloat(args[9]);
                    int device = Integer.parseInt(args[10]);
                    int edgeFlags = Integer.parseInt(args[11]);
                    int pointerId = Integer.parseInt(args[12]);
    
                    MonkeyMotionEvent e;
                    if (s.indexOf("Pointer") > 0) {
                        if (action == MotionEvent.ACTION_POINTER_DOWN) {
                            e = new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_DOWN
                                    | (pointerId << MotionEvent.ACTION_POINTER_INDEX_SHIFT))
                                            .setIntermediateNote(true);
                        } else {
                            e = new MonkeyTouchEvent(action);
                        }
                        if (mScriptStartTime < 0) {
                            mMonkeyStartTime = SystemClock.uptimeMillis();
                            mScriptStartTime = eventTime;
                        }
                    } else {
                        e = new MonkeyTrackballEvent(action);
                    }
    
                    if (pointerId == 1) {
                        e.setDownTime(downTime)
                                .setEventTime(eventTime)
                                .setMetaState(metaState)
                                .setPrecision(xPrecision, yPrecision)
                                .setDeviceId(device)
                                .setEdgeFlags(edgeFlags)
                                .addPointer(0, mLastX[0], mLastY[0], pressure, size)
                                .addPointer(1, x, y, pressure, size);
                        mLastX[1] = x;
                        mLastY[1] = y;
                    } else if (pointerId == 0) {
                        e.setDownTime(downTime)
                                .setEventTime(eventTime)
                                .setMetaState(metaState)
                                .setPrecision(xPrecision, yPrecision)
                                .setDeviceId(device)
                                .setEdgeFlags(edgeFlags)
                                .addPointer(0, x, y, pressure, size);
                         if(action == MotionEvent.ACTION_POINTER_UP) {
                             e.addPointer(1, mLastX[1], mLastY[1]);
                         }
                         mLastX[0] = x;
                         mLastY[0] = y;
                    }
    
                    // Dynamically adjust waiting time to ensure that simulated evnets follow
                    // the time tap specified in the script
                    if (mReadScriptLineByLine) {
                        long curUpTime = SystemClock.uptimeMillis();
                        long realElapsedTime = curUpTime - mMonkeyStartTime;
                        long scriptElapsedTime = eventTime - mScriptStartTime;
                        if (realElapsedTime < scriptElapsedTime) {
                            long waitDuration = scriptElapsedTime - realElapsedTime;
                            mQ.addLast(new MonkeyWaitEvent(waitDuration));
                        }
                    }
                    mQ.addLast(e);
                } catch (NumberFormatException e) {
                }
                return;
            }
    
            // Handle screen rotation events
            if ((s.indexOf(EVENT_KEYWORD_ROTATION) >= 0) && args.length == 2) {
                try {
                    int rotationDegree = Integer.parseInt(args[0]);
                    int persist = Integer.parseInt(args[1]);
                    if ((rotationDegree == Surface.ROTATION_0) ||
                        (rotationDegree == Surface.ROTATION_90) ||
                        (rotationDegree == Surface.ROTATION_180) ||
                        (rotationDegree == Surface.ROTATION_270)) {
                        mQ.addLast(new MonkeyRotationEvent(rotationDegree,
                                                           persist != 0));
                    }
                } catch (NumberFormatException e) {
                }
                return;
            }
    
            // Handle tap event
            if ((s.indexOf(EVENT_KEYWORD_TAP) >= 0) && args.length >= 2) {
                try {
                    float x = Float.parseFloat(args[0]);
                    float y = Float.parseFloat(args[1]);
                    long tapDuration = 0;
                    if (args.length == 3) {
                        tapDuration = Long.parseLong(args[2]);
                    }
    
                    // Set the default parameters
                    long downTime = SystemClock.uptimeMillis();
                    MonkeyMotionEvent e1 = new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
                            .setDownTime(downTime)
                            .setEventTime(downTime)
                            .addPointer(0, x, y, 1, 5);
                    mQ.addLast(e1);
                    if (tapDuration > 0){
                        mQ.addLast(new MonkeyWaitEvent(tapDuration));
                    }
                    MonkeyMotionEvent e2 = new MonkeyTouchEvent(MotionEvent.ACTION_UP)
                            .setDownTime(downTime)
                            .setEventTime(downTime)
                            .addPointer(0, x, y, 1, 5);
                    mQ.addLast(e2);
                } catch (NumberFormatException e) {
                    System.err.println("// " + e.toString());
                }
                return;
            }
    
            //Handle the press and hold
            if ((s.indexOf(EVENT_KEYWORD_PRESSANDHOLD) >= 0) && args.length == 3) {
                try {
                    float x = Float.parseFloat(args[0]);
                    float y = Float.parseFloat(args[1]);
                    long pressDuration = Long.parseLong(args[2]);
    
                    // Set the default parameters
                    long downTime = SystemClock.uptimeMillis();
    
                    MonkeyMotionEvent e1 = new MonkeyTouchEvent(MotionEvent.ACTION_DOWN)
                            .setDownTime(downTime)
                            .setEventTime(downTime)
                            .addPointer(0, x, y, 1, 5);
                    MonkeyWaitEvent e2 = new MonkeyWaitEvent(pressDuration);
                    MonkeyMotionEvent e3 = new MonkeyTouchEvent(MotionEvent.ACTION_UP)
                            .setDownTime(downTime + pressDuration)
                            .setEventTime(downTime + pressDuration)
                            .addPointer(0, x, y, 1, 5);
                    mQ.addLast(e1);
                    mQ.addLast(e2);
                    mQ.addLast(e2);
    
                } catch (NumberFormatException e) {
                    System.err.println("// " + e.toString());
                }
                return;
            }
    
            // Handle drag event
            if ((s.indexOf(EVENT_KEYWORD_DRAG) >= 0) && args.length == 5) {
                float xStart = Float.parseFloat(args[0]);
                float yStart = Float.parseFloat(args[1]);
                float xEnd = Float.parseFloat(args[2]);
                float yEnd = Float.parseFloat(args[3]);
                int stepCount = Integer.parseInt(args[4]);
    
                float x = xStart;
                float y = yStart;
                long downTime = SystemClock.uptimeMillis();
                long eventTime = SystemClock.uptimeMillis();
    
                if (stepCount > 0) {
                    float xStep = (xEnd - xStart) / stepCount;
                    float yStep = (yEnd - yStart) / stepCount;
    
                    MonkeyMotionEvent e =
                            new MonkeyTouchEvent(MotionEvent.ACTION_DOWN).setDownTime(downTime)
                                    .setEventTime(eventTime).addPointer(0, x, y, 1, 5);
                    mQ.addLast(e);
    
                    for (int i = 0; i < stepCount; ++i) {
                        x += xStep;
                        y += yStep;
                        eventTime = SystemClock.uptimeMillis();
                        e = new MonkeyTouchEvent(MotionEvent.ACTION_MOVE).setDownTime(downTime)
                            .setEventTime(eventTime).addPointer(0, x, y, 1, 5);
                        mQ.addLast(e);
                    }
    
                    eventTime = SystemClock.uptimeMillis();
                    e = new MonkeyTouchEvent(MotionEvent.ACTION_UP).setDownTime(downTime)
                        .setEventTime(eventTime).addPointer(0, x, y, 1, 5);
                    mQ.addLast(e);
                }
            }
    
            // Handle pinch or zoom action
            if ((s.indexOf(EVENT_KEYWORD_PINCH_ZOOM) >= 0) && args.length == 9) {
                //Parse the parameters
                float pt1xStart = Float.parseFloat(args[0]);
                float pt1yStart = Float.parseFloat(args[1]);
                float pt1xEnd = Float.parseFloat(args[2]);
                float pt1yEnd = Float.parseFloat(args[3]);
    
                float pt2xStart = Float.parseFloat(args[4]);
                float pt2yStart = Float.parseFloat(args[5]);
                float pt2xEnd = Float.parseFloat(args[6]);
                float pt2yEnd = Float.parseFloat(args[7]);
    
                int stepCount = Integer.parseInt(args[8]);
    
                float x1 = pt1xStart;
                float y1 = pt1yStart;
                float x2 = pt2xStart;
                float y2 = pt2yStart;
    
                long downTime = SystemClock.uptimeMillis();
                long eventTime = SystemClock.uptimeMillis();
    
                if (stepCount > 0) {
                    float pt1xStep = (pt1xEnd - pt1xStart) / stepCount;
                    float pt1yStep = (pt1yEnd - pt1yStart) / stepCount;
    
                    float pt2xStep = (pt2xEnd - pt2xStart) / stepCount;
                    float pt2yStep = (pt2yEnd - pt2yStart) / stepCount;
    
                    mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_DOWN).setDownTime(downTime)
                            .setEventTime(eventTime).addPointer(0, x1, y1, 1, 5));
    
                    mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_DOWN
                            | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT)).setDownTime(downTime)
                            .addPointer(0, x1, y1).addPointer(1, x2, y2).setIntermediateNote(true));
    
                    for (int i = 0; i < stepCount; ++i) {
                        x1 += pt1xStep;
                        y1 += pt1yStep;
                        x2 += pt2xStep;
                        y2 += pt2yStep;
    
                        eventTime = SystemClock.uptimeMillis();
                        mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_MOVE).setDownTime(downTime)
                                .setEventTime(eventTime).addPointer(0, x1, y1, 1, 5).addPointer(1, x2,
                                        y2, 1, 5));
                    }
                    eventTime = SystemClock.uptimeMillis();
                    mQ.addLast(new MonkeyTouchEvent(MotionEvent.ACTION_POINTER_UP)
                            .setDownTime(downTime).setEventTime(eventTime).addPointer(0, x1, y1)
                            .addPointer(1, x2, y2));
                }
            }
    
            // Handle flip events
            if (s.indexOf(EVENT_KEYWORD_FLIP) >= 0 && args.length == 1) {
                boolean keyboardOpen = Boolean.parseBoolean(args[0]);
                MonkeyFlipEvent e = new MonkeyFlipEvent(keyboardOpen);
                mQ.addLast(e);
            }
    
            // Handle launch events
            if (s.indexOf(EVENT_KEYWORD_ACTIVITY) >= 0 && args.length >= 2) {
                String pkg_name = args[0];
                String cl_name = args[1];
                long alarmTime = 0;
    
                ComponentName mApp = new ComponentName(pkg_name, cl_name);
    
                if (args.length > 2) {
                    try {
                        alarmTime = Long.parseLong(args[2]);
                    } catch (NumberFormatException e) {
                        System.err.println("// " + e.toString());
                        return;
                    }
                }
    
                if (args.length == 2) {
                    MonkeyActivityEvent e = new MonkeyActivityEvent(mApp);
                    mQ.addLast(e);
                } else {
                    MonkeyActivityEvent e = new MonkeyActivityEvent(mApp, alarmTime);
                    mQ.addLast(e);
                }
                return;
            }
    
            //Handle the device wake up event
            if (s.indexOf(EVENT_KEYWORD_DEVICE_WAKEUP) >= 0){
                String pkg_name = "com.google.android.powerutil";
                String cl_name = "com.google.android.powerutil.WakeUpScreen";
                long deviceSleepTime = mDeviceSleepTime;
    
                //Start the wakeUpScreen test activity to turn off the screen.
                ComponentName mApp = new ComponentName(pkg_name, cl_name);
                mQ.addLast(new MonkeyActivityEvent(mApp, deviceSleepTime));
    
                //inject the special key for the wakeUpScreen test activity.
                mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0));
                mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_0));
    
                //Add the wait event after the device sleep event so that the monkey
                //can continue after the device wake up.
                mQ.addLast(new MonkeyWaitEvent(deviceSleepTime + 3000));
    
                //Insert the menu key to unlock the screen
                mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU));
                mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU));
    
                //Insert the back key to dismiss the test activity
                mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK));
                mQ.addLast(new MonkeyKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));
    
                return;
            }
    
            // Handle launch instrumentation events
            if (s.indexOf(EVENT_KEYWORD_INSTRUMENTATION) >= 0 && args.length == 2) {
                String test_name = args[0];
                String runner_name = args[1];
                MonkeyInstrumentationEvent e = new MonkeyInstrumentationEvent(test_name, runner_name);
                mQ.addLast(e);
                return;
            }
    
            // Handle wait events
            if (s.indexOf(EVENT_KEYWORD_WAIT) >= 0 && args.length == 1) {
                try {
                    long sleeptime = Integer.parseInt(args[0]);
                    MonkeyWaitEvent e = new MonkeyWaitEvent(sleeptime);
                    mQ.addLast(e);
                } catch (NumberFormatException e) {
                }
                return;
            }
    
    
            // Handle the profile wait time
            if (s.indexOf(EVENT_KEYWORD_PROFILE_WAIT) >= 0) {
                MonkeyWaitEvent e = new MonkeyWaitEvent(mProfileWaitTime);
                mQ.addLast(e);
                return;
            }
    
            // Handle keypress events
            if (s.indexOf(EVENT_KEYWORD_KEYPRESS) >= 0 && args.length == 1) {
                String key_name = args[0];
                int keyCode = MonkeySourceRandom.getKeyCode(key_name);
                if (keyCode == KeyEvent.KEYCODE_UNKNOWN) {
                    return;
                }
                MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, keyCode);
                mQ.addLast(e);
                e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, keyCode);
                mQ.addLast(e);
                return;
            }
    
            // Handle longpress events
            if (s.indexOf(EVENT_KEYWORD_LONGPRESS) >= 0) {
                MonkeyKeyEvent e;
                e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER);
                mQ.addLast(e);
                MonkeyWaitEvent we = new MonkeyWaitEvent(LONGPRESS_WAIT_TIME);
                mQ.addLast(we);
                e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER);
                mQ.addLast(e);
            }
    
            //The power log event is mainly for the automated power framework
            if (s.indexOf(EVENT_KEYWORD_POWERLOG) >= 0 && args.length > 0) {
                String power_log_type = args[0];
                String test_case_status;
    
                if (args.length == 1){
                    MonkeyPowerEvent e = new MonkeyPowerEvent(power_log_type);
                    mQ.addLast(e);
                } else if (args.length == 2){
                    test_case_status = args[1];
                    MonkeyPowerEvent e = new MonkeyPowerEvent(power_log_type, test_case_status);
                    mQ.addLast(e);
                }
            }
    
            //Write power log to sdcard
            if (s.indexOf(EVENT_KEYWORD_WRITEPOWERLOG) >= 0) {
                MonkeyPowerEvent e = new MonkeyPowerEvent();
                mQ.addLast(e);
            }
    
            //Run the shell command
            if (s.indexOf(EVENT_KEYWORD_RUNCMD) >= 0 && args.length == 1) {
                String cmd = args[0];
                MonkeyCommandEvent e = new MonkeyCommandEvent(cmd);
                mQ.addLast(e);
            }
    
            //Input the string through the shell command
            if (s.indexOf(EVENT_KEYWORD_INPUT_STRING) >= 0 && args.length == 1) {
                String input = args[0];
                String cmd = "input text " + input;
                MonkeyCommandEvent e = new MonkeyCommandEvent(cmd);
                mQ.addLast(e);
                return;
            }
    
            if (s.indexOf(EVENT_KEYWORD_START_FRAMERATE_CAPTURE) >= 0) {
                MonkeyGetFrameRateEvent e = new MonkeyGetFrameRateEvent("start");
                mQ.addLast(e);
                return;
            }
    
            if (s.indexOf(EVENT_KEYWORD_END_FRAMERATE_CAPTURE) >= 0 && args.length == 1) {
                String input = args[0];
                MonkeyGetFrameRateEvent e = new MonkeyGetFrameRateEvent("end", input);
                mQ.addLast(e);
                return;
            }
    
            if (s.indexOf(EVENT_KEYWORD_START_APP_FRAMERATE_CAPTURE) >= 0 && args.length == 1) {
                String app = args[0];
                MonkeyGetAppFrameRateEvent e = new MonkeyGetAppFrameRateEvent("start", app);
                mQ.addLast(e);
                return;
            }
    
            if (s.indexOf(EVENT_KEYWORD_END_APP_FRAMERATE_CAPTURE) >= 0 && args.length == 2) {
                String app = args[0];
                String label = args[1];
                MonkeyGetAppFrameRateEvent e = new MonkeyGetAppFrameRateEvent("end", app, label);
                mQ.addLast(e);
                return;
            }
    
    
        }
    
        /**
         * Extracts an event and a list of arguments from a line. If the line does
         * not match the format required, it is ignored.
         *
         * @param line A string in the form {@code cmd(arg1,arg2,arg3)}.
         */
        private void processLine(String line) {
            int index1 = line.indexOf('(');
            int index2 = line.indexOf(')');
    
            if (index1 < 0 || index2 < 0) {
                return;
            }
    
            String[] args = line.substring(index1 + 1, index2).split(",");
    
            for (int i = 0; i < args.length; i++) {
                args[i] = args[i].trim();
            }
    
            handleEvent(line, args);
        }
    
        /**
         * Closes the script file.
         *
         * @throws IOException If there was an error closing the file.
         */
        private void closeFile() throws IOException {
            mFileOpened = false;
    
            try {
                mFStream.close();
                mInputStream.close();
            } catch (NullPointerException e) {
                // File was never opened so it can't be closed.
            }
        }
    
        /**
         * Read next batch of events from the script file into the event queue.
         * Checks if the script is open and then reads the next MAX_ONE_TIME_READS
         * events or reads until the end of the file. If no events are read, then
         * the script is closed.
         *
         * @throws IOException If there was an error reading the file.
         */
        private void readNextBatch() throws IOException {
            int linesRead = 0;
    
            if (THIS_DEBUG) {
                System.out.println("readNextBatch(): reading next batch of events");
            }
    
            if (!mFileOpened) {
                resetValue();
                readHeader();
            }
    
            if (mReadScriptLineByLine) {
                linesRead = readOneLine();
            } else {
                linesRead = readLines();
            }
    
            if (linesRead == 0) {
                closeFile();
            }
        }
    
        /**
         * Sleep for a period of given time. Used to introduce latency between
         * events.
         *
         * @param time The amount of time to sleep in ms
         */
        private void needSleep(long time) {
            if (time < 1) {
                return;
            }
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
            }
        }
    
        /**
         * Checks if the file can be opened and if the header is valid.
         *
         * @return True if the file exists and the header is valid, false otherwise.
         */
        @Override
        public boolean validate() {
            boolean validHeader;
            try {
                validHeader = readHeader();
                closeFile();
            } catch (IOException e) {
                return false;
            }
    
            if (mVerbose > 0) {
                System.out.println("Replaying " + mEventCountInScript + " events with speed " + mSpeed);
            }
            return validHeader;
        }
    
        @Override
        public void setVerbose(int verbose) {
            mVerbose = verbose;
        }
    
        /**
         * Adjust key downtime and eventtime according to both recorded values and
         * current system time.
         *
         * @param e A KeyEvent
         */
        private void adjustKeyEventTime(MonkeyKeyEvent e) {
            if (e.getEventTime() < 0) {
                return;
            }
            long thisDownTime = 0;
            long thisEventTime = 0;
            long expectedDelay = 0;
    
            if (mLastRecordedEventTime <= 0) {
                // first time event
                thisDownTime = SystemClock.uptimeMillis();
                thisEventTime = thisDownTime;
            } else {
                if (e.getDownTime() != mLastRecordedDownTimeKey) {
                    thisDownTime = e.getDownTime();
                } else {
                    thisDownTime = mLastExportDownTimeKey;
                }
                expectedDelay = (long) ((e.getEventTime() - mLastRecordedEventTime) * mSpeed);
                thisEventTime = mLastExportEventTime + expectedDelay;
                // add sleep to simulate everything in recording
                needSleep(expectedDelay - SLEEP_COMPENSATE_DIFF);
            }
            mLastRecordedDownTimeKey = e.getDownTime();
            mLastRecordedEventTime = e.getEventTime();
            e.setDownTime(thisDownTime);
            e.setEventTime(thisEventTime);
            mLastExportDownTimeKey = thisDownTime;
            mLastExportEventTime = thisEventTime;
        }
    
        /**
         * Adjust motion downtime and eventtime according to current system time.
         *
         * @param e A MotionEvent
         */
        private void adjustMotionEventTime(MonkeyMotionEvent e) {
            long thisEventTime = SystemClock.uptimeMillis();
            long thisDownTime = e.getDownTime();
    
            if (thisDownTime == mLastRecordedDownTimeMotion) {
                // this event is the same batch as previous one
                e.setDownTime(mLastExportDownTimeMotion);
            } else {
                // this event is the start of a new batch
                mLastRecordedDownTimeMotion = thisDownTime;
                // update down time to match current time
                e.setDownTime(thisEventTime);
                mLastExportDownTimeMotion = thisEventTime;
            }
            // always refresh event time
            e.setEventTime(thisEventTime);
        }
    
        /**
         * Gets the next event to be injected from the script. If the event queue is
         * empty, reads the next n events from the script into the queue, where n is
         * the lesser of the number of remaining events and the value specified by
         * MAX_ONE_TIME_READS. If the end of the file is reached, no events are
         * added to the queue and null is returned.
         *
         * @return The first event in the event queue or null if the end of the file
         *         is reached or if an error is encountered reading the file.
         */
        @Override
        public MonkeyEvent getNextEvent() {
            long recordedEventTime = -1;
            MonkeyEvent ev;
    
            if (mQ.isEmpty()) {
                try {
                    readNextBatch();
                } catch (IOException e) {
                    return null;
                }
            }
    
            try {
                ev = mQ.getFirst();
                mQ.removeFirst();
            } catch (NoSuchElementException e) {
                return null;
            }
    
            if (ev.getEventType() == MonkeyEvent.EVENT_TYPE_KEY) {
                adjustKeyEventTime((MonkeyKeyEvent) ev);
            } else if (ev.getEventType() == MonkeyEvent.EVENT_TYPE_TOUCH
                    || ev.getEventType() == MonkeyEvent.EVENT_TYPE_TRACKBALL) {
                adjustMotionEventTime((MonkeyMotionEvent) ev);
            }
            return ev;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:MonkeySourceScript.java 源码

          本文链接:https://www.haomeiwen.com/subject/okjdwctx.html