| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> android添加micphone静音事件处理 -> 正文阅读 |
|
[移动开发]android添加micphone静音事件处理 |
软件版本:Android9 硬件平台:Mtk8175 需求:物理按键触发,底层上报静音事件,上层响应; 按键驱动层面的内容,在此不做记录分析,从驱动上报事件到系统层事件映射透传做起: 1、修改kl映射表: diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl index 860aa9c118b..fd9773a5415 100644 --- a/data/keyboards/Generic.kl +++ b/data/keyboards/Generic.kl @@ -132,7 +132,7 @@ key 109 ? PAGE_DOWN key 110 ? INSERT key 111 ? FORWARD_DEL # key 112 "KEY_MACRO" -key 248 ? VOLUME_MUTE +key 248 ? MUTE key 114 ? VOLUME_DOWN key 115 ? VOLUME_UP key 116 ? POWER 248代表驱动上报的事件键值,由于内核和Framework层键值并未统一,因此在此做映射,后边的MUTE对应的是框架层的KEYCODE_MUTE键值,该按键在framework层代表mic静音。 2、Framework层改动,PhoneWindowManager对事件进行接收和派发,改动如下: diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index b74ae77729b..6ae526ec0ce 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -300,6 +300,7 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; +import java.io.BufferedReader; import java.util.List; /** @@ -460,6 +461,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { ?? ? private final Object mLock = new Object(); ?? ? Context mContext; +? ? AudioManager mAudioManager; ?? ? IWindowManager mWindowManager; ?? ? WindowManagerFuncs mWindowManagerFuncs; ?? ? WindowManagerInternal mWindowManagerInternal; @@ -499,6 +501,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { ?? ? /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */ ?? ? boolean mEnableShiftMenuBugReports = false; +? ? // Switch for micmute debug +? ? private static boolean mMicmuteDebug = false; + ?? ? /** Controller that supports enabling an AccessibilityService by holding down the volume keys */ ?? ? private AccessibilityShortcutController mAccessibilityShortcutController; @@ -506,6 +511,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { ?? ? private final ArraySet<WindowState> mScreenDecorWindows = new ArraySet<>(); ?? ? WindowState mStatusBar = null; ?? ? private final int[] mStatusBarHeightForRotation = new int[4]; +? ? private boolean mMicStatus = false; ?? ? WindowState mNavigationBar = null; ?? ? boolean mHasNavigationBar = false; ?? ? boolean mNavigationBarCanMove = false; // can the navigation bar ever move to the side? @@ -2022,6 +2028,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { ?? ? ? ? mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class); ?? ? ? ? mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); ?? ? ? ? mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); +? ? ? ? mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); ?? ? ? ? mHasFeatureWatch = mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH); ?? ? ? ? mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK); ?? ? ? ? mAccessibilityShortcutController = @@ -2098,6 +2105,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { ?? ? ? ? mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, ?? ? ? ? ? ? ? ? "PhoneWindowManager.mPowerKeyWakeLock"); ?? ? ? ? mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable")); +? ? ? ? mMicmuteDebug = "1".equals(SystemProperties.get("sys.mic.debug")); ?? ? ? ? mSupportAutoRotation = mContext.getResources().getBoolean( ?? ? ? ? ? ? ? ? com.android.internal.R.bool.config_supportAutoRotation); ?? ? ? ? mLidOpenRotation = readRotation( @@ -3889,7 +3897,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { ?? ? ? ? ? ? return -1; ?? ? ? ? } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP ?? ? ? ? ? ? ? ? || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN -? ? ? ? ? ? ? ? || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) { +? ? ? ? ? ? ? ? || keyCode == KeyEvent.KEYCODE_VOLUME_MUTE +? ? ? ? ? ? ? ? || keyCode == KeyEvent.KEYCODE_MUTE) { ?? ? ? ? ? ? if (mUseTvRouting || mHandleVolumeKeysInWM) { ?? ? ? ? ? ? ? ? // On TVs or when the configuration is enabled, volume keys never ?? ? ? ? ? ? ? ? // go to the foreground app. @@ -3897,6 +3906,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { ?? ? ? ? ? ? ? ? return -1; ?? ? ? ? ? ? } +? ? ? ? ? ? if(keyCode == KeyEvent.KEYCODE_MUTE){ +? ? ? ? ? ? ? ? dispatchDirectAudioEvent(event); +? ? ? ? ? ? } + ?? ? ? ? ? ? // If the device is in VR mode and keys are "internal" (e.g. on the side of the ?? ? ? ? ? ? // device), then drop the volume keys and don't forward it to the application/dispatch ?? ? ? ? ? ? // the audio event. @@ -6132,6 +6145,38 @@ public class PhoneWindowManager implements WindowManagerPolicy { ?? ? ? ? setHdmiPlugged(!mHdmiPlugged); ?? ? } +? ? public static boolean isMicMute(){ +? ? ? ? /*if (null == mAudioManager) { +? ? ? ? ? ? mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); +? ? ? ? } +? ? ? ? int current = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); +? ? ? ? */ +? ? ? ? String prop = "tal";// 默认值 +? ? ? ? BufferedReader reader = null; +? ? ? ? try { +? ? ? ? ? ? reader = new BufferedReader(new FileReader("/sys/devices/platform/odm/odm:gpio-keys/MicMuteState")); +? ? ? ? ? ? prop = reader.readLine(); +? ? ? ? ? ? if (mMicmuteDebug) { +? ? ? ? ? ? ? ? Slog.e("======", "read micstate value:" + prop); +? ? ? ? ? ? } +? ? ? ? } catch (IOException e) { +? ? ? ? ? ? e.printStackTrace(); +? ? ? ? } finally { +? ? ? ? ? ? if(reader != null){ +? ? ? ? ? ? ? ? try { +? ? ? ? ? ? ? ? ? ? reader.close(); +? ? ? ? ? ? ? ? } catch (IOException e) { +? ? ? ? ? ? ? ? ? ? e.printStackTrace(); +? ? ? ? ? ? ? ? } +? ? ? ? ? ? } +? ? ? ? } + +? ? ? ? if (prop.indexOf("1") != -1) { +? ? ? ? ? ? return false; +? ? ? ? } + +? ? ? ? return true; +? ? } ?? ? /** {@inheritDoc} */ ?? ? @Override @@ -6708,6 +6753,37 @@ public class PhoneWindowManager implements WindowManagerPolicy { ?? ? ? ? ? ? ? ? | AudioManager.FLAG_FROM_KEY; ?? ? ? ? String pkgName = mContext.getOpPackageName(); ?? ? ? ? switch (keyCode) { +? ? ? ? ? ? case KeyEvent.KEYCODE_MUTE: +? ? ? ? ? ? ? ? try { +? ? ? ? ? ? ? ? ? ? mMicStatus = isMicMute(); +? ? ? ? ? ? ? ? ? ? if (mMicmuteDebug) { +? ? ? ? ? ? ? ? ? ? ? ? Slog.e("======", " set mMicStatus to " + mMicStatus); +? ? ? ? ? ? ? ? ? ? } +? ? ? ? ? ? ? ? ? ? mAudioManager.setMicrophoneMute(mMicStatus); +? ? ? ? ? ? ? ? ? ? /*if(mMicStatus) +? ? ? ? ? ? ? ? ? ? { +? ? ? ? ? ? ? ? ? ? ? ? Handler handlerToast = new Handler(Looper.getMainLooper()); +? ? ? ? ? ? ? ? ? ? ? ? handlerToast.post(new Runnable(){ +? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run(){ +? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(mContext,"Mute Mic",Toast.LENGTH_SHORT).show(); +? ? ? ? ? ? ? ? ? ? ? ? ? ? }; +? ? ? ? ? ? ? ? ? ? ? ? }); +? ? ? ? ? ? ? ? ? ? } +? ? ? ? ? ? ? ? ? ? else +? ? ? ? ? ? ? ? ? ? { +? ? ? ? ? ? ? ? ? ? ? ? Handler handlerToast = new Handler(Looper.getMainLooper()); +? ? ? ? ? ? ? ? ? ? ? ? handlerToast.post(new Runnable(){ +? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run(){ +? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(mContext,"UnMute Mic",Toast.LENGTH_SHORT).show(); +? ? ? ? ? ? ? ? ? ? ? ? ? ? }; +? ? ? ? ? ? ? ? ? ? ? ? }); +? ? ? ? ? ? ? ? ? ? } +? ? ? ? ? ? ? ? ? ? //? ? Toast.makeText(mContext,"UnMute Mic",Toast.LENGTH_SHORT).show();*/ +? ? ? ? ? ? ? ? } catch (Exception e) { +? ? ? ? ? ? ? ? ? ? Log.e(TAG, "Error dispatching mic mute in dispatchTvAudioEvent.", e); +? ? ? ? ? ? ? ? } +? ? ? ? ? ? ? ? break; + ?? ? ? ? ? ? case KeyEvent.KEYCODE_VOLUME_UP: ?? ? ? ? ? ? ? ? try { ?? ? ? ? ? ? ? ? ? ? getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, 这里涵盖对事件的接收处理,以及对key事件sys节点获取或者写入以控制状态的操作 3、调试过程中遇到了selinux的问题,systemserver无法读取sys节点,因此添加了如下te规则: device/mediatek/sepolicy/bsp/non_plat: 修改file_contexts --- a/non_plat/file_contexts +++ b/non_plat/file_contexts @@ -171,3 +171,9 @@ # mcu /sys/devices/platform/soc/11009000.i2c/i2c-3/3-0011/as9072_debug(/.*)? u:object_r:mcu_file:s0 +# mute key +/sys/devices/platform/odm/odm:gpio-keys/MicMuteState u:object_r:mute_key_file:s0 修改file.te diff --git a/non_plat/file.te b/non_plat/file.te index 7d85882..a3d25b8 100755 --- a/non_plat/file.te +++ b/non_plat/file.te @@ -70,4 +70,13 @@ type sysfs_mrdump, fs_type, sysfs_type; type doe_vendor_data_file, file_type, data_file_type; +# mute key +type mute_key_file, fs_type, sysfs_type; 修改system_server.te: diff --git a/non_plat/system_server.te b/non_plat/system_server.te index 857791f..6565630 100644 --- a/non_plat/system_server.te +++ b/non_plat/system_server.te @@ -132,6 +132,10 @@ allow system_server mtk_fullscreen_switch_service:service_manager add; # Purpose : dfps hal interface permission hal_client_domain(system_server,hal_dfps) +# For system service MicMute permission +allow system_server mute_key_file:dir { search read }; +allow system_server mute_key_file:file { read open getattr }; + #============= system_server ============== allow system_server audioserver:file write; 4、权限修改完成,service对内核节点可读可写,但是系统软件层面默认mic是可收声的,当物理按键默认为静音位置切第一次起机时,状态就反了,需要在系统第一次启动,添加一个mic键值状态的判断,是静音则切换静音: diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 61469e22e79..601e974d6da 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -141,6 +141,7 @@ import com.android.server.audio.AudioServiceEvents.PhoneStateEvent; import com.android.server.audio.AudioServiceEvents.VolumeEvent; import com.android.server.audio.AudioServiceEvents.WiredDevConnectEvent; import com.android.server.pm.UserManagerService; +import com.android.server.policy.PhoneWindowManager; import org.xmlpull.v1.XmlPullParserException; @@ -175,6 +176,11 @@ public class AudioService extends IAudioService.Stub ?? ? private static final String TAG = "AudioService"; +? ? private boolean mInitMicStatus = false; + +? ? // Switch for micmute debug +? ? boolean mMicmuteDebug = false; + ?? ? /// M: Add for control debug log, only default enable it on eng/userdebug load. ?? ? protected static final boolean LOGD = !"user".equals(Build.TYPE); @@ -732,6 +738,8 @@ public class AudioService extends IAudioService.Stub ?? ? ? ? mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); ?? ? ? ? mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); +? ? ? ? mMicmuteDebug = "1".equals(SystemProperties.get("sys.mic.debug")); + ?? ? ? ? // Initialize volume ?? ? ? ? int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1); ?? ? ? ? if (maxCallVolume != -1) { @@ -875,6 +883,13 @@ public class AudioService extends IAudioService.Stub ?? ? ? ? mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener); ?? ? ? ? mRecordMonitor.initMonitor(); + +? ? ? ? //Set Mic state when system starting.. +? ? ? ? mInitMicStatus = PhoneWindowManager.isMicMute(); +? ? ? ? if (mMicmuteDebug) { +? ? ? ? ? ? Slog.e("======", "AudioService init set mMicStatus to: " + mInitMicStatus); +? ? ? ? } +? ? ? ? AudioSystem.muteMicrophone(mInitMicStatus); ?? ? } ?? ? public void systemReady() { 这里调用了第二步PhoneWindowManager添加获取mic状态的方法,从而去初始化micphone的状态是否静音。 至此,改动大功告成,Mark一下~~~~~ |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/28 11:41:57- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |