rk3399 android 11 音频设备优先级管理

功能:根据需求选择音频音频设备的输入输出

1.在Settings中增加设备管理选项

packages/apps/Settings/src/com/android/settings/notification/AudioManagerReceiver.java


/*

  • Copyright © 2013 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.
    */

package com.android.settings.notification;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.FileUtils;
import android.provider.Settings;

/*
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
*/
import androidx.preference.SwitchPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.util.Log;

import android.os.SystemProperties;
import java.io.FileOutputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.DataOutputStream;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
//import com.android.settings.dashboard.SummaryLoader;

import java.util.List;

public class AudioManagerReceiver extends BroadcastReceiver {
private static final String TAG = “AudioManagerReceiver”;

    @Override
    public void onReceive(Context context, Intent intent) {
         if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
             Log.d(TAG,"AudioManagerReceiver---max-chen");
     			                       
			
			String audioOutDevice = getAudioOutDeviceState();
			if(audioOutDevice.equals("SPEAKER")){
			}else if(audioOutDevice.equals("USB SPEAKER")){
			}

			String audioInDevice = getAudioInDeviceState();
		
			if(audioInDevice.equals("BuildIn Mic")){
			}else if(audioInDevice.equals("USB Mic")){
			}
			
		}
    }

	private  static String getAudioOutDeviceState(){
		return SystemProperties.get("persist.current.audio.output.device","SPEAKER");	
	}

	private  static String getAudioInDeviceState(){
		return SystemProperties.get("persist.current.audio.input.device","BuildIn Mic");	
	}

}

waysion@waysion:/home/sdb/workspace/rk3399_android11.0_sdk/packages/apps/Settings$ git diff
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 16b29dc…fc5985e 100644
— a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -107,6 +107,10 @@

  • <application android:label=“@string/settings_label”
    android:icon=“@drawable/ic_launcher_settings”
    android:theme=“@style/Theme.Settings”
    @@ -3291,6 +3295,13 @@
    android:permission=“android.permission.MANAGE_SLICE_PERMISSIONS”
    android:exported=“true” />

  •    <receiver 
    
  •        android:name=".notification.AudioManagerReceiver" >
    
  •        <intent-filter android:priority="1000" >
    
  •            <action android:name="android.intent.action.BOOT_COMPLETED"/>
    
  •        </intent-filter>
    
  •    </receiver>
    
  •    <!-- Couldn't be triggered from outside of settings. Statsd can trigger it because we send
            PendingIntent to it-->
       <receiver android:name=".fuelgauge.batterytip.AnomalyDetectionReceiver"
    

diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 035feed…f06d42b 100644
— a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1602,4 +1602,26 @@
2
3

+

  • SPEAKER
  • USB SPEAKER
  • SPEAKER
  • USB SPEAKER
  • BuildIn Mic
  • USB Mic
  • BuildIn Mic
  • USB Mic

diff --git a/res/values/strings.xml b/res/values/strings.xml
index 692ab2c…0de019d 100644
— a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7909,6 +7909,11 @@
<xliff:g id=“on_count” example=“10”>%d</xliff:g> schedules set

  • Audio Device Manager
  • Audio OutPut Device
  • Audio Input Device
  • Do Not Disturb

diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index fc5c3e2…494174e 100644
— a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -210,6 +210,30 @@
android:summary=“%s”/>

  • <PreferenceCategory
  •   android:key="audio_device_manager"
    
  •    android:title="@string/audio_device_manager_preference_title"
    
  •    android:order="-50">
    
  •   <ListPreference
    
  •        android:key="audio_output_device_manager"
    
  •        android:title="@string/audio_output_device_manager_title"
    
  •        android:summary="audio_output_device_summary"
    
  •        android:entries="@array/audio_device_output_entries"
    
  •        android:entryValues="@array/audio_device_output_values" 
    
  •       android:defaultValue="SPEAKER"
    
  •       />
    
  •   <ListPreference
    
  •      android:key="audio_input_device_manager"
    
  •      android:title="@string/audio_input_device_manager_title"
    
  •      android:summary="audio_input_device_summary"
    
  •      android:entries="@array/audio_device_input_entries"
    
  •      android:entryValues="@array/audio_device_input_values"
    
  •      android:defaultValue="BuildIn Mic"
    
  •   />
    
  • <com.android.settings.widget.WorkOnlyCategory
    android:key=“sound_work_settings_section”
    android:title=“@string/sound_work_settings”
    diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
    index b088fe3…6dd3010 100644
    — a/src/com/android/settings/notification/SoundSettings.java
    +++ b/src/com/android/settings/notification/SoundSettings.java
    @@ -19,18 +19,20 @@ package com.android.settings.notification;
    import android.app.settings.SettingsEnums;
    import android.content.Context;
    import android.content.Intent;
    +import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.os.Handler;
    +import android.os.SystemProperties;
    import android.os.Looper;
    import android.os.Message;
    import android.os.UserHandle;
    import android.preference.SeekBarVolumizer;
    +import android.preference.Preference.OnPreferenceChangeListener;
    import android.text.TextUtils;

import androidx.annotation.VisibleForTesting;
import androidx.preference.ListPreference;
import androidx.preference.Preference;

import com.android.settings.R;
import com.android.settings.RingtonePreference;
import com.android.settings.core.OnActivityResultListener;
@@ -44,18 +46,25 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.UpdatableListPreferenceDialogFragment;

+import android.media.AudioManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import android.util.Log;

@SearchIndexable
-public class SoundSettings extends DashboardFragment implements OnActivityResultListener {
+public class SoundSettings extends DashboardFragment implements OnActivityResultListener, Preference.OnPreferenceChangeListener {
private static final String TAG = “SoundSettings”;

 private static final String SELECTED_PREFERENCE_KEY = "selected_preference";
 private static final int REQUEST_CODE = 200;
 private static final int SAMPLE_CUTOFF = 2000;  // manually cap sample playback at 2 seconds
  • private static final String KEY_AUDIO_OUTPUT_DEVICE = “audio_output_device_manager”;
  • private static final String KEY_AUDIO_INPUT_DEVICE = “audio_input_device_manager”;
  • private static Context mContext;
  • private AudioManager am;
    @VisibleForTesting
    static final int STOP_SAMPLE = 1;

@@ -78,6 +87,9 @@ public class SoundSettings extends DashboardFragment implements OnActivityResult
private String mHfpOutputControllerKey;
private String mVibrationPreferencesKey = “vibration_preference_screen”;

  • private ListPreference mAudioOutputDevicePreference = null;

  • private ListPreference mAudioInputDevicePreference = null;

  • @Override
    public int getMetricsCategory() {
    return SettingsEnums.SOUND;
    @@ -97,6 +109,26 @@ public class SoundSettings extends DashboardFragment implements OnActivityResult
    .findFragmentByTag(TAG);
    mDialogFragment = dialogFragment;
    }

  •   mContext = getContext();
    
  •   am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
    
  •   if(mAudioOutputDevicePreference==null && mAudioInputDevicePreference==null){
    
  •           mAudioOutputDevicePreference = (ListPreference) findPreference(KEY_AUDIO_OUTPUT_DEVICE);
    
  •           mAudioInputDevicePreference = (ListPreference) findPreference(KEY_AUDIO_INPUT_DEVICE);
    
  •           mAudioOutputDevicePreference.setOnPreferenceChangeListener(this);
    
  •            mAudioInputDevicePreference.setOnPreferenceChangeListener(this);
    
  •           String audioOutDevice = getAudioOutDeviceState();
    
  •           Log.d("max.chen","------audioOutDevice:"+audioOutDevice);
    
  •           mAudioOutputDevicePreference.setValue(audioOutDevice);
    
  •           mAudioOutputDevicePreference.setSummary(audioOutDevice);
    
  •           String audioInDevice = getAudioInDeviceState();
    
  •           Log.d("max.chen","------audioOutDevice:"+audioInDevice);
    
  •           mAudioInputDevicePreference.setValue(audioInDevice);
    
  •           mAudioInputDevicePreference.setSummary(audioInDevice);
    
  •   }
    
  • }

    @Override
    @@ -110,6 +142,51 @@ public class SoundSettings extends DashboardFragment implements OnActivityResult
    mVolumeCallback.stopSample();
    }

  • @Override

  • public boolean onPreferenceChange(Preference preference, Object value) {

  •   // TODO Auto-generated method stub
    
  •     Log.d("max.chen", "max.chen preference = " + preference + " value = " + value);
    
  •           //把preference这个Preference强制转化为ListPreference类型
    
  •           ListPreference listPreference=(ListPreference)preference;
    
  •           //获取ListPreference中的实体内容
    
  •           CharSequence[] entries=listPreference.getEntries();
    
  •           //获取ListPreference中的实体内容的下标值
    
  •           int index=listPreference.findIndexOfValue((String)value);
    
  •           //把listPreference中的摘要显示为当前ListPreference的实体内容中选择的那个项目
    
  •           listPreference.setSummary(entries[index]);
    
  •           if(listPreference == mAudioOutputDevicePreference){
    
  •                   SystemProperties.set("persist.vendor.audio.output.device",(String)value);
    
  •                  if(String.valueOf(value).contains("USB")){
    
  •                           am.setParameters("saintway_usb_headset_enable=true");
    
  •                   }else{
    
  •                                   am.setParameters("saintway_usb_headset_enable=false");
    
  •                   }
    
  •           }else if(listPreference == mAudioInputDevicePreference){
    
  •                   SystemProperties.set("persist.vendor.audio.input.device",(String)value);
    
  •                      if(String.valueOf(value).contains("USB")){
    
  •                            am.setParameters("saintway_usb_headset_enable=true");
    
  •                    }else{
    
  •                            am.setParameters("saintway_usb_headset_enable=false");
    
  •                    }
    
  •           }
    
  •   return true;
    
  • }

  •   private   String getAudioOutDeviceState(){
    
  •           return SystemProperties.get("persist.vendor.audio.output.device","SPEAKER");    
    
  •   }
    
  •   private   String getAudioInDeviceState(){
    
  •           return SystemProperties.get("persist.vendor.audio.input.device","BuildIn Mic"); 
    
  •   }
    
  • @Override
    public boolean onPreferenceTreeClick(Preference preference) {
    if (preference instanceof RingtonePreference) {

2.frameworks/av/media/utils/ServiceUtilities.cpp中开放APP更改音频的权限

diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index cc64f9f…ed2ecd2 100644
— a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -196,12 +196,13 @@ bool captureHotwordAllowed(const String16& opPackageName, pid_t pid, uid_t uid)

bool settingsAllowed() {
// given this is a permission check, could this be isAudioServerOrRootUid()?

  • if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
  • static const String16 sAudioSettings(“android.permission.MODIFY_AUDIO_SETTINGS”);
  • //if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
  • //static const String16 sAudioSettings(“android.permission.MODIFY_AUDIO_SETTINGS”);
    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
  • bool ok = PermissionCache::checkCallingPermission(sAudioSettings);
  • if (!ok) ALOGE(“Request requires android.permission.MODIFY_AUDIO_SETTINGS”);
  • return ok;
  • //bool ok = PermissionCache::checkCallingPermission(sAudioSettings);
  • //if (!ok) ALOGE(“Request requires android.permission.MODIFY_AUDIO_SETTINGS”);
  • //return ok;
  • return true;
    }
    3.修改音频策略

frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp

+#pragma clang diagnostic ignored “-Wunused-parameter”
+#include <cutils/properties.h>

DeviceVector Engine::getDevicesForStrategyInt函数中修改输出

   DeviceVector devices2;
   char value[PROPERTY_VALUE_MAX] = "";
   char value_usb[PROPERTY_VALUE_MAX] = "";

   property_get("persist.system.usb.headset_state",value, "unknow");
   property_get("persist.vendor.audio.output.device",value_usb,"unknow");

   if(devices2.isEmpty()){
           devices2 = availableOutputDevices.getFirstDevicesFromTypes({
   }

    if(/*!(strcmp(value,"on")&&*/!strcmp(value_usb,"USB SPEAKER")){
             if(devices2.isEmpty()){
                    devices2 = availableOutputDevices.getFirstDevicesFromTypes({
                    AUDIO_DEVICE_OUT_USB_HEADSET, AUDIO_DEVICE_OUT_USB_DEVICE});
              }
    }

   if(devices2.isEmpty()){
           devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_AUX_DIGITAL);
   }
   if(devices2.isEmpty()){
           devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET);
   }

   if(devices2.isEmpty()){
           devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
   }
   devices.add(devices2);

Engine::getDeviceForInputSource 中修改输出
char value[PROPERTY_VALUE_MAX] = “”;
char value_usb[PROPERTY_VALUE_MAX] = “”;
char value_hdmiin[PROPERTY_VALUE_MAX] = “”;

property_get(“persist.system.usb.headset_state”,value, “unknow”);
property_get(“persist.vendor.audio.input.device”,value_usb,“unknow”);
property_get(“media.audio.hdmiin”,value_hdmiin,“0”);

if (isInCall()) {

         if(/*!(strcmp(value,"on")&&*/!strcmp(value_usb,"USB Mic")){

            device = availableDevices.getFirstExistingDevice({
                    AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,AUDIO_DEVICE_IN_BLUETOOTH_A2DP,  AUDIO_DEVICE_IN_USB_HEADSET,
                    AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_WIRED_HEADSET,AUDIO_DEVICE_IN_BUILTIN_MIC});
         }else{

            device = availableDevices.getFirstExistingDevice({

          }
}else{
       if(/*!(strcmp(value,"on")&&*/!strcmp(value_usb,"USB Mic")){

            device = availableDevices.getFirstExistingDevice({
                    AUDIO_DEVICE_IN_USB_HEADSET,AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_WIRED_HEADSET,AUDIO_DEVICE_IN_BUILTIN_MIC});
         }else{

            device = availableDevices.getFirstExistingDevice({
                     AUDIO_DEVICE_IN_WIRED_HEADSET,AUDIO_DEVICE_IN_BUILTIN_MIC});

          }

}

if(strcmp(value_hdmiin,"1")==0){
  device = availableDevices.getFirstExistingDevice({AUDIO_DEVICE_IN_HDMI});
}

if (device == nullptr) {
    ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
    device = availableDevices.getDevice(
            AUDIO_DEVICE_IN_STUB, String8(""), AUDIO_FORMAT_DEFAULT);
    ALOGE_IF(device == nullptr,
             "getDeviceForInputSource() no default device defined");
}
ALOGD("max.chen getDeviceForInputSource()input source %d, device %08x",
         inputSource, device->type());
return device;

4.修改hardware/rockchip/audio/tinyalsa/audio_hw.c

static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)

/* usb_headset enable/disable */
ret = str_parms_get_str(parms, “saintway_usb_headset_enable”, value, sizeof(value));
if (0 <= ret) {

    if (strcmp(value, "true") == 0) {
        ALOGD("max.chen Enable usb headset ");
        struct stream_out *out = adev->outputs[OUTPUT_DIRECT];
        out->snd_reopen = true;
    } else if (strcmp(value, "false") == 0) {
        ALOGD("max.chen Disable usb headset");
        struct stream_out *out = adev->outputs[OUTPUT_DIRECT];
        out->snd_reopen = true;

    }

}

————————————————
版权声明:本文为CSDN博主「Max.Chen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chgh1306/article/details/126065722

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值