AudioTrack获取进程修改指定app的StreamType

android车机设备为了特定的区别于手机终端设备的应用场景,需要将部分特殊的音频流在系统框架层强制进行转换,针对这一需求,所以我们可以在音频数据流生产之处,强制改变。

首先看看系统定义多少种Audio StreamType
上源码system/media/audio/include/system/audio-base.h

typedef enum {
    
    
    AUDIO_STREAM_DEFAULT = -1, // (-1)
    AUDIO_STREAM_MIN = 0,
    AUDIO_STREAM_VOICE_CALL = 0,
    AUDIO_STREAM_SYSTEM = 1,
    AUDIO_STREAM_RING = 2,
    AUDIO_STREAM_MUSIC = 3,
    AUDIO_STREAM_ALARM = 4,
    AUDIO_STREAM_NOTIFICATION = 5,
    AUDIO_STREAM_BLUETOOTH_SCO = 6,
    AUDIO_STREAM_ENFORCED_AUDIBLE = 7,
    AUDIO_STREAM_DTMF = 8,
    AUDIO_STREAM_TTS = 9,
    AUDIO_STREAM_ACCESSIBILITY = 10,
    AUDIO_STREAM_REROUTING = 11,
    AUDIO_STREAM_PATCH = 12,
    AUDIO_STREAM_PUBLIC_CNT = 11, // (ACCESSIBILITY + 1)
    AUDIO_STREAM_FOR_POLICY_CNT = 12, // PATCH
    AUDIO_STREAM_CNT = 13, // (PATCH + 1)
} audio_stream_type_t;

下面以导航app为例,导航在车机的应用场景的数据流级别高于普通的媒体播放,所以我们把导航app默认设置的music type强制修改为alarm流,这样以备后续的车机音频策略的实施。

音频数据的生产者AudioTrack可以助我们一臂之力,简单的描述下思路便直接上代码,直接获取到对应导航app的进程,当前进程活跃(导航在进行tts语音播报的时刻),强制修改为AUDIO_STREAM_ALARM .

frameworks\av\media\libaudioclient\AudioTrack.cpp
增加函数获取

static int get_pack_from_cmdline(int pid, char *buf, int len) {
    
    
   char filename[256];
   int n = 0;
   int fd;
   if (pid < 1 || buf == NULL || len < 256) {
    
    
       return -1;
   }
   memset(filename, 0, 256);
   sprintf(filename, "/proc/%d/cmdline", pid);
   fd = open(filename, O_RDONLY);
   if (fd < 0) {
    
    
       perror("open:");
       return -1;
   }
   int ret = read(fd, buf, len);
   close(fd);
   memset(filename, 0, 256);
   while (1) {
    
    
       if (buf[n] == ' '||buf[n] == ':')
           break;
       filename[n] = buf[n];
       n++;
       if (n == ret)
           break;
   }
   memset(buf, 0, len);
   memcpy(buf, filename, n + 1);
   return ret;
}

AudioTrack最初设置playback参数的set函数具体实施流类型的转变

  status_t AudioTrack::set(
        audio_stream_type_t streamType,
        uint32_t sampleRate,
        audio_format_t format,
        audio_channel_mask_t channelMask,
        size_t frameCount,
        audio_output_flags_t flags,
        callback_t cbf,
        void* user,
        int32_t notificationFrames,
        const sp<IMemory>& sharedBuffer,
        bool threadCanCallJava,
        audio_session_t sessionId,
        transfer_type transferType,
        const audio_offload_info_t *offloadInfo,
        uid_t uid,
        pid_t pid,
        const audio_attributes_t* pAttributes,
        bool doNotReconnect,
        float maxRequiredSpeed)
{
    
    
    MTK_ALOGI("set(): %p, streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
          "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
          this, streamType, sampleRate, format, channelMask, frameCount, flags,
          notificationFrames, sessionId, transferType, uid, pid);
    ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
          "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
          streamType, sampleRate, format, channelMask, frameCount, flags, notificationFrames,
          sessionId, transferType, uid, pid);
...
...

   //获取进程
	char pidName[256];
	memset(pidName, 0, 256);
	get_pack_from_cmdline(getpid(), pidName, 256);
	if (strcmp(pidName,"具体的导航app进程名,eg.高德com.autonavi.amapauto")== 0){
    
    
		mSteamType = AUDIO_STREAM_ALARM ;
	}

如此一来,就可以将导航的audio数据流和媒体播放的数据流区别,以便车机上的音频策略的实现.

猜你喜欢

转载自blog.csdn.net/jeephao/article/details/107302285
今日推荐