一、简析HAL结构
- HAL是一个位于操作系统和驱动程序之上,运行在用户空间中的服务程序。
- 目的:对上层应用提供一个统一的查询硬件设备的接口。
- 注意:HAL所谓的抽象不提供对硬件的实际操作,对硬件的操作仍然由具体的驱动程序来完成。
1.android为什么引入HAL
- 由于安卓是基于Linux内核进行开发,而linux内核使用GPL许可证,这就要求,使用到这个许可证的软件,对开源软件的任何修改扩充都必须开源,如果引入了HAL,就可以让android系统层和内核靠HAL隔离开,而HAL是遵循APL许可证,这个就不要求,使用了开源软件的修改必须开源的准则,所以能保证一些开发者的利益。
2.android中HAL运行结构
- RIL(Radio Interface Layer 无线通信接口层
- HAL Stub运行原理:上层调用底层,通过底层HAL提供的函数,而底层在处理完上层请求后或硬件状态发生变化的时候回调上层,而通过Runtime提供的callback接口完成。
- Hal Stub有一种包含关系,也就是HAL里包含了很多Stub,Runtime只要说明请求类型,就可以取得并操作Stub对应的operations方法,其实现都是在hardware.c和hardware.h中,实质是通过dlopen方法加载.so动态链接库,从而调用*.so里的符号实现。
二、深入解析通话流程
- AndoridTelephony主要包括四个方面的手机通信能力:
- ServiceState/SIM(网络服务,包好SIM)
1.点击拨号盘
- 原理:ActivityManagerService见启动com.android.dialer包下的DialtactsActivity将启动com.android.dialer包下的DialtactsActivity
@DialtactsActivity
.......
## 省略上面的代码
@Override
protected void onCreate(Bundle savedInstanceState) {
Trace.beginSection(TAG + " onCreate");
LogUtil.enterBlock("DialtactsActivity.onCreate");
super.onCreate(savedInstanceState);
firstLaunch = true;
isLastTabEnabled =
ConfigProviderComponent.get(this).getConfigProvider().getBoolean("last_tab_enabled", false);
........
# 根据layout中的你的id来注册这个按钮
FloatingActionButton floatingActionButton = findViewById(R.id.floating_action_button);
floatingActionButton.setOnClickListener(this);
floatingActionButtonController = new FloatingActionButtonController(this, floatingActionButton);
...........
# 查看DialtacksActivity类的onClick方法
private void showDialpadFragment(boolean animate) {
...........
final FragmentTransaction ft = getFragmentManager().beginTransaction();
if (dialpadFragment == null) {
dialpadFragment = new DialpadFragment();
ft.add(R.id.dialtacts_container, dialpadFragment, TAG_DIALPAD_FRAGMENT);
} else {
ft.show(dialpadFragment);
}
..........
setTitle(R.string.launcherDialpadActivityLabel);
}
@DialpadFragment
..........
@Override
public void onClick(View view) {
int resId = view.getId();
if (resId == R.id.dialpad_floating_action_button) {
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
handleDialButtonPressed();
} else if (resId == R.id.deleteButton) {
keyPressed(KeyEvent.KEYCODE_DEL);
} else if (resId == R.id.digits) {
if (!isDigitsEmpty()) {
digits.setCursorVisible(true);
}
} else if (resId == R.id.dialpad_overflow) {
overflowPopupMenu.show();
} else {
LogUtil.w("DialpadFragment.onClick", "Unexpected event from: " + view);
}
}
三、源码:
- 欢迎关注微信公众号:傅里叶变换,个人账号,仅用于技术交流