diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java index f739f2d40..fcf08931b 100644 --- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java +++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java @@ -34,6 +34,7 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserId; import android.view.IWindowManager; +import android.view.Surface; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -204,6 +205,8 @@ public class Monkey { long mDroppedFlipEvents = 0; + long mDroppedRotationEvents = 0; + /** The delay between user actions. This is for the scripted monkey. **/ long mProfileWaitTime = 5000; @@ -608,7 +611,15 @@ public class Monkey { } mNetworkMonitor.start(); - int crashedAtCycle = runMonkeyCycles(); + int crashedAtCycle = 0; + try { + crashedAtCycle = runMonkeyCycles(); + } finally { + // Release the rotation lock if it's still held and restore the + // original orientation. + new MonkeyRotationEvent(Surface.ROTATION_0, false).injectEvent( + mWm, mAm, mVerbose); + } mNetworkMonitor.stop(); synchronized (this) { @@ -662,7 +673,9 @@ public class Monkey { System.out.print(" trackballs="); System.out.print(mDroppedTrackballEvents); System.out.print(" flips="); - System.out.println(mDroppedFlipEvents); + System.out.print(mDroppedFlipEvents); + System.out.print(" rotations="); + System.out.println(mDroppedRotationEvents); } // report network stats @@ -726,6 +739,9 @@ public class Monkey { } else if (opt.equals("--pct-trackball")) { int i = MonkeySourceRandom.FACTOR_TRACKBALL; mFactors[i] = -nextOptionLong("trackball events percentage"); + } else if (opt.equals("--pct-rotation")) { + int i = MonkeySourceRandom.FACTOR_ROTATION; + mFactors[i] = -nextOptionLong("screen rotation events percentage"); } else if (opt.equals("--pct-syskeys")) { int i = MonkeySourceRandom.FACTOR_SYSOPS; mFactors[i] = -nextOptionLong("system (key) operations percentage"); @@ -1082,6 +1098,8 @@ public class Monkey { mDroppedPointerEvents++; } else if (ev instanceof MonkeyFlipEvent) { mDroppedFlipEvents++; + } else if (ev instanceof MonkeyRotationEvent) { + mDroppedRotationEvents++; } } else if (injectCode == MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION) { systemCrashed = true; diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java index 1f703eabc..0a06604ac 100644 --- a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java @@ -27,10 +27,11 @@ public abstract class MonkeyEvent { public static final int EVENT_TYPE_KEY = 0; public static final int EVENT_TYPE_TOUCH = 1; public static final int EVENT_TYPE_TRACKBALL = 2; - public static final int EVENT_TYPE_ACTIVITY = 3; - public static final int EVENT_TYPE_FLIP = 4; // Keyboard flip - public static final int EVENT_TYPE_THROTTLE = 5; - public static final int EVENT_TYPE_NOOP = 6; + public static final int EVENT_TYPE_ROTATION = 3; // Screen rotation + public static final int EVENT_TYPE_ACTIVITY = 4; + public static final int EVENT_TYPE_FLIP = 5; // Keyboard flip + public static final int EVENT_TYPE_THROTTLE = 6; + public static final int EVENT_TYPE_NOOP = 7; public static final int INJECT_SUCCESS = 1; public static final int INJECT_FAIL = 0; diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyRotationEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyRotationEvent.java new file mode 100644 index 000000000..26108ecb3 --- /dev/null +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyRotationEvent.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2012 Google Inc. + * + * 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.app.IActivityManager; +import android.os.RemoteException; +import android.view.IWindowManager; +/** + * monkey screen rotation event + */ +public class MonkeyRotationEvent extends MonkeyEvent { + + private final int mRotationDegree; + private final boolean mPersist; + + /** + * Construct a rotation Event. + * + * @param degree Possible rotation degrees, see constants in + * anroid.view.Suface. + * @param persist Should we keep the rotation lock after the orientation + * change. + */ + public MonkeyRotationEvent(int degree, boolean persist) { + super(EVENT_TYPE_ROTATION); + mRotationDegree = degree; + mPersist = persist; + } + + @Override + public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) { + if (verbose > 0) { + System.out.println(":Sending rotation degree=" + mRotationDegree + + ", persist=" + mPersist); + } + + // inject rotation event + try { + iwm.freezeRotation(mRotationDegree); + if (!mPersist) { + iwm.thawRotation(); + } + return MonkeyEvent.INJECT_SUCCESS; + } catch (RemoteException ex) { + return MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION; + } + } +} diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java index c18152bf0..3d940a88e 100644 --- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java @@ -23,6 +23,7 @@ import android.view.Display; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.Surface; import android.view.WindowManagerImpl; import java.util.ArrayList; @@ -63,18 +64,26 @@ public class MonkeySourceRandom implements MonkeyEventSource { PHYSICAL_KEY_EXISTS[SYS_KEYS[i]] = KeyCharacterMap.deviceHasKey(SYS_KEYS[i]); } } + /** Possible screen rotation degrees **/ + private static final int[] SCREEN_ROTATION_DEGREES = { + Surface.ROTATION_0, + Surface.ROTATION_90, + Surface.ROTATION_180, + Surface.ROTATION_270, + }; public static final int FACTOR_TOUCH = 0; public static final int FACTOR_MOTION = 1; public static final int FACTOR_PINCHZOOM = 2; public static final int FACTOR_TRACKBALL = 3; - public static final int FACTOR_NAV = 4; - public static final int FACTOR_MAJORNAV = 5; - public static final int FACTOR_SYSOPS = 6; - public static final int FACTOR_APPSWITCH = 7; - public static final int FACTOR_FLIP = 8; - public static final int FACTOR_ANYTHING = 9; - public static final int FACTORZ_COUNT = 10; // should be last+1 + public static final int FACTOR_ROTATION = 4; + public static final int FACTOR_NAV = 5; + public static final int FACTOR_MAJORNAV = 6; + public static final int FACTOR_SYSOPS = 7; + public static final int FACTOR_APPSWITCH = 8; + public static final int FACTOR_FLIP = 9; + public static final int FACTOR_ANYTHING = 10; + public static final int FACTORZ_COUNT = 11; // should be last+1 private static final int GESTURE_TAP = 0; private static final int GESTURE_DRAG = 1; @@ -116,6 +125,8 @@ public class MonkeySourceRandom implements MonkeyEventSource { mFactors[FACTOR_TOUCH] = 15.0f; mFactors[FACTOR_MOTION] = 10.0f; mFactors[FACTOR_TRACKBALL] = 15.0f; + // Adjust the values if we want to enable rotation by default. + mFactors[FACTOR_ROTATION] = 0.0f; mFactors[FACTOR_NAV] = 25.0f; mFactors[FACTOR_MAJORNAV] = 15.0f; mFactors[FACTOR_SYSOPS] = 2.0f; @@ -369,6 +380,18 @@ public class MonkeySourceRandom implements MonkeyEventSource { } } + /** + * Generates a random screen rotation event. + * + * @param random Random number source for rotation degree. + */ + private void generateRotationEvent(Random random) { + mQ.addLast(new MonkeyRotationEvent( + SCREEN_ROTATION_DEGREES[random.nextInt( + SCREEN_ROTATION_DEGREES.length)], + random.nextBoolean())); + } + /** * generate a random event based on mFactor */ @@ -388,6 +411,9 @@ public class MonkeySourceRandom implements MonkeyEventSource { } else if (cls < mFactors[FACTOR_TRACKBALL]) { generateTrackballEvent(mRandom); return; + } else if (cls < mFactors[FACTOR_ROTATION]) { + generateRotationEvent(mRandom); + return; } // The remaining event categories are injected as key events diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java index 5b050bfec..e1569f887 100644 --- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java @@ -20,6 +20,7 @@ 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; @@ -85,6 +86,8 @@ public class MonkeySourceScript implements MonkeyEventSource { 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"; @@ -299,6 +302,23 @@ public class MonkeySourceScript implements MonkeyEventSource { 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 {