Merge "Snap for 5660618 from 09e9b71758936129088ef94cc6928b47c8afa19d to nougat-mr1-cts-release" into nougat-mr1-cts-release
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 8aff6d0..aeaddc9 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.cts.verifier"
       android:versionCode="5"
-      android:versionName="7.1_r27">
+      android:versionName="7.1_r28">
 
     <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="25"/>
 
@@ -1324,6 +1324,7 @@
             <meta-data android:name="test_category" android:value="@string/test_category_notifications" />
             <meta-data android:name="test_excluded_features"
                     android:value="android.hardware.type.watch:android.hardware.type.television:android.software.leanback" />
+            <meta-data android:name="test_required_features" android:value="android.software.device_admin" />
         </activity>
         <activity android:name=".security.CANotifyOnBootActivity"
                 android:label="@string/caboot_test">
@@ -1334,6 +1335,7 @@
             <meta-data android:name="test_category" android:value="@string/test_category_notifications" />
             <meta-data android:name="test_excluded_features"
                     android:value="android.hardware.type.watch:android.hardware.type.television:android.software.leanback" />
+            <meta-data android:name="test_required_features" android:value="android.software.device_admin" />
         </activity>
 
         <activity android:name=".security.KeyChainTest"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 37d013d..ace06d3 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2495,7 +2495,7 @@
         Check that \'Dummy Input method\' is not enabled in Settings and disallow \'Dummy Input method\' from permitted input methods by turning on the switch below.
     </string>
     <string name="set_permitted_input_methods_action">
-        Enabling \'Dummy Input Method\' in the list of accessibility services
+        Enabling \'Dummy Input Method\' in the list of input methods
     </string>
     <string name="set_permitted_input_methods_widget_label">
         Allow only system input methods:
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
index cf8ec89..f2b81e7 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
@@ -25,12 +25,16 @@
 import android.os.Bundle;
 import android.os.UserManager;
 import android.util.Log;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
 
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.managedprovisioning.Utils;
 
 import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 public class CommandReceiverActivity extends Activity {
     private static final String TAG = "CommandReceiverActivity";
@@ -131,7 +135,7 @@
                 } break;
                 case COMMAND_ALLOW_ONLY_SYSTEM_INPUT_METHODS: {
                     boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
-                    mDpm.setPermittedInputMethods(mAdmin, enforced ? new ArrayList() : null);
+                    mDpm.setPermittedInputMethods(mAdmin, enforced ? getEnabledNonSystemImes() : null);
                 } break;
                 case COMMAND_ALLOW_ONLY_SYSTEM_ACCESSIBILITY_SERVICES: {
                     boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
@@ -227,4 +231,19 @@
         mDpm.setPermittedAccessibilityServices(mAdmin, null);
         mDpm.setPermittedInputMethods(mAdmin, null);
     }
+
+    private List<String> getEnabledNonSystemImes() {
+        InputMethodManager inputMethodManager = getSystemService(InputMethodManager.class);
+        final List<InputMethodInfo> inputMethods = inputMethodManager.getEnabledInputMethodList();
+        return inputMethods.stream()
+                .filter(inputMethodInfo -> !isSystemInputMethodInfo(inputMethodInfo))
+                .map(inputMethodInfo -> inputMethodInfo.getPackageName())
+                .filter(packageName -> !packageName.equals(getPackageName()))
+                .distinct()
+                .collect(Collectors.toList());
+    }
+
+    private boolean isSystemInputMethodInfo(InputMethodInfo inputMethodInfo) {
+        return inputMethodInfo.getServiceInfo().applicationInfo.isSystemApp();
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
index 260ffbf..c15d2ac 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
@@ -30,6 +30,7 @@
 import org.opencv.core.MatOfFloat;
 import org.opencv.core.MatOfPoint2f;
 import org.opencv.core.MatOfPoint3f;
+import org.opencv.core.Point;
 import org.opencv.core.Size;
 import org.opencv.imgcodecs.Imgcodecs;
 import org.opencv.imgproc.Imgproc;
@@ -65,7 +66,7 @@
 
     private static final boolean OUTPUT_DEBUG_IMAGE = false;
     private static final double VALID_FRAME_THRESHOLD = 0.8;
-    private static final double REPROJECTION_THREASHOLD_RATIO = 0.008;
+    private static final double REPROJECTION_THRESHOLD_RATIO = 0.01;
     private static final boolean FORCE_CV_ANALYSIS  = false;
     private static final boolean TRACE_VIDEO_ANALYSIS = false;
     private static final double DECIMATION_FPS_TARGET = 15.0;
@@ -811,7 +812,9 @@
             Debug.startMethodTracing("cvprocess");
         }
 
-        Size patternSize = new Size(4,11);
+        final int patternWidth = 4;
+        final int patternHeight = 11;
+        Size patternSize = new Size(patternWidth, patternHeight);
 
         float fc = (float)(meta.frameWidth/2.0/Math.tan(meta.fovWidth/2.0));
         Mat camMat = cameraMatrix(fc, new Size(frameSize.width/2, frameSize.height/2));
@@ -877,16 +880,36 @@
             // reproject points to for evaluation of result accuracy of solvePnP
             Calib3d.projectPoints(grid, rvec, tvec, camMat, coeff, reprojCenters);
 
-            // error is evaluated in norm2, which is real error in pixel distance / sqrt(2)
-            double error = Core.norm(centers, reprojCenters, Core.NORM_L2);
+            // Calculate the average distance between opposite corners of the pattern in pixels
+            Point[] centerPoints = centers.toArray();
+            Point bottomLeftPos = centerPoints[0];
+            Point bottomRightPos = centerPoints[patternWidth - 1];
+            Point topLeftPos = centerPoints[(patternHeight * patternWidth) - patternWidth];
+            Point topRightPos = centerPoints[(patternHeight * patternWidth) - 1];
+            double avgPixelDist = (getDistanceBetweenPoints(bottomLeftPos, topRightPos)
+                    + getDistanceBetweenPoints(bottomRightPos, topLeftPos)) / 2;
+
+            // Calculate the average pixel error between the circle centers from the video and the
+            // reprojected circle centers based on the estimated camera position. The error provides
+            // a way to estimate how accurate the assumed test device's position is. If the error
+            // is high, then the frame should be discarded to prevent an inaccurate test device's
+            // position from being compared against the rotation vector sample at that time.
+            Point[] reprojectedPointsArray = reprojCenters.toArray();
+            double avgCenterError = 0.0;
+            for (int curCenter = 0; curCenter < reprojectedPointsArray.length; curCenter++) {
+                avgCenterError += getDistanceBetweenPoints(
+                        reprojectedPointsArray[curCenter], centerPoints[curCenter]);
+            }
+            avgCenterError /= reprojectedPointsArray.length;
 
             if (LOCAL_LOGV) {
-                Log.v(TAG, "Found attitude, re-projection error = " + error);
+                Log.v(TAG, "Found attitude, re-projection error = " + avgCenterError);
             }
 
-            // if error is reasonable, add it into the results. use ratio to frame height to avoid
-            // discriminating higher definition videos
-            if (error < REPROJECTION_THREASHOLD_RATIO * frameSize.height) {
+            // if error is reasonable, add it into the results. Use a dynamic threshold based on
+            // the pixel distance of opposite corners of the pattern to prevent higher resolution
+            // video or the distance between the camera and the test pattern from impacting the test
+            if (avgCenterError < REPROJECTION_THRESHOLD_RATIO * avgPixelDist) {
                 double [] rv = new double[3];
                 double timestamp;
 
@@ -1325,6 +1348,10 @@
     private static double [] rodr2rpy( double [] r) {
         return quat2rpy(rodr2quat(r));
     }
+
+    private double getDistanceBetweenPoints(Point a, Point b) {
+        return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
+    }
     //////////////////
 
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
index 789de68..fec593c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
@@ -301,10 +301,8 @@
 
         String message = "Test Roll Axis Accuracy";
 
-        Assert.assertEquals("Roll RMS error", 0.0, mReport.roll_rms_error,
-                Criterion.roll_rms_error);
-        Assert.assertEquals("Roll max error", 0.0, mReport.roll_max_error,
-                Criterion.roll_max_error);
+        assertLessThan("Roll RMS error", mReport.roll_rms_error, Criterion.roll_rms_error);
+        assertLessThan("Roll max error", mReport.roll_max_error, Criterion.roll_max_error);
         return message;
     }
 
@@ -316,10 +314,8 @@
 
         String message = "Test Pitch Axis Accuracy";
 
-        Assert.assertEquals("Pitch RMS error", 0.0, mReport.pitch_rms_error,
-                Criterion.pitch_rms_error);
-        Assert.assertEquals("Pitch max error", 0.0, mReport.pitch_max_error,
-                Criterion.pitch_max_error);
+        assertLessThan("Pitch RMS error", mReport.pitch_rms_error, Criterion.pitch_rms_error);
+        assertLessThan("Pitch max error", mReport.pitch_max_error, Criterion.pitch_max_error);
         return message;
     }
 
@@ -331,13 +327,16 @@
 
         String message = "Test Yaw Axis Accuracy";
 
-        Assert.assertEquals("Yaw RMS error", 0.0, mReport.yaw_rms_error,
-                Criterion.yaw_rms_error);
-        Assert.assertEquals("Yaw max error", 0.0, mReport.yaw_max_error,
-                Criterion.yaw_max_error);
+        assertLessThan("Yaw RMS error", mReport.yaw_rms_error, Criterion.yaw_rms_error);
+        assertLessThan("Yaw max error", mReport.yaw_max_error, Criterion.yaw_max_error);
         return message;
     }
 
+    private void assertLessThan(String message, double lhs, double rhs) {
+        Assert.assertTrue(String.format("%s - expected %.4f < %.4f", message, lhs, rhs),
+                lhs < rhs);
+    }
+
     private void loadOpenCVSuccessfulOrSkip() throws SensorTestStateNotSupportedException {
         if (!mOpenCVLoadSuccessful)
             throw new SensorTestStateNotSupportedException("Skipped due to OpenCV cannot be loaded");
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/CrashReporter.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/CrashReporter.java
new file mode 100644
index 0000000..42d71e7
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/CrashReporter.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2019 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.compatibility.common.tradefed.targetprep;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.Crash;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmlib.MultiLineReceiver;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.BackgroundDeviceAction;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import java.io.ObjectOutputStream;
+import java.io.FileOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.util.regex.Matcher;
+import java.util.ArrayList;
+
+/**
+ * Starts and kills the crash reporter thread. This thread uploads crash results to devices as they
+ * occurring allowing for device side crash analysis.
+ */
+public class CrashReporter implements ITargetCleaner {
+
+    private BackgroundDeviceAction mBackgroundThread;
+
+    /** Uploads the current buffer of Crashes to the phone under the current test name. */
+    private static void upload(ITestDevice device, String testname, ArrayList<Crash> crashes) {
+        try {
+            if (testname == null) {
+                CLog.logAndDisplay(LogLevel.ERROR, "Attempted upload with no test name");
+                return;
+            }
+            device.executeShellCommand(
+                    String.format("rm -f %s%s", CrashUtils.DEVICE_PATH, CrashUtils.LOCK_FILENAME));
+            Path tmpPath = Files.createTempFile(testname, ".txt");
+            try {
+                Files.setPosixFilePermissions(
+                        tmpPath, PosixFilePermissions.fromString("rw-r--r--"));
+                File reportFile = tmpPath.toFile();
+                try (ObjectOutputStream writer = new ObjectOutputStream(
+                    new FileOutputStream(reportFile))) {
+                    writer.writeObject(crashes);
+                }
+                device.pushFile(reportFile, CrashUtils.DEVICE_PATH + testname);
+            } finally {
+                Files.deleteIfExists(tmpPath);
+            }
+            device.executeShellCommand(
+                    String.format("touch %s%s", CrashUtils.DEVICE_PATH, CrashUtils.LOCK_FILENAME));
+        } catch (IOException | RuntimeException | DeviceNotAvailableException e) {
+            CLog.logAndDisplay(LogLevel.ERROR, "Upload to device failed");
+            CLog.logAndDisplay(LogLevel.ERROR, e.getMessage());
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo) {
+        try {
+            device.executeShellCommand("rm -rf " + CrashUtils.DEVICE_PATH);
+            device.executeShellCommand("mkdir " + CrashUtils.DEVICE_PATH);
+        } catch (DeviceNotAvailableException e) {
+            CLog.logAndDisplay(
+                    LogLevel.ERROR,
+                    "CrashReporterThread failed to setup storage directory on device");
+            CLog.logAndDisplay(LogLevel.ERROR, e.getMessage());
+            return;
+        }
+        mBackgroundThread =
+                new BackgroundDeviceAction(
+                        "logcat",
+                        "CrashReporter logcat thread",
+                        device,
+                        new CrashReporterReceiver(device),
+                        0);
+        mBackgroundThread.start();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable e) {
+        if (mBackgroundThread != null) {
+            mBackgroundThread.cancel();
+        }
+    }
+
+    /**
+     * Scans through lines received, parses out crashes, and stores them into a buffer. When a new
+     * test started signal is received the buffered is cleared. When an upload signal is received
+     * uploads the current buffer to the phone.
+     */
+    private class CrashReporterReceiver extends MultiLineReceiver {
+
+        private String mTestName;
+        private ArrayList<Crash> mCrashes;
+        private StringBuilder mLogcatChunk;
+        private ITestDevice mDevice;
+
+        public CrashReporterReceiver(ITestDevice device) {
+            mLogcatChunk = new StringBuilder();
+            mCrashes = new ArrayList<Crash>();
+            mDevice = device;
+        }
+
+        private void processLogLine(String line) {
+            mLogcatChunk.append(line);
+            Matcher m;
+            if ((m = CrashUtils.sNewTestPattern.matcher(line)).matches()) {
+                mTestName = m.group(1);
+                mCrashes = new ArrayList<Crash>();
+                mLogcatChunk.setLength(0);
+            } else if (CrashUtils.sEndofCrashPattern.matcher(line).matches()) {
+                mCrashes = CrashUtils.getAllCrashes(mLogcatChunk.toString());
+                mLogcatChunk.setLength(0);
+            } else if (CrashUtils.sUploadRequestPattern.matcher(line).matches()) {
+                upload(mDevice, mTestName, mCrashes);
+            }
+        }
+
+        @Override
+        public void processNewLines(String[] lines) {
+            if (!isCancelled()) {
+                for (String line : lines) {
+                    processLogLine(line);
+                }
+            }
+        }
+
+        @Override
+        public boolean isCancelled() {
+            return mBackgroundThread == null || mBackgroundThread.isCancelled();
+        }
+    }
+}
diff --git a/common/util/src/com/android/compatibility/common/util/Crash.java b/common/util/src/com/android/compatibility/common/util/Crash.java
new file mode 100644
index 0000000..190ec39
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/Crash.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 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.compatibility.common.util;
+
+import java.util.Objects;
+import java.io.Serializable;
+import javax.annotation.Nullable;
+
+public class Crash implements Serializable {
+
+    public static final long serialVersionUID = 42L;
+    public final int pid;
+    public final int tid;
+    @Nullable
+    public final String name;
+    @Nullable
+    public final Long faultAddress;
+    @Nullable
+    public final String signal;
+
+    public Crash(int pid, int tid, String name, Long faultAddress, String signal) {
+        this.pid = pid;
+        this.tid = tid;
+        this.name = name;
+        this.faultAddress = faultAddress;
+        this.signal = signal;
+    }
+
+    @Override
+    public String toString() {
+        return "Crash{" +
+            "pid=" + pid +
+            ", tid=" + tid +
+            ", name=" + name +
+            ", faultAddress=" + faultAddress +
+            ", signal=" + signal +
+            '}';
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (!(object instanceof Crash)) {
+            return false;
+        }
+        Crash crash = (Crash) object;
+        return pid == crash.pid &&
+            tid == crash.tid &&
+            Objects.equals(name, crash.name) &&
+            Objects.equals(faultAddress, crash.faultAddress) &&
+            Objects.equals(signal, crash.signal);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(pid, tid, name, faultAddress, signal);
+    }
+}
\ No newline at end of file
diff --git a/common/util/src/com/android/compatibility/common/util/CrashUtils.java b/common/util/src/com/android/compatibility/common/util/CrashUtils.java
new file mode 100644
index 0000000..d77b9a0
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/CrashUtils.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2019 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.compatibility.common.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Contains helper functions and shared constants for crash parsing. */
+public class CrashUtils {
+
+    public static final long MIN_CRASH_ADDR = 32768;
+    // Matches the end of a crash
+    public static final Pattern sEndofCrashPattern =
+            Pattern.compile(".*DEBUG\\s+:\\s+backtrace:.*");
+    public static final String DEVICE_PATH = "/data/local/tmp/CrashParserResults/";
+    public static final String LOCK_FILENAME = "lockFile.loc";
+    public static final String UPLOAD_REQUEST = "Please upload a result file to stagefright";
+    public static final Pattern sUploadRequestPattern =
+            Pattern.compile(".*" + UPLOAD_REQUEST + ".*");
+    public static final String NEW_TEST_ALERT = "New test starting with name: ";
+    public static final Pattern sNewTestPattern =
+            Pattern.compile(".*" + NEW_TEST_ALERT + "(\\w+)\\(.*\\).*");
+    // Matches the smallest blob that has the appropriate header and footer
+    private static final Pattern sCrashBlobPattern =
+            Pattern.compile("DEBUG\\s+:( [*]{3})+.*?DEBUG\\s+:\\s+backtrace:", Pattern.DOTALL);
+    // Matches process id and name line and captures them
+    private static final Pattern sPidtidNamePattern =
+            Pattern.compile("pid: (\\d+), tid: (\\d+), name: ([^\\s]+\\s+)*>>> (.*) <<<");
+    // Matches fault address and signal type line
+    private static final Pattern sFaultLinePattern =
+            Pattern.compile(
+                    "\\w+ \\d+ \\((.*)\\), code -*\\d+ \\(.*\\), fault addr "
+                            + "(?:0x(\\p{XDigit}+)|-+)");
+    // Matches the abort message line if it contains CHECK_
+    private static Pattern sAbortMessageCheckPattern =
+            Pattern.compile("(?i)Abort message.*CHECK_.*");
+
+    /**
+     * Determines if the given input has a {@link com.android.compatibility.common.util.Crash} that
+     * should fail an sts test
+     *
+     * @param processNames list of applicable process names
+     * @param checkMinAddr if the minimum fault address should be respected
+     * @param crashes list of crashes to check
+     * @return if a crash is serious enough to fail an sts test
+     */
+    public static boolean detectCrash(
+        String[] processNames, boolean checkMinAddr, List<Crash> crashes) {
+        for (Crash crash : crashes) {
+            if (!crash.signal.toLowerCase().matches("sig(segv|bus)")) {
+                continue;
+            }
+
+            if (checkMinAddr) {
+                if (crash.faultAddress != null && crash.faultAddress < MIN_CRASH_ADDR) {
+                    continue;
+                }
+            }
+
+            boolean foundProcess = false;
+            for (String process : processNames) {
+                if (crash.name.equals(process)) {
+                    foundProcess = true;
+                    break;
+                }
+            }
+
+            if (!foundProcess) {
+                continue;
+            }
+
+            return true; // crash detected
+        }
+
+        return false;
+    }
+
+    /**
+     * Creates a list of all crashes found within the input
+     *
+     * @param input logs to scan through
+     * @return List of all crashes as Crash objects
+     */
+    public static ArrayList<Crash> getAllCrashes(String input) {
+        ArrayList<Crash> crashes = new ArrayList<>();
+        Matcher crashBlobFinder = sCrashBlobPattern.matcher(input);
+        while (crashBlobFinder.find()) {
+            String crashStr = crashBlobFinder.group(0);
+            int tid = 0, pid = 0;
+            Long faultAddress = null;
+            String name = null, signal = null;
+
+            Matcher pidtidNameMatcher = sPidtidNamePattern.matcher(crashStr);
+            if (pidtidNameMatcher.find()) {
+                try {
+                    pid = Integer.parseInt(pidtidNameMatcher.group(1));
+                } catch (NumberFormatException e) {
+                }
+                try {
+                    tid = Integer.parseInt(pidtidNameMatcher.group(2));
+                } catch (NumberFormatException e) {
+                }
+                name = pidtidNameMatcher.group(3).trim();
+            }
+
+            Matcher faultLineMatcher = sFaultLinePattern.matcher(crashStr);
+            if (faultLineMatcher.find()) {
+                signal = faultLineMatcher.group(1);
+                String faultAddrMatch = faultLineMatcher.group(2);
+                if (faultAddrMatch != null) {
+                    try {
+                        faultAddress = Long.parseLong(faultAddrMatch, 16);
+                    } catch (NumberFormatException e) {
+                    }
+                }
+            }
+            if (!sAbortMessageCheckPattern.matcher(crashStr).find()) {
+                crashes.add(new Crash(pid, tid, name, faultAddress, signal));
+            }
+        }
+
+        return crashes;
+    }
+}
diff --git a/common/util/tests/Android.mk b/common/util/tests/Android.mk
index 0e0af50..9b9ee55 100644
--- a/common/util/tests/Android.mk
+++ b/common/util/tests/Android.mk
@@ -18,6 +18,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_JAVA_RESOURCE_DIRS := res
+
 LOCAL_JAVA_LIBRARIES := junit kxml2-2.3.0 tradefed-prebuilt compatibility-common-util-hostsidelib
 
 LOCAL_MODULE := compatibility-common-util-tests
diff --git a/common/util/tests/res/logcat.txt b/common/util/tests/res/logcat.txt
new file mode 100644
index 0000000..ad778c7
--- /dev/null
+++ b/common/util/tests/res/logcat.txt
@@ -0,0 +1,274 @@
+--------- beginning of system
+09-03 17:47:59.490  7039  7054 D AtCkpdCmdHandler: De-queing command
+--------- beginning of crash
+09-03 17:48:05.627 11071 11189 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xe9380000 in tid 11189 (AudioOut_D)
+09-03 17:48:05.707   359   359 W         : debuggerd: handling request: pid=11071 uid=1041 gid=1005 tid=11189
+09-03 17:48:05.796  7072  7072 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+09-03 17:48:05.796  7072  7072 F DEBUG   : Build fingerprint: 'google/angler/angler:7.1.1/N4F26T/3687331:userdebug/dev-keys'
+09-03 17:48:05.796  7072  7072 F DEBUG   : Revision: '0'
+09-03 17:48:05.796  7072  7072 F DEBUG   : ABI: 'arm'
+09-03 17:48:05.796  7072  7072 F DEBUG   : pid: 11071, tid: 11189, name: AudioOut_D  >>> /system/bin/audioserver <<<
+09-03 17:48:05.797  7072  7072 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xe9380000
+09-03 17:48:05.797  7072  7072 F DEBUG   :     r0 e9e7a240  r1 e9380000  r2 00000170  r3 00000000
+09-03 17:48:05.797  7072  7072 F DEBUG   :     r4 00000002  r5 00000000  r6 ec1e1f25  r7 eb6f8000
+09-03 17:48:05.797  7072  7072 F DEBUG   :     r8 00000000  r9 eb105204  sl 00000000  fp 000003c0
+09-03 17:48:05.797  7072  7072 F DEBUG   :     ip ebd3df18  sp eaf80688  lr ec1e1f41  pc ebd38dd6  cpsr 20000030
+09-03 17:48:05.805  7072  7072 F DEBUG   :
+09-03 17:48:05.805  7072  7072 F DEBUG   : backtrace:
+09-03 17:48:05.806  7072  7072 F DEBUG   :     #00 pc 00002dd6  /system/lib/libaudioutils.so (memcpy_to_float_from_i16+5)
+09-03 17:48:05.806  7072  7072 F DEBUG   :     #01 pc 00040f3d  /system/lib/libaudioflinger.so
+09-03 17:48:05.806  7072  7072 F DEBUG   :     #02 pc 00040799  /system/lib/libaudioflinger.so
+09-03 17:48:05.806  7072  7072 F DEBUG   :     #03 pc 00011178  /system/lib/libaudioflinger.so
+09-03 17:48:05.806  7072  7072 F DEBUG   :     #04 pc 0003180b  /system/lib/libaudioflinger.so
+09-03 17:48:05.806  7072  7072 F DEBUG   :     #05 pc 0002fe57  /system/lib/libaudioflinger.so
+09-03 17:48:05.806  7072  7072 F DEBUG   :     #06 pc 0000e345  /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
+09-03 17:48:05.806  7072  7072 F DEBUG   :     #07 pc 000470b3  /system/lib/libc.so (_ZL15__pthread_startPv+22)
+09-03 17:48:05.806  7072  7072 F DEBUG   :     #08 pc 00019e3d  /system/lib/libc.so (__start_thread+6)
+09-03 17:48:05.967 11272 11568 W NativeCrashListener: Couldn't find ProcessRecord for pid 11071
+09-03 17:48:05.969   359   359 W         : debuggerd: resuming target 11071
+09-03 17:48:05.981 11272 11307 I BootReceiver: Copying /data/tombstones/tombstone_01 to DropBox (SYSTEM_TOMBSTONE)
+09-03 17:48:06.067   394   394 I ServiceManager: service 'media.sound_trigger_hw' died
+06-15 19:57:33.607 12736 12761 D PermissionCache: checking android.permission.MODIFY_AUDIO_SETTINGS for uid=10197 => granted (698 us)
+--------- beginning of crash
+06-15 19:57:33.607 12736 12761 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 12761 (Binder:12736_2)
+06-15 19:57:33.608   379   379 W         : debuggerd: handling request: pid=12736 uid=1041 gid=1005 tid=12761
+06-15 19:57:33.670 26192 26192 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+06-15 19:57:33.670 26192 26192 F DEBUG   : Build fingerprint: 'google/bullhead/bullhead:7.1.2/N2G48C/4104010:userdebug/dev-keys'
+06-15 19:57:33.670 26192 26192 F DEBUG   : Revision: 'rev_1.0'
+06-15 19:57:33.670 26192 26192 F DEBUG   : ABI: 'arm'
+06-15 19:57:33.670 26192 26192 F DEBUG   : pid: 12736, tid: 12761, name: Binder:12736_2  >>> /system/bin/audioserver <<<
+06-15 19:57:33.670 26192 26192 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
+06-15 19:57:33.670 26192 26192 F DEBUG   :     r0 00000000  r1 00000000  r2 0000005f  r3 00000000
+06-15 19:57:33.670 26192 26192 F DEBUG   :     r4 ffffffff  r5 00000000  r6 f14f9000  r7 00000001
+06-15 19:57:33.670 26192 26192 F DEBUG   :     r8 00000004  r9 f3353114  sl f3313900  fp 00000000
+06-15 19:57:33.670 26192 26192 F DEBUG   :     ip f3bd4d88  sp f127d9c8  lr f3b9cbc5  pc f3b65af4  cpsr 60000030
+06-15 19:57:33.676 26192 26192 F DEBUG   :
+06-15 19:57:33.676 26192 26192 F DEBUG   : backtrace:
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #00 pc 00018af4  /system/lib/libc.so (strlen+71)
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #01 pc 0004fbc1  /system/lib/libc.so (__strlen_chk+4)
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #02 pc 0000c599  /system/lib/libutils.so (_ZN7android7String8C2EPKc+12)
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #03 pc 0002fdbf  /system/lib/libaudiopolicymanagerdefault.so (_ZNK7android18HwModuleCollection19getDeviceDescriptorEjPKcS2_b+458)
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #04 pc 0001de47  /system/lib/libaudiopolicymanagerdefault.so (_ZN7android18AudioPolicyManager27setDeviceConnectionStateIntEj24audio_policy_dev_state_tPKcS3_+178)
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #05 pc 0000a009  /system/lib/libaudiopolicyservice.so
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #06 pc 000a01a5  /system/lib/libmedia.so (_ZN7android20BnAudioPolicyService10onTransactEjRKNS_6ParcelEPS1_j+1256)
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #07 pc 000359c3  /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+70)
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #08 pc 0003d1bb  /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+702)
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #09 pc 0003ce07  /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+114)
+06-15 19:57:33.677 26192 26192 F DEBUG   :     #10 pc 0003d31b  /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+46)
+06-15 19:57:33.678 26192 26192 F DEBUG   :     #11 pc 0004f8c5  /system/lib/libbinder.so
+06-15 19:57:33.678 26192 26192 F DEBUG   :     #12 pc 0000e345  /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
+06-15 19:57:33.678 26192 26192 F DEBUG   :     #13 pc 000470b3  /system/lib/libc.so (_ZL15__pthread_startPv+22)
+06-15 19:57:33.678 26192 26192 F DEBUG   :     #14 pc 00019e3d  /system/lib/libc.so (__start_thread+6)
+06-15 19:57:33.839   934  2991 W NativeCrashListener: Couldn't find ProcessRecord for pid 12736
+06-15 19:57:33.846   934   952 I BootReceiver: Copying /data/tombstones/tombstone_01 to DropBox (SYSTEM_TOMBSTONE)
+06-15 19:57:35.130 26201 26227 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 26227 (Binder:26201_3)
+06-15 19:57:35.130 26201 26228 D PermissionCache: checking android.permission.MODIFY_AUDIO_SETTINGS for uid=1000 => granted (318 us)
+06-15 19:57:35.130   379   379 W         : debuggerd: handling request: pid=26201 uid=1041 gid=1005 tid=26227
+06-15 19:57:35.131 26201 26212 D audio_hw_primary: select_devices: changing use case low-latency-playback output device from(0: none, acdb -1) to (2: speaker, acdb 14)
+06-15 19:57:35.191 26230 26230 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+06-15 19:57:35.191 26230 26230 F DEBUG   : Build fingerprint: 'google/bullhead/bullhead:7.1.2/N2G48C/4104010:userdebug/dev-keys'
+06-15 19:57:35.191 26230 26230 F DEBUG   : Revision: 'rev_1.0'
+06-15 19:57:35.191 26230 26230 F DEBUG   : ABI: 'arm'
+06-15 19:57:35.191 26230 26230 F DEBUG   : pid: 26201, tid: 26227, name: Binder:26201_3  >>> /system/bin/audioserver <<<
+06-15 19:57:35.191 26230 26230 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
+06-15 19:57:35.191 26230 26230 F DEBUG   :     r0 00000000  r1 00000000  r2 0000005f  r3 00000000
+06-15 19:57:35.191 26230 26230 F DEBUG   :     r4 ffffffff  r5 00000000  r6 e49bb000  r7 00000001
+06-15 19:57:35.191 26230 26230 F DEBUG   :     r8 00000004  r9 e6b53114  sl e6b13900  fp 00000000
+06-15 19:57:35.191 26230 26230 F DEBUG   :     ip e746bd88  sp e4c009c8  lr e7433bc5  pc e73fcaf4  cpsr 60000030
+06-15 19:57:35.195 26230 26230 F DEBUG   :
+06-15 19:57:35.195 26230 26230 F DEBUG   : backtrace:
+06-15 19:57:35.195 26230 26230 F DEBUG   :     #00 pc 00018af4  /system/lib/libc.so (strlen+71)
+06-15 19:57:35.195 26230 26230 F DEBUG   :     #01 pc 0004fbc1  /system/lib/libc.so (__strlen_chk+4)
+06-15 19:57:35.195 26230 26230 F DEBUG   :     #02 pc 0000c599  /system/lib/libutils.so (_ZN7android7String8C2EPKc+12)
+06-15 19:57:35.195 26230 26230 F DEBUG   :     #03 pc 0002fdbf  /system/lib/libaudiopolicymanagerdefault.so (_ZNK7android18HwModuleCollection19getDeviceDescriptorEjPKcS2_b+458)
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #04 pc 0001de47  /system/lib/libaudiopolicymanagerdefault.so (_ZN7android18AudioPolicyManager27setDeviceConnectionStateIntEj24audio_policy_dev_state_tPKcS3_+178)
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #05 pc 0000a009  /system/lib/libaudiopolicyservice.so
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #06 pc 000a01a5  /system/lib/libmedia.so (_ZN7android20BnAudioPolicyService10onTransactEjRKNS_6ParcelEPS1_j+1256)
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #07 pc 000359c3  /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+70)
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #08 pc 0003d1bb  /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+702)
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #09 pc 0003ce07  /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+114)
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #10 pc 0003d31b  /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+46)
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #11 pc 0004f8c5  /system/lib/libbinder.so
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #12 pc 0000e345  /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #13 pc 000470b3  /system/lib/libc.so (_ZL15__pthread_startPv+22)
+06-15 19:57:35.196 26230 26230 F DEBUG   :     #14 pc 00019e3d  /system/lib/libc.so (__start_thread+6)
+06-15 19:57:35.346   934  2991 W NativeCrashListener: Couldn't find ProcessRecord for pid 26201
+06-15 19:57:35.346 26230 26230 E         : AM data write failed: Broken pipe
+06-15 19:57:40.605 26246 26261 D audio_hw_primary: enable_snd_device: snd_device(78: vi-feedback)
+06-15 19:57:40.606 26246 26261 D audio_hw_primary: enable_audio_route: usecase(21) apply and update mixer path: spkr-vi-record
+06-15 19:57:40.673 26283 26283 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+06-15 19:57:40.674 26283 26283 F DEBUG   : Build fingerprint: 'google/bullhead/bullhead:7.1.2/N2G48C/4104010:userdebug/dev-keys'
+06-15 19:57:40.674 26283 26283 F DEBUG   : Revision: 'rev_1.0'
+06-15 19:57:40.674 26283 26283 F DEBUG   : ABI: 'arm'
+06-15 19:57:40.674 26283 26283 F DEBUG   : pid: 26246, tid: 26282, name: Binder:26246_5  >>> /system/bin/audioserver <<<
+06-15 19:57:40.674 26283 26283 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
+06-15 19:57:40.674 26283 26283 F DEBUG   :     r0 00000000  r1 00000000  r2 0000005f  r3 00000000
+06-15 19:57:40.674 26283 26283 F DEBUG   :     r4 ffffffff  r5 00000000  r6 eb750000  r7 00000001
+06-15 19:57:40.674 26283 26283 F DEBUG   :     r8 00000004  r9 ed953114  sl ed913900  fp 00000000
+06-15 19:57:40.674 26283 26283 F DEBUG   :     ip eda8bd88  sp eb4fd9c8  lr eda53bc5  pc eda1caf4  cpsr 60000030
+06-15 19:57:40.679 26283 26283 F DEBUG   :
+06-15 19:57:40.679 26283 26283 F DEBUG   : backtrace:
+06-15 19:57:40.679 26283 26283 F DEBUG   :     #00 pc 00018af4  /system/lib/libc.so (strlen+71)
+06-15 19:57:40.679 26283 26283 F DEBUG   :     #01 pc 0004fbc1  /system/lib/libc.so (__strlen_chk+4)
+06-15 19:57:40.679 26283 26283 F DEBUG   :     #02 pc 0000c599  /system/lib/libutils.so (_ZN7android7String8C2EPKc+12)
+06-15 19:57:40.679 26283 26283 F DEBUG   :     #03 pc 0002fdbf  /system/lib/libaudiopolicymanagerdefault.so (_ZNK7android18HwModuleCollection19getDeviceDescriptorEjPKcS2_b+458)
+06-15 19:57:40.679 26283 26283 F DEBUG   :     #04 pc 0001de47  /system/lib/libaudiopolicymanagerdefault.so (_ZN7android18AudioPolicyManager27setDeviceConnectionStateIntEj24audio_policy_dev_state_tPKcS3_+178)
+06-15 19:57:40.679 26283 26283 F DEBUG   :     #05 pc 0000a009  /system/lib/libaudiopolicyservice.so
+06-15 19:57:40.680 26283 26283 F DEBUG   :     #06 pc 000a01a5  /system/lib/libmedia.so (_ZN7android20BnAudioPolicyService10onTransactEjRKNS_6ParcelEPS1_j+1256)
+06-15 19:57:40.680 26283 26283 F DEBUG   :     #07 pc 000359c3  /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+70)
+06-15 19:57:40.680 26283 26283 F DEBUG   :     #08 pc 0003d1bb  /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+702)
+06-15 19:57:40.680 26283 26283 F DEBUG   :     #09 pc 0003ce07  /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+114)
+06-15 19:57:40.680 26283 26283 F DEBUG   :     #10 pc 0003d31b  /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+46)
+06-15 19:57:40.680 26283 26283 F DEBUG   :     #11 pc 0004f8c5  /system/lib/libbinder.so
+06-15 19:57:40.680 26283 26283 F DEBUG   :     #12 pc 0000e345  /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+140)
+06-15 19:57:40.680 26283 26283 F DEBUG   :     #13 pc 000470b3  /system/lib/libc.so (_ZL15__pthread_startPv+22)
+06-15 19:57:40.680 26283 26283 F DEBUG   :     #14 pc 00019e3d  /system/lib/libc.so (__start_thread+6)
+06-15 19:57:40.882   934  2991 W NativeCrashListener: Couldn't find ProcessRecord for pid 26246
+06-15 19:57:40.889   934   952 I BootReceiver: Copying /data/tombstones/tombstone_03 to DropBox (SYSTEM_TOMBSTONE)
+09-23 01:55:43.022   245   245 F installd: utils.cpp:67] Check failed: is_valid_package_name(package_name) == 0
+--------- beginning of crash
+09-23 01:55:43.022   245   245 F libc    : Fatal signal 6 (SIGABRT), code -6 in tid 245 (installd)
+09-23 01:55:43.022   166   166 W         : debuggerd: handling request: pid=245 uid=0 gid=0 tid=245
+09-23 01:55:43.026   546   546 E         : debuggerd: Unable to connect to activity manager (connect failed: Connection refused)
+09-23 01:55:43.076   546   546 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+09-23 01:55:43.076   546   546 F DEBUG   : Build fingerprint: 'google/ryu/dragon:7.1.2/N2G48C/4104010:userdebug/dev-keys'
+09-23 01:55:43.076   546   546 F DEBUG   : Revision: '0'
+09-23 01:55:43.076   546   546 F DEBUG   : ABI: 'arm64'
+09-23 01:55:43.077   546   546 F DEBUG   : pid: 245, tid: 245, name: installd  >>> /system/bin/installd <<<
+09-23 01:55:43.077   546   546 F DEBUG   : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+09-23 01:55:43.077   546   546 F DEBUG   : Abort message: 'utils.cpp:67] Check failed: is_valid_package_name(package_name) == 0 '
+09-23 01:55:43.077   546   546 F DEBUG   :     x0   0000000000000000  x1   00000000000000f5  x2   0000000000000006  x3   0000000000000008
+09-23 01:55:43.078   546   546 F DEBUG   :     x4   0000000000000000  x5   0000000000000000  x6   00000076a4172000  x7   0000000000000000
+09-23 01:55:43.078   546   546 F DEBUG   :     x8   0000000000000083  x9   ffffffffffffffdf  x10  0000000000000000  x11  0000000000000001
+09-23 01:55:43.078   546   546 F DEBUG   :     x12  0000000000000018  x13  0000000000000000  x14  0000000000000000  x15  000157de95b365f0
+09-23 01:55:43.078   546   546 F DEBUG   :     x16  00000076a4099ee0  x17  00000076a4043b24  x18  0000000000000000  x19  00000076a4227b40
+09-23 01:55:43.078   546   546 F DEBUG   :     x20  0000000000000006  x21  00000076a4227a98  x22  0000000000000014  x23  0000000000000005
+09-23 01:55:43.078   546   546 F DEBUG   :     x24  00000076a3834040  x25  0000000000000000  x26  0000000000000005  x27  0000000000000006
+09-23 01:55:43.078   546   546 F DEBUG   :     x28  0000007ff8a77879  x29  0000007ff8a777f0  x30  00000076a4040f50
+09-23 01:55:43.078   546   546 F DEBUG   :     sp   0000007ff8a777d0  pc   00000076a4043b2c  pstate 0000000060000000
+09-23 01:55:43.081   546   546 F DEBUG   :
+09-23 01:55:43.081   546   546 F DEBUG   : backtrace:
+09-23 01:55:43.081   546   546 F DEBUG   :     #00 pc 000000000006bb2c  /system/lib64/libc.so (tgkill+8)
+09-23 01:55:43.081   546   546 F DEBUG   :     #01 pc 0000000000068f4c  /system/lib64/libc.so (pthread_kill+64)
+09-23 01:55:43.081   546   546 F DEBUG   :     #02 pc 0000000000023f58  /system/lib64/libc.so (raise+24)
+09-23 01:55:43.081   546   546 F DEBUG   :     #03 pc 000000000001c810  /system/lib64/libc.so (abort+52)
+09-23 01:55:43.081   546   546 F DEBUG   :     #04 pc 000000000000609c  /system/lib64/libbase.so (_ZN7android4base10LogMessageD1Ev+1084)
+09-23 01:55:43.082   546   546 F DEBUG   :     #05 pc 000000000001bbd4  /system/bin/installd
+09-23 01:55:43.082   546   546 F DEBUG   :     #06 pc 000000000001be38  /system/bin/installd
+09-23 01:55:43.082   546   546 F DEBUG   :     #07 pc 0000000000007f08  /system/bin/installd
+09-23 01:55:43.082   546   546 F DEBUG   :     #08 pc 0000000000005bd4  /system/bin/installd
+09-23 01:55:43.082   546   546 F DEBUG   :     #09 pc 000000000001a594  /system/lib64/libc.so (__libc_init+88)
+09-23 01:55:43.082   546   546 F DEBUG   :     #10 pc 0000000000004818  /system/bin/installd
+09-23 01:55:43.093   166   166 W         : debuggerd: resuming target 245
+09-23 01:55:43.132   516   516 E InstallerConnection: read exception
+09-23 01:55:43.132   516   516 I InstallerConnection: disconnecting...
+09-23 01:55:48.494   516   537 W WindowManager: App freeze timeout expired.
+09-23 01:55:52.058   163   163 W auditd  : type=1404 audit(0.0:4): enforcing=0 old_enforcing=1 auid=4294967295 ses=4294967295
+--------- beginning of main
+11-03 02:59:48.505  8049  8049 I stagefright: type=1400 audit(0.0:130): avc: denied { read } for path="/data/data/test1.mp4" dev="sda35" ino=868967 scontext=u:r:drmserver:s0 tcontext=u:object_r:system_data_file:s0 tclass=file permissive=1
+11-03 02:59:48.505  3939  3939 I chatty  : uid=10040(u0_a40) com.google.android.setupwizard expire 52528 lines
+11-03 02:59:48.559  8049  8054 I OMXClient: Treble IOmx obtained
+--------- beginning of crash
+11-03 02:59:48.892  6371  8072 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+11-03 02:59:48.892  6371  8072 F DEBUG   : Build fingerprint: 'google/marlin/marlin:8.0.0/OC/mspect11021711:userdebug/dev-keys'
+11-03 02:59:48.892  6371  8072 F DEBUG   : Revision: '0'
+11-03 02:59:48.892  6371  8072 F DEBUG   : ABI: 'arm'
+11-03 02:59:48.892  6371  8072 F DEBUG   : pid: 6371, tid: 8072, name: media.codec  >>> omx@1.0-service <<<
+11-03 02:59:48.892  6371  8072 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xed000000
+11-03 02:59:48.900  6371  8072 F DEBUG   :     r0 ecffdba0  r1 ed000000  r2 d44854c0  r3 00000070
+11-03 02:59:48.900  6371  8072 F DEBUG   :     r4 00000070  r5 000021a0  r6 00000070  r7 00000070
+11-03 02:59:48.900  6371  8072 F DEBUG   :     r8 00000040  r9 ffc2b278  sl ffffde70  fp 00000060
+11-03 02:59:48.900  6371  8072 F DEBUG   :     ip ffffffa0  sp d2fff620  lr 00004308  pc ed1c0e7c  cpsr a00f0010
+11-03 02:59:48.901  6371  8072 F DEBUG   :
+11-03 02:59:48.901  6371  8072 F DEBUG   : backtrace:
+11-03 02:59:48.901  6371  8072 F DEBUG   :     #00 pc 00034e7c  /system/lib/libstagefright_soft_hevcdec.so
+--------- beginning of system
+11-03 02:59:48.905  1135  1155 I BootReceiver: Copying /data/tombstones/tombstone_03 to DropBox (SYSTEM_TOMBSTONE)
+05-04 21:59:23.695  9363  9363 I crash_dump64: performing dump of process 8373 (target tid = 8414)
+05-04 21:59:23.695  9363  9363 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+05-04 21:59:23.696  9363  9363 F DEBUG   : Build fingerprint: 'google/taimen/taimen:8.1.0/OPM2.171026.006.A1/4756228:userdebug/dev-keys'
+05-04 21:59:23.696  9363  9363 F DEBUG   : Revision: 'rev_10'
+05-04 21:59:23.696  9363  9363 F DEBUG   : ABI: 'arm64'
+05-04 21:59:23.696  9363  9363 F DEBUG   : pid: 8373, tid: 8414, name: btu message loo  >>> com.android.bluetooth <<<
+05-04 21:59:23.696  9363  9363 F DEBUG   : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+05-04 21:59:23.700  9363  9363 F DEBUG   : Abort message: '[FATAL:allocation_tracker.cc(143)] Check failed: map_entry != allocations.end().
+05-04 21:59:23.700  9363  9363 F DEBUG   : '
+05-04 21:59:23.700  9363  9363 F DEBUG   :     x0   0000000000000000  x1   00000000000020de  x2   0000000000000006  x3   0000000000000008
+05-04 21:59:23.701  9363  9363 F DEBUG   :     x4   613a4c415441465b  x5   613a4c415441465b  x6   613a4c415441465b  x7   6f697461636f6c6c
+05-04 21:59:23.701  9363  9363 F DEBUG   :     x8   0000000000000083  x9   0000000010000000  x10  000000703a7a7c80  x11  0000000000000001
+05-04 21:59:23.701  9363  9363 F DEBUG   :     x12  746e655f70616d20  x13  6c61203d21207972  x14  ff00000000000000  x15  ffffffffffffffff
+05-04 21:59:23.701  9363  9363 F DEBUG   :     x16  0000006380f4afa8  x17  00000070d20af52c  x18  0000000000000000  x19  00000000000020b5
+05-04 21:59:23.701  9363  9363 F DEBUG   :     x20  00000000000020de  x21  0000000000000083  x22  000000703a7a9588  x23  000000703b8ee000
+05-04 21:59:23.701  9363  9363 F DEBUG   :     x24  000000703a7a7d01  x25  000000703a7a9588  x26  000000703bc7d948  x27  00000070484c92d8
+05-04 21:59:23.701  9363  9363 F DEBUG   :     x28  0000000000000006  x29  000000703a7a7cc0  x30  00000070d2064760
+05-04 21:59:23.701  9363  9363 F DEBUG   :     sp   000000703a7a7c80  pc   00000070d2064788  pstate 0000000060000000
+05-04 21:59:23.742  9363  9363 F DEBUG   :
+05-04 21:59:23.742  9363  9363 F DEBUG   : backtrace:
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #00 pc 000000000001d788  /system/lib64/libc.so (abort+120)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #01 pc 0000000000083470  /system/lib64/libchrome.so (base::debug::BreakDebugger()+20)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #02 pc 000000000009affc  /system/lib64/libchrome.so (logging::LogMessage::~LogMessage()+1068)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #03 pc 0000000000199130  /system/lib64/hw/bluetooth.default.so (allocation_tracker_notify_free(unsigned char, void*)+720)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #04 pc 000000000019984c  /system/lib64/hw/bluetooth.default.so (osi_free(void*)+20)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #05 pc 0000000000163f1c  /system/lib64/hw/bluetooth.default.so (l2c_fcr_cleanup(t_l2c_ccb*)+92)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #06 pc 000000000016adc8  /system/lib64/hw/bluetooth.default.so (l2cu_release_ccb(t_l2c_ccb*)+176)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #07 pc 0000000000162ea0  /system/lib64/hw/bluetooth.default.so (l2c_csm_execute(t_l2c_ccb*, unsigned short, void*)+1852)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #08 pc 000000000015e4f4  /system/lib64/hw/bluetooth.default.so (L2CA_DisconnectRsp(unsigned short)+92)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #09 pc 00000000001838b0  /system/lib64/hw/bluetooth.default.so (sdp_disconnect_ind(unsigned short, bool)+52)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #10 pc 0000000000163574  /system/lib64/hw/bluetooth.default.so (l2c_csm_execute(t_l2c_ccb*, unsigned short, void*)+3600)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #11 pc 0000000000169f94  /system/lib64/hw/bluetooth.default.so (l2c_rcv_acl_data(BT_HDR*)+3980)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #12 pc 00000000000849cc  /system/lib64/libchrome.so (base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask const&)+188)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #13 pc 000000000009efa4  /system/lib64/libchrome.so (base::MessageLoop::RunTask(base::PendingTask const&)+444)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #14 pc 000000000009f26c  /system/lib64/libchrome.so (base::MessageLoop::DeferOrRunPendingTask(base::PendingTask)+52)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #15 pc 000000000009f698  /system/lib64/libchrome.so (base::MessageLoop::DoWork()+356)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #16 pc 00000000000a08a8  /system/lib64/libchrome.so (base::MessagePumpDefault::Run(base::MessagePump::Delegate*)+220)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #17 pc 00000000000ba124  /system/lib64/libchrome.so (base::RunLoop::Run()+136)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #18 pc 0000000000138660  /system/lib64/hw/bluetooth.default.so (btu_message_loop_run(void*)+248)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #19 pc 00000000001a24fc  /system/lib64/hw/bluetooth.default.so (work_queue_read_cb(void*)+92)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #20 pc 00000000001a0758  /system/lib64/hw/bluetooth.default.so (run_reactor(reactor_t*, int)+320)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #21 pc 00000000001a05ec  /system/lib64/hw/bluetooth.default.so (reactor_start(reactor_t*)+84)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #22 pc 00000000001a1f94  /system/lib64/hw/bluetooth.default.so (run_thread(void*)+184)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #23 pc 0000000000067d80  /system/lib64/libc.so (__pthread_start(void*)+36)
+05-04 21:59:23.743  9363  9363 F DEBUG   :     #24 pc 000000000001ec18  /system/lib64/libc.so (__start_thread+68)
+1-25 19:47:35.417  8080 11665 F MPEG4Extractor: frameworks/av/media/libstagefright/MPEG4Extractor.cpp:6853 CHECK_EQ( (unsigned)ptr[0],1u) failed: 129 vs. 1
+11-25 19:47:35.417  8080 11665 F libc    : Fatal signal 6 (SIGABRT), code -6 in tid 11665 (generic)
+11-25 19:47:35.487   940   940 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
+11-25 19:47:35.487   940   940 F DEBUG   : Build fingerprint: 'samsung/hero2qltezc/hero2qltechn:6.0.1/MMB29M/G9350ZCU2APJ6:user/release-keys'
+11-25 19:47:35.487   940   940 F DEBUG   : Revision: '15'
+11-25 19:47:35.487   940   940 F DEBUG   : ABI: 'arm'
+11-25 19:47:35.487   940   940 F DEBUG   : pid: 8080, tid: 11665, name: generic  >>> /system/bin/mediaserver <<<
+11-25 19:47:35.487   940   940 F DEBUG   : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
+11-25 19:47:35.577   940   940 F DEBUG   : Abort message: 'frameworks/av/media/libstagefright/MPEG4Extractor.cpp:6853 CHECK_EQ( (unsigned)ptr[0],1u) failed: 129 vs. 1'
+11-25 19:47:35.577   940   940 F DEBUG   :     r0 00000000  r1 00002d91  r2 00000006  r3 eb23f978
+11-25 19:47:35.577   940   940 F DEBUG   :     r4 eb23f980  r5 eb23f930  r6 00000009  r7 0000010c
+11-25 19:47:35.577   940   940 F DEBUG   :     r8 e9e91140  r9 00000000  sl 00000000  fp 000003d3
+11-25 19:47:35.577   940   940 F DEBUG   :     ip 00000006  sp eb23db70  lr f701313d  pc f7015538  cpsr 40010010
+11-25 19:47:35.597   940   940 F DEBUG   :
+11-25 19:47:35.597   940   940 F DEBUG   : backtrace:
+11-25 19:47:35.597   940   940 F DEBUG   :     #00 pc 00042538  /system/lib/libc.so (tgkill+12)
+11-25 19:47:35.597   940   940 F DEBUG   :     #01 pc 00040139  /system/lib/libc.so (pthread_kill+32)
+11-25 19:47:35.597   940   940 F DEBUG   :     #02 pc 0001c783  /system/lib/libc.so (raise+10)
+11-25 19:47:35.597   940   940 F DEBUG   :     #03 pc 000199f1  /system/lib/libc.so (__libc_android_abort+34)
+11-25 19:47:35.597   940   940 F DEBUG   :     #04 pc 000175ac  /system/lib/libc.so (abort+4)
+11-25 19:47:35.597   940   940 F DEBUG   :     #05 pc 000085e7  /system/lib/libcutils.so (__android_log_assert+86)
+11-25 19:47:35.597   940   940 F DEBUG   :     #06 pc 000c1f49  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor25avcc_getCodecSpecificInfoERNS_2spINS_7ABufferEEEPKcj+392)
+11-25 19:47:35.597   940   940 F DEBUG   :     #07 pc 000c213f  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor15checkConfigDataEjRKNS_2spINS_8MetaDataEEE+218)
+11-25 19:47:35.597   940   940 F DEBUG   :     #08 pc 000bbd25  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor12checkSupportEjRKNS_2spINS_8MetaDataEEE+136)
+11-25 19:47:35.597   940   940 F DEBUG   :     #09 pc 000ba555  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+13060)
+11-25 19:47:35.597   940   940 F DEBUG   :     #10 pc 000ba32d  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+12508)
+11-25 19:47:35.597   940   940 F DEBUG   :     #11 pc 000b8a6f  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+6174)
+11-25 19:47:35.597   940   940 F DEBUG   :     #12 pc 000b8a6f  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+6174)
+11-25 19:47:35.597   940   940 F DEBUG   :     #13 pc 000b8a6f  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+6174)
+11-25 19:47:35.597   940   940 F DEBUG   :     #14 pc 000b8a6f  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+6174)
+11-25 19:47:35.597   940   940 F DEBUG   :     #15 pc 000b8a6f  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+6174)
+11-25 19:47:35.597   940   940 F DEBUG   :     #16 pc 000b6e3b  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor12readMetaDataEv+94)
+11-25 19:47:35.597   940   940 F DEBUG   :     #17 pc 000b6daf  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor11getMetaDataEv+10)
+11-25 19:47:35.597   940   940 F DEBUG   :     #18 pc 00088c53  /system/lib/libmediaplayerservice.so (_ZN7android8NuPlayer13GenericSource18initFromDataSourceEv+386)
+11-25 19:47:35.597   940   940 F DEBUG   :     #19 pc 00089b43  /system/lib/libmediaplayerservice.so (_ZN7android8NuPlayer13GenericSource14onPrepareAsyncEv+238)
+11-25 19:47:35.597   940   940 F DEBUG   :     #20 pc 0000b405  /system/lib/libstagefright_foundation.so (_ZN7android8AHandler14deliverMessageERKNS_2spINS_8AMessageEEE+16)
+11-25 19:47:35.597   940   940 F DEBUG   :     #21 pc 0000d423  /system/lib/libstagefright_foundation.so (_ZN7android8AMessage7deliverEv+54)
+11-25 19:47:35.597   940   940 F DEBUG   :     #22 pc 0000be29  /system/lib/libstagefright_foundation.so (_ZN7android7ALooper4loopEv+224)
+11-25 19:47:35.597   940   940 F DEBUG   :     #23 pc 0001011d  /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+112)
+11-25 19:47:35.597   940   940 F DEBUG   :     #24 pc 0003fa3b  /system/lib/libc.so (_ZL15__pthread_startPv+30)
+11-25 19:47:35.597   940   940 F DEBUG   :     #25 pc 0001a085  /system/lib/libc.so (__start_thread+6)
+11-25 19:47:35.837   940   940 F DEBUG   :
+11-25 19:47:35.837   940   940 F DEBUG   : Tombstone written to: /data/tombstones/tombstone_01
\ No newline at end of file
diff --git a/common/util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java b/common/util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java
new file mode 100644
index 0000000..431571eb
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/CrashUtilsTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2019 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.compatibility.common.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+@RunWith(JUnit4.class)
+public class CrashUtilsTest extends TestCase {
+
+    private List<Crash> mCrashes;
+
+    @Before
+    public void setUp() throws IOException {
+        BufferedReader txtReader =
+            new BufferedReader(
+                new InputStreamReader(
+                    getClass().getClassLoader().getResourceAsStream("logcat.txt")));
+        try {
+            StringBuffer input = new StringBuffer();
+            String tmp;
+            while ((tmp = txtReader.readLine()) != null) {
+                input.append(tmp + "\n");
+            }
+            mCrashes = CrashUtils.getAllCrashes(input.toString());
+        } finally {
+            txtReader.close();
+        }
+    }
+
+    @Test
+    public void testGetAllCrashes() throws Exception {
+        List<Crash> expectedResults = new ArrayList<>();
+        expectedResults.add(new Crash(11071, 11189, "AudioOut_D", 3912761344L, "SIGSEGV"));
+        expectedResults.add(new Crash(12736, 12761, "Binder:12736_2", 0L, "SIGSEGV"));
+        expectedResults.add(new Crash(26201, 26227, "Binder:26201_3", 0L, "SIGSEGV"));
+        expectedResults.add(new Crash(26246, 26282, "Binder:26246_5", 0L, "SIGSEGV"));
+        expectedResults.add(new Crash(245, 245, "installd", null, "SIGABRT"));
+        expectedResults.add(new Crash(6371, 8072, "media.codec", 3976200192L, "SIGSEGV"));
+        expectedResults.add(new Crash(8373, 8414, "loo", null, "SIGABRT"));
+
+        assertEquals(expectedResults, mCrashes);
+    }
+
+    @Test
+    public void testValidCrash() throws Exception {
+        assertTrue(CrashUtils.detectCrash(new String[]{"AudioOut_D"}, true, mCrashes));
+    }
+
+    @Test
+    public void testMissingName() throws Exception {
+        assertFalse(CrashUtils.detectCrash(new String[]{""}, true, mCrashes));
+    }
+
+    @Test
+    public void testSIGABRT() throws Exception {
+        assertFalse(CrashUtils.detectCrash(new String[]{"installd"}, true, mCrashes));
+    }
+
+    @Test
+    public void testFaultAddressBelowMin() throws Exception {
+        assertFalse(
+            CrashUtils.detectCrash(new String[]{"Binder:12736_2"}, true, mCrashes));
+    }
+
+    @Test
+    public void testIgnoreMinAddressCheck() throws Exception {
+        assertTrue(
+            CrashUtils.detectCrash(new String[]{"Binder:12736_2"}, false, mCrashes));
+    }
+
+    @Test
+    public void testBadAbortMessage() throws Exception {
+        assertFalse(CrashUtils.detectCrash(new String[]{"generic"}, true, mCrashes));
+    }
+
+    @Test
+    public void testGoodAndBadCrashes() throws Exception {
+        assertTrue(
+            CrashUtils.detectCrash(new String[]{"AudioOut_D", "generic"}, true, mCrashes));
+    }
+}
\ No newline at end of file
diff --git a/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java b/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java
index 0a7dd47..4a93208 100644
--- a/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java
+++ b/common/util/tests/src/com/android/compatibility/common/util/UnitTests.java
@@ -29,6 +29,7 @@
         super();
         addTestSuite(AbiUtilsTest.class);
         addTestSuite(CaseResultTest.class);
+        addTestSuite(CrashUtilsTest.class);
         addTestSuite(DynamicConfigTest.class);
         addTestSuite(LightInvocationResultTest.class);
         addTestSuite(MetricsXmlSerializerTest.class);
diff --git a/tests/core/runner/src/com/android/cts/runner/CrashParserRunListener.java b/tests/core/runner/src/com/android/cts/runner/CrashParserRunListener.java
new file mode 100644
index 0000000..fbbb684
--- /dev/null
+++ b/tests/core/runner/src/com/android/cts/runner/CrashParserRunListener.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.cts.runner;
+
+import android.support.test.internal.runner.listener.InstrumentationRunListener;
+import android.util.Log;
+import org.junit.runner.Description;
+
+/**
+ * A {@link RunListener} for CrashParser. Dumps the test name to logs when
+ * tests start.
+ */
+public class CrashParserRunListener extends InstrumentationRunListener {
+
+    private static final String TAG = "CrashParserRunListener";
+
+    // Constant must be kept in sync with CrashUtils.java
+    public static final String NEW_TEST_ALERT = "New test starting with name: ";
+
+    @Override
+    public void testStarted(Description description) throws Exception {
+        Log.i(TAG, NEW_TEST_ALERT + description.toString());
+    }
+
+}
diff --git a/tests/filesystem/src/android/filesystem/cts/FileUtil.java b/tests/filesystem/src/android/filesystem/cts/FileUtil.java
index 8149105..5433f0a 100755
--- a/tests/filesystem/src/android/filesystem/cts/FileUtil.java
+++ b/tests/filesystem/src/android/filesystem/cts/FileUtil.java
@@ -143,15 +143,14 @@
     public static File createNewFilledFile(Context context, String dirName, long length)
             throws IOException {
         File file = createNewFile(context, dirName);
-        FileOutputStream out = new FileOutputStream(file);
+        final RandomAccessFile randomFile = new RandomAccessFile(file, "rwd"); // force O_SYNC
         byte[] data = generateRandomData(BUFFER_SIZE);
-        long written = 0;
-        while (written < length) {
-            out.write(data);
-            written += BUFFER_SIZE;
+
+        while (file.length() < length) {
+            randomFile.write(data);
         }
-        out.flush();
-        out.close();
+
+        randomFile.close();
         return file;
     }
 
diff --git a/tests/tests/media/assets/hls_variant/165340/00.ts b/tests/tests/media/assets/hls_variant/165340/00.ts
new file mode 100644
index 0000000..8a95fc5
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/00.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/01.ts b/tests/tests/media/assets/hls_variant/165340/01.ts
new file mode 100644
index 0000000..7983a01
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/01.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/02.ts b/tests/tests/media/assets/hls_variant/165340/02.ts
new file mode 100644
index 0000000..2582937
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/02.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/03.ts b/tests/tests/media/assets/hls_variant/165340/03.ts
new file mode 100644
index 0000000..4e4711e
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/03.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/04.ts b/tests/tests/media/assets/hls_variant/165340/04.ts
new file mode 100644
index 0000000..e210aac
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/04.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/05.ts b/tests/tests/media/assets/hls_variant/165340/05.ts
new file mode 100644
index 0000000..5d445bf
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/05.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/06.ts b/tests/tests/media/assets/hls_variant/165340/06.ts
new file mode 100644
index 0000000..e83d2a3
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/06.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/07.ts b/tests/tests/media/assets/hls_variant/165340/07.ts
new file mode 100644
index 0000000..37322c0
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/07.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/08.ts b/tests/tests/media/assets/hls_variant/165340/08.ts
new file mode 100644
index 0000000..25f9f00
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/08.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/09.ts b/tests/tests/media/assets/hls_variant/165340/09.ts
new file mode 100644
index 0000000..2debe48
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/09.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/10.ts b/tests/tests/media/assets/hls_variant/165340/10.ts
new file mode 100644
index 0000000..3eed736
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/10.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/11.ts b/tests/tests/media/assets/hls_variant/165340/11.ts
new file mode 100644
index 0000000..7ae79e9
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/11.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/12.ts b/tests/tests/media/assets/hls_variant/165340/12.ts
new file mode 100644
index 0000000..4153626
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/12.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/13.ts b/tests/tests/media/assets/hls_variant/165340/13.ts
new file mode 100644
index 0000000..027adf4
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/13.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/14.ts b/tests/tests/media/assets/hls_variant/165340/14.ts
new file mode 100644
index 0000000..ea7d0be
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/14.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/15.ts b/tests/tests/media/assets/hls_variant/165340/15.ts
new file mode 100644
index 0000000..48c92c9
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/15.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/16.ts b/tests/tests/media/assets/hls_variant/165340/16.ts
new file mode 100644
index 0000000..19f0ebd
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/16.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/17.ts b/tests/tests/media/assets/hls_variant/165340/17.ts
new file mode 100644
index 0000000..7d4897d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/17.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/18.ts b/tests/tests/media/assets/hls_variant/165340/18.ts
new file mode 100644
index 0000000..47431d0
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/18.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/19.ts b/tests/tests/media/assets/hls_variant/165340/19.ts
new file mode 100644
index 0000000..9e98a4f
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/19.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/20.ts b/tests/tests/media/assets/hls_variant/165340/20.ts
new file mode 100644
index 0000000..e674296
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/20.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/21.ts b/tests/tests/media/assets/hls_variant/165340/21.ts
new file mode 100644
index 0000000..2affe9d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/21.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/22.ts b/tests/tests/media/assets/hls_variant/165340/22.ts
new file mode 100644
index 0000000..0634296
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/22.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/23.ts b/tests/tests/media/assets/hls_variant/165340/23.ts
new file mode 100644
index 0000000..faf9ca8
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/23.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/24.ts b/tests/tests/media/assets/hls_variant/165340/24.ts
new file mode 100644
index 0000000..3b3f4d7
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/24.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/165340/index.m3u8 b/tests/tests/media/assets/hls_variant/165340/index.m3u8
new file mode 100644
index 0000000..f36f33d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/165340/index.m3u8
@@ -0,0 +1,53 @@
+#EXTM3U
+#EXT-X-VERSION:3
+#EXT-X-TARGETDURATION:5
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:5,
+00.ts
+#EXTINF:5,
+01.ts
+#EXTINF:5,
+02.ts
+#EXTINF:5,
+03.ts
+#EXTINF:5,
+04.ts
+#EXTINF:5,
+05.ts
+#EXTINF:5,
+06.ts
+#EXTINF:5,
+07.ts
+#EXTINF:5,
+08.ts
+#EXTINF:5,
+09.ts
+#EXTINF:5,
+10.ts
+#EXTINF:5,
+11.ts
+#EXTINF:5,
+12.ts
+#EXTINF:5,
+13.ts
+#EXTINF:5,
+14.ts
+#EXTINF:5,
+15.ts
+#EXTINF:5,
+16.ts
+#EXTINF:5,
+17.ts
+#EXTINF:5,
+18.ts
+#EXTINF:5,
+19.ts
+#EXTINF:5,
+20.ts
+#EXTINF:5,
+21.ts
+#EXTINF:5,
+22.ts
+#EXTINF:5,
+23.ts
+#EXT-X-ENDLIST
\ No newline at end of file
diff --git a/tests/tests/media/assets/hls_variant/1676816/00.ts b/tests/tests/media/assets/hls_variant/1676816/00.ts
new file mode 100644
index 0000000..aba6f79
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/00.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/01.ts b/tests/tests/media/assets/hls_variant/1676816/01.ts
new file mode 100644
index 0000000..18c382b
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/01.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/02.ts b/tests/tests/media/assets/hls_variant/1676816/02.ts
new file mode 100644
index 0000000..8b45649
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/02.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/03.ts b/tests/tests/media/assets/hls_variant/1676816/03.ts
new file mode 100644
index 0000000..5a1dee6
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/03.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/04.ts b/tests/tests/media/assets/hls_variant/1676816/04.ts
new file mode 100644
index 0000000..69c4dfa
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/04.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/05.ts b/tests/tests/media/assets/hls_variant/1676816/05.ts
new file mode 100644
index 0000000..bd1e938
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/05.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/06.ts b/tests/tests/media/assets/hls_variant/1676816/06.ts
new file mode 100644
index 0000000..dfdfe31
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/06.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/07.ts b/tests/tests/media/assets/hls_variant/1676816/07.ts
new file mode 100644
index 0000000..be22e90
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/07.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/08.ts b/tests/tests/media/assets/hls_variant/1676816/08.ts
new file mode 100644
index 0000000..a892318
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/08.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/09.ts b/tests/tests/media/assets/hls_variant/1676816/09.ts
new file mode 100644
index 0000000..9a1e3c9
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/09.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/10.ts b/tests/tests/media/assets/hls_variant/1676816/10.ts
new file mode 100644
index 0000000..528e424
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/10.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/11.ts b/tests/tests/media/assets/hls_variant/1676816/11.ts
new file mode 100644
index 0000000..2ad52f9
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/11.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/12.ts b/tests/tests/media/assets/hls_variant/1676816/12.ts
new file mode 100644
index 0000000..5275b47
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/12.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/13.ts b/tests/tests/media/assets/hls_variant/1676816/13.ts
new file mode 100644
index 0000000..5894d31
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/13.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/14.ts b/tests/tests/media/assets/hls_variant/1676816/14.ts
new file mode 100644
index 0000000..44f5200
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/14.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/15.ts b/tests/tests/media/assets/hls_variant/1676816/15.ts
new file mode 100644
index 0000000..e548fb1
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/15.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/16.ts b/tests/tests/media/assets/hls_variant/1676816/16.ts
new file mode 100644
index 0000000..9ad2c6a
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/16.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/17.ts b/tests/tests/media/assets/hls_variant/1676816/17.ts
new file mode 100644
index 0000000..1cd735f
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/17.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/18.ts b/tests/tests/media/assets/hls_variant/1676816/18.ts
new file mode 100644
index 0000000..a593dba
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/18.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/19.ts b/tests/tests/media/assets/hls_variant/1676816/19.ts
new file mode 100644
index 0000000..3fb49cb
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/19.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/20.ts b/tests/tests/media/assets/hls_variant/1676816/20.ts
new file mode 100644
index 0000000..7a586e7
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/20.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/21.ts b/tests/tests/media/assets/hls_variant/1676816/21.ts
new file mode 100644
index 0000000..bd70554
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/21.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/22.ts b/tests/tests/media/assets/hls_variant/1676816/22.ts
new file mode 100644
index 0000000..12ea80d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/22.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/23.ts b/tests/tests/media/assets/hls_variant/1676816/23.ts
new file mode 100644
index 0000000..c1b5be9
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/23.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/24.ts b/tests/tests/media/assets/hls_variant/1676816/24.ts
new file mode 100644
index 0000000..76bd0b5
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/24.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/1676816/index.m3u8 b/tests/tests/media/assets/hls_variant/1676816/index.m3u8
new file mode 100644
index 0000000..f36f33d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/1676816/index.m3u8
@@ -0,0 +1,53 @@
+#EXTM3U
+#EXT-X-VERSION:3
+#EXT-X-TARGETDURATION:5
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:5,
+00.ts
+#EXTINF:5,
+01.ts
+#EXTINF:5,
+02.ts
+#EXTINF:5,
+03.ts
+#EXTINF:5,
+04.ts
+#EXTINF:5,
+05.ts
+#EXTINF:5,
+06.ts
+#EXTINF:5,
+07.ts
+#EXTINF:5,
+08.ts
+#EXTINF:5,
+09.ts
+#EXTINF:5,
+10.ts
+#EXTINF:5,
+11.ts
+#EXTINF:5,
+12.ts
+#EXTINF:5,
+13.ts
+#EXTINF:5,
+14.ts
+#EXTINF:5,
+15.ts
+#EXTINF:5,
+16.ts
+#EXTINF:5,
+17.ts
+#EXTINF:5,
+18.ts
+#EXTINF:5,
+19.ts
+#EXTINF:5,
+20.ts
+#EXTINF:5,
+21.ts
+#EXTINF:5,
+22.ts
+#EXTINF:5,
+23.ts
+#EXT-X-ENDLIST
\ No newline at end of file
diff --git a/tests/tests/media/assets/hls_variant/344388/00.ts b/tests/tests/media/assets/hls_variant/344388/00.ts
new file mode 100644
index 0000000..e26ad20
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/00.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/01.ts b/tests/tests/media/assets/hls_variant/344388/01.ts
new file mode 100644
index 0000000..fa5395d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/01.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/02.ts b/tests/tests/media/assets/hls_variant/344388/02.ts
new file mode 100644
index 0000000..a924b05
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/02.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/03.ts b/tests/tests/media/assets/hls_variant/344388/03.ts
new file mode 100644
index 0000000..4136491
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/03.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/04.ts b/tests/tests/media/assets/hls_variant/344388/04.ts
new file mode 100644
index 0000000..cf03032
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/04.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/05.ts b/tests/tests/media/assets/hls_variant/344388/05.ts
new file mode 100644
index 0000000..25d127b
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/05.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/06.ts b/tests/tests/media/assets/hls_variant/344388/06.ts
new file mode 100644
index 0000000..f132be4
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/06.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/07.ts b/tests/tests/media/assets/hls_variant/344388/07.ts
new file mode 100644
index 0000000..b1e7f36
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/07.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/08.ts b/tests/tests/media/assets/hls_variant/344388/08.ts
new file mode 100644
index 0000000..bbeb4fd
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/08.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/09.ts b/tests/tests/media/assets/hls_variant/344388/09.ts
new file mode 100644
index 0000000..f444ab9
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/09.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/10.ts b/tests/tests/media/assets/hls_variant/344388/10.ts
new file mode 100644
index 0000000..910dd43
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/10.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/11.ts b/tests/tests/media/assets/hls_variant/344388/11.ts
new file mode 100644
index 0000000..892a6b3
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/11.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/12.ts b/tests/tests/media/assets/hls_variant/344388/12.ts
new file mode 100644
index 0000000..2a8bfeb
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/12.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/13.ts b/tests/tests/media/assets/hls_variant/344388/13.ts
new file mode 100644
index 0000000..bf9f1a4
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/13.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/14.ts b/tests/tests/media/assets/hls_variant/344388/14.ts
new file mode 100644
index 0000000..45c604c
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/14.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/15.ts b/tests/tests/media/assets/hls_variant/344388/15.ts
new file mode 100644
index 0000000..4d5de4f
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/15.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/16.ts b/tests/tests/media/assets/hls_variant/344388/16.ts
new file mode 100644
index 0000000..9551838
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/16.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/17.ts b/tests/tests/media/assets/hls_variant/344388/17.ts
new file mode 100644
index 0000000..dde4452
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/17.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/18.ts b/tests/tests/media/assets/hls_variant/344388/18.ts
new file mode 100644
index 0000000..c7b3919
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/18.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/19.ts b/tests/tests/media/assets/hls_variant/344388/19.ts
new file mode 100644
index 0000000..5aa3c84
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/19.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/20.ts b/tests/tests/media/assets/hls_variant/344388/20.ts
new file mode 100644
index 0000000..0d509bb
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/20.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/21.ts b/tests/tests/media/assets/hls_variant/344388/21.ts
new file mode 100644
index 0000000..252a953
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/21.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/22.ts b/tests/tests/media/assets/hls_variant/344388/22.ts
new file mode 100644
index 0000000..7098fdd
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/22.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/23.ts b/tests/tests/media/assets/hls_variant/344388/23.ts
new file mode 100644
index 0000000..69bd886
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/23.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/24.ts b/tests/tests/media/assets/hls_variant/344388/24.ts
new file mode 100644
index 0000000..0542cc2
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/24.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/344388/index.m3u8 b/tests/tests/media/assets/hls_variant/344388/index.m3u8
new file mode 100644
index 0000000..f36f33d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/344388/index.m3u8
@@ -0,0 +1,53 @@
+#EXTM3U
+#EXT-X-VERSION:3
+#EXT-X-TARGETDURATION:5
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:5,
+00.ts
+#EXTINF:5,
+01.ts
+#EXTINF:5,
+02.ts
+#EXTINF:5,
+03.ts
+#EXTINF:5,
+04.ts
+#EXTINF:5,
+05.ts
+#EXTINF:5,
+06.ts
+#EXTINF:5,
+07.ts
+#EXTINF:5,
+08.ts
+#EXTINF:5,
+09.ts
+#EXTINF:5,
+10.ts
+#EXTINF:5,
+11.ts
+#EXTINF:5,
+12.ts
+#EXTINF:5,
+13.ts
+#EXTINF:5,
+14.ts
+#EXTINF:5,
+15.ts
+#EXTINF:5,
+16.ts
+#EXTINF:5,
+17.ts
+#EXTINF:5,
+18.ts
+#EXTINF:5,
+19.ts
+#EXTINF:5,
+20.ts
+#EXTINF:5,
+21.ts
+#EXTINF:5,
+22.ts
+#EXTINF:5,
+23.ts
+#EXT-X-ENDLIST
\ No newline at end of file
diff --git a/tests/tests/media/assets/hls_variant/387360/00.ts b/tests/tests/media/assets/hls_variant/387360/00.ts
new file mode 100644
index 0000000..c7233c2
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/00.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/01.ts b/tests/tests/media/assets/hls_variant/387360/01.ts
new file mode 100644
index 0000000..4d092dd
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/01.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/02.ts b/tests/tests/media/assets/hls_variant/387360/02.ts
new file mode 100644
index 0000000..5b0322e
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/02.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/03.ts b/tests/tests/media/assets/hls_variant/387360/03.ts
new file mode 100644
index 0000000..5081ef0
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/03.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/04.ts b/tests/tests/media/assets/hls_variant/387360/04.ts
new file mode 100644
index 0000000..0f6f0fe
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/04.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/05.ts b/tests/tests/media/assets/hls_variant/387360/05.ts
new file mode 100644
index 0000000..e455dec
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/05.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/06.ts b/tests/tests/media/assets/hls_variant/387360/06.ts
new file mode 100644
index 0000000..14afcb9d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/06.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/07.ts b/tests/tests/media/assets/hls_variant/387360/07.ts
new file mode 100644
index 0000000..6f23d02
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/07.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/08.ts b/tests/tests/media/assets/hls_variant/387360/08.ts
new file mode 100644
index 0000000..a3d8dfd
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/08.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/09.ts b/tests/tests/media/assets/hls_variant/387360/09.ts
new file mode 100644
index 0000000..87d6de1
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/09.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/10.ts b/tests/tests/media/assets/hls_variant/387360/10.ts
new file mode 100644
index 0000000..04ab37a
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/10.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/11.ts b/tests/tests/media/assets/hls_variant/387360/11.ts
new file mode 100644
index 0000000..1fa238b
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/11.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/12.ts b/tests/tests/media/assets/hls_variant/387360/12.ts
new file mode 100644
index 0000000..445b0b9
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/12.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/13.ts b/tests/tests/media/assets/hls_variant/387360/13.ts
new file mode 100644
index 0000000..6bcd81b
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/13.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/14.ts b/tests/tests/media/assets/hls_variant/387360/14.ts
new file mode 100644
index 0000000..f3f8e78
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/14.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/15.ts b/tests/tests/media/assets/hls_variant/387360/15.ts
new file mode 100644
index 0000000..6b12e72
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/15.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/16.ts b/tests/tests/media/assets/hls_variant/387360/16.ts
new file mode 100644
index 0000000..d95eeba
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/16.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/17.ts b/tests/tests/media/assets/hls_variant/387360/17.ts
new file mode 100644
index 0000000..141ae44
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/17.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/18.ts b/tests/tests/media/assets/hls_variant/387360/18.ts
new file mode 100644
index 0000000..fc52f1d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/18.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/19.ts b/tests/tests/media/assets/hls_variant/387360/19.ts
new file mode 100644
index 0000000..077db9b
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/19.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/20.ts b/tests/tests/media/assets/hls_variant/387360/20.ts
new file mode 100644
index 0000000..4ffb301
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/20.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/21.ts b/tests/tests/media/assets/hls_variant/387360/21.ts
new file mode 100644
index 0000000..6072368
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/21.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/22.ts b/tests/tests/media/assets/hls_variant/387360/22.ts
new file mode 100644
index 0000000..5edc055
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/22.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/23.ts b/tests/tests/media/assets/hls_variant/387360/23.ts
new file mode 100644
index 0000000..7870e39
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/23.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/24.ts b/tests/tests/media/assets/hls_variant/387360/24.ts
new file mode 100644
index 0000000..f4fc858
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/24.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/387360/index.m3u8 b/tests/tests/media/assets/hls_variant/387360/index.m3u8
new file mode 100644
index 0000000..f36f33d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/387360/index.m3u8
@@ -0,0 +1,53 @@
+#EXTM3U
+#EXT-X-VERSION:3
+#EXT-X-TARGETDURATION:5
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:5,
+00.ts
+#EXTINF:5,
+01.ts
+#EXTINF:5,
+02.ts
+#EXTINF:5,
+03.ts
+#EXTINF:5,
+04.ts
+#EXTINF:5,
+05.ts
+#EXTINF:5,
+06.ts
+#EXTINF:5,
+07.ts
+#EXTINF:5,
+08.ts
+#EXTINF:5,
+09.ts
+#EXTINF:5,
+10.ts
+#EXTINF:5,
+11.ts
+#EXTINF:5,
+12.ts
+#EXTINF:5,
+13.ts
+#EXTINF:5,
+14.ts
+#EXTINF:5,
+15.ts
+#EXTINF:5,
+16.ts
+#EXTINF:5,
+17.ts
+#EXTINF:5,
+18.ts
+#EXTINF:5,
+19.ts
+#EXTINF:5,
+20.ts
+#EXTINF:5,
+21.ts
+#EXTINF:5,
+22.ts
+#EXTINF:5,
+23.ts
+#EXT-X-ENDLIST
\ No newline at end of file
diff --git a/tests/tests/media/assets/hls_variant/765178/00.ts b/tests/tests/media/assets/hls_variant/765178/00.ts
new file mode 100644
index 0000000..c544131
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/00.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/01.ts b/tests/tests/media/assets/hls_variant/765178/01.ts
new file mode 100644
index 0000000..11adb7a
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/01.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/02.ts b/tests/tests/media/assets/hls_variant/765178/02.ts
new file mode 100644
index 0000000..d5300f4
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/02.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/03.ts b/tests/tests/media/assets/hls_variant/765178/03.ts
new file mode 100644
index 0000000..8a3ce79
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/03.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/04.ts b/tests/tests/media/assets/hls_variant/765178/04.ts
new file mode 100644
index 0000000..94b1ced
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/04.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/05.ts b/tests/tests/media/assets/hls_variant/765178/05.ts
new file mode 100644
index 0000000..d44d4a6
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/05.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/06.ts b/tests/tests/media/assets/hls_variant/765178/06.ts
new file mode 100644
index 0000000..52455dd
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/06.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/07.ts b/tests/tests/media/assets/hls_variant/765178/07.ts
new file mode 100644
index 0000000..cea2858
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/07.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/08.ts b/tests/tests/media/assets/hls_variant/765178/08.ts
new file mode 100644
index 0000000..79a1ef1
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/08.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/09.ts b/tests/tests/media/assets/hls_variant/765178/09.ts
new file mode 100644
index 0000000..6e987f2
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/09.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/10.ts b/tests/tests/media/assets/hls_variant/765178/10.ts
new file mode 100644
index 0000000..c5f1af4
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/10.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/11.ts b/tests/tests/media/assets/hls_variant/765178/11.ts
new file mode 100644
index 0000000..1a96c19
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/11.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/12.ts b/tests/tests/media/assets/hls_variant/765178/12.ts
new file mode 100644
index 0000000..b6095bb
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/12.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/13.ts b/tests/tests/media/assets/hls_variant/765178/13.ts
new file mode 100644
index 0000000..b91b740
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/13.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/14.ts b/tests/tests/media/assets/hls_variant/765178/14.ts
new file mode 100644
index 0000000..d033f16
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/14.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/15.ts b/tests/tests/media/assets/hls_variant/765178/15.ts
new file mode 100644
index 0000000..f294842
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/15.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/16.ts b/tests/tests/media/assets/hls_variant/765178/16.ts
new file mode 100644
index 0000000..15a9e9e
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/16.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/17.ts b/tests/tests/media/assets/hls_variant/765178/17.ts
new file mode 100644
index 0000000..e024ce0
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/17.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/18.ts b/tests/tests/media/assets/hls_variant/765178/18.ts
new file mode 100644
index 0000000..9e7fea2
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/18.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/19.ts b/tests/tests/media/assets/hls_variant/765178/19.ts
new file mode 100644
index 0000000..4bb80bf
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/19.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/20.ts b/tests/tests/media/assets/hls_variant/765178/20.ts
new file mode 100644
index 0000000..591fda9
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/20.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/21.ts b/tests/tests/media/assets/hls_variant/765178/21.ts
new file mode 100644
index 0000000..a3cab10
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/21.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/22.ts b/tests/tests/media/assets/hls_variant/765178/22.ts
new file mode 100644
index 0000000..c60c3f8
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/22.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/23.ts b/tests/tests/media/assets/hls_variant/765178/23.ts
new file mode 100644
index 0000000..e60a254
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/23.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/24.ts b/tests/tests/media/assets/hls_variant/765178/24.ts
new file mode 100644
index 0000000..bc75f31
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/24.ts
Binary files differ
diff --git a/tests/tests/media/assets/hls_variant/765178/index.m3u8 b/tests/tests/media/assets/hls_variant/765178/index.m3u8
new file mode 100644
index 0000000..f36f33d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/765178/index.m3u8
@@ -0,0 +1,53 @@
+#EXTM3U
+#EXT-X-VERSION:3
+#EXT-X-TARGETDURATION:5
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:5,
+00.ts
+#EXTINF:5,
+01.ts
+#EXTINF:5,
+02.ts
+#EXTINF:5,
+03.ts
+#EXTINF:5,
+04.ts
+#EXTINF:5,
+05.ts
+#EXTINF:5,
+06.ts
+#EXTINF:5,
+07.ts
+#EXTINF:5,
+08.ts
+#EXTINF:5,
+09.ts
+#EXTINF:5,
+10.ts
+#EXTINF:5,
+11.ts
+#EXTINF:5,
+12.ts
+#EXTINF:5,
+13.ts
+#EXTINF:5,
+14.ts
+#EXTINF:5,
+15.ts
+#EXTINF:5,
+16.ts
+#EXTINF:5,
+17.ts
+#EXTINF:5,
+18.ts
+#EXTINF:5,
+19.ts
+#EXTINF:5,
+20.ts
+#EXTINF:5,
+21.ts
+#EXTINF:5,
+22.ts
+#EXTINF:5,
+23.ts
+#EXT-X-ENDLIST
\ No newline at end of file
diff --git a/tests/tests/media/assets/hls_variant/index.m3u8 b/tests/tests/media/assets/hls_variant/index.m3u8
new file mode 100644
index 0000000..2e94f5d
--- /dev/null
+++ b/tests/tests/media/assets/hls_variant/index.m3u8
@@ -0,0 +1,12 @@
+#EXTM3U
+#EXT-X-INDEPENDENT-SEGMENTS
+#EXT-X-STREAM-INF:CLOSED-CAPTIONS=NONE,BANDWIDTH=165340,RESOLUTION=256x144,CODECS="mp4a.40.5,avc1.42c00b"
+165340/index.m3u8
+#EXT-X-STREAM-INF:CLOSED-CAPTIONS=NONE,BANDWIDTH=344388,RESOLUTION=426x240,CODECS="mp4a.40.5,avc1.4d4015"
+344388/index.m3u8
+#EXT-X-STREAM-INF:CLOSED-CAPTIONS=NONE,BANDWIDTH=387360,RESOLUTION=640x360,CODECS="mp4a.40.2,avc1.4d401e"
+387360/index.m3u8
+#EXT-X-STREAM-INF:CLOSED-CAPTIONS=NONE,BANDWIDTH=765178,RESOLUTION=854x480,CODECS="mp4a.40.2,avc1.4d401f"
+765178/index.m3u8
+#EXT-X-STREAM-INF:CLOSED-CAPTIONS=NONE,BANDWIDTH=1676816,RESOLUTION=1280x720,CODECS="mp4a.40.2,avc1.4d401f"
+1676816/index.m3u8
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 3f0cc39..5479ba4 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -24,6 +24,7 @@
 import android.graphics.Rect;
 import android.hardware.Camera;
 import android.media.AudioManager;
+import android.media.CamcorderProfile;
 import android.media.MediaCodec;
 import android.media.MediaDataSource;
 import android.media.MediaExtractor;
@@ -51,6 +52,7 @@
 import java.io.File;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.StringTokenizer;
 import java.util.UUID;
@@ -903,7 +905,14 @@
         // getSupportedVideoSizes returns null when separate video/preview size
         // is not supported.
         if (videoSizes == null) {
-            videoSizes = parameters.getSupportedPreviewSizes();
+            // If we have CamcorderProfile use it instead of Preview size.
+            if (CamcorderProfile.hasProfile(0, CamcorderProfile.QUALITY_LOW)) {
+                CamcorderProfile profile = CamcorderProfile.get(0, CamcorderProfile.QUALITY_LOW);
+                videoSizes = new ArrayList();
+                videoSizes.add(mCamera.new Size(profile.videoFrameWidth, profile.videoFrameHeight));
+            } else {
+                videoSizes = parameters.getSupportedPreviewSizes();
+            }
         }
         for (Camera.Size size : videoSizes)
         {
diff --git a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
index 0db2e05..f8fcbcd 100644
--- a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
@@ -29,14 +29,24 @@
 import com.android.compatibility.common.util.DynamicConfigDeviceSide;
 
 import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.Socket;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.http.impl.DefaultHttpServerConnection;
+import org.apache.http.impl.io.SocketOutputBuffer;
+import org.apache.http.io.SessionOutputBuffer;
+import org.apache.http.params.HttpParams;
+
 /**
  * Tests of MediaPlayer streaming capabilities.
  */
 public class StreamingMediaPlayerTest extends MediaPlayerTestBase {
+
     private static final String TAG = "StreamingMediaPlayerTest";
 
+    private static final int LOCAL_HLS_BITS_PER_MS = 100 * 1000;
+
     private static final String HTTP_H263_AMR_VIDEO_1_KEY =
             "streaming_media_player_test_http_h263_amr_video1";
     private static final String HTTP_H263_AMR_VIDEO_2_KEY =
@@ -145,19 +155,15 @@
         playVideoTest(urlString, 640, 360);
     }
 
-    // Streaming HLS video from YouTube
+    // Streaming HLS video downloaded from YouTube
     public void testHLS() throws Exception {
         if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
             return; // skip
         }
 
         // Play stream for 60 seconds
-        playLiveVideoTest("http://www.youtube.com/api/manifest/hls_variant/id/"
-                + "0168724d02bd9945/itag/5/source/youtube/playlist_type/DVR/ip/"
-                + "0.0.0.0/ipbits/0/expire/19000000000/sparams/ip,ipbits,expire"
-                + ",id,itag,source,playlist_type/signature/773AB8ACC68A96E5AA48"
-                + "1996AD6A1BBCB70DCB87.95733B544ACC5F01A1223A837D2CF04DF85A336"
-                + "0/key/ik0/file/m3u8", 60 * 1000);
+        // limit rate to workaround multiplication overflow in framework
+        localHlsTest("hls_variant/index.m3u8", 60 * 1000, LOCAL_HLS_BITS_PER_MS);
     }
 
     // Streaming audio from local HTTP server
@@ -494,8 +500,27 @@
     }
 
     private void localHlsTest(final String name, boolean appendQueryString, boolean redirect)
-            throws Throwable {
-        mServer = new CtsTestServer(mContext);
+            throws Exception {
+        localHlsTest(name, appendQueryString, redirect, 10, -1);
+    }
+
+    private void localHlsTest(final String name, int playTime, int bitsPerMs)
+            throws Exception {
+        localHlsTest(name, false, false, playTime, bitsPerMs);
+    }
+
+    private void localHlsTest(String name, boolean appendQueryString, boolean redirect,
+            int playTime, int bitsPerMs) throws Exception {
+        if (bitsPerMs >= 0) {
+            mServer = new CtsTestServer(mContext) {
+                @Override
+                protected DefaultHttpServerConnection createHttpServerConnection() {
+                    return new RateLimitHttpServerConnection(bitsPerMs);
+                }
+            };
+        } else {
+            mServer = new CtsTestServer(mContext);
+        }
         try {
             String stream_url = null;
             if (redirect) {
@@ -507,9 +532,63 @@
                 stream_url += "?foo=bar/baz";
             }
 
-            playLiveVideoTest(stream_url, 10);
+            playLiveVideoTest(stream_url, playTime);
         } finally {
             mServer.shutdown();
         }
     }
+
+    private static final class RateLimitHttpServerConnection extends DefaultHttpServerConnection {
+
+        private final int mBytesPerMs;
+        private int mBytesWritten;
+
+        public RateLimitHttpServerConnection(int bitsPerMs) {
+            mBytesPerMs = bitsPerMs / 8;
+        }
+
+        @Override
+        protected SessionOutputBuffer createHttpDataTransmitter(
+                Socket socket, int buffersize, HttpParams params) throws IOException {
+            return createSessionOutputBuffer(socket, buffersize, params);
+        }
+
+        SessionOutputBuffer createSessionOutputBuffer(
+                Socket socket, int buffersize, HttpParams params) throws IOException {
+            return new SocketOutputBuffer(socket, buffersize, params) {
+                @Override
+                public void write(int b) throws IOException {
+                    write(new byte[] {(byte)b});
+                }
+
+                @Override
+                public void write(byte[] b) throws IOException {
+                    write(b, 0, b.length);
+                }
+
+                @Override
+                public synchronized void write(byte[] b, int off, int len) throws IOException {
+                    mBytesWritten += len;
+                    if (mBytesWritten >= mBytesPerMs * 10) {
+                        int r = mBytesWritten % mBytesPerMs;
+                        int nano = 999999 * r / mBytesPerMs;
+                        delay(mBytesWritten / mBytesPerMs, nano);
+                        mBytesWritten = 0;
+                    }
+                    super.write(b, off, len);
+                }
+
+                private void delay(long millis, int nanos) throws IOException {
+                    try {
+                        Thread.sleep(millis, nanos);
+                        flush();
+                    } catch (InterruptedException e) {
+                        throw new InterruptedIOException();
+                    }
+                }
+
+            };
+        }
+    }
+
 }
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 7b87851..2e936c6 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -49,6 +49,8 @@
                      android:label="CTS tests of android.security.cts">
         <meta-data android:name="listener"
             android:value="com.android.cts.runner.CtsTestRunListener" />
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CrashParserRunListener" />
     </instrumentation>
 
 </manifest>
diff --git a/tests/tests/security/AndroidTest.xml b/tests/tests/security/AndroidTest.xml
index ab2e57a..1a67e87 100644
--- a/tests/tests/security/AndroidTest.xml
+++ b/tests/tests/security/AndroidTest.xml
@@ -18,6 +18,7 @@
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsSecurityTestCases.apk" />
     </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.CrashReporter" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.security.cts" />
         <option name="runtime-hint" value="3m15s" />
diff --git a/tests/tests/security/src/android/security/cts/EncryptionTest.java b/tests/tests/security/src/android/security/cts/EncryptionTest.java
index 751afd0..ecce366 100644
--- a/tests/tests/security/src/android/security/cts/EncryptionTest.java
+++ b/tests/tests/security/src/android/security/cts/EncryptionTest.java
@@ -71,6 +71,11 @@
     }
 
     private boolean isRequired() {
+        // Optional for device without secure lock screen
+        if (!hasSecureLockScreen()) {
+            return false;
+        }
+
         // Optional before MIN_API_LEVEL
         return PropertyUtil.getFirstApiLevel() >= MIN_API_LEVEL && !isTelevision();
     }
@@ -104,6 +109,18 @@
                 || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
     }
 
+    /*
+     * Device that don't report android.software.device_admin doesn't have secure lock screen
+     * because device with secure lock screen MUST report android.software.device_admin .
+     *
+     * https://source.android.com/compatibility/7.0/android-7.0-cdd.html#3_9_device_administration
+     *
+     */
+    private boolean hasSecureLockScreen() {
+        PackageManager pm = getContext().getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
+    }
+
     public void testEncryption() throws Exception {
         if (!isRequired() || deviceIsEncrypted()) {
             return;
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index b08ac44..394ae14 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -46,7 +46,13 @@
 
 import com.android.cts.util.SecurityTest;
 
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.Crash;
+
+import java.io.ObjectInputStream;
+import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
@@ -65,6 +71,7 @@
     static final String TAG = "StagefrightTest";
 
     private final long TIMEOUT_NS = 10000000000L;  // 10 seconds.
+    private final static long CHECK_INTERVAL = 50;
 
     public StagefrightTest() {
     }
@@ -415,10 +422,35 @@
         return new Surface(surfaceTex);
     }
 
+    public ArrayList<Crash> getCrashReport(String testname, long timeout)
+        throws InterruptedException {
+        Log.i(TAG, CrashUtils.UPLOAD_REQUEST);
+        File reportFile = new File(CrashUtils.DEVICE_PATH, testname);
+        File lockFile = new File(CrashUtils.DEVICE_PATH, CrashUtils.LOCK_FILENAME);
+        while ((!reportFile.exists() || !lockFile.exists()) && timeout > 0) {
+            Thread.sleep(CHECK_INTERVAL);
+            timeout -= CHECK_INTERVAL;
+        }
+        if (!reportFile.exists() || !reportFile.isFile() || !lockFile.exists()) {
+            return null;
+        }
+        try (ObjectInputStream reader = new ObjectInputStream(new FileInputStream(reportFile))) {
+            return (ArrayList<Crash>) reader.readObject();
+        } catch (IOException | ClassNotFoundException e) {
+            Log.e(TAG, "Failed to deserialize crash list with error " + e.getMessage());
+            return null;
+        }
+    }
+
     class MediaPlayerCrashListener
-    implements MediaPlayer.OnErrorListener,
+        implements MediaPlayer.OnErrorListener,
         MediaPlayer.OnPreparedListener,
         MediaPlayer.OnCompletionListener {
+
+        private final String[] validProcessNames = {
+            "mediaserver", "mediadrmserver", "media.extractor", "media.codec", "media.metrics"
+        };
+
         @Override
         public boolean onError(MediaPlayer mp, int newWhat, int extra) {
             Log.i(TAG, "error: " + newWhat + "/" + extra);
@@ -459,6 +491,21 @@
                 // and see if more errors show up.
                 SystemClock.sleep(1000);
             }
+            if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
+                ArrayList<Crash> crashes = getCrashReport(getName(), 5000);
+                if (crashes == null) {
+                    Log.e(TAG, "Crash results not found for test " + getName());
+                    return what;
+                } else if (CrashUtils.detectCrash(validProcessNames, true, crashes)) {
+                    return what;
+                } else {
+                    Log.i(TAG, "Crash ignored due to no security crash found for test " +
+                        getName());
+                    // 0 is the code for no error.
+                    return 0;
+                }
+
+            }
             return what;
         }
 
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index ef4ed3a..1ff307b 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -1731,17 +1731,34 @@
                     && mOnUiThread.getHeight() != 0;
             }
         }.run();
-        assertEquals(mOnUiThread.getHeight(),
-                mOnUiThread.getContentHeight() * mOnUiThread.getScale(), 2f);
+
+        final int tolerance = 2;
+        // getHeight() returns physical pixels and it is from web contents' size, getContentHeight()
+        // returns CSS pixels and it is from compositor. In order to compare these two values, we
+        // need to scale getContentHeight() by the device scale factor. This also amplifies any
+        // rounding errors. Internally, getHeight() could also have rounding error first and then
+        // times device scale factor, so we are comparing two rounded numbers below.
+        // We allow 2 * getScale() as the delta, because getHeight() and getContentHeight() may
+        // use different rounding algorithms and the results are from different computation
+        // sequences. The extreme case is that in CSS pixel we have 2 as differences (0.9999 rounded
+        // down and 1.0001 rounded up), therefore we ended with 2 * getScale().
+        assertEquals(
+                mOnUiThread.getHeight(),
+                mOnUiThread.getContentHeight() * mOnUiThread.getScale(),
+                tolerance * Math.max(mOnUiThread.getScale(), 1.0f));
 
         // Make pageHeight bigger than the larger dimension of the device, so the page is taller
         // than viewport. Because when layout_height set to match_parent, getContentHeight() will
         // give maximum value between the actual web content height and the viewport height. When
         // viewport height is bigger, |extraSpace| below is not the extra space on the web page.
-        // Note that we are passing physical pixels rather than CSS pixels here, since screen
-        // density scale is generally greater than 1, it only makes the page content taller.
+        // Note that we are passing physical pixels rather than CSS pixels here, when screen density
+        // scale is lower than 1.0f, we need to scale it up.
         DisplayMetrics metrics = mOnUiThread.getDisplayMetrics();
-        final int pageHeight = Math.max(metrics.widthPixels, metrics.heightPixels);
+        final float scaleFactor = Math.max(1.0f, 1.0f / mOnUiThread.getScale());
+        final int pageHeight =
+                (int)(Math.ceil(Math.max(metrics.widthPixels, metrics.heightPixels)
+                * scaleFactor));
+
         // set the margin to 0
         final String p = "<p style=\"height:" + pageHeight
                 + "px;margin:0px auto;\">Get the height of HTML content.</p>";
@@ -1760,7 +1777,13 @@
         new PollingCheck() {
             @Override
             protected boolean check() {
-                return pageHeight + pageHeight + extraSpace == mOnUiThread.getContentHeight();
+                // |pageHeight| is accurate, |extraSpace| = getContentheight() - |pageHeight|, so it
+                // might have rounding error +-1, also getContentHeight() might have rounding error
+                // +-1, so we allow error 2. Note that |pageHeight|, |extraSpace| and
+                // getContentHeight() are all CSS pixels.
+                final int expectedContentHeight = pageHeight + pageHeight + extraSpace;
+                return Math.abs(expectedContentHeight - mOnUiThread.getContentHeight())
+                        <= tolerance;
             }
         }.run();
     }
diff --git a/tools/cts-tradefed/Android.mk b/tools/cts-tradefed/Android.mk
index 32fd5bc..540d0a4 100644
--- a/tools/cts-tradefed/Android.mk
+++ b/tools/cts-tradefed/Android.mk
@@ -25,7 +25,7 @@
 LOCAL_SUITE_TARGET_ARCH := $(TARGET_ARCH)
 LOCAL_SUITE_NAME := CTS
 LOCAL_SUITE_FULLNAME := "Compatibility Test Suite"
-LOCAL_SUITE_VERSION := 7.1_r27
+LOCAL_SUITE_VERSION := 7.1_r28
 
 LOCAL_MODULE := cts-tradefed