Minor updates to startup scripts

Change-Id: I10332bdb6cf6db481d8fe4246a60a67c9c4379e0
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupConfiguration.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupConfiguration.java
index 0f9ad9c..0c1425c 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupConfiguration.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupConfiguration.java
@@ -45,11 +45,13 @@
    */
   public static StartupConfiguration createStartupConfiguration(
       DexItemFactory dexItemFactory, Reporter reporter) {
-    String propertyValue = System.getProperty("com.android.tools.r8.startupclassdescriptors");
+    String propertyValue = System.getProperty("com.android.tools.r8.startup.config");
     if (propertyValue == null) {
       return null;
     }
 
+    reporter.warning("Use of startupconfig is experimental");
+
     List<String> startupDescriptors;
     try {
       startupDescriptors = FileUtils.readAllLines(Paths.get(propertyValue));
@@ -115,10 +117,10 @@
 
     String protoWithNameDescriptor = startupMethodDescriptor.substring(methodNameStartIndex);
     int methodNameEndIndex = protoWithNameDescriptor.indexOf('(');
-    if (methodNameEndIndex <= 1) {
+    if (methodNameEndIndex <= 0) {
       return null;
     }
-    String methodName = protoWithNameDescriptor.substring(methodNameEndIndex);
+    String methodName = protoWithNameDescriptor.substring(0, methodNameEndIndex);
 
     String protoDescriptor = protoWithNameDescriptor.substring(methodNameEndIndex);
     DexProto proto = parseStartupMethodProto(protoDescriptor, dexItemFactory);
diff --git a/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java b/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java
index a8b4476..04af8a4 100644
--- a/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java
+++ b/src/main/java/com/android/tools/r8/experimental/startup/StartupOptions.java
@@ -4,10 +4,14 @@
 
 package com.android.tools.r8.experimental.startup;
 
+import static com.android.tools.r8.utils.InternalOptions.isSystemPropertyForDevelopmentSet;
+
 public class StartupOptions {
 
-  private boolean enableMinimalStartupDex = false;
-  private boolean enableStartupCompletenessCheckForTesting = false;
+  private boolean enableMinimalStartupDex =
+      isSystemPropertyForDevelopmentSet("com.android.tools.r8.startup.minimalstartupdex");
+  private boolean enableStartupCompletenessCheckForTesting =
+      isSystemPropertyForDevelopmentSet("com.android.tools.r8.startup.completenesscheck");
 
   private StartupConfiguration startupConfiguration;
 
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 8036e59..3839809 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -866,7 +866,7 @@
     return ImmutableSet.of();
   }
 
-  private static boolean isSystemPropertyForDevelopmentSet(String propertyName) {
+  public static boolean isSystemPropertyForDevelopmentSet(String propertyName) {
     if (Version.isDevelopmentVersion()) {
       return System.getProperty(propertyName) != null;
     }
diff --git a/tools/startup/adb_utils.py b/tools/startup/adb_utils.py
index 136c99a..981bcbd 100644
--- a/tools/startup/adb_utils.py
+++ b/tools/startup/adb_utils.py
@@ -91,7 +91,7 @@
 
 def get_minor_major_page_faults(app_id, device_id=None):
   pid = get_pid(app_id, device_id)
-  cmd = create_adb_cmd('shell ps -p %i -o MINFL,MAJFL' % pid)
+  cmd = create_adb_cmd('shell ps -p %i -o MINFL,MAJFL' % pid, device_id)
   stdout = subprocess.check_output(cmd).decode('utf-8')
   lines_it = iter(stdout.splitlines())
   first_line = next(lines_it)
@@ -145,7 +145,7 @@
   cmd = create_adb_cmd(
     'shell profman --dump-classes-and-methods'
     ' --profile-file=%s --apk=%s --dex-location=%s'
-        % (profile_path, apk_path, apk_path))
+        % (profile_path, apk_path, apk_path), device_id)
   stdout = subprocess.check_output(cmd).decode('utf-8').strip()
   lines = stdout.splitlines()
   classes_and_methods = []
diff --git a/tools/startup/generate_startup_descriptors.py b/tools/startup/generate_startup_descriptors.py
index a3eb72c..ea0fdf3 100755
--- a/tools/startup/generate_startup_descriptors.py
+++ b/tools/startup/generate_startup_descriptors.py
@@ -22,6 +22,7 @@
     print(
         'Found %i new startup descriptors in iteration %i'
             % (number_of_new_startup_descriptors, iteration + 1))
+  return number_of_new_startup_descriptors
 
 def generate_startup_profile_on_device(options):
   if not options.use_existing_profile:
@@ -74,6 +75,8 @@
 def parse_options(argv):
   result = argparse.ArgumentParser(
       description='Generate a perfetto trace file.')
+  result.add_argument('--apk',
+                      help='Path to the APK')
   result.add_argument('--app-id',
                       help='The application ID of interest',
                       required=True)
@@ -104,6 +107,11 @@
                            'descriptors are found',
                       action='store_true',
                       default=False)
+  result.add_argument('--until-stable-iterations',
+                      help='Number of times that profile generation must must '
+                           'not find new startup descriptors before exiting',
+                      default=1,
+                      type=int)
   result.add_argument('--use-existing-profile',
                       help='Do not launch app to generate startup profile',
                       action='store_true',
@@ -116,13 +124,22 @@
 
 def main(argv):
   (options, args) = parse_options(argv)
+  adb_utils.root(options.device_id)
+  if options.apk:
+    adb_utils.uninstall(options.app_id, options.device_id)
+    adb_utils.install(options.apk, options.device_id)
   startup_descriptors = set()
   if options.until_stable:
     iteration = 0
+    stable_iterations = 0
     while True:
       diff = extend_startup_descriptors(startup_descriptors, iteration, options)
       if diff == 0:
-        break
+        stable_iterations = stable_iterations + 1
+        if stable_iterations == options.until_stable_iterations:
+          break
+      else:
+        stable_iterations = 0
       iteration = iteration + 1
   else:
     for iteration in range(options.iterations):
diff --git a/tools/startup/trace_generator.py b/tools/startup/measure_startup.py
similarity index 95%
rename from tools/startup/trace_generator.py
rename to tools/startup/measure_startup.py
index 37f5c71..080f827 100755
--- a/tools/startup/trace_generator.py
+++ b/tools/startup/measure_startup.py
@@ -82,11 +82,14 @@
   os.makedirs(out_dir, exist_ok=True)
 
 def run(out_dir, options, tmp_dir):
-  assert adb_utils.get_screen_state().is_on_and_unlocked()
+  assert adb_utils.get_screen_state(options.device_id).is_on_and_unlocked()
 
   # Start perfetto trace collector.
-  perfetto_process, perfetto_trace_path = perfetto_utils.record_android_trace(
-      out_dir, tmp_dir)
+  perfetto_process = None
+  perfetto_trace_path = None
+  if not options.no_perfetto:
+    perfetto_process, perfetto_trace_path = perfetto_utils.record_android_trace(
+        out_dir, tmp_dir)
 
   # Launch main activity.
   launch_activity_result = adb_utils.launch_activity(
@@ -96,7 +99,8 @@
       wait_for_activity_to_launch=True)
 
   # Wait for perfetto trace collector to stop.
-  perfetto_utils.stop_record_android_trace(perfetto_process, out_dir)
+  if not options.no_perfetto:
+    perfetto_utils.stop_record_android_trace(perfetto_process, out_dir)
 
   # Get minor and major page faults from app process.
   data = compute_data(launch_activity_result, perfetto_trace_path, options)