Merge "Disable transcoding by default if no HEVC support"
diff --git a/core/java/android/hardware/soundtrigger/OWNERS b/core/java/android/hardware/soundtrigger/OWNERS
index 01b2cb9..1e41886 100644
--- a/core/java/android/hardware/soundtrigger/OWNERS
+++ b/core/java/android/hardware/soundtrigger/OWNERS
@@ -1,2 +1 @@
-atneya@google.com
-elaurent@google.com
+include /media/java/android/media/soundtrigger/OWNERS
diff --git a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
index 38b3174..46cf016 100644
--- a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
@@ -354,6 +354,7 @@
     }
 
     /** @hide */
+    @Override
     public Map<Integer, Integer> getCapabilitiesMatchCriteria() {
         return Collections.unmodifiableMap(new HashMap<>(mCapabilitiesMatchCriteria));
     }
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
index 9235d09..edf2c09 100644
--- a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
@@ -29,6 +29,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -307,4 +308,7 @@
     public int getMinExitDownstreamBandwidthKbps() {
         return mMinExitDownstreamBandwidthKbps;
     }
+
+    /** @hide */
+    public abstract Map<Integer, Integer> getCapabilitiesMatchCriteria();
 }
diff --git a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
index 2544a6d..2e6b09f 100644
--- a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
+++ b/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
@@ -15,6 +15,9 @@
  */
 package android.net.vcn;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_ANY;
+
 import static com.android.internal.annotations.VisibleForTesting.Visibility;
 import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER;
 import static com.android.server.vcn.util.PersistableBundleUtils.STRING_SERIALIZER;
@@ -23,6 +26,7 @@
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.net.NetworkCapabilities;
+import android.net.vcn.VcnUnderlyingNetworkTemplate.MatchCriteria;
 import android.os.PersistableBundle;
 import android.util.ArraySet;
 
@@ -32,6 +36,7 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
@@ -162,6 +167,12 @@
         return Collections.unmodifiableSet(mSsids);
     }
 
+    /** @hide */
+    @Override
+    public Map<Integer, Integer> getCapabilitiesMatchCriteria() {
+        return Collections.singletonMap(NET_CAPABILITY_INTERNET, MATCH_REQUIRED);
+    }
+
     /** This class is used to incrementally build VcnWifiUnderlyingNetworkTemplate objects. */
     public static final class Builder {
         private int mMeteredMatchCriteria = MATCH_ANY;
diff --git a/media/OWNERS b/media/OWNERS
index 5f50137..4a6648e 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -1,4 +1,5 @@
 # Bug component: 1344
+atneya@google.com
 elaurent@google.com
 essick@google.com
 etalvala@google.com
diff --git a/media/aidl/android/media/soundtrigger_middleware/OWNERS b/media/aidl/android/media/soundtrigger_middleware/OWNERS
index 01b2cb9..1e41886 100644
--- a/media/aidl/android/media/soundtrigger_middleware/OWNERS
+++ b/media/aidl/android/media/soundtrigger_middleware/OWNERS
@@ -1,2 +1 @@
-atneya@google.com
-elaurent@google.com
+include /media/java/android/media/soundtrigger/OWNERS
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 22033c6d..6b29fc3 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -72,7 +72,7 @@
         throw new UnsupportedOperationException("Trying to instantiate AudioSystem");
     }
 
-    /* These values must be kept in sync with system/audio.h */
+    /* These values must be kept in sync with system/media/audio/include/system/audio-hal-enums.h */
     /*
      * If these are modified, please also update Settings.System.VOLUME_SETTINGS
      * and attrs.xml and AudioManager.java.
@@ -963,7 +963,8 @@
      */
 
     //
-    // audio device definitions: must be kept in sync with values in system/core/audio.h
+    // audio device definitions: must be kept in sync with values
+    // in system/media/audio/include/system/audio-hal-enums.h
     //
     /** @hide */
     public static final int DEVICE_NONE = 0x0;
diff --git a/media/java/android/media/soundtrigger/OWNERS b/media/java/android/media/soundtrigger/OWNERS
index 01b2cb9..85f7a4d 100644
--- a/media/java/android/media/soundtrigger/OWNERS
+++ b/media/java/android/media/soundtrigger/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 48436
 atneya@google.com
 elaurent@google.com
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d48723a..99f1863 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8415,13 +8415,16 @@
             }
         }
 
+        boolean recoverable = eventType.equals("native_recoverable_crash");
+
         EventLogTags.writeAmCrash(Binder.getCallingPid(),
                 UserHandle.getUserId(Binder.getCallingUid()), processName,
                 r == null ? -1 : r.info.flags,
                 crashInfo.exceptionClassName,
                 crashInfo.exceptionMessage,
                 crashInfo.throwFileName,
-                crashInfo.throwLineNumber);
+                crashInfo.throwLineNumber,
+                recoverable ? 1 : 0);
 
         int processClassEnum = processName.equals("system_server") ? ServerProtoEnums.SYSTEM_SERVER
                 : (r != null) ? r.getProcessClassEnum()
@@ -8489,7 +8492,13 @@
                 eventType, r, processName, null, null, null, null, null, null, crashInfo,
                 new Float(loadingProgress), incrementalMetrics, null);
 
-        mAppErrors.crashApplication(r, crashInfo);
+        // For GWP-ASan recoverable crashes, don't make the app crash (the whole point of
+        // 'recoverable' is that the app doesn't crash). Normally, for nonrecoreable native crashes,
+        // debuggerd will terminate the process, but there's a backup where ActivityManager will
+        // also kill it. Avoid that.
+        if (!recoverable) {
+            mAppErrors.crashApplication(r, crashInfo);
+        }
     }
 
     public void handleApplicationStrictModeViolation(
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index d080036..6ce70a1 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -53,7 +53,7 @@
 30037 am_process_start_timeout (User|1|5),(PID|1|5),(UID|1|5),(Process Name|3)
 
 # Unhandled exception
-30039 am_crash (User|1|5),(PID|1|5),(Process Name|3),(Flags|1|5),(Exception|3),(Message|3),(File|3),(Line|1|5)
+30039 am_crash (User|1|5),(PID|1|5),(Process Name|3),(Flags|1|5),(Exception|3),(Message|3),(File|3),(Line|1|5),(Recoverable|1|5)
 # Log.wtf() called
 30040 am_wtf (User|1|5),(PID|1|5),(Process Name|3),(Flags|1|5),(Tag|3),(Message|3)
 
diff --git a/services/core/java/com/android/server/am/NativeCrashListener.java b/services/core/java/com/android/server/am/NativeCrashListener.java
index 94eb076..cd119e7 100644
--- a/services/core/java/com/android/server/am/NativeCrashListener.java
+++ b/services/core/java/com/android/server/am/NativeCrashListener.java
@@ -64,12 +64,15 @@
     class NativeCrashReporter extends Thread {
         ProcessRecord mApp;
         int mSignal;
+        boolean mGwpAsanRecoverableCrash;
         String mCrashReport;
 
-        NativeCrashReporter(ProcessRecord app, int signal, String report) {
+        NativeCrashReporter(ProcessRecord app, int signal, boolean gwpAsanRecoverableCrash,
+                            String report) {
             super("NativeCrashReport");
             mApp = app;
             mSignal = signal;
+            mGwpAsanRecoverableCrash = gwpAsanRecoverableCrash;
             mCrashReport = report;
         }
 
@@ -85,7 +88,9 @@
                 ci.stackTrace = mCrashReport;
 
                 if (DEBUG) Slog.v(TAG, "Calling handleApplicationCrash()");
-                mAm.handleApplicationCrashInner("native_crash", mApp, mApp.processName, ci);
+                mAm.handleApplicationCrashInner(
+                        mGwpAsanRecoverableCrash ? "native_recoverable_crash" : "native_crash",
+                        mApp, mApp.processName, ci);
                 if (DEBUG) Slog.v(TAG, "<-- handleApplicationCrash() returned");
             } catch (Exception e) {
                 Slog.e(TAG, "Unable to report native crash", e);
@@ -207,9 +212,14 @@
             // permits crash_dump to connect to it. This allows us to trust the
             // received values.
 
-            // first, the pid and signal number
-            int headerBytes = readExactly(fd, buf, 0, 8);
-            if (headerBytes != 8) {
+            // Activity Manager protocol:
+            //  - 32-bit network-byte-order: pid
+            //  - 32-bit network-byte-order: signal number
+            //  - byte: gwpAsanRecoverableCrash
+            //  - bytes: raw text of the dump
+            //  - null terminator
+            int headerBytes = readExactly(fd, buf, 0, 9);
+            if (headerBytes != 9) {
                 // protocol failure; give up
                 Slog.e(TAG, "Unable to read from debuggerd");
                 return;
@@ -217,69 +227,76 @@
 
             int pid = unpackInt(buf, 0);
             int signal = unpackInt(buf, 4);
+            boolean gwpAsanRecoverableCrash = buf[8] != 0;
             if (DEBUG) {
-                Slog.v(TAG, "Read pid=" + pid + " signal=" + signal);
+                Slog.v(TAG, "Read pid=" + pid + " signal=" + signal
+                        + " recoverable=" + gwpAsanRecoverableCrash);
+            }
+            if (pid < 0) {
+                Slog.e(TAG, "Bogus pid!");
+                return;
             }
 
             // now the text of the dump
-            if (pid > 0) {
-                final ProcessRecord pr;
-                synchronized (mAm.mPidsSelfLocked) {
-                    pr = mAm.mPidsSelfLocked.get(pid);
-                }
-                if (pr != null) {
-                    // Don't attempt crash reporting for persistent apps
-                    if (pr.isPersistent()) {
-                        if (DEBUG) {
-                            Slog.v(TAG, "Skipping report for persistent app " + pr);
-                        }
-                        return;
-                    }
-
-                    int bytes;
-                    do {
-                        // get some data
-                        bytes = Os.read(fd, buf, 0, buf.length);
-                        if (bytes > 0) {
-                            if (MORE_DEBUG) {
-                                String s = new String(buf, 0, bytes, "UTF-8");
-                                Slog.v(TAG, "READ=" + bytes + "> " + s);
-                            }
-                            // did we just get the EOD null byte?
-                            if (buf[bytes-1] == 0) {
-                                os.write(buf, 0, bytes-1);  // exclude the EOD token
-                                break;
-                            }
-                            // no EOD, so collect it and read more
-                            os.write(buf, 0, bytes);
-                        }
-                    } while (bytes > 0);
-
-                    // Okay, we've got the report.
-                    if (DEBUG) Slog.v(TAG, "processing");
-
-                    // Mark the process record as being a native crash so that the
-                    // cleanup mechanism knows we're still submitting the report
-                    // even though the process will vanish as soon as we let
-                    // debuggerd proceed.
-                    synchronized (mAm) {
-                        synchronized (mAm.mProcLock) {
-                            pr.mErrorState.setCrashing(true);
-                            pr.mErrorState.setForceCrashReport(true);
-                        }
-                    }
-
-                    // Crash reporting is synchronous but we want to let debuggerd
-                    // go about it business right away, so we spin off the actual
-                    // reporting logic on a thread and let it take it's time.
-                    final String reportString = new String(os.toByteArray(), "UTF-8");
-                    (new NativeCrashReporter(pr, signal, reportString)).start();
-                } else {
-                    Slog.w(TAG, "Couldn't find ProcessRecord for pid " + pid);
-                }
-            } else {
-                Slog.e(TAG, "Bogus pid!");
+            final ProcessRecord pr;
+            synchronized (mAm.mPidsSelfLocked) {
+                pr = mAm.mPidsSelfLocked.get(pid);
             }
+            if (pr == null) {
+                Slog.w(TAG, "Couldn't find ProcessRecord for pid " + pid);
+                return;
+            }
+
+            // Don't attempt crash reporting for persistent apps
+            if (pr.isPersistent()) {
+                if (DEBUG) {
+                    Slog.v(TAG, "Skipping report for persistent app " + pr);
+                }
+                return;
+            }
+
+            int bytes;
+            do {
+                // get some data
+                bytes = Os.read(fd, buf, 0, buf.length);
+                if (bytes > 0) {
+                    if (MORE_DEBUG) {
+                        String s = new String(buf, 0, bytes, "UTF-8");
+                        Slog.v(TAG, "READ=" + bytes + "> " + s);
+                    }
+                    // did we just get the EOD null byte?
+                    if (buf[bytes - 1] == 0) {
+                        os.write(buf, 0, bytes - 1); // exclude the EOD token
+                        break;
+                    }
+                    // no EOD, so collect it and read more
+                    os.write(buf, 0, bytes);
+                }
+            } while (bytes > 0);
+
+            // Okay, we've got the report.
+            if (DEBUG) Slog.v(TAG, "processing");
+
+            // Mark the process record as being a native crash so that the
+            // cleanup mechanism knows we're still submitting the report even
+            // though the process will vanish as soon as we let debuggerd
+            // proceed. This isn't relevant for recoverable crashes, as we don't
+            // show the user an "app crashed" dialogue because the app (by
+            // design) didn't crash.
+            if (!gwpAsanRecoverableCrash) {
+                synchronized (mAm) {
+                    synchronized (mAm.mProcLock) {
+                        pr.mErrorState.setCrashing(true);
+                        pr.mErrorState.setForceCrashReport(true);
+                    }
+                }
+            }
+
+            // Crash reporting is synchronous but we want to let debuggerd
+            // go about it business right away, so we spin off the actual
+            // reporting logic on a thread and let it take it's time.
+            final String reportString = new String(os.toByteArray(), "UTF-8");
+            (new NativeCrashReporter(pr, signal, gwpAsanRecoverableCrash, reportString)).start();
         } catch (Exception e) {
             Slog.e(TAG, "Exception dealing with report", e);
             // ugh, fail.
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/OWNERS b/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
index 01b2cb9..1e41886 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
+++ b/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
@@ -1,2 +1 @@
-atneya@google.com
-elaurent@google.com
+include /media/java/android/media/soundtrigger/OWNERS
diff --git a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java b/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
index 2141eba..7f129ea 100644
--- a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
+++ b/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
@@ -171,6 +171,18 @@
             return false;
         }
 
+        for (Map.Entry<Integer, Integer> entry :
+                networkPriority.getCapabilitiesMatchCriteria().entrySet()) {
+            final int cap = entry.getKey();
+            final int matchCriteria = entry.getValue();
+
+            if (matchCriteria == MATCH_REQUIRED && !caps.hasCapability(cap)) {
+                return false;
+            } else if (matchCriteria == MATCH_FORBIDDEN && caps.hasCapability(cap)) {
+                return false;
+            }
+        }
+
         if (vcnContext.isInTestMode() && caps.hasTransport(TRANSPORT_TEST)) {
             return true;
         }
@@ -319,18 +331,6 @@
             return false;
         }
 
-        for (Map.Entry<Integer, Integer> entry :
-                networkPriority.getCapabilitiesMatchCriteria().entrySet()) {
-            final int cap = entry.getKey();
-            final int matchCriteria = entry.getValue();
-
-            if (matchCriteria == MATCH_REQUIRED && !caps.hasCapability(cap)) {
-                return false;
-            } else if (matchCriteria == MATCH_FORBIDDEN && caps.hasCapability(cap)) {
-                return false;
-            }
-        }
-
         return true;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS
index 33385af..1e41886 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS
@@ -1 +1 @@
-include /media/aidl/android/media/soundtrigger_middleware/OWNERS
+include /media/java/android/media/soundtrigger/OWNERS
diff --git a/services/voiceinteraction/OWNERS b/services/voiceinteraction/OWNERS
index ef1061b..40e8d26 100644
--- a/services/voiceinteraction/OWNERS
+++ b/services/voiceinteraction/OWNERS
@@ -1 +1,2 @@
 include /core/java/android/service/voice/OWNERS
+include /media/java/android/media/soundtrigger/OWNERS
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS b/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS
index 01b2cb9..1e41886 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS
@@ -1,2 +1 @@
-atneya@google.com
-elaurent@google.com
+include /media/java/android/media/soundtrigger/OWNERS
diff --git a/tests/SoundTriggerTestApp/OWNERS b/tests/SoundTriggerTestApp/OWNERS
index 9db19a3..a0fcfc5 100644
--- a/tests/SoundTriggerTestApp/OWNERS
+++ b/tests/SoundTriggerTestApp/OWNERS
@@ -1,2 +1,2 @@
-include /core/java/android/media/soundtrigger/OWNERS
+include /media/java/android/media/soundtrigger/OWNERS
 mdooley@google.com
diff --git a/tests/SoundTriggerTests/OWNERS b/tests/SoundTriggerTests/OWNERS
index 816bc6b..1e41886 100644
--- a/tests/SoundTriggerTests/OWNERS
+++ b/tests/SoundTriggerTests/OWNERS
@@ -1 +1 @@
-include /core/java/android/media/soundtrigger/OWNERS
+include /media/java/android/media/soundtrigger/OWNERS
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
index 629e988..2266041 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
@@ -95,6 +95,7 @@
     private static final NetworkCapabilities WIFI_NETWORK_CAPABILITIES =
             new NetworkCapabilities.Builder()
                     .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                     .setSignalStrength(WIFI_RSSI)
                     .setSsid(SSID)
                     .setLinkUpstreamBandwidthKbps(LINK_UPSTREAM_BANDWIDTH_KBPS)
@@ -509,12 +510,14 @@
             VcnCellUnderlyingNetworkTemplate template, boolean expectMatch) {
         assertEquals(
                 expectMatch,
-                checkMatchesCellPriorityRule(
+                checkMatchesPriorityRule(
                         mVcnContext,
                         template,
                         mCellNetworkRecord,
                         SUB_GROUP,
-                        mSubscriptionSnapshot));
+                        mSubscriptionSnapshot,
+                        null /* currentlySelected */,
+                        null /* carrierConfig */));
     }
 
     @Test