Merge "Add explicit handling for an unspecified gwpAsanMode manifest flag."
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index deafd19..05cad77 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -178,7 +178,14 @@
      * GWP-ASan is activated unconditionally (but still, only a small subset of
      * allocations is protected).
      */
-    public static final int GWP_ASAN_LEVEL_ALWAYS = 1 << 22;
+    public static final int GWP_ASAN_LEVEL_ALWAYS = 2 << 21;
+
+    /**
+     * GWP-ASan's `gwpAsanMode` manifest flag was unspecified. Currently, this
+     * means GWP_ASAN_LEVEL_LOTTERY for system apps, and GWP_ASAN_LEVEL_NONE for
+     * non-system apps.
+     */
+    public static final int GWP_ASAN_LEVEL_DEFAULT = 3 << 21;
 
     /** Enable automatic zero-initialization of native heap memory allocations. */
     public static final int NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23;
@@ -1347,15 +1354,13 @@
                     ? GWP_ASAN_LEVEL_ALWAYS
                     : GWP_ASAN_LEVEL_NEVER;
         }
-        // If the app does not specify gwpAsanMode, the default behavior is lottery among the
-        // system apps, and disabled for user apps, unless overwritten by the compat feature.
         if (isCompatChangeEnabled(GWP_ASAN, info, platformCompat, 0)) {
             return GWP_ASAN_LEVEL_ALWAYS;
         }
         if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
             return GWP_ASAN_LEVEL_LOTTERY;
         }
-        return GWP_ASAN_LEVEL_NEVER;
+        return GWP_ASAN_LEVEL_DEFAULT;
     }
 
     private static boolean enableNativeHeapZeroInit(
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index d3a3492..19bcd7f 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -353,6 +353,7 @@
     GWP_ASAN_LEVEL_NEVER = 0 << 21,
     GWP_ASAN_LEVEL_LOTTERY = 1 << 21,
     GWP_ASAN_LEVEL_ALWAYS = 2 << 21,
+    GWP_ASAN_LEVEL_DEFAULT = 3 << 21,
     NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23,
     PROFILEABLE = 1 << 24,
 };
@@ -1926,6 +1927,13 @@
     gwp_asan_options.program_name = nice_name_ptr ?: process_name;
     switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {
         default:
+        case RuntimeFlags::GWP_ASAN_LEVEL_DEFAULT:
+            // TODO(b/247012630): Switch this to Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING once
+            // performance and syshealth testing is completed, making the default for non-system
+            // apps that don't specify a `gwpAsanMode` in their manifest to be sampled-recoverable.
+            gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN;
+            android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));
+            break;
         case RuntimeFlags::GWP_ASAN_LEVEL_NEVER:
             gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN;
             android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options));