[android-telephony]Android_Telephony(基于N&&O版本)模块介绍
来源:互联网 发布:mac windows 10 编辑:程序博客网 时间:2024/06/05 19:35
1.在启动系统一些服务的时候会执行一个startOtherServices的方法
frameworks/base/services/java/com/android/server/SystemServer.java
{
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,"StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
}catch (Throwable ex) {
Slog.e("System","******************************************");
Slog.e("System","************ Failure starting system services", ex);
throw ex;
}finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
2.在startOtherServices方法内会启动TelecomLoaderService
mSystemServiceManager.startService(TelecomLoaderService.class);
-------------------------------------------------------------------------------------------------------------------->
frameworks/base/services/core/java/com/android/server/telecom/TelecomLoaderService.java
/**
* Starts thetelecom component by binding to its ITelecomService implementation. Telecom is setup
* to run in the system-server process so once it is loaded into memory it will stay running.
*@hide
*/
public class TelecomLoaderServiceextends SystemService {
@Override
public void onBootPhase(int phase) {
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
registerDefaultAppNotifier();
registerCarrierConfigChangedReceiver();
connectToTelecom();
}
}
}
3.主要看connectToTelecom
private void connectToTelecom() {
synchronized (mLock) {
if (mServiceConnection !=null) {
//TODO: Is unbinding worth doing or wait for system to rebind?
mContext.unbindService(mServiceConnection);
mServiceConnection =null;
}
TelecomServiceConnection serviceConnection =new TelecomServiceConnection();
Intent intent =new Intent(SERVICE_ACTION);
intent.setComponent(SERVICE_COMPONENT);
int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE
| Context.BIND_AUTO_CREATE;
// Bind to Telecom and register the service
if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.SYSTEM)) {
mServiceConnection = serviceConnection;
}
}
}
4.而SERVICE_COMPONENT为
private static final ComponentNameSERVICE_COMPONENT =new ComponentName(
"com.android.server.telecom",
"com.android.server.telecom.components.TelecomService");
这样就绑定了TelecomService服务
5.
------------------------------------------------------------------->
packages/services/Telecomm/src/com/android/server/telecom/components/TelecomService.java
@Override
public IBinder onBind(Intent intent) {
Log.d(this,"onBind");
initializeTelecomSystem(this);
synchronized (getTelecomSystem().getLock()) {
return getTelecomSystem().getTelecomServiceImpl().getBinder();
}
}
在 initializeTelecomSystem里主要生成一个单例TelecomSystem
if (TelecomSystem.getInstance() == null) {
TelecomSystem.setInstance(
new TelecomSystem(。。。)...
------------------------------------------------------------------->
在TelecomSystem的构造方法内会生成TeleCom的很多实例类并保存到 TelecomServiceImpl类中
{
mPhoneAccountRegistrar =new PhoneAccountRegistrar(mContext);
BluetoothManager bluetoothManager =new BluetoothManager(mContext,
new BluetoothAdapterProxy());
WiredHeadsetManager wiredHeadsetManager =new WiredHeadsetManager(mContext);
mMissedCallNotifier = missedCallNotifierImplFactory
.makeMissedCallNotifierImpl(mContext,mPhoneAccountRegistrar);
DefaultDialerManagerAdapter defaultDialerAdapter =
new TelecomServiceImpl.DefaultDialerManagerAdapterImpl();
mCallsManager =new CallsManager(
….........
mTelecomServiceImpl =new TelecomServiceImpl(...
}
而在mTelecomServiceImpl类中有ITelecomService的实例
private final ITelecomService.StubmBinderImpl =new ItelecomService.Stub()
所以在 TelecomLoaderService绑定完TelecomService后 返回的是mBinderImpl
返回后会通过如下方法添加到系统服务类
ServiceManager.addService(Context.TELECOM_SERVICE, service);
所以上层可以通过mContext.getSystemService(Context.TELECOM_SERVICE)调用TelecomServiceImpl类调用相关接口
------------------------------------------------------------------->
packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java
在生成TelecomServiceImpl中的时候 有一个很重要的类建立new CallsManager
在CallsManager的构造方法内会保存很多监听器用来控制拨打电话和来电和CallLog等电话逻辑操作的监听器
{
mListeners.add(mInCallWakeLockController);
mListeners.add(statusBarNotifier);
mListeners.add(mCallLogManager);
mListeners.add(mPhoneStateBroadcaster);
mListeners.add(mInCallController);
mListeners.add(mCallAudioManager);
mListeners.add(missedCallNotifier);
mListeners.add(mHeadsetMediaButton);
mListeners.add(mProximitySensorManager);
}
{
private final Set<CallsManagerListener>mListeners = Collections.newSetFromMap(
new ConcurrentHashMap<CallsManagerListener, Boolean>(16, 0.9f, 1));
}
------------------------------------------------------------------->
packages/services/Telephony/src/com/android/phone/PhoneApp.java
前面讲完了如何启动TelecomService的流程 现在讲一下Telephony流程 在系统加载Telecom.apk的时候 会执行PhoneApp
/**
* Top-level Application class for the Phone app.
*/
public class PhoneAppextends Application {
PhoneGlobalsmPhoneGlobals;
TelephonyGlobalsmTelephonyGlobals;
@Override
public void onCreate() {
if (UserHandle.myUserId() == 0) {
// We are running as the primary user, so should bring up the
// global phone state.
mPhoneGlobals =new PhoneGlobals(this);
mPhoneGlobals.onCreate();
mTelephonyGlobals =new TelephonyGlobals(this);
mTelephonyGlobals.onCreate();//和PhoneAccountHandle账户管理有关
}
}
------------------------------------------------------------------->
这里主要讲下mPhoneGlobals.onCreate方法
frameworks/opt/telephony/src/java/com/android/internal/telephony/PhoneFactory.java
makeDefaultPhone
{
for (int i = 0; i < numPhones; i++) {
// reads the system properties and makes commandsinterface
// Get preferred network type.
//先获取配置的手机支持网络类型
networkModes[i] = RILConstants.PREFERRED_NETWORK_MODE;
//int PREFERRED_NETWORK_MODE = //SystemProperties.getInt("ro.telephony.default_network",
// NETWORK_MODE_WCDMA_PREF);
Rlog.i(LOG_TAG,"Network Mode set to " + Integer.toString(networkModes[i]));
sCommandsInterfaces[i] = new RIL(context, networkModes[i],
cdmaSubscription, i);
}
//初始化SubscriptionController
SubscriptionController.init(context,sCommandsInterfaces);
// Instantiate UiccController so that all other classes can just
// call getInstance()
//初始化SIM卡框架
sUiccController = UiccController.make(context, sCommandsInterfaces);
//生成Phone对象
for (int i = 0; i < numPhones; i++) {
Phone phone =null;
int phoneType = TelephonyManager.getPhoneType(networkModes[i]);
if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
phone =new GsmCdmaPhone(context,
sCommandsInterfaces[i],sPhoneNotifier, i,
PhoneConstants.PHONE_TYPE_GSM,
TelephonyComponentFactory.getInstance());
}else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
phone =new GsmCdmaPhone(context,
sCommandsInterfaces[i],sPhoneNotifier, i,
PhoneConstants.PHONE_TYPE_CDMA_LTE,
TelephonyComponentFactory.getInstance());
}
Rlog.i(LOG_TAG,"Creating Phone with type = " + phoneType +" sub = " + i);
sPhones[i] = phone;
}
{
在生成Phone对象的时候 会传入 TelephonyComponentFactory类而每个Phone对象初始化可以通过这个类的方法makeGsmCdmaCallTracker 建立GsmCdmaCallTracker和通过makeServiceStateTracker方法建立ServiceStateTracker和通过makeDcTracker方法建立DcTracker,这样Phone的通话相关的GsmCdmaCallTracker和电话服务状态ServiceStateTracker类 和数据连接的DcTracker三大类就在Phone对象初始化完成 具体类由于
篇幅关系 不在分析
}
//SubscriptionInfoUpdate通过注册通知监听更新SubScriptionController相关值
// IntentFilter intentFilter =new //IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
//intentFilter.addAction(IccCardProxy.ACTION_INTERNAL_SIM_STATE_CHANGED);
//intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
//mContext.registerReceiver(sReceiver, intentFilter);
//
sSubInfoRecordUpdater =new SubscriptionInfoUpdater(context,
sPhones,sCommandsInterfaces);
//在phone对象类完成Data模块的初始化后在设置其工厂类
sPhoneSwitcher =new PhoneSwitcher(MAX_ACTIVE_PHONES, numPhones,
sContext, sc, Looper.myLooper(), tr, sCommandsInterfaces,
sPhones);
sTelephonyNetworkFactories =new TelephonyNetworkFactory[numPhones];
for (int i = 0; i < numPhones; i++) {
sTelephonyNetworkFactories[i] = new TelephonyNetworkFactory(
sPhoneSwitcher, sc, sSubscriptionMonitor, Looper.myLooper(),
sContext, i, sPhones[i].mDcTracker);
}
}
------------------------------------------------------------------->
前面流程分解SubscriptionController.init
{
主要是把SubscriptionController保存到系统服务中 ServiceManager.addService("isub",this);
}
后面SubscriptionManager就可以通过如下方法调用SubscriptionController获取SIM卡相关信息
比如getActiveSubscriptionInfo
{
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
subInfo = iSub.getActiveSubscriptionInfo(subId,mContext.getOpPackageName());
}
}
Telephony其它类直接调用SubscriptionController设置相关属性 比如ServiceStateTracker直接
通过mSubscriptionController.setPlmnSpn
------------------------------------------------------------------->
frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/UiccController.java
1.UiccController.make--->首先生成一个 new UiccController类的实例
2.在UiccController::UiccController方法内
{
mCis[i].registerForIccStatusChanged(this,EVENT_ICC_STATUS_CHANGED
}
3.当icc_status_changed状态发生改变继续调用EVENT_GET_ICC_STATUS_DONE
switch (msg.what) {
case EVENT_ICC_STATUS_CHANGED:
if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE, index));
break;
case EVENT_GET_ICC_STATUS_DONE:
if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE");
onGetIccCardStatusDone(ar, index);
break;
4. onGetIccCardStatusDone
//如果是第一次状态上传就建立一个UiccCard类
if (mUiccCards[index] == null) {
//Create new card
mUiccCards[index] = new UiccCard(mContext,mCis[index], status, index);
}else {
//Update already existing card
mUiccCards[index].update(mContext,mCis[index] , status);
}
5.在UiccCard的构造方法内 还会调用一次update 会生成UiccCardApplication或者更新UiccCardApplication
if (mUiccApplications[i] == null) {
//Create newly added Applications
if (i < ics.mApplications.length) {
mUiccApplications[i] = new UiccCardApplication(this,
ics.mApplications[i],mContext,mCi);
}
}else {
//Update the rest
mUiccApplications[i].update(ics.mApplications[i],mContext,mCi);
}
--->接着调用createAndUpdateCatService(); 创建stk
6.在UiccCardApplication的构造方法和update方法内 都会按照条件调用如下逻辑
{
mIccFh = createIccFileHandler(as.app_type);//IccFileHandler
mIccRecords = createIccRecords(as.app_type,mContext,mCi);//mIccRecords
}
她们会更新SIM卡内的文件系统内容并获取他们的值 供上层使用 而且要通过他们去操作SIM卡内容读写
6.1相应的逻辑如下
private IccFileHandler createIccFileHandler(AppType type) {
switch (type) {
case APPTYPE_SIM:
return new SIMFileHandler(this,mAid,mCi);
case APPTYPE_RUIM:
return new RuimFileHandler(this,mAid,mCi);
case APPTYPE_USIM:
return new UsimFileHandler(this,mAid,mCi);
case APPTYPE_CSIM:
return new CsimFileHandler(this,mAid,mCi);
case APPTYPE_ISIM:
return new IsimFileHandler(this,mAid,mCi);
default:
return null;
}
}
private IccRecords createIccRecords(AppType type, Context c, CommandsInterface ci) {
if (type == AppType.APPTYPE_USIM || type == AppType.APPTYPE_SIM) {
return new SIMRecords(this, c, ci);
}else if (type == AppType.APPTYPE_RUIM || type == AppType.APPTYPE_CSIM){
return new RuimRecords(this, c, ci);
}else if (type == AppType.APPTYPE_ISIM) {
return new IsimUiccRecords(this, c, ci);
}else {
// Unknown app type (maybe detection is still in progress)
return null;
}
}
通过上面的简单介绍大家可以看出来SIM框见简单架构如下
*
* UiccController
* #
* |
* UiccCard
* # #
* | ------------------
* UiccCardApplication CatService
* # #
* | |
* IccRecords IccFileHandler
* ^ ^ ^ ^ ^ ^ ^ ^
* SIMRecords---- | | | | | | ---SIMFileHandler
* RuimRecords----- | | | | ----RuimFileHandler
* IsimUiccRecords--- | | -----UsimFileHandler
* |------CsimFileHandler
* ----IsimFileHandler
UICC简单介绍到这 逻辑的具体介绍比如类里面的逻辑 需要感兴趣的同学自己去学习总结
------------------------------------------------------------------->
总结:前面讲到了启动TelecomService,Telecom.
其中Telecom中makeDefaultPhone关键方法中对创建SubscriptionController,UiccController,Phone对象的建立进行了整体初步分析.希望大家对Telephony整体有自己的初步认识.
其中Phone相关的重要的流程逻辑类ServiceStateTracker,DcTracker,GsmCdmaCallTracker都是在Phone建立的时候通过TelephonyComponentFactory工厂类进行建立的,在这不具体详细介绍 请大家对这三个主干部分进行自学添加 其中DcTracker是属于Data模块部分后面会有同学具体介绍.
对如下一个流程进行简单介绍
第一个:拨号电话
整体的拨号流程涉及
Dialer--->frameworks.base.telecom--->package.service.telecom--->InCallUI--->package.service.telephony--->frameworks.opt.telephony
Dialer--->telecomService--->InCallUI--->telephony
整体流程是
UserCallActivity--->UserCallIntentProcessor.processIntent--->PrimaryCallReceiver
--->CallIntentProcessor.processIntent---->CallsManager.startOutgoingCall
--->CallsManager::addCall
--->InCallController::onCallAdded
{
1.绑定服务frameworks.base.telecom.InCallService
InCallUI.nCallServiceImplextends InCallService.onBind
{
//初始化值和启动界面
InCallPresenter.getInstance().maybeStartRevealAnimation(intent);//启动InCallUI界面
}
2.onConnected之后执行InCallService.setInCallAdapter
{
mPhone =new Phone
生成frameworks.base.telecom.Phone
mPhone.addListener(mPhoneListener) 设置监听器则以后所有的Telephony电话状态和相关信息都会通过
Telecomservice--->mPhone调用监听器回调 InCallService到InCallUI的InCallServiceImpl相应方法内
}
3.执行inCallService.addCall
{
mPhone.internalAddCall
//会传递ParcelableCall对象过来 在frameworks.base.telecomm在新建立frameworks.base.telecom.Call call = new Call
会调用到InCallUI的 InCallServiceImpl.onCallAdded--->InCallPresenter.onCallAdded最终生成DialerCall会通过传过来的TelecomCall通过registerCallback注册回调也就是说 InCallUI除了一部分状态和事件是通过InCallService传递过来之外 InCallUI的Call会直接通过TeleComCall的回调方法传过来的部分状态进行更新 具体大家打印LOG看吧 这里不具体说明.另外Call状态在service一种 frameworks.base.telecom里一种 InCallUI里一种这里不继续说明.
}
}
--->NewOutgoingCallIntentBroadcaster.processIntent---->NewOutgoingCallBroadcastIntentReceiver.onReceive
--->CallsManager.placeOutgoingCall--->Call.startCreateConnection--->CreateConnectionProcessor.process
--->CreateConnectionProcessor.createConnection--->ConnectionService.createConnectin
--->TelephonyConnectionService::onCreateOutgoingConnection
--->TelephonyConnectionService.placeOutgoingConnection
{
phone.dial
}
-->GsmCdmaPhone.Dial
-->IMS||RIl.dial
-------------------------------------------end----------------------
- [android-telephony]Android_Telephony(基于N&&O版本)模块介绍
- android telephony 模块.config
- android telephony 模块.config
- android telephony 模块Rules.make
- android telephony 模块makefile, .config , Rules.make
- android telephony 模块makefile, .config , Rules.make
- android telephony模块——serviceStateTracker
- android telephony
- Android Telephony
- Android--Telephony
- Android--Telephony
- Android:Telephony
- Android的RIL驱动模块 telephony启动流程
- Android的RIL驱动模块telephony启动流程
- telephony-1(ril模块)
- andorid Telephony 整体介绍
- andorid Telephony 整体介绍
- android-O RescueParty 介绍
- GNU Make 自动生成依存(依赖)关系的完善解决方案
- I
- java Scanner出现 java.util.NoSuchElementException
- C/C++ 中的0长数组(柔性数组)
- [详细分析]实现一个8bit数据(unsigned char)的指定位的置0或者置1操作,并保持其他位不变
- [android-telephony]Android_Telephony(基于N&&O版本)模块介绍
- 计算文件词频
- HDU1434 幸福列车【模拟+优先队列】
- 全站统一字符编码的几种方式
- 关于按值传递和按地址传递
- 其他类
- spring笔记--从零搭建一个简单的HelloWorld程序
- Spring boot学习之spring-data-jpa的使用(一)
- WM_DEVICECHANGE