Loading services/core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -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", Loading services/core/jni/com_android_server_UsbAlsaDevice.cpp 0 → 100644 +70 −0 Original line number Diff line number Diff line /* * 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 services/core/jni/onload.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading services/usb/java/com/android/server/usb/UsbAlsaDevice.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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*/); } Loading Loading @@ -412,5 +416,7 @@ public final class UsbAlsaDevice { return result; } private native void nativeSetVolume(int card, float volume); } services/usb/java/com/android/server/usb/flags/usb_flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -21,3 +21,10 @@ flag { description: "This flag checks if phone is unlocked after boot" bug: "73654179" } flag { name: "maximize_usb_audio_volume_when_connecting" namespace: "usb" description: "This flag maximizes the usb audio volume when it is connected" bug: "245041322" } Loading
services/core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -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", Loading
services/core/jni/com_android_server_UsbAlsaDevice.cpp 0 → 100644 +70 −0 Original line number Diff line number Diff line /* * 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
services/core/jni/onload.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading
services/usb/java/com/android/server/usb/UsbAlsaDevice.java +6 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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*/); } Loading Loading @@ -412,5 +416,7 @@ public final class UsbAlsaDevice { return result; } private native void nativeSetVolume(int card, float volume); }
services/usb/java/com/android/server/usb/flags/usb_flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -21,3 +21,10 @@ flag { description: "This flag checks if phone is unlocked after boot" bug: "73654179" } flag { name: "maximize_usb_audio_volume_when_connecting" namespace: "usb" description: "This flag maximizes the usb audio volume when it is connected" bug: "245041322" }