Relax startup scripts to devices not supporting nfc

This also extends apk_masseur.py with an option to store the dex compressed.

Change-Id: I4695acc9d7f41f4020225f54cdea93de384dce72
diff --git a/tools/apk_masseur.py b/tools/apk_masseur.py
index 51e9366..487cb7c 100755
--- a/tools/apk_masseur.py
+++ b/tools/apk_masseur.py
@@ -23,6 +23,10 @@
                       'assets/dexopt/',
                       default=False,
                       action='store_true')
+    parser.add_option('--compress-dex',
+                      help='Whether the dex should be stored compressed',
+                      action='store_true',
+                      default=False)
     parser.add_option('--dex',
                       help='Directory or archive with dex files to use instead '
                       'of those in the apk',
@@ -67,8 +71,8 @@
     return file.endswith('.zip') or file.endswith('.jar')
 
 
-def repack(apk, clear_profile, processed_out, desugared_library_dex, resources,
-           temp, quiet, logging):
+def repack(apk, clear_profile, processed_out, desugared_library_dex,
+           compress_dex, resources, temp, quiet, logging):
     processed_apk = os.path.join(temp, 'processed.apk')
     shutil.copyfile(apk, processed_apk)
 
@@ -119,7 +123,12 @@
         dex_files = glob.glob('*.dex')
         dex_files.sort()
         resource_files = glob.glob(resources) if resources else []
-        cmd = ['zip', '-u', '-0', processed_apk] + dex_files + resource_files
+        cmd = ['zip', '-u']
+        if not compress_dex:
+            cmd.append('-0')
+        cmd.append(processed_apk)
+        cmd.extend(dex_files)
+        cmd.extend(resource_files)
         utils.RunCmd(cmd, quiet=quiet, logging=logging)
     return processed_apk
 
@@ -143,6 +152,7 @@
             clear_profile=False,
             dex=None,
             desugared_library_dex=None,
+            compress_dex=False,
             resources=None,
             out=None,
             adb_options=None,
@@ -159,8 +169,8 @@
         processed_apk = None
         if dex or clear_profile:
             processed_apk = repack(apk, clear_profile, dex,
-                                   desugared_library_dex, resources, temp,
-                                   quiet, logging)
+                                   desugared_library_dex, compress_dex,
+                                   resources, temp, quiet, logging)
         else:
             assert not desugared_library_dex
             utils.Print('Signing original APK without modifying apk',
diff --git a/tools/startup/adb_utils.py b/tools/startup/adb_utils.py
index 6ce19ab..0a4ae59 100755
--- a/tools/startup/adb_utils.py
+++ b/tools/startup/adb_utils.py
@@ -41,10 +41,14 @@
     OFF_UNLOCKED = 2
     ON_LOCKED = 3
     ON_UNLOCKED = 4
+    UNKNOWN = 5
 
     def is_off(self):
         return self == ScreenState.OFF_LOCKED or self == ScreenState.OFF_UNLOCKED
 
+    def is_off_or_unknown(self):
+        return self.is_off() or self.is_unknown()
+
     def is_on(self):
         return self == ScreenState.ON_LOCKED or self == ScreenState.ON_UNLOCKED
 
@@ -54,6 +58,15 @@
     def is_on_and_unlocked(self):
         return self == ScreenState.ON_UNLOCKED
 
+    def is_on_and_unlocked_or_unknown(self):
+        return self.is_on_and_unlocked() or self.is_unknown()
+
+    def is_on_or_unknown(self):
+        return self.is_on() or self.is_unknown()
+
+    def is_unknown(self):
+        return self == ScreenState.UNKNOWN
+
 
 def broadcast(action, component, device_id=None):
     print('Sending broadcast %s' % action)
@@ -147,13 +160,13 @@
 def ensure_screen_on(device_id=None):
     if get_screen_state(device_id).is_off():
         toggle_screen(device_id)
-    assert get_screen_state(device_id).is_on()
+    assert get_screen_state(device_id).is_on_or_unknown()
 
 
 def ensure_screen_off(device_id=None):
     if get_screen_state(device_id).is_on():
         toggle_screen(device_id)
-    assert get_screen_state(device_id).is_off()
+    assert get_screen_state(device_id).is_off_or_unknown()
 
 
 def force_compilation(app_id, device_id=None):
@@ -243,7 +256,11 @@
 
 def get_screen_state(device_id=None):
     cmd = create_adb_cmd('shell dumpsys nfc', device_id)
-    stdout = subprocess.check_output(cmd).decode('utf-8').strip()
+    process_result = subprocess.run(cmd, capture_output=True)
+    stderr = process_result.stderr.decode('utf-8')
+    if "Can't find service: nfc" in stderr:
+        return ScreenState.UNKNOWN
+    stdout = process_result.stdout.decode('utf-8').strip()
     screen_state_value = None
     for line in stdout.splitlines():
         if line.startswith('mScreenState='):
@@ -480,6 +497,8 @@
 def unlock(device_id=None, device_pin=None):
     ensure_screen_on(device_id)
     screen_state = get_screen_state(device_id)
+    if screen_state.is_unknown():
+        return
     assert screen_state.is_on(), 'was %s' % screen_state
     if screen_state.is_on_and_locked():
         if device_pin is not None:
diff --git a/tools/startup/measure_startup.py b/tools/startup/measure_startup.py
index 7e97735..322dfbe 100755
--- a/tools/startup/measure_startup.py
+++ b/tools/startup/measure_startup.py
@@ -138,7 +138,8 @@
 
 
 def teardown_for_run(out_dir, options, teardown_options):
-    assert adb_utils.get_screen_state(options.device_id).is_on_and_unlocked()
+    assert adb_utils.get_screen_state(
+        options.device_id).is_on_and_unlocked_or_unknown()
 
     if options.capture_screen:
         target = os.path.join(out_dir, 'screen.png')
@@ -153,7 +154,8 @@
 
 
 def run(out_dir, options, tmp_dir):
-    assert adb_utils.get_screen_state(options.device_id).is_on_and_unlocked()
+    assert adb_utils.get_screen_state(
+        options.device_id).is_on_and_unlocked_or_unknown()
 
     # Start logcat for time to fully drawn.
     logcat_process = None
@@ -445,7 +447,7 @@
     if options.cooldown == 0:
         teardown_options = adb_utils.prepare_for_interaction_with_device(
             options.device_id, options.device_pin)
-        assert adb_utils.get_screen_state(options.device_id).is_on()
+        assert adb_utils.get_screen_state(options.device_id).is_on_or_unknown()
     else:
         adb_utils.ensure_screen_off(options.device_id)
     return teardown_options