拷贝与网络,感谢作者 xwj@rock-chips.com:
App应用程序
Frameworks中间层
Hardware 硬件抽象层
Kernel驱动层
程序流程
PhoneApp首先启动
设置打印级别static final int DBG_LEVEL = 2;
phoneApp.create----->
PhoneFactory.makeDefaultPhones(this);//初始化phone frameworks层
phone = PhoneFactory.getDefaultPhone();//得到的是PhoneProxy 对象
NotificationMgr.init(this); //状态栏等信息的管理初始化
phoneMgr = new PhoneInterfaceManager(this, phone); //是一个phone的应用层服务,ITelephony.Stub的实现。
int phoneType = phone.getPhoneType(); //获取电话类型
ringer = new Ringer(phone); //响铃初始化
同时还注册一些事件监听和phone状态的初始化判断(有可能开机就有来电)
应用层框架
PhoneApp是应用层的主体,他维护了以个phone的实例。其他类通过PhoneApp的getInstance得到PhoneApp的实例。其他类中维护的phone的实例是通过PhoneApp来引用的。如:setPhone(app.phone);
Phone应用层中的中其他的类的关系:
PhoneUtils.java 主要是一些静态方法供其他类来共享。比如拨打、挂断电话等
InCallScreen.java 是来电和拨出电话的主界面。
PhoneInterfaceManager.java是一个java层的服务进程,一些后台服务可以获取到该服务,该服务调用的方法也是PhoneUtils.java 中的方法。
CallNotifier.java主要是消息的通知处理。
Ringer.java是来电处理类。
Frameworks层
Phone类之间的关系
public interface Phone
public class PhoneProxy extends Handler implements Phone {};
public abstract class PhoneBase extends Handler implements Phone {}
public class GSMPhone extends PhoneBase {}
下面这段代码根据网络类型来建立一个phone实例:同时与RIL.JAVA建立连接
int phoneType = getPhoneType(networkMode);
if (phoneType == Phone.PHONE_TYPE_GSM) {
sProxyPhone = new PhoneProxy(new GSMPhone(context,
sCommandsInterface, sPhoneNotifier));
if(DBG)Log.d(LOG_TAG, "Creating GSMPhone");
} else if (phoneType == Phone.PHONE_TYPE_CDMA)
sProxyPhone = new PhoneProxy(new CDMAPhone(context,
sCommandsInterface, sPhoneNotifier));
上层得到的是一个phoneproxy的对象, phoneproxy根据phonetype来决定调用哪个实例的方法。如:
mActivePhone.acceptVideoCall();
GSMPhone初始化对象
mCM.setPhoneType(Phone.PHONE_TYPE_GSM);
mCT = new GsmCallTracker(this);
mSST = new GsmServiceStateTracker (this);
mSMS = new GsmSMSDispatcher(this);
mIccFileHandler = new SIMFileHandler(this);
mSIMRecords = new SIMRecords(this);
mDataConnection = new GsmDataConnectionTracker (this);
mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); mSIMRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
CommandsInterface 继承关系
public interface CommandsInterface {}
public abstract class BaseCommands implements CommandsInterface{};
BaseCommands 有很多注册事件监听的方法。如:
public void registerForCallStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mCallStateRegistrants.add(r);
}
mCallStateRegistrants是一个数组可以接受多个注册,到callstate发生变化时所有注册了接收该消息的handler都会收到。
public final class RIL extends BaseCommands implements CommandsInterface {};
RIL.JAVA
RIL类主要是用来与hardware层进行交互的。主要是用来发送AT命令和处理响应。
响应有两种,一是我们发送AT命令后的返回,另外是主动上报,比如网络变化、来电、短信等。
有些响应到来的时候会发出通知,使得注册到ril中的handler能够收到。如:
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
if (RILJ_LOGD) unsljLog(response);
mCallStateRegistrants
.notifyRegistrants(new AsyncResult(null, null, null));
Hardware层
Hardware层主要分三块:
rild.c 系统开机会启动是一个守护进程,系统启动的时候会加载reference-ril.c编译生成的库。
reference-ril.c主要是用来和modem交互的。
Ril.cpp主要是用来和frameworks层进行交互的。ril_commands.h定义了request的处理函数。ril_unsol_commands.h定义的主动上报的处理函数。
当我们添加一个请求类型和上报类型的时候需要在ril.h、ril_unsol_commands.h和ril_commands.h中添加相应的函数和定义。
视频电话进度
参考incallscreen.java设计一个视频电话界面---inVideocallscreen.java
在PhoneUtils.java中添加相应接口。
在frameworks层中添加对来电类型的判断。用来启动相应的界面。
电话拨打流程:
TwelveKeyDialer---->OutgoingCallBroadcaster.onCreate----->OutgoingCallReceiver.doReceive
----->InCallScreen.onCreate----->InCallScreen.internalResolveIntent(getIntent()----->InCallScreen.placeCall
-------->PhoneUtils.placeVideoCall(mPhone, number, contactUri)---------> phone.videoDial(number)
-------->GsmCallTracker.videoDial(newDialString)--------->ril.videoDial---->reference-ril.onrequest