功能描述
在系統開機時,強制開機鈴聲只通過耳機通道播放;
不管是否有插入耳機,最終開機鈴聲都通過耳機通道輸出;開機后保持原有的音頻策略設定;
android開機鈴聲添加程序
android的開機鈴聲添加方案,一般是放在 開機影片bootanimation的程序中實作的;
Android bootanimation所在的位置是:(qcom android N)
frameworks/base/cmds/bootanimation/
code/frameworks/base/cmds/bootanimation$ tree ./
./
├── Android.mk
├── audioplay.cpp
├── audioplay.h
├── BootAnimation.cpp
├── BootAnimation.h
├── bootanimation_main.cpp
├── bootanim.rc
└── FORMAT.md
開機鈴聲的添加可以通過兩種方式:
通過 audioplay.cpp
通過[[OpenSLES]]; 待詳細分析…
通過MediaPlayer 類
在BootAnimation類定義中,添加 bootMusic介面;
void BootAnimation::bootMusic()
{
int index;
const char *fileName = "/system/media/boot.wav"; //選擇一個有權限訪問的位置 存放開機鈴聲
MediaPlayer* mp = new MediaPlayer(); //創建MediaPlayer
MediaPlayer* mp = new MediaPlayer();
audio_devices_t device = AudioSystem::getDevicesForStream(AUDIO_STREAM_ENFORCED_AUDIBLE);
if (mp->setDataSource(NULL, fileName, NULL) == NO_ERROR)
{
mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE/*AudioSystem: :ENFORCED_AUDIBLE*/);
mp->prepare();
}
LOGE ("bootMusic\n");
AudioSystem::initStreamVolume(AUDIO_STREAM_ENFORCED_AUDIBLE, 0,7);
AudioSystem::setStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, 7, device);
AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE/*AudioSystem::ENFORCED_AUDIBLE*/, &index, device);
LOGE ("index %d",index);
if (index != 0)
{
LOGD("playing %s", fileName);
mp->setVolume(0.4f, 0.4f);
mp->seekTo(0);
mp->start();
}
}
AudioSystem 型別的選擇
/* Audio stream types */
typedef enum {
/* These values must kept in sync with
* frameworks/base/media/java/android/media/AudioSystem.java
*/
AUDIO_STREAM_DEFAULT = -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, /* Sounds that cannot be muted by user
* and must be routed to speaker
*/
AUDIO_STREAM_DTMF = 8,
AUDIO_STREAM_TTS = 9, /* Transmitted Through Speaker.
* Plays over speaker only, silent on other devices.
*/
AUDIO_STREAM_ACCESSIBILITY = 10, /* For accessibility talk back prompts */
AUDIO_STREAM_REROUTING = 11, /* For dynamic policy output mixes */
AUDIO_STREAM_PATCH = 12, /* For internal audio flinger tracks. Fixed volume */
AUDIO_STREAM_PUBLIC_CNT = AUDIO_STREAM_TTS + 1,
AUDIO_STREAM_FOR_POLICY_CNT = AUDIO_STREAM_PATCH, /* number of streams considered by
audio policy for volume and routing */
AUDIO_STREAM_CNT = AUDIO_STREAM_PATCH + 1,
} audio_stream_type_t;
通常場景下,開機鈴聲選擇AUDIO_STREAM_ENFORCED_AUDIBLE 型別;
在開機影片播放前 呼叫
bool BootAnimation::threadLoop()
{
bool r;
// We have no bootanimation file, so we use the stock android logo
// animation.
bootMusic();
// sleep(5);
if (mZipFileName.isEmpty()) {
r = android();
} else {
r = movie();
}
//......
}
在除錯程序中,在播放開機影片之前,可以設定一段延時用于除錯,因為 BootAnimation最終是被編譯成可執行檔案被訪問,為了提高效率,在debug階段,
我們可以直接編譯 BootAnimation, 將得到的可執行檔案bootanimation push到設備中,直接執行,設定延時的目的是防止開機影片直接結束;
audio output device的選擇
添加完開機鈴聲的播放,考慮下如何選擇音頻輸出設備的選擇;
在執行bootanimation時,可以獲取到如下log:

默認選擇的是 speaker輸出,即使android 設備上插著耳機;
針對這個需求,可將audio_stream_type 選擇為AUDIO_STREAM_MUSIC;通過執行bootanimation 去測驗,當耳機插入時,聲音會通過耳機輸出;
但是存在的問題是,當未插入耳機是,聲音還是會沖speaker輸出,另外在執行播放開機鈴聲的時候,系統還未檢測到耳機的存在,即使在開機后執行bootanimation 能夠通過耳機播放鈴聲,開機程序中依舊是不行的;
在默認的音頻策略中,耳機的優先級本就高于speaker, 想到一個思路就是在,播放開機鈴聲之前,強制設定耳機存在的狀態; 完成開機后,還需要再設定回去;
暫時未測驗該方案,使用了另外一個方案;
強制系結輸出設備
思路是在hal中,不管之前的策略如何設定,只要判斷到未完成開機(根據"service.bootanim.exit" 的property 值來判斷),就將輸出設備 設定為HEADPHONES;
修改點如下:
diff --git a/hardware/qcom/audio/hal/audio_hw.c b/hardware/qcom/audio/hal/audio_hw.c
old mode 100644
newmode 100755
index d0d1e6031d..f91a5c7979
--- a/hardware/qcom/audio/hal/audio_hw.c
+++ b/hardware/qcom/audio/hal/audio_hw.c
@@ -825,7 +825,15 @@ intselect_devices(struct audio_device *adev, audio_usecase_t uc_id)
in_snd_device == usecase->in_snd_device) {
return0;
}
-
+ charpropValue[16];
+ if(property_get("service.bootanim.exit", propValue, "0")) {
+ if(atoi(propValue) == 0){
+ out_snd_device = SND_DEVICE_OUT_HEADPHONES;
+ ALOGD("%s: out_snd_device force select headphone\n", __func__);
+ }
+ else+ ALOGV("bootanimation exit,normal select device\n ");
+ }
ALOGD("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
out_snd_device, platform_get_snd_device_name(out_snd_device),
in_snd_device, platform_get_snd_device_name(in_snd_device));
開機完成后,“service.bootanim.exit” 將被置1, 即有新的音頻輸出時,使用默認的選擇策略;
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/295683.html
標籤:其他
