diff options
| -rw-r--r-- | services/core/jni/Android.bp | 1 | ||||
| -rw-r--r-- | services/core/jni/com_android_server_UsbAlsaDevice.cpp | 70 | ||||
| -rw-r--r-- | services/core/jni/onload.cpp | 2 | ||||
| -rw-r--r-- | services/usb/java/com/android/server/usb/UsbAlsaDevice.java | 6 |
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); } |