diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java index 8b182b7f87804..333a59490c81d 100644 --- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java +++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java @@ -46,6 +46,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -72,6 +73,7 @@ public class AppLaunch extends InstrumentationTestCase { private static final String KEY_REQUIRED_ACCOUNTS = "required_accounts"; private static final String KEY_APPS = "apps"; private static final String KEY_IORAP_TRIAL_LAUNCH = "iorap_trial_launch"; + private static final String KEY_IORAP_COMPILER_FILTERS = "iorap_compiler_filters"; private static final String KEY_TRIAL_LAUNCH = "trial_launch"; private static final String KEY_LAUNCH_ITERATIONS = "launch_iterations"; private static final String KEY_LAUNCH_ORDER = "launch_order"; @@ -153,6 +155,7 @@ public class AppLaunch extends InstrumentationTestCase { private BufferedWriter mBufferedWriter = null; private boolean mSimplePerfAppOnly = false; private String[] mCompilerFilters = null; + private List mIorapCompilerFilters = null; private String mLastAppName = ""; private boolean mCycleCleanUp = false; private boolean mTraceAll = false; @@ -507,16 +510,68 @@ public class AppLaunch extends InstrumentationTestCase { for (int i = 0; i < IORAP_COMPILE_CMD_TIMEOUT; ++i) { IorapCompilationStatus status = waitForIorapCompiled(appPkgName); if (status == IorapCompilationStatus.COMPLETE) { + Log.v(TAG, "compileAppForIorap: success"); + logDumpsysIorapd(appPkgName); return true; } else if (status == IorapCompilationStatus.INSUFFICIENT_TRACES) { + Log.e(TAG, "compileAppForIorap: failed due to insufficient traces"); + logDumpsysIorapd(appPkgName); return false; } // else INCOMPLETE. keep asking iorapd if it's done yet. sleep(1000); } + Log.e(TAG, "compileAppForIorap: failed due to timeout"); + logDumpsysIorapd(appPkgName); return false; } + /** Save the contents of $(adb shell dumpsys iorapd) to the launch_logs directory. */ + private void logDumpsysIorapd(String packageName) throws IOException { + InstrumentationTestRunner instrumentation = + (InstrumentationTestRunner)getInstrumentation(); + Bundle args = instrumentation.getArguments(); + + String launchDirectory = args.getString(KEY_LAUNCH_DIRECTORY); + + // Root directory for applaunch file to log the app launch output + // Will be useful in case of simpleperf command is used + File launchRootDir = null; + if (null != launchDirectory && !launchDirectory.isEmpty()) { + launchRootDir = new File(launchDirectory); + if (!launchRootDir.exists() && !launchRootDir.mkdirs()) { + throw new IOException("Unable to create the destination directory " + + launchRootDir + ". Try disabling selinux."); + } + } else { + Log.w(TAG, "logDumpsysIorapd: Missing launch-directory arg"); + return; + } + + File launchSubDir = new File(launchRootDir, LAUNCH_SUB_DIRECTORY); + + if (!launchSubDir.exists() && !launchSubDir.mkdirs()) { + throw new IOException("Unable to create the lauch file sub directory " + + launchSubDir + ". Try disabling selinux."); + } + String path = "iorapd_dumpsys_" + packageName + "_" + System.nanoTime() + ".txt"; + File file = new File(launchSubDir, path); + try (FileOutputStream outputStream = new FileOutputStream(file); + BufferedWriter writer = new BufferedWriter( + new OutputStreamWriter(outputStream)); + ParcelFileDescriptor result = getInstrumentation().getUiAutomation(). + executeShellCommand(IORAP_DUMPSYS_CMD); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader( + new FileInputStream(result.getFileDescriptor())))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + writer.write(line + "\n"); + } + } + + Log.v(TAG, "logDumpsysIorapd: Saved to file: " + path); + } + enum IorapCompilationStatus { INCOMPLETE, COMPLETE, @@ -564,6 +619,24 @@ public class AppLaunch extends InstrumentationTestCase { return reason; } + private boolean shouldIncludeIorap(String compilerFilter) { + if (!mIorapTrialLaunch) { + return false; + } + + // No iorap compiler filters specified: treat all compiler filters as ok. + if (mIorapCompilerFilters == null) { + return true; + } + + // iorap compiler filters specified: the compilerFilter must be in the whitelist. + if (mIorapCompilerFilters.indexOf(compilerFilter) != -1) { + return true; + } + + return false; + } + /** * If launch order is "cyclic" then apps will be launched one after the * other for each iteration count. @@ -578,7 +651,7 @@ public class AppLaunch extends InstrumentationTestCase { mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH, /*iorapEnabled*/false)); } } - if (mIorapTrialLaunch) { + if (shouldIncludeIorap(compilerFilter)) { for (int launchCount = 0; launchCount < IORAP_TRIAL_LAUNCH_ITERATIONS; ++launchCount) { for (String app : mNameToResultKey.keySet()) { String reason = makeReasonForIorapTrialLaunch(launchCount); @@ -592,14 +665,16 @@ public class AppLaunch extends InstrumentationTestCase { for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) { for (String app : mNameToResultKey.keySet()) { mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, - String.format(LAUNCH_ITERATION, launchCount), mIorapTrialLaunch)); + String.format(LAUNCH_ITERATION, launchCount), + shouldIncludeIorap(compilerFilter))); } } if (mTraceDirectoryStr != null && !mTraceDirectoryStr.isEmpty()) { for (int traceCount = 0; traceCount < mTraceLaunchCount; traceCount++) { for (String app : mNameToResultKey.keySet()) { mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, - String.format(TRACE_ITERATION, traceCount), mIorapTrialLaunch)); + String.format(TRACE_ITERATION, traceCount), + shouldIncludeIorap(compilerFilter))); } } } @@ -610,7 +685,7 @@ public class AppLaunch extends InstrumentationTestCase { if (mTrialLaunch) { mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, TRIAL_LAUNCH, /*iorapEnabled*/false)); } - if (mIorapTrialLaunch) { + if (shouldIncludeIorap(compilerFilter)) { for (int launchCount = 0; launchCount < IORAP_TRIAL_LAUNCH_ITERATIONS; ++launchCount) { String reason = makeReasonForIorapTrialLaunch(launchCount); mLaunchOrderList.add( @@ -621,12 +696,14 @@ public class AppLaunch extends InstrumentationTestCase { } for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) { mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, - String.format(LAUNCH_ITERATION, launchCount), mIorapTrialLaunch)); + String.format(LAUNCH_ITERATION, launchCount), + shouldIncludeIorap(compilerFilter))); } if (mTraceDirectoryStr != null && !mTraceDirectoryStr.isEmpty()) { for (int traceCount = 0; traceCount < mTraceLaunchCount; traceCount++) { mLaunchOrderList.add(new LaunchOrder(app, compilerFilter, - String.format(TRACE_ITERATION, traceCount), mIorapTrialLaunch)); + String.format(TRACE_ITERATION, traceCount), + shouldIncludeIorap(compilerFilter))); } } } @@ -768,6 +845,13 @@ public class AppLaunch extends InstrumentationTestCase { mCompilerFilters = new String[1]; } + String iorapCompilerFilterList = args.getString(KEY_IORAP_COMPILER_FILTERS); + if (iorapCompilerFilterList != null) { + // Passing in iorap compiler filters implies an iorap trial launch. + mIorapTrialLaunch = true; + mIorapCompilerFilters = Arrays.asList(iorapCompilerFilterList.split("\\|")); + } + // Pre-populate the results map to avoid null checks. for (String app : mNameToLaunchTime.keySet()) { HashMap> map = new HashMap<>();