summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author jiabin <jiabin@google.com> 2024-12-11 20:43:07 +0000
committer jiabin <jiabin@google.com> 2024-12-12 17:49:34 +0000
commitaef77326754762d6390242f4a332651352ff7ac5 (patch)
tree1fa963c9f1381db8fad50f5805ca3d1f3e31468a
parentd1d03a20c92a21219456bf763333f2435fda0621 (diff)
Maximize USB audio volume when connecting.
Some of the USB audio devices have low hardware volume by default. If the audio system doesn't set the hardware volume, the user will not be able to get the full range of volume that is supported by the device. Bug: 245041322 Test: connect USB device with default low hw volume Flag: com.android.server.usb.flags.maximize_usb_audio_volume_when_connecting Change-Id: I86874254c31bfb009ad7c36add11f8ab6496fe96
-rw-r--r--services/core/jni/Android.bp1
-rw-r--r--services/core/jni/com_android_server_UsbAlsaDevice.cpp70
-rw-r--r--services/core/jni/onload.cpp2
-rw-r--r--services/usb/java/com/android/server/usb/UsbAlsaDevice.java6
4 files changed, 79 insertions, 0 deletions
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 82699ea3badb..01639cc3b516 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -61,6 +61,7 @@ cc_library_static {
"com_android_server_SystemServer.cpp",
"com_android_server_tv_TvUinputBridge.cpp",
"com_android_server_tv_TvInputHal.cpp",
+ "com_android_server_UsbAlsaDevice.cpp",
"com_android_server_UsbAlsaJackDetector.cpp",
"com_android_server_UsbAlsaMidiDevice.cpp",
"com_android_server_UsbDeviceManager.cpp",
diff --git a/services/core/jni/com_android_server_UsbAlsaDevice.cpp b/services/core/jni/com_android_server_UsbAlsaDevice.cpp
new file mode 100644
index 000000000000..166932f167ed
--- /dev/null
+++ b/services/core/jni/com_android_server_UsbAlsaDevice.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+#define LOG_TAG "UsbAlsaDeviceJNI"
+
+#include <nativehelper/JNIPlatformHelp.h>
+#include <tinyalsa/asoundlib.h>
+
+#include <string>
+#include <vector>
+
+#include "jni.h"
+#include "utils/Log.h"
+
+static const std::vector<std::string> POSSIBLE_HARDWARE_VOLUME_MIXER_NAMES =
+ {"Headphone Playback Volume", "Headset Playback Volume", "PCM Playback Volume"};
+
+namespace android {
+
+static void android_server_UsbAlsaDevice_setVolume(JNIEnv* /*env*/, jobject /*thiz*/, jint card,
+ float volume) {
+ ALOGD("%s(%d, %f)", __func__, card, volume);
+ struct mixer* alsaMixer = mixer_open(card);
+ if (alsaMixer == nullptr) {
+ ALOGW("%s(%d, %f) returned as no mixer is opened", __func__, card, volume);
+ return;
+ }
+ struct mixer_ctl* ctl = nullptr;
+ for (const auto& mixerName : POSSIBLE_HARDWARE_VOLUME_MIXER_NAMES) {
+ ctl = mixer_get_ctl_by_name(alsaMixer, mixerName.c_str());
+ if (ctl != nullptr) {
+ break;
+ }
+ }
+ if (ctl == nullptr) {
+ ALOGW("%s(%d, %f) returned as no volume mixer is found", __func__, card, volume);
+ return;
+ }
+ const unsigned int n = mixer_ctl_get_num_values(ctl);
+ for (unsigned int id = 0; id < n; id++) {
+ if (int error = mixer_ctl_set_percent(ctl, id, 100 * volume); error != 0) {
+ ALOGE("%s(%d, %f) failed, error=%d", __func__, card, volume, error);
+ return;
+ }
+ }
+ ALOGD("%s(%d, %f) succeed", __func__, card, volume);
+}
+
+static JNINativeMethod method_table[] = {
+ {"nativeSetVolume", "(IF)V", (void*)android_server_UsbAlsaDevice_setVolume},
+};
+
+int register_android_server_UsbAlsaDevice(JNIEnv* env) {
+ return jniRegisterNativeMethods(env, "com/android/server/usb/UsbAlsaDevice", method_table,
+ NELEM(method_table));
+}
+} // namespace android
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 09fd8d4ac02e..e3bd69c30de7 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -33,6 +33,7 @@ int register_android_server_power_stats_CpuPowerStatsCollector(JNIEnv* env);
int register_android_server_HintManagerService(JNIEnv* env);
int register_android_server_storage_AppFuse(JNIEnv* env);
int register_android_server_SystemServer(JNIEnv* env);
+int register_android_server_UsbAlsaDevice(JNIEnv* env);
int register_android_server_UsbAlsaJackDetector(JNIEnv* env);
int register_android_server_UsbAlsaMidiDevice(JNIEnv* env);
int register_android_server_UsbDeviceManager(JavaVM* vm, JNIEnv* env);
@@ -98,6 +99,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_InputManager(env);
register_android_server_LightsService(env);
register_android_server_UsbDeviceManager(vm, env);
+ register_android_server_UsbAlsaDevice(env);
register_android_server_UsbAlsaJackDetector(env);
register_android_server_UsbAlsaMidiDevice(env);
register_android_server_UsbHostManager(env);
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaDevice.java b/services/usb/java/com/android/server/usb/UsbAlsaDevice.java
index c508fa968b14..ce3cd29a3ce2 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaDevice.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaDevice.java
@@ -26,6 +26,7 @@ import android.util.Slog;
import com.android.internal.util.dump.DualDumpOutputStream;
import com.android.server.audio.AudioService;
+import com.android.server.usb.flags.Flags;
import java.util.Arrays;
@@ -211,6 +212,9 @@ public final class UsbAlsaDevice {
mIsSelected[direction] = true;
mState[direction] = 0;
startJackDetect();
+ if (direction == OUTPUT && Flags.maximizeUsbAudioVolumeWhenConnecting()) {
+ nativeSetVolume(mCardNum, 1.0f /*volume*/);
+ }
updateWiredDeviceConnectionState(direction, true /*enable*/);
}
@@ -412,5 +416,7 @@ public final class UsbAlsaDevice {
return result;
}
+
+ private native void nativeSetVolume(int card, float volume);
}