正常测试平台
latform: RK3328
OS: Android10.0
现象
在3328 android10.0上开发app,发现无法监听音量,在3399
分析解决
查看代码发现在PhoneWindowManager.java中根据mUseTvRouting || mHandleVolumeKeysInWM的值会决定重量键是否下发到app
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
private long interceptKeyBeforeDispatchingInner(WindowState win, KeyEvent event,
。..。
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP
|| keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
if (mUseTvRouting || mHandleVolumeKeysInWM) {
// On TVs or when the configuration is enabled, volume keys never
// go to the foreground app.
dispatchDirectAudioEvent(event);
return -1;
}
打印日志发现 mUseTvRouting:true,mHandleVolumeKeysInWM:false
mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION;
mHandleVolumeKeysInWM = mHandleVolumeKeysInWM = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_handleVolumeKeysInWindowManager);
查看AudioSystem代码可知:
frameworks/base/media/java/android/media/AudioSystem.java
public static int getPlatformType(Context context) {
if (context.getResources().getBoolean(com.android.internal.R.bool.config_voice_capable)) {
return PLATFORM_VOICE;
} else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|| “box”.equals(SystemProperties.get(“ro.target.product”, “unknown”))) {
return PLATFORM_TELEVISION;
} else {
return PLATFORM_DEFAULT;
}
}
系统没有声明PackageManager.FEATURE_LEANBACK的权限,但是ro.target.product=box
所以我们把
else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|| “box”.equals(SystemProperties.get(“ro.target.product”, “unknown”))) {undefined
修改为
else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {undefined
编译更新后重启,发现音量按键不但无法监听,连音量都无法调节
继续查看代码,发现PhoneWindowManager中还有一个地方会截获按键
// Maps global key codes to the components that will handle them.
private GlobalKeyManager mGlobalKeyManager;
。..
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
…
// If the key would be handled globally, just return the result, don’t worry about special
// key processing.
if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
if (isWakeKey) {
wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey,
PowerManager.WAKE_REASON_WAKE_KEY, “android.policy:KEY”);
}
return result;
}
GlobalKeyManager的作用是把指定按键事件转发到特定的app接收,转发按键定义在
com.android.internal.R.xml.global_keys
查看global_keys的值
find device/rockchip/ -name “global_keys.xml”
device/rockchip/common/tv/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/rk3328_box/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/roc_rk3328_pc_32/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/rk3328_atv/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/rk3328_box_32/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/roc_rk3328_pc/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/overlay/frameworks/base/core/res/res/xml/global_keys.xml
cat device/rockchip/rk3328/overlay/frameworks/base/core/res/res/xml/global_keys.xml
《?xml version=“1.0” encoding=“utf-8”?》
《global_keys version=“1”》
《!-- Example format: id = keycode to handle globally. component = component which will handle this key. --》
《key keyCode=“KEYCODE_GUIDE” component=“com.google.android.tv/.receiver.GlobalKeyReceiver” /》
《key keyCode=“KEYCODE_TV” component=“com.google.android.tv/.receiver.GlobalKeyReceiver” /》
《key keyCode=“KEYCODE_TV_INPUT” component=“com.google.android.tv/.receiver.GlobalKeyReceiver” /》
《key keyCode=“KEYCODE_TV_POWER” component=“com.google.android.athome.globalkeyinterceptor/.Receiver” /》
《key keyCode=“KEYCODE_PAIRING” component=“com.google.android.athome.globalkeyinterceptor/.Receiver” /》
《key keyCode=“KEYCODE_VOLUME_UP” component=“com.google.android.athome.globalkeyinterceptor/.Receiver” /》
《key keyCode=“KEYCODE_VOLUME_DOWN” component=“com.google.android.athome.globalkeyinterceptor/.Receiver” /》
《/global_keys》
可以看出音量按键截获并转发给了com.google.android.athome.globalkeyinterceptor/.Receiver
由于系统内并没有内置对应的apk,导致音量调节无效。
删除所有global_keys.xml中音量按键转发
编译更新后测试正常,音量可以正常调节,app也可以监听到音量键事件。
正常测试平台
latform: RK3328
OS: Android10.0
现象
在3328 android10.0上开发app,发现无法监听音量,在3399
分析解决
查看代码发现在PhoneWindowManager.java中根据mUseTvRouting || mHandleVolumeKeysInWM的值会决定重量键是否下发到app
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
private long interceptKeyBeforeDispatchingInner(WindowState win, KeyEvent event,
。..。
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP
|| keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
if (mUseTvRouting || mHandleVolumeKeysInWM) {
// On TVs or when the configuration is enabled, volume keys never
// go to the foreground app.
dispatchDirectAudioEvent(event);
return -1;
}
打印日志发现 mUseTvRouting:true,mHandleVolumeKeysInWM:false
mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION;
mHandleVolumeKeysInWM = mHandleVolumeKeysInWM = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_handleVolumeKeysInWindowManager);
查看AudioSystem代码可知:
frameworks/base/media/java/android/media/AudioSystem.java
public static int getPlatformType(Context context) {
if (context.getResources().getBoolean(com.android.internal.R.bool.config_voice_capable)) {
return PLATFORM_VOICE;
} else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|| “box”.equals(SystemProperties.get(“ro.target.product”, “unknown”))) {
return PLATFORM_TELEVISION;
} else {
return PLATFORM_DEFAULT;
}
}
系统没有声明PackageManager.FEATURE_LEANBACK的权限,但是ro.target.product=box
所以我们把
else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|| “box”.equals(SystemProperties.get(“ro.target.product”, “unknown”))) {undefined
修改为
else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {undefined
编译更新后重启,发现音量按键不但无法监听,连音量都无法调节
继续查看代码,发现PhoneWindowManager中还有一个地方会截获按键
// Maps global key codes to the components that will handle them.
private GlobalKeyManager mGlobalKeyManager;
。..
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
…
// If the key would be handled globally, just return the result, don’t worry about special
// key processing.
if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
if (isWakeKey) {
wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey,
PowerManager.WAKE_REASON_WAKE_KEY, “android.policy:KEY”);
}
return result;
}
GlobalKeyManager的作用是把指定按键事件转发到特定的app接收,转发按键定义在
com.android.internal.R.xml.global_keys
查看global_keys的值
find device/rockchip/ -name “global_keys.xml”
device/rockchip/common/tv/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/rk3328_box/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/roc_rk3328_pc_32/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/rk3328_atv/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/rk3328_box_32/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/roc_rk3328_pc/overlay/frameworks/base/core/res/res/xml/global_keys.xml
device/rockchip/rk3328/overlay/frameworks/base/core/res/res/xml/global_keys.xml
cat device/rockchip/rk3328/overlay/frameworks/base/core/res/res/xml/global_keys.xml
《?xml version=“1.0” encoding=“utf-8”?》
《global_keys version=“1”》
《!-- Example format: id = keycode to handle globally. component = component which will handle this key. --》
《key keyCode=“KEYCODE_GUIDE” component=“com.google.android.tv/.receiver.GlobalKeyReceiver” /》
《key keyCode=“KEYCODE_TV” component=“com.google.android.tv/.receiver.GlobalKeyReceiver” /》
《key keyCode=“KEYCODE_TV_INPUT” component=“com.google.android.tv/.receiver.GlobalKeyReceiver” /》
《key keyCode=“KEYCODE_TV_POWER” component=“com.google.android.athome.globalkeyinterceptor/.Receiver” /》
《key keyCode=“KEYCODE_PAIRING” component=“com.google.android.athome.globalkeyinterceptor/.Receiver” /》
《key keyCode=“KEYCODE_VOLUME_UP” component=“com.google.android.athome.globalkeyinterceptor/.Receiver” /》
《key keyCode=“KEYCODE_VOLUME_DOWN” component=“com.google.android.athome.globalkeyinterceptor/.Receiver” /》
《/global_keys》
可以看出音量按键截获并转发给了com.google.android.athome.globalkeyinterceptor/.Receiver
由于系统内并没有内置对应的apk,导致音量调节无效。
删除所有global_keys.xml中音量按键转发
编译更新后测试正常,音量可以正常调节,app也可以监听到音量键事件。
举报