Merge "[Thread] define Thread network flags for platform code" into main
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 9b77b79..bccea93 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -1471,7 +1471,15 @@
     @UnsupportedAppUsage
     public static final native long getPss(int pid);
 
-    /** @hide */
+    /**
+     * Gets the total Rss value for a given process, in bytes.
+     *
+     * @param pid the process to the Rss for
+     * @return an ordered array containing multiple values, they are:
+     *  [total_rss, file, anon, swap, shmem].
+     *  or NULL if the value cannot be determined
+     * @hide
+     */
     public static final native long[] getRss(int pid);
 
     /**
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 7af69f2..d2e58bb 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -28,6 +28,7 @@
 #include <meminfo/sysmeminfo.h>
 #include <processgroup/processgroup.h>
 #include <processgroup/sched_policy.h>
+#include <android-base/logging.h>
 #include <android-base/unique_fd.h>
 
 #include <algorithm>
@@ -232,6 +233,31 @@
     }
 }
 
+// Look up the user ID of a process in /proc/${pid}/status. The Uid: line is present in
+// /proc/${pid}/status since at least kernel v2.5.
+static int uid_from_pid(int pid)
+{
+    int uid = -1;
+    std::array<char, 64> path;
+    int res = snprintf(path.data(), path.size(), "/proc/%d/status", pid);
+    if (res < 0 || res >= static_cast<int>(path.size())) {
+        DCHECK(false);
+        return uid;
+    }
+    FILE* f = fopen(path.data(), "r");
+    if (!f) {
+        return uid;
+    }
+    char line[256];
+    while (fgets(line, sizeof(line), f)) {
+        if (sscanf(line, "Uid: %d", &uid) == 1) {
+            break;
+        }
+    }
+    fclose(f);
+    return uid;
+}
+
 void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
 {
     ALOGV("%s pid=%d grp=%" PRId32, __func__, pid, grp);
@@ -275,7 +301,12 @@
         }
     }
 
-    if (!SetProcessProfilesCached(0, pid, {get_cpuset_policy_profile_name((SchedPolicy)grp)}))
+    const int uid = uid_from_pid(pid);
+    if (uid < 0) {
+        signalExceptionForGroupError(env, ESRCH, pid);
+        return;
+    }
+    if (!SetProcessProfilesCached(uid, pid, {get_cpuset_policy_profile_name((SchedPolicy)grp)}))
         signalExceptionForGroupError(env, errno ? errno : EPERM, pid);
 }
 
@@ -1134,12 +1165,11 @@
 
 static jlongArray android_os_Process_getRss(JNIEnv* env, jobject clazz, jint pid)
 {
-    // total, file, anon, swap
-    jlong rss[4] = {0, 0, 0, 0};
+    // total, file, anon, swap, shmem
+    jlong rss[5] = {0, 0, 0, 0, 0};
     std::string status_path =
             android::base::StringPrintf("/proc/%d/status", pid);
     UniqueFile file = MakeUniqueFile(status_path.c_str(), "re");
-
     char line[256];
     while (file != nullptr && fgets(line, sizeof(line), file.get())) {
         jlong v;
@@ -1151,17 +1181,18 @@
             rss[2] = v;
         } else if ( sscanf(line, "VmSwap: %" SCNd64 " kB", &v) == 1) {
             rss[3] = v;
+        } else if ( sscanf(line, "RssShmem: %" SCNd64 " kB", &v) == 1) {
+            rss[4] = v;
         }
     }
 
-    jlongArray rssArray = env->NewLongArray(4);
+    jlongArray rssArray = env->NewLongArray(5);
     if (rssArray == NULL) {
         jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
         return NULL;
     }
 
-    env->SetLongArrayRegion(rssArray, 0, 4, rss);
-
+    env->SetLongArrayRegion(rssArray, 0, 5, rss);
     return rssArray;
 }
 
diff --git a/media/jni/soundpool/StreamManager.cpp b/media/jni/soundpool/StreamManager.cpp
index 52060f1..66fec1c 100644
--- a/media/jni/soundpool/StreamManager.cpp
+++ b/media/jni/soundpool/StreamManager.cpp
@@ -35,10 +35,9 @@
 // In R, we change this to true, as it is the correct way per SoundPool documentation.
 static constexpr bool kStealActiveStream_OldestFirst = true;
 
-// kPlayOnCallingThread = true prior to R.
 // Changing to false means calls to play() are almost instantaneous instead of taking around
 // ~10ms to launch the AudioTrack. It is perhaps 100x faster.
-static constexpr bool kPlayOnCallingThread = true;
+static constexpr bool kPlayOnCallingThread = false;
 
 // Amount of time for a StreamManager thread to wait before closing.
 static constexpr int64_t kWaitTimeBeforeCloseNs = 9 * NANOS_PER_SECOND;
diff --git a/media/jni/soundpool/StreamManager.h b/media/jni/soundpool/StreamManager.h
index adbab4b..340b49b 100644
--- a/media/jni/soundpool/StreamManager.h
+++ b/media/jni/soundpool/StreamManager.h
@@ -48,7 +48,7 @@
 public:
     JavaThread(std::function<void()> f, const char *name)
         : mF{std::move(f)} {
-        createThreadEtc(staticFunction, this, name);
+        createThreadEtc(staticFunction, this, name, ANDROID_PRIORITY_AUDIO);
     }
 
     JavaThread(JavaThread &&) = delete; // uses "this" ptr, not moveable.
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index 10c570b..8ea4632 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -72,6 +72,9 @@
             ],
         },
     },
+    stubs: {
+        symbol_file: "libjnigraphics.map.txt",
+    },
 }
 
 // The headers module is in frameworks/native/Android.bp.
@@ -93,15 +96,18 @@
     ],
     static_libs: ["libarect"],
     fuzz_config: {
-        cc: ["dichenzhang@google.com","scroggo@google.com"],
+        cc: [
+            "dichenzhang@google.com",
+            "scroggo@google.com",
+        ],
         asan_options: [
             "detect_odr_violation=1",
         ],
         hwasan_options: [
-             // Image decoders may attempt to allocate a large amount of memory
-             // (especially if the encoded image is large). This doesn't
-             // necessarily mean there is a bug. Set allocator_may_return_null=1
-             // for hwasan so the fuzzer can continue running.
+            // Image decoders may attempt to allocate a large amount of memory
+            // (especially if the encoded image is large). This doesn't
+            // necessarily mean there is a bug. Set allocator_may_return_null=1
+            // for hwasan so the fuzzer can continue running.
             "allocator_may_return_null = 1",
         ],
     },
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index b9535d6..43ecec4 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1024,11 +1024,9 @@
     private void initAudioHalBluetoothState() {
         synchronized (mBluetoothAudioStateLock) {
             mBluetoothScoOnApplied = false;
-            AudioSystem.setParameters("BT_SCO=off");
             mBluetoothA2dpSuspendedApplied = false;
-            AudioSystem.setParameters("A2dpSuspended=false");
             mBluetoothLeSuspendedApplied = false;
-            AudioSystem.setParameters("LeAudioSuspended=false");
+            reapplyAudioHalBluetoothState();
         }
     }
 
@@ -1091,6 +1089,34 @@
         }
     }
 
+    @GuardedBy("mBluetoothAudioStateLock")
+    private void reapplyAudioHalBluetoothState() {
+        if (AudioService.DEBUG_COMM_RTE) {
+            Log.v(TAG, "reapplyAudioHalBluetoothState() mBluetoothScoOnApplied: "
+                    + mBluetoothScoOnApplied + ", mBluetoothA2dpSuspendedApplied: "
+                    + mBluetoothA2dpSuspendedApplied + ", mBluetoothLeSuspendedApplied: "
+                    + mBluetoothLeSuspendedApplied);
+        }
+        // Note: the order of parameters is important.
+        if (mBluetoothScoOnApplied) {
+            AudioSystem.setParameters("A2dpSuspended=true");
+            AudioSystem.setParameters("LeAudioSuspended=true");
+            AudioSystem.setParameters("BT_SCO=on");
+        } else {
+            AudioSystem.setParameters("BT_SCO=off");
+            if (mBluetoothA2dpSuspendedApplied) {
+                AudioSystem.setParameters("A2dpSuspended=true");
+            } else {
+                AudioSystem.setParameters("A2dpSuspended=false");
+            }
+            if (mBluetoothLeSuspendedApplied) {
+                AudioSystem.setParameters("LeAudioSuspended=true");
+            } else {
+                AudioSystem.setParameters("LeAudioSuspended=false");
+            }
+        }
+    }
+
     /*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
         if (AudioService.DEBUG_COMM_RTE) {
             Log.v(TAG, "setBluetoothScoOn: " + on + " " + eventSource);
@@ -1727,6 +1753,9 @@
                             initRoutingStrategyIds();
                             updateActiveCommunicationDevice();
                             mDeviceInventory.onRestoreDevices();
+                            synchronized (mBluetoothAudioStateLock) {
+                                reapplyAudioHalBluetoothState();
+                            }
                             mBtHelper.onAudioServerDiedRestoreA2dp();
                             updateCommunicationRoute("MSG_RESTORE_DEVICES");
                         }