您的位置:首页 > 移动开发 > Android开发

[android-telephony]Android_Telephony(基于N&&O版本)模块介绍

2017-07-25 20:44 411 查看
1.在启动系统一些服务的时候会执行一个startOtherServices的方法
[b]frameworks/base/services/java/com/android/server/SystemServer.java[/b]
{
[b]    try[/b] {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,"StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
        }[b]catch[/b] (Throwable
ex) {
            Slog.e("System","******************************************");
            Slog.e("System","************
Failure starting system services", ex);
            [b]throw[/b] ex;
        }[b]finally[/b] {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
  
}
2.在startOtherServices方法内会启动TelecomLoaderService
mSystemServiceManager.startService(TelecomLoaderService.[b]class[/b]);
 
[b]-------------------------------------------------------------------------------------------------------------------->[/b]
[b]frameworks/base/services/core/java/com/android/server/telecom/TelecomLoaderService.java[/b]
/**
 * Starts the[u]telecom[/u] component
by binding to its ITelecomService implementation. [u]Telecom[/u] is
setup
 * to run in the system-server
process so once it is loaded into memory it will stay running.
 *[b]@hide[/b]
 */
[b]public[/b] [b]class[/b] TelecomLoaderService[b]extends[/b] SystemService
{
   @Override
    [b]public[/b] [b]void[/b] onBootPhase([b]int[/b] phase)
{
        [b]if[/b] (phase
== PHASE_ACTIVITY_MANAGER_READY) {
            registerDefaultAppNotifier();
            registerCarrierConfigChangedReceiver();
            connectToTelecom();
        }
    }
}
3.主要看connectToTelecom
[b]private[/b] [b]void[/b] connectToTelecom()
{
        [b]synchronized[/b] (mLock)
{
            [b]if[/b] (mServiceConnection !=[b]null[/b])
{
                //[b]TODO[/b]:
Is [u]unbinding[/u] worth doing or wait
for system to [u]rebind[/u]?
                mContext.unbindService(mServiceConnection);
                mServiceConnection =[b]null[/b];
            }
 
   TelecomServiceConnection serviceConnection =[b]new[/b] TelecomServiceConnection();
            Intent intent =[b]new[/b] Intent(SERVICE_ACTION);
            intent.setComponent(SERVICE_COMPONENT);
            [b]int[/b] flags
= Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE
                    | Context.BIND_AUTO_CREATE;
 
            //
Bind to [u]Telecom[/u] and register the
service
            [b]if[/b] (mContext.bindServiceAsUser(intent,
serviceConnection, flags, UserHandle.SYSTEM)) {
                mServiceConnection =
serviceConnection;
            }
        }
    }
4.而SERVICE_COMPONENT为
 [b]private[/b] [b]static[/b] [b]final[/b] ComponentNameSERVICE_COMPONENT =[b]new[/b] ComponentName(
            "com.android.server.telecom",
            "com.android.server.telecom.components.TelecomService");
这样就绑定了TelecomService服务
5.
[b]------------------------------------------------------------------->[/b]
[b]packages/services/Telecomm/src/com/android/server/telecom/components/TelecomService.java[/b]
[b]    @Override[/b]
    [b]public[/b] IBinder
onBind(Intent intent) {
        Log.d([b]this[/b],"onBind");
        initializeTelecomSystem([b]this[/b]);
        [b]synchronized[/b] (getTelecomSystem().getLock())
{
            [b]return[/b] getTelecomSystem().getTelecomServiceImpl().getBinder();
        }
    }
在 initializeTelecomSystem里主要生成一个单例TelecomSystem
[b]if[/b] (TelecomSystem.getInstance()
== [b]null[/b]) {
            TelecomSystem.setInstance(
                    [b]new[/b] TelecomSystem(。。。)...
[b]------------------------------------------------------------------->[/b]
在TelecomSystem的构造方法内会生成TeleCom的很多实例类并保存到 TelecomServiceImpl类中
{
 mPhoneAccountRegistrar =[b]new[/b] PhoneAccountRegistrar(mContext);
 BluetoothManager bluetoothManager =[b]new[/b] BluetoothManager(mContext,
                [b]new[/b] BluetoothAdapterProxy());
  WiredHeadsetManager wiredHeadsetManager =[b]new[/b]  WiredHeadsetManager(mContext);
mMissedCallNotifier =
missedCallNotifierImplFactory
                .makeMissedCallNotifierImpl(mContext,mPhoneAccountRegistrar);
 
        DefaultDialerManagerAdapter defaultDialerAdapter =
                [b]new[/b] TelecomServiceImpl.DefaultDialerManagerAdapterImpl();
 
        mCallsManager =[b]new[/b] CallsManager(
….........
mTelecomServiceImpl =[b]new[/b] TelecomServiceImpl(...
}
而在mTelecomServiceImpl类中有ITelecomService的实例
[b]private[/b] [b]final[/b] ITelecomService.StubmBinderImpl =[b]new[/b] ItelecomService.Stub()
 
所以在 TelecomLoaderService绑定完TelecomService后 返回的是mBinderImpl
返回后会通过如下方法添加到系统服务类
ServiceManager.addService(Context.TELECOM_SERVICE,
service);
 
所以上层可以通过mContext.getSystemService(Context.TELECOM_SERVICE)调用TelecomServiceImpl类调用相关接口
[b]------------------------------------------------------------------->[/b]
[b]packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java[/b]
在生成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);
}
{
 [b]private[/b] [b]final[/b] Set<CallsManagerListener>mListeners =
Collections.newSetFromMap(
            [b]new[/b] ConcurrentHashMap<CallsManagerListener,
Boolean>(16, 0.9f, 1));
}
 
 
[b]------------------------------------------------------------------->[/b]
[b]packages/services/Telephony/src/com/android/phone/PhoneApp.java[/b]
[b]前面讲完了如何启动TelecomService的流程 现在讲一下Telephony流程 在系统加载Telecom.apk的时候 会执行PhoneApp[/b]
[b] [/b]
[b]/**[/b]
 * Top-level
Application class for the Phone [u]app[/u].
 */
[b]public[/b] [b]class[/b] PhoneApp[b]extends[/b] Application
{
    PhoneGlobalsmPhoneGlobals;
    TelephonyGlobalsmTelephonyGlobals;
 
[b]@Override[/b]
    [b]public[/b] [b]void[/b] onCreate()
{
        [b]if[/b] (UserHandle.myUserId()
== 0) {
            //
We are running as the primary user, so should bring up the
            //
global phone state.
            mPhoneGlobals =[b]new[/b] PhoneGlobals([b]this[/b]);
            mPhoneGlobals.onCreate();
 
            mTelephonyGlobals =[b]new[/b] TelephonyGlobals([b]this[/b]);
            mTelephonyGlobals.onCreate();//和PhoneAccountHandle账户管理有关
        }
    }
 
[b]------------------------------------------------------------------->[/b]
这里主要讲下mPhoneGlobals.onCreate方法
frameworks/opt/telephony/src/java/com/android/internal/telephony/PhoneFactory.java
makeDefaultPhone
{
[b]     for[/b] ([b]int[/b] i
= 0; i < numPhones; i++) {
         //
reads the system properties and makes [u]commandsinterface[/u]
         //
Get preferred network type.
         //先获取配置的手机支持网络类型
         networkModes[i] = RILConstants.PREFERRED_NETWORK_MODE;
 //[b]int[/b] 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]
= [b]new[/b] RIL(context,
networkModes[i],
                            cdmaSubscription, i);
                }
[b]//初始化SubscriptionController[/b]
SubscriptionController.init(context,sCommandsInterfaces);
 
// Instantiate UiccController so that all other classes can just
// call getInstance()
[b]//初始化SIM卡框架[/b]
sUiccController =
UiccController.make(context, sCommandsInterfaces);
[b]//生成Phone对象[/b]
[b]  for[/b] ([b]int[/b] i
= 0; i < numPhones; i++) {
          Phone phone =[b]null[/b];
  [b]int[/b] phoneType
= TelephonyManager.getPhoneType(networkModes[i]);
                    [b]if[/b] (phoneType
== PhoneConstants.PHONE_TYPE_GSM) {
                        phone =[b]new[/b] GsmCdmaPhone(context,
                                sCommandsInterfaces[i],sPhoneNotifier,
i,
                                PhoneConstants.PHONE_TYPE_GSM,
                                TelephonyComponentFactory.getInstance());
                    }[b]else[/b] [b]if[/b] (phoneType
== PhoneConstants.PHONE_TYPE_CDMA) {
                        phone =[b]new[/b] 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 =[b]new[/b] //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 =[b]new[/b] SubscriptionInfoUpdater(context,
                        sPhones,sCommandsInterfaces);
 
[b]//在phone对象类完成Data模块的初始化后在设置其工厂类[/b]
sPhoneSwitcher =[b]new[/b] PhoneSwitcher(MAX_ACTIVE_PHONES,
numPhones,
                        sContext,
sc, Looper.myLooper(), tr, sCommandsInterfaces,
                        sPhones);
sTelephonyNetworkFactories =[b]new[/b] TelephonyNetworkFactory[numPhones];
                [b]for[/b] ([b]int[/b] i
= 0; i < numPhones; i++) {
                    sTelephonyNetworkFactories[i]
= [b]new[/b] TelephonyNetworkFactory(
                            sPhoneSwitcher,
sc, sSubscriptionMonitor, Looper.myLooper(),
                            sContext,
i, sPhones[i].mDcTracker);
                }
}
 
[b]------------------------------------------------------------------->[/b]
[b]前面流程分解SubscriptionController.init[/b]
{
主要是把SubscriptionController保存到系统服务中 ServiceManager.[u]addService[/u]("isub",[b]this[/b]);
}
后面SubscriptionManager就可以通过如下方法调用SubscriptionController获取SIM卡相关信息
比如getActiveSubscriptionInfo
{
    ISub iSub
= ISub.Stub.asInterface(ServiceManager.getService("isub"));
    [b]if[/b] (iSub
!= [b]null[/b]) {
     subInfo = iSub.getActiveSubscriptionInfo(subId,mContext.getOpPackageName());
     }
}
 
Telephony其它类直接调用SubscriptionController设置相关属性 比如ServiceStateTracker直接
通过mSubscriptionController.setPlmnSpn
[b]------------------------------------------------------------------->[/b]
[b]frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/UiccController.java[/b]
[b]1.UiccController.make--->首先生成一个[/b] [b]new[/b] UiccController[b]类的实例[/b]
[b]2.在UiccController::UiccController方法内[/b]
[b]{[/b]
[b]mCis[i].registerForIccStatusChanged(this,EVENT_ICC_STATUS_CHANGED[/b]
[b]}[/b]
[b]3.当icc_status_changed状态发生改变继续调用EVENT_GET_ICC_STATUS_DONE[/b]
[b]switch (msg.what)
{
[/b]
                [b]case[/b] EVENT_ICC_STATUS_CHANGED:
                    [b]if[/b] (DBG)
log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
                    mCis[index].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE,
index));
                    [b]break[/b];
                [b]case[/b] EVENT_GET_ICC_STATUS_DONE:
                    [b]if[/b] (DBG)
log("Received EVENT_GET_ICC_STATUS_DONE");
                    onGetIccCardStatusDone(ar, index);
                    [b]break[/b];
[b] [/b]
[b] [/b]
[b] [/b]
[b] [/b]
4. [b]onGetIccCardStatusDone[/b]
[b]//如果是第一次状态上传就建立一个UiccCard类[/b]
[b]        if (mUiccCards[index]
==
null) {[/b]
            //Create
new card
            mUiccCards[index]
= [b]new[/b] UiccCard(mContext,mCis[index],
status, index);
        }[b]else[/b] {
            //Update
already existing card
            mUiccCards[index].update(mContext,mCis[index]
, status);
        }
[b] [/b]
[b]5.在UiccCard的构造方法内 还会调用一次update 会生成UiccCardApplication或者更新UiccCardApplication[/b]
[b]     if (mUiccApplications[i]
==
null) {[/b]
                    //Create
newly added Applications
                    [b]if[/b] (i
< ics.mApplications.length)
{
                        mUiccApplications[i]
= [b]new[/b] UiccCardApplication([b]this[/b],
                                ics.mApplications[i],mContext,mCi);
                    }
                }[b]else[/b] {
                    //Update
the rest
                    mUiccApplications[i].update(ics.mApplications[i],mContext,mCi);
                }
[b] --->接着调用[/b]createAndUpdateCatService();[b] 创建stk[/b]
 
[b]6.在UiccCardApplication的构造方法和update方法内 都会按照条件调用如下逻辑[/b]
[b]{[/b]
[b]        mIccFh =
createIccFileHandler(as.
app_type);//IccFileHandler[/b]
        mIccRecords =
createIccRecords(as.app_type,mContext,mCi);[b]//mIccRecords[/b]
[b]}[/b]
[b]她们会更新SIM卡内的文件系统内容并获取他们的值 供上层使用 而且要通过他们去操作SIM卡内容读写[/b]
[b]  6.1相应的逻辑如下[/b]
[b]     private IccFileHandler
createIccFileHandler(AppType type) {
[/b]
        [b]switch[/b] (type)
{
            [b]case[/b] APPTYPE_SIM:
                [b]return[/b] [b]new[/b] SIMFileHandler([b]this[/b],mAid,mCi);
            [b]case[/b] APPTYPE_RUIM:
                [b]return[/b] [b]new[/b] RuimFileHandler([b]this[/b],mAid,mCi);
            [b]case[/b] APPTYPE_USIM:
                [b]return[/b] [b]new[/b] UsimFileHandler([b]this[/b],mAid,mCi);
            [b]case[/b] APPTYPE_CSIM:
                [b]return[/b] [b]new[/b] CsimFileHandler([b]this[/b],mAid,mCi);
            [b]case[/b] APPTYPE_ISIM:
                [b]return[/b] [b]new[/b] IsimFileHandler([b]this[/b],mAid,mCi);
            [b]default[/b]:
                [b]return[/b] [b]null[/b];
        }
       }
 
  [b]private[/b] IccRecords
createIccRecords(AppType type, Context c, CommandsInterface ci) {
        [b]if[/b] (type
== AppType.APPTYPE_USIM || type == AppType.APPTYPE_SIM)
{
            [b]return[/b] [b]new[/b] SIMRecords([b]this[/b],
c, ci);
        }[b]else[/b] [b]if[/b] (type
== AppType.APPTYPE_RUIM || type == AppType.APPTYPE_CSIM){
            [b]return[/b] [b]new[/b] RuimRecords([b]this[/b],
c, ci);
        }[b]else[/b] [b]if[/b] (type
== AppType.APPTYPE_ISIM) {
            [b]return[/b] [b]new[/b] IsimUiccRecords([b]this[/b],
c, ci);
        }[b]else[/b] {
            //
Unknown [u]app[/u] type (maybe detection
is still in progress)
            [b]return[/b] [b]null[/b];
        }
    }
 
 
 
[b]通过上面的简单介绍大家可以看出来SIM框见简单架构如下[/b]
 
[b] *[/b]
 *                       UiccController
 *                            #
 *                            |
 *                        UiccCard
 *                          #   #
 *                          |   ------------------
 *                    UiccCardApplication    CatService
 *                      #            #
 *                      |            |
 *                 IccRecords    IccFileHandler
 *                 ^ ^ ^           ^ ^ ^ ^ ^
 *          SIMRecords---- |
|           | | | | ---SIMFileHandler
 *          RuimRecords----- |
          | | | ----RuimFileHandler
 *          IsimUiccRecords---           |
| -----UsimFileHandler
 *                                |------CsimFileHandler
 *                                 ----IsimFileHandler
 
[b]UICC简单介绍到这  逻辑的具体介绍比如类里面的逻辑 需要感兴趣的同学自己去学习总结[/b]
 
 
[b]------------------------------------------------------------------->[/b]
 
[b]总结:前面讲到了启动TelecomService,Telecom.[/b]
[b]其中Telecom中makeDefaultPhone关键方法中对创建SubscriptionController,UiccController,Phone对象的建立进行了整体初步分析.希望大家对Telephony整体有自己的初步认识.[/b]
[b]其中Phone相关的重要的流程逻辑类ServiceStateTracker,DcTracker,GsmCdmaCallTracker都是在Phone建立的时候通过TelephonyComponentFactory工厂类进行建立的,在这不具体详细介绍
请大家对这三个主干部分进行自学添加 其中DcTracker是属于Data模块部分后面会有同学具体介绍.
[/b]

[b]对如下一个流程进行简单介绍[/b]
 
[b]第一个:拨号电话[/b]
 
 
[b]整体的拨号流程涉及[/b]
[b]Dialer--->frameworks.base.telecom--->package.service.telecom--->InCallUI--->package.service.telephony--->frameworks.opt.telephony[/b]
 
[b]Dialer--->telecomService--->InCallUI--->telephony[/b]
 
[b]整体流程是[/b]
[b]UserCallActivity--->UserCallIntentProcessor.processIntent--->PrimaryCallReceiver[/b]
[b]--->CallIntentProcessor.processIntent---->CallsManager.startOutgoingCall[/b]
[b]--->CallsManager::addCall[/b]
 
[b]--->InCallController::onCallAdded[/b]
[b]{[/b]
[b]1.绑定服务frameworks.base.telecom.InCallService[/b]
[b]  InCallUI.nCallServiceImplextends InCallService.onBind[/b]
[b]  {  [/b]
[b]     //初始化值和启动界面[/b]
[b]     InCallPresenter.getInstance().maybeStartRevealAnimation(intent);//启动InCallUI界面[/b]
[b]  }[/b]
[b]2.onConnected之后执行InCallService.setInCallAdapter[/b]
[b] {[/b]
[b]   mPhone =new Phone[/b]
   生成frameworks.base.telecom.Phone
[b]   mPhone.[u]addListener([/u]mPhoneListener) 设置监听器则以后所有的Telephony电话状态和相关信息都会通过[/b]
[b]   Telecomservice--->mPhone调用监听器回调 InCallService到InCallUI的InCallServiceImpl相应方法内[/b]
[b] }[/b]
[b]3.执行inCallService.addCall[/b]
[b] {[/b]
[b]   mPhone.internalAddCall[/b]
[b]   //会传递[u]ParcelableCall对象过来
在frameworks.base.telecomm在新建立frameworks.base.telecom.Call call =
[/u]new Call[/b]
    会调用到InCallUI的
InCallServiceImpl.onCallAdded--->InCallPresenter.onCallAdded最终生成DialerCall会通过传过来的TelecomCall通过
registerCallback注册回调也就是说
InCallUI除了一部分状态和事件是通过InCallService传递过来之外 InCallUI的Call会直接通过TeleComCall的回调方法传过来的部分状态进行更新 具体大家打印LOG看吧 这里不具体说明.另外Call状态在service一种 frameworks.base.telecom里一种 InCallUI里一种这里不继续说明.

[b] }[/b]
[b]}[/b]
 
[b]--->NewOutgoingCallIntentBroadcaster.processIntent---->NewOutgoingCallBroadcastIntentReceiver.onReceive[/b]
[b]--->CallsManager.placeOutgoingCall--->Call.startCreateConnection--->CreateConnectionProcessor.process[/b]
[b]--->CreateConnectionProcessor.createConnection--->ConnectionService.createConnectin[/b]
[b]--->TelephonyConnectionService::onCreateOutgoingConnection[/b]
[b]--->TelephonyConnectionService.placeOutgoingConnection[/b]
[b]{[/b]
[b]phone.dial[/b]
[b]}[/b]
[b]-->GsmCdmaPhone.Dial[/b]
[b]-->IMS||RIl.dial[/b]
[b]-------------------------------------------end----------------------[/b]
 
 
 
 
 
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  androido androidn te