teach monkey to flip permissions on apps
1. added a new MonkeyEvent type for permission events 2. added monkey permission utility for randomized permission events generation against targeted packages 3. refactored package whitelist/blacklist into MonkeyUtils class Change-Id: I8f7998d74c3e28d02f5bcd47a0f9cc6167b93c93
This commit is contained in:
@@ -31,15 +31,12 @@ import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.StrictMode;
|
||||
import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.Surface;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
@@ -47,12 +44,12 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Writer;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Application that injects random key events and other actions into the system.
|
||||
@@ -181,12 +178,6 @@ public class Monkey {
|
||||
/** Package whitelist file. */
|
||||
private String mPkgWhitelistFile;
|
||||
|
||||
/** Packages we are allowed to run, or empty if no restriction. */
|
||||
private HashSet<String> mValidPackages = new HashSet<String>();
|
||||
|
||||
/** Packages we are not allowed to run. */
|
||||
private HashSet<String> mInvalidPackages = new HashSet<String>();
|
||||
|
||||
/** Categories we are allowed to launch **/
|
||||
private ArrayList<String> mMainCategories = new ArrayList<String>();
|
||||
|
||||
@@ -251,36 +242,20 @@ public class Monkey {
|
||||
|
||||
private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor();
|
||||
|
||||
private boolean mPermissionTargetSystem = false;
|
||||
|
||||
// information on the current activity.
|
||||
public static Intent currentIntent;
|
||||
|
||||
public static String currentPackage;
|
||||
|
||||
/**
|
||||
* Check whether we should run against the givn package.
|
||||
*
|
||||
* @param pkg The package name.
|
||||
* @return Returns true if we should run against pkg.
|
||||
*/
|
||||
private boolean checkEnteringPackage(String pkg) {
|
||||
if (mInvalidPackages.size() > 0) {
|
||||
if (mInvalidPackages.contains(pkg)) {
|
||||
return false;
|
||||
}
|
||||
} else if (mValidPackages.size() > 0) {
|
||||
if (!mValidPackages.contains(pkg)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitor operations happening in the system.
|
||||
*/
|
||||
private class ActivityController extends IActivityController.Stub {
|
||||
public boolean activityStarting(Intent intent, String pkg) {
|
||||
boolean allow = checkEnteringPackage(pkg) || (DEBUG_ALLOW_ANY_STARTS != 0);
|
||||
boolean allow = MonkeyUtils.getPackageFilter().checkEnteringPackage(pkg)
|
||||
|| (DEBUG_ALLOW_ANY_STARTS != 0);
|
||||
if (mVerbose > 0) {
|
||||
// StrictMode's disk checks end up catching this on
|
||||
// userdebug/eng builds due to PrintStream going to a
|
||||
@@ -301,7 +276,8 @@ public class Monkey {
|
||||
public boolean activityResuming(String pkg) {
|
||||
StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
|
||||
System.out.println(" // activityResuming(" + pkg + ")");
|
||||
boolean allow = checkEnteringPackage(pkg) || (DEBUG_ALLOW_ANY_RESTARTS != 0);
|
||||
boolean allow = MonkeyUtils.getPackageFilter().checkEnteringPackage(pkg)
|
||||
|| (DEBUG_ALLOW_ANY_RESTARTS != 0);
|
||||
if (!allow) {
|
||||
if (mVerbose > 0) {
|
||||
System.out.println(" // " + (allow ? "Allowing" : "Rejecting")
|
||||
@@ -559,18 +535,7 @@ public class Monkey {
|
||||
|
||||
if (mVerbose > 0) {
|
||||
System.out.println(":Monkey: seed=" + mSeed + " count=" + mCount);
|
||||
if (mValidPackages.size() > 0) {
|
||||
Iterator<String> it = mValidPackages.iterator();
|
||||
while (it.hasNext()) {
|
||||
System.out.println(":AllowPackage: " + it.next());
|
||||
}
|
||||
}
|
||||
if (mInvalidPackages.size() > 0) {
|
||||
Iterator<String> it = mInvalidPackages.iterator();
|
||||
while (it.hasNext()) {
|
||||
System.out.println(":DisallowPackage: " + it.next());
|
||||
}
|
||||
}
|
||||
MonkeyUtils.getPackageFilter().dump();
|
||||
if (mMainCategories.size() != 0) {
|
||||
Iterator<String> it = mMainCategories.iterator();
|
||||
while (it.hasNext()) {
|
||||
@@ -626,7 +591,8 @@ public class Monkey {
|
||||
if (mVerbose >= 2) { // check seeding performance
|
||||
System.out.println("// Seeded: " + mSeed);
|
||||
}
|
||||
mEventSource = new MonkeySourceRandom(mRandom, mMainApps, mThrottle, mRandomizeThrottle);
|
||||
mEventSource = new MonkeySourceRandom(mRandom, mMainApps,
|
||||
mThrottle, mRandomizeThrottle, mPermissionTargetSystem);
|
||||
mEventSource.setVerbose(mVerbose);
|
||||
// set any of the factors that has been set
|
||||
for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) {
|
||||
@@ -756,11 +722,12 @@ public class Monkey {
|
||||
|
||||
try {
|
||||
String opt;
|
||||
Set<String> validPackages = new HashSet<>();
|
||||
while ((opt = nextOption()) != null) {
|
||||
if (opt.equals("-s")) {
|
||||
mSeed = nextOptionLong("Seed");
|
||||
} else if (opt.equals("-p")) {
|
||||
mValidPackages.add(nextOptionData());
|
||||
validPackages.add(nextOptionData());
|
||||
} else if (opt.equals("-c")) {
|
||||
mMainCategories.add(nextOptionData());
|
||||
} else if (opt.equals("-v")) {
|
||||
@@ -812,6 +779,9 @@ public class Monkey {
|
||||
} else if (opt.equals("--pct-pinchzoom")) {
|
||||
int i = MonkeySourceRandom.FACTOR_PINCHZOOM;
|
||||
mFactors[i] = -nextOptionLong("pinch zoom events percentage");
|
||||
} else if (opt.equals("--pct-permission")) {
|
||||
int i = MonkeySourceRandom.FACTOR_PERMISSION;
|
||||
mFactors[i] = -nextOptionLong("runtime permission toggle events percentage");
|
||||
} else if (opt.equals("--pkg-blacklist-file")) {
|
||||
mPkgBlacklistFile = nextOptionData();
|
||||
} else if (opt.equals("--pkg-whitelist-file")) {
|
||||
@@ -845,6 +815,8 @@ public class Monkey {
|
||||
} else if (opt.equals("--periodic-bugreport")){
|
||||
mGetPeriodicBugreport = true;
|
||||
mBugreportFrequency = nextOptionLong("Number of iterations");
|
||||
} else if (opt.equals("--permission-target-system")){
|
||||
mPermissionTargetSystem = true;
|
||||
} else if (opt.equals("-h")) {
|
||||
showUsage();
|
||||
return false;
|
||||
@@ -854,6 +826,7 @@ public class Monkey {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
MonkeyUtils.getPackageFilter().addValidPackages(validPackages);
|
||||
} catch (RuntimeException ex) {
|
||||
System.err.println("** Error: " + ex.toString());
|
||||
showUsage();
|
||||
@@ -889,7 +862,7 @@ public class Monkey {
|
||||
* @param list The destination list.
|
||||
* @return Returns false if any error occurs.
|
||||
*/
|
||||
private static boolean loadPackageListFromFile(String fileName, HashSet<String> list) {
|
||||
private static boolean loadPackageListFromFile(String fileName, Set<String> list) {
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new FileReader(fileName));
|
||||
@@ -921,20 +894,24 @@ public class Monkey {
|
||||
* @return Returns false if any error occurs.
|
||||
*/
|
||||
private boolean loadPackageLists() {
|
||||
if (((mPkgWhitelistFile != null) || (mValidPackages.size() > 0))
|
||||
if (((mPkgWhitelistFile != null) || (MonkeyUtils.getPackageFilter().hasValidPackages()))
|
||||
&& (mPkgBlacklistFile != null)) {
|
||||
System.err.println("** Error: you can not specify a package blacklist "
|
||||
+ "together with a whitelist or individual packages (via -p).");
|
||||
return false;
|
||||
}
|
||||
Set<String> validPackages = new HashSet<>();
|
||||
if ((mPkgWhitelistFile != null)
|
||||
&& (!loadPackageListFromFile(mPkgWhitelistFile, mValidPackages))) {
|
||||
&& (!loadPackageListFromFile(mPkgWhitelistFile, validPackages))) {
|
||||
return false;
|
||||
}
|
||||
MonkeyUtils.getPackageFilter().addValidPackages(validPackages);
|
||||
Set<String> invalidPackages = new HashSet<>();
|
||||
if ((mPkgBlacklistFile != null)
|
||||
&& (!loadPackageListFromFile(mPkgBlacklistFile, mInvalidPackages))) {
|
||||
&& (!loadPackageListFromFile(mPkgBlacklistFile, invalidPackages))) {
|
||||
return false;
|
||||
}
|
||||
MonkeyUtils.getPackageFilter().addInvalidPackages(invalidPackages);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1014,7 +991,7 @@ public class Monkey {
|
||||
for (int a = 0; a < NA; a++) {
|
||||
ResolveInfo r = mainApps.get(a);
|
||||
String packageName = r.activityInfo.applicationInfo.packageName;
|
||||
if (checkEnteringPackage(packageName)) {
|
||||
if (MonkeyUtils.getPackageFilter().checkEnteringPackage(packageName)) {
|
||||
if (mVerbose >= 2) { // very verbose
|
||||
System.out.println("// + Using main activity " + r.activityInfo.name
|
||||
+ " (from package " + packageName + ")");
|
||||
@@ -1352,6 +1329,7 @@ public class Monkey {
|
||||
usage.append(" [--pct-nav PERCENT] [--pct-majornav PERCENT]\n");
|
||||
usage.append(" [--pct-appswitch PERCENT] [--pct-flip PERCENT]\n");
|
||||
usage.append(" [--pct-anyevent PERCENT] [--pct-pinchzoom PERCENT]\n");
|
||||
usage.append(" [--pct-permission PERCENT]\n");
|
||||
usage.append(" [--pkg-blacklist-file PACKAGE_BLACKLIST_FILE]\n");
|
||||
usage.append(" [--pkg-whitelist-file PACKAGE_WHITELIST_FILE]\n");
|
||||
usage.append(" [--wait-dbg] [--dbg-no-events]\n");
|
||||
@@ -1365,6 +1343,7 @@ public class Monkey {
|
||||
usage.append(" [--script-log]\n");
|
||||
usage.append(" [--bugreport]\n");
|
||||
usage.append(" [--periodic-bugreport]\n");
|
||||
usage.append(" [--permission-target-system]\n");
|
||||
usage.append(" COUNT\n");
|
||||
System.err.println(usage.toString());
|
||||
}
|
||||
|
||||
@@ -31,7 +31,8 @@ public abstract class MonkeyEvent {
|
||||
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 EVENT_TYPE_PERMISSION = 7;
|
||||
public static final int EVENT_TYPE_NOOP = 8;
|
||||
|
||||
public static final int INJECT_SUCCESS = 1;
|
||||
public static final int INJECT_FAIL = 0;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.app.IActivityManager;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.view.IWindowManager;
|
||||
|
||||
public class MonkeyPermissionEvent extends MonkeyEvent {
|
||||
private String mPkg;
|
||||
private PermissionInfo mPermissionInfo;
|
||||
|
||||
public MonkeyPermissionEvent(String pkg, PermissionInfo permissionInfo) {
|
||||
super(EVENT_TYPE_PERMISSION);
|
||||
mPkg = pkg;
|
||||
mPermissionInfo = permissionInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
|
||||
IPackageManager pm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
|
||||
try {
|
||||
// determine if we should grant or revoke permission
|
||||
int perm = pm.checkPermission(mPermissionInfo.name, mPkg, UserHandle.myUserId());
|
||||
boolean grant = perm == PackageManager.PERMISSION_DENIED;
|
||||
// log before calling pm in case we hit an error
|
||||
System.out.println(String.format(":Permission %s %s to package %s",
|
||||
grant ? "grant" : "revoke", mPermissionInfo.name, mPkg));
|
||||
if (grant) {
|
||||
pm.grantRuntimePermission(mPkg, mPermissionInfo.name, UserHandle.myUserId());
|
||||
} else {
|
||||
pm.revokeRuntimePermission(mPkg, mPermissionInfo.name, UserHandle.myUserId());
|
||||
}
|
||||
return MonkeyEvent.INJECT_SUCCESS;
|
||||
} catch (RemoteException re) {
|
||||
return MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.Manifest;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.os.Build;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Utility class that encapsulates runtime permission related methods for monkey
|
||||
*
|
||||
*/
|
||||
public class MonkeyPermissionUtil {
|
||||
|
||||
private static final String PERMISSION_PREFIX = "android.permission.";
|
||||
private static final String PERMISSION_GROUP_PREFIX = "android.permission-group.";
|
||||
|
||||
// from com.android.packageinstaller.permission.utils
|
||||
private static final String[] MODERN_PERMISSION_GROUPS = {
|
||||
Manifest.permission_group.CALENDAR, Manifest.permission_group.CAMERA,
|
||||
Manifest.permission_group.CONTACTS, Manifest.permission_group.LOCATION,
|
||||
Manifest.permission_group.SENSORS, Manifest.permission_group.SMS,
|
||||
Manifest.permission_group.PHONE, Manifest.permission_group.MICROPHONE,
|
||||
Manifest.permission_group.STORAGE
|
||||
};
|
||||
|
||||
// from com.android.packageinstaller.permission.utils
|
||||
private static boolean isModernPermissionGroup(String name) {
|
||||
for (String modernGroup : MODERN_PERMISSION_GROUPS) {
|
||||
if (modernGroup.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* actual list of packages to target, with invalid packages excluded, and may optionally include
|
||||
* system packages
|
||||
*/
|
||||
private List<String> mTargetedPackages;
|
||||
/** if we should target system packages regardless if they are listed */
|
||||
private boolean mTargetSystemPackages;
|
||||
private IPackageManager mPm;
|
||||
|
||||
/** keep track of runtime permissions requested for each package targeted */
|
||||
private Map<String, List<PermissionInfo>> mPermissionMap;
|
||||
|
||||
public MonkeyPermissionUtil() {
|
||||
mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
|
||||
}
|
||||
|
||||
public void setTargetSystemPackages(boolean targetSystemPackages) {
|
||||
mTargetSystemPackages = targetSystemPackages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide if a package should be targeted by permission monkey
|
||||
* @param info
|
||||
* @return
|
||||
*/
|
||||
private boolean shouldTargetPackage(PackageInfo info) {
|
||||
// target if permitted by white listing / black listing rules
|
||||
if (MonkeyUtils.getPackageFilter().checkEnteringPackage(info.packageName)) {
|
||||
return true;
|
||||
}
|
||||
if (mTargetSystemPackages
|
||||
// not explicitly black listed
|
||||
&& !MonkeyUtils.getPackageFilter().isPackageInvalid(info.packageName)
|
||||
// is a system app
|
||||
&& (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean shouldTargetPermission(String pkg, PermissionInfo pi) throws RemoteException {
|
||||
int flags = mPm.getPermissionFlags(pi.name, pkg, UserHandle.myUserId());
|
||||
int fixedPermFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
|
||||
| PackageManager.FLAG_PERMISSION_POLICY_FIXED;
|
||||
return pi.group != null && pi.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS
|
||||
&& ((flags & fixedPermFlags) == 0)
|
||||
&& isModernPermissionGroup(pi.group);
|
||||
}
|
||||
|
||||
public boolean populatePermissionsMapping() {
|
||||
mPermissionMap = new HashMap<>();
|
||||
try {
|
||||
List<?> pkgInfos = mPm.getInstalledPackages(
|
||||
PackageManager.GET_PERMISSIONS, UserHandle.myUserId()).getList();
|
||||
for (Object o : pkgInfos) {
|
||||
PackageInfo info = (PackageInfo)o;
|
||||
if (!shouldTargetPackage(info)) {
|
||||
continue;
|
||||
}
|
||||
List<PermissionInfo> permissions = new ArrayList<>();
|
||||
if (info.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||
// skip apps targetting lower API level
|
||||
continue;
|
||||
}
|
||||
if (info.requestedPermissions == null) {
|
||||
continue;
|
||||
}
|
||||
for (String perm : info.requestedPermissions) {
|
||||
PermissionInfo pi = mPm.getPermissionInfo(perm, 0);
|
||||
if (pi != null && shouldTargetPermission(info.packageName, pi)) {
|
||||
permissions.add(pi);
|
||||
}
|
||||
}
|
||||
if (!permissions.isEmpty()) {
|
||||
mPermissionMap.put(info.packageName, permissions);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
System.err.println("** Failed talking with package manager!");
|
||||
return false;
|
||||
}
|
||||
if (!mPermissionMap.isEmpty()) {
|
||||
mTargetedPackages = new ArrayList<>(mPermissionMap.keySet());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void dump() {
|
||||
System.out.println("// Targeted packages and permissions:");
|
||||
for (Map.Entry<String, List<PermissionInfo>> e : mPermissionMap.entrySet()) {
|
||||
System.out.println(String.format("// + Using %s", e.getKey()));
|
||||
for (PermissionInfo pi : e.getValue()) {
|
||||
String name = pi.name;
|
||||
if (name != null) {
|
||||
if (name.startsWith(PERMISSION_PREFIX)) {
|
||||
name = name.substring(PERMISSION_PREFIX.length());
|
||||
}
|
||||
}
|
||||
String group = pi.group;
|
||||
if (group != null) {
|
||||
if (group.startsWith(PERMISSION_GROUP_PREFIX)) {
|
||||
group = group.substring(PERMISSION_GROUP_PREFIX.length());
|
||||
}
|
||||
}
|
||||
System.out.println(String.format("// Permission: %s [%s]", name, group));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MonkeyPermissionEvent generateRandomPermissionEvent(Random random) {
|
||||
String pkg = mTargetedPackages.get(random.nextInt(mTargetedPackages.size()));
|
||||
List<PermissionInfo> infos = mPermissionMap.get(pkg);
|
||||
return new MonkeyPermissionEvent(pkg, infos.get(random.nextInt(infos.size())));
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
@@ -82,8 +82,9 @@ public class MonkeySourceRandom implements MonkeyEventSource {
|
||||
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
|
||||
public static final int FACTOR_PERMISSION = 10;
|
||||
public static final int FACTOR_ANYTHING = 11;
|
||||
public static final int FACTORZ_COUNT = 12; // should be last+1
|
||||
|
||||
private static final int GESTURE_TAP = 0;
|
||||
private static final int GESTURE_DRAG = 1;
|
||||
@@ -93,12 +94,13 @@ public class MonkeySourceRandom implements MonkeyEventSource {
|
||||
* values after we read any optional values.
|
||||
**/
|
||||
private float[] mFactors = new float[FACTORZ_COUNT];
|
||||
private ArrayList<ComponentName> mMainApps;
|
||||
private List<ComponentName> mMainApps;
|
||||
private int mEventCount = 0; //total number of events generated so far
|
||||
private MonkeyEventQueue mQ;
|
||||
private Random mRandom;
|
||||
private int mVerbose = 0;
|
||||
private long mThrottle = 0;
|
||||
private MonkeyPermissionUtil mPermissionUtil;
|
||||
|
||||
private boolean mKeyboardOpen = false;
|
||||
|
||||
@@ -117,8 +119,8 @@ public class MonkeySourceRandom implements MonkeyEventSource {
|
||||
return KeyEvent.keyCodeFromString(keyName);
|
||||
}
|
||||
|
||||
public MonkeySourceRandom(Random random, ArrayList<ComponentName> MainApps,
|
||||
long throttle, boolean randomizeThrottle) {
|
||||
public MonkeySourceRandom(Random random, List<ComponentName> MainApps,
|
||||
long throttle, boolean randomizeThrottle, boolean permissionTargetSystem) {
|
||||
// default values for random distributions
|
||||
// note, these are straight percentages, to match user input (cmd line args)
|
||||
// but they will be converted to 0..1 values before the main loop runs.
|
||||
@@ -132,12 +134,16 @@ public class MonkeySourceRandom implements MonkeyEventSource {
|
||||
mFactors[FACTOR_SYSOPS] = 2.0f;
|
||||
mFactors[FACTOR_APPSWITCH] = 2.0f;
|
||||
mFactors[FACTOR_FLIP] = 1.0f;
|
||||
// disbale permission by default
|
||||
mFactors[FACTOR_PERMISSION] = 0.0f;
|
||||
mFactors[FACTOR_ANYTHING] = 13.0f;
|
||||
mFactors[FACTOR_PINCHZOOM] = 2.0f;
|
||||
|
||||
mRandom = random;
|
||||
mMainApps = MainApps;
|
||||
mQ = new MonkeyEventQueue(random, throttle, randomizeThrottle);
|
||||
mPermissionUtil = new MonkeyPermissionUtil();
|
||||
mPermissionUtil.setTargetSystemPackages(permissionTargetSystem);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -410,6 +416,9 @@ public class MonkeySourceRandom implements MonkeyEventSource {
|
||||
} else if (cls < mFactors[FACTOR_ROTATION]) {
|
||||
generateRotationEvent(mRandom);
|
||||
return;
|
||||
} else if (cls < mFactors[FACTOR_PERMISSION]) {
|
||||
mQ.add(mPermissionUtil.generateRandomPermissionEvent(mRandom));
|
||||
return;
|
||||
}
|
||||
|
||||
// The remaining event categories are injected as key events
|
||||
@@ -450,8 +459,15 @@ public class MonkeySourceRandom implements MonkeyEventSource {
|
||||
}
|
||||
|
||||
public boolean validate() {
|
||||
//check factors
|
||||
return adjustEventFactors();
|
||||
boolean ret = true;
|
||||
// only populate & dump permissions if enabled
|
||||
if (mFactors[FACTOR_PERMISSION] != 0.0f) {
|
||||
ret &= mPermissionUtil.populatePermissionsMapping();
|
||||
if (ret && mVerbose >= 2) {
|
||||
mPermissionUtil.dump();
|
||||
}
|
||||
}
|
||||
return ret & adjustEventFactors();
|
||||
}
|
||||
|
||||
public void setVerbose(int verbose) {
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
package com.android.commands.monkey;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Misc utilities.
|
||||
@@ -26,6 +29,7 @@ public abstract class MonkeyUtils {
|
||||
private static final java.util.Date DATE = new java.util.Date();
|
||||
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat(
|
||||
"yyyy-MM-dd HH:mm:ss.SSS ");
|
||||
private static PackageFilter sFilter;
|
||||
|
||||
private MonkeyUtils() {
|
||||
}
|
||||
@@ -38,4 +42,72 @@ public abstract class MonkeyUtils {
|
||||
return DATE_FORMATTER.format(DATE);
|
||||
}
|
||||
|
||||
public static PackageFilter getPackageFilter() {
|
||||
if (sFilter == null) {
|
||||
sFilter = new PackageFilter();
|
||||
}
|
||||
return sFilter;
|
||||
}
|
||||
|
||||
public static class PackageFilter {
|
||||
private Set<String> mValidPackages = new HashSet<>();
|
||||
private Set<String> mInvalidPackages = new HashSet<>();
|
||||
|
||||
private PackageFilter() {
|
||||
}
|
||||
|
||||
public void addValidPackages(Set<String> validPackages) {
|
||||
mValidPackages.addAll(validPackages);
|
||||
}
|
||||
|
||||
public void addInvalidPackages(Set<String> invalidPackages) {
|
||||
mInvalidPackages.addAll(invalidPackages);
|
||||
}
|
||||
|
||||
public boolean hasValidPackages() {
|
||||
return mValidPackages.size() > 0;
|
||||
}
|
||||
|
||||
public boolean isPackageValid(String pkg) {
|
||||
return mValidPackages.contains(pkg);
|
||||
}
|
||||
|
||||
public boolean isPackageInvalid(String pkg) {
|
||||
return mInvalidPackages.contains(pkg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether we should run against the given package.
|
||||
*
|
||||
* @param pkg The package name.
|
||||
* @return Returns true if we should run against pkg.
|
||||
*/
|
||||
public boolean checkEnteringPackage(String pkg) {
|
||||
if (mInvalidPackages.size() > 0) {
|
||||
if (mInvalidPackages.contains(pkg)) {
|
||||
return false;
|
||||
}
|
||||
} else if (mValidPackages.size() > 0) {
|
||||
if (!mValidPackages.contains(pkg)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void dump() {
|
||||
if (mValidPackages.size() > 0) {
|
||||
Iterator<String> it = mValidPackages.iterator();
|
||||
while (it.hasNext()) {
|
||||
System.out.println(":AllowPackage: " + it.next());
|
||||
}
|
||||
}
|
||||
if (mInvalidPackages.size() > 0) {
|
||||
Iterator<String> it = mInvalidPackages.iterator();
|
||||
while (it.hasNext()) {
|
||||
System.out.println(":DisallowPackage: " + it.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user