[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----------------------