sichen
1 判断音频流来自于哪个程序,如果来源于导航,则将音频类型默认为导航音。
./framework/av/include/media/NaviInfo.h
#include <utils/String8.h>
namespace Android {
class NaviInfo
{
public:
NaviInfo();
~NaviInfo();
bool isNavicalling();
private:
void getCallingProcessName(char *name);
char *mProcName;
bool isNaviProcess;
};
}
./framework/av/media/libmedia/NaviInfo.cpp
#define LOG_NDEBUG 0
#define LOG_TAG "NaviInfo"
#include <utils/Log.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <media/NaviInfo.h>
#include <binder/IPCThreadState.h>
namespace android {
static const char *naviPackageName[] =
{
"com.navitel",
"title.navi",
"com.mapabc.android.activity",
"cld.navi.mobile.mainframe",
"cld.navi.c2335.mainframe",
"cld.navi.c3198.mainframe",
"cld.navi.c2739.mainframe",
"cld.navi.c3347.mainframe",
"cld.navi.c3440.mainframe",
"cld.navi.c2920.mainframe",
"cld.navi.c3380.mainframe",
"cld.navi.c3567.mainframe",
"cld.navi.c3525.mainframe",
"com.nuro.r1.main",
"com.autonavi.xm.navigation",
"com.autonavi.xmgd.navigator",
"com.mxnavi.mxnavi",
"com.baidu.BaiduMap",
"com.baidu.navi",
"com.autonavi.cmccmap",
"com.autonavi.Minimap",
"com.sogou.map.android.maps",
"com.navngo.igo.javaclient",
"com.basarsoft.igo.javaclient",
"com.nng.igoprimoisr2013march24.javaclient",
"ru.yandex.yandexnavi",
"com.sygic.aura_pndindash",
"com.mireo.dontpanic.mmi_pnd",
"com.sogou.map.android.maps",
"com.uu.uunavi",
"com.tigerknows",
"com.sogou.map.android.maps",
"com.mapquest.android.ace",
"cz.aponia.bor3",
"com.kingwaytek",
"com.waze",
"com.Google.android.APPs.maps",
"cld.navi.p3597.mainframe",
"com.tencent.navsns",
"com.tencent.map",
"com.movon.fcw",
"com.autonavi.amapauto",
"com.sygic.aura"
};
NaviInfo::NaviInfo()
{
}
NaviInfo::~NaviInfo()
{
}
void NaviInfo::getCallingProcessName(char *name)
{
char proc_node[128];
int pid = IPCThreadState::self()->getCallingPid();
if (name == 0)
{
ALOGE("ERROR in params");
return;
}
memset(proc_node, 0, sizeof(proc_node));
sprintf(proc_node, "/proc/%d/cmdline", pid);
int fp = ::open(proc_node, O_RDONLY);
if (fp > 0)
{
memset(name, 0, 128);
::read(fp, name, 128);
::close(fp);
fp = 0;
ALOGD("Calling process is: %s", name);
}
else
{
ALOGE("obtain calling process failed");
}
ALOGD("NaviInfo::getCallingProcessName() pid = %d, name = %s", pid, name);
}
bool NaviInfo::isNaviCalling()
{
char name[128];
int i = 0;
int count = sizeof(naviPackageName) / sizeof(naviPackageName[0]);
memset(name, 0x00, 128);
getCallingProcessName(name);
for(i = 0; i < count; i++)
{
if(strcmp(name, naviPackageName[i]) == 0)
{
return true;
}
}
return false;
}
}
由上可以看到,就是抓取访问的进程pid,再进一步获取应用包名,比对默认提供的导航包名。如果符合,则将音频类型默认为导航音。此导航音类型也是修改系统后增加,非原生的音频类型。
2 在上层将导航申请发声的音频流强制转化成导航音类型,下面AudioFlinger可以根据音频流类型,强制执行优先级策略。
./framework/av/media/libmedia/mediaplayer.cpp
status_t AudioTrack::set(...){
+ NaviInfo *info = new NaviInfo();
+ bool isNavi = info -> isNaviCalling();
+ if(isNavi) streamType = AUDIO_STREAM_NAVI;
}
./framework/av/media/libmedia/mediaplayer.cpp
status_t MediaPlayer::setAudiOStreamType(audio_stream_type_t type){
+ NaviInfo *info = new NaviInfo();
+ bool isNavi = info -> isNaviCalling();
+ if(isNavi) streamType = AUDIO_STREAM_NAVI;
}
3 在AudioFlinger的混音线程内针对音频流类型做策略即可。
./framework/av/services/audioflinger/Threads.cpp
AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
vector< sp<Track> > *tracksToRemove)
{
+ naviMixer();
+ if(mIsNaviOn){
+ if(track->streamType() != AUDIO_STREAM_NAVI)
+ {
+ typeVolume *= 0.5;
+ }
+ }
}
void AudioFlinger::MixerThread::naviMixer()
{
size_t count = mActiveTracks.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Track> t = mActiveTracks[i].promote();
if (t == 0) {
continue;
}
// this const just means the local variable doesn't change
Track* const track = t.get();
if(track->streamType() == AUDIO_STREAM_NAVI)
{
mIsNaviOn = true;
return;
}
}
mIsNaviOn = false;
}
文章最后发布于: 2018-09-05 14:28:18