telephony

相关代码

frameworks/base/telephony --- telephony framework
frameworks/base/telecomm --- telecomm framework 没有详细看
package/services/telephony --- teleService.apk
package/services/Telecomm --- telepcomm.apk 没有详细看
frameworks/opt/telephony --- telephony-common

telephony,第1张
Telephony流程.png

TELEPHONY_SERVICE

系统启动后,由systemserver.java的main方法开始:

systemserver.java
main() -> run() -> startBootstrapServices(其中启动AMS)
->startotherServices -> AMS. systemReady 中调用startPersistentApps去启动phone应用:

phoneapp-> 
phoneglobals->onCreat() -> 
PhoneInterfaceManager.init(this) -> public() ->
TelephonyFrameworkInitializer
                .getTelephonyServiceManager()
                .getTelephonyServiceRegisterer()
                .register(this);
//看下具体的实现
public ServiceRegisterer getTelephonyServiceRegisterer() {
        return new ServiceRegisterer(Context.TELEPHONY_SERVICE);
 }

如上,在启动phone过程中通过register操作,将PhoneInterfaceManager注册成为真正的Context.TELEPHONY_SERVICE的service端。
一个细节问题,上述的getTelephonyServiceManager是在什么时候赋值的?通过搜索setTelephonyServiceManager方法,发现是在ActivityThread中的main方法中:

调用initializeMainlineModules() ->
TelephonyFrameworkInitializer.setTelephonyServiceManager(new TelephonyServiceManager());

TelephonyServiceManager是用于管理和telephony相关的各种service,主要是确保telephony相关的各种service能够注册成功。

SystemServiceRegistry

SystemServiceRegistry用于在APP端缓存各种系统服务,方便调用系统服务。其static方法如下:

       static {   
            //......
           JobSchedulerFrameworkInitializer.registerServiceWrappers();
           BlobStoreManagerFrameworkInitializer.initialize();
           TelephonyFrameworkInitializer.registerServiceWrappers();
           WifiFrameworkInitializer.registerServiceWrappers();
           StatsFrameworkInitializer.registerServiceWrappers();
           //......
       } 


   // TelephonyFrameworkInitializer 的 registerServiceWrappers方法具体实现:
   /**
    * Called by {@link SystemServiceRegistry}'s static initializer and registers all telephony
    * services to {@link Context}, so that {@link Context#getSystemService} can return them.
    *
    * @throws IllegalStateException if this is called from anywhere besides
    * {@link SystemServiceRegistry}
    */
   public static void registerServiceWrappers() {
       SystemServiceRegistry.registerContextAwareService(
               Context.TELEPHONY_SERVICE,
               TelephonyManager.class,
               context -> new TelephonyManager(context)
       );
       SystemServiceRegistry.registerContextAwareService(
               Context.TELEPHONY_SUBSCRIPTION_SERVICE,
               SubscriptionManager.class,
               context -> new SubscriptionManager(context)
       );
       SystemServiceRegistry.registerContextAwareService(
               Context.CARRIER_CONFIG_SERVICE,
               CarrierConfigManager.class,
               context -> new CarrierConfigManager(context)
       );
       SystemServiceRegistry.registerContextAwareService(
               Context.EUICC_SERVICE,
               EuiccManager.class,
               context -> new EuiccManager(context)
       );
       SystemServiceRegistry.registerContextAwareService(
               Context.EUICC_CARD_SERVICE,
               EuiccCardManager.class,
               context -> new EuiccCardManager(context)
       );
       SystemServiceRegistry.registerContextAwareService(
               Context.TELEPHONY_IMS_SERVICE,
               ImsManager.class,
               context -> new ImsManager(context)
       );
   }

那么SystemServiceRegistry的调用是在什么时候呢?

    //ConextImpl.java
    final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();

当ConextImpl对象创建时,其属性就会创建,由于上述所说,SystemServiceRegistry有static代码块,因此该代码块会在第一次使用时就会加载。即在ConextImpl对象创建好之前,相关的服务就已经在其中注册了。

Telcommservice

systemserver.java
main() -> run() -> startBootstrapServices(其中启动AMS)
->startotherServices -> 去StartTelecomLoaderService

            t.traceBegin("StartTelecomLoaderService");
            mSystemServiceManager.startService(TelecomLoaderService.class);
            t.traceEnd();

后面当完成开机后,在AMS的finishBooting中去执行
// Let system services know.
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_BOOT_COMPLETED);
这个方法中回去回调service.onBootPhase(mCurrentPhase)。
继续查看TelecomLoaderService的onBootPhase实现:

    @Override
    public void onBootPhase(int phase) {
        if (phase == PHASE_ACTIVITY_MANAGER_READY) {
            registerDefaultAppNotifier();
            registerCarrierConfigChangedReceiver();
            // core services will have already been loaded.
            setupServiceRepository();
            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;
            }
        }
    }
    private static final ComponentName SERVICE_COMPONENT = new ComponentName(
            "com.android.server.telecom",
            "com.android.server.telecom.components.TelecomService");

    private static final String SERVICE_ACTION = "com.android.ITelecomService";

可以看到TelecomLoaderService去bind了TelecomService,TelecomService做为TelecomLoaderService的服务端,实现了ITelecomLoader.Stub:

public class TelecomService extends Service implements TelecomSystem.Component {

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(this, "onBind");
        //Task9999555-zhengpinhuang@tcl.com-Mobile data off-begin
        TelecomGlobals.createInstance(getApplicationContext());
        CarrierConfigManagerEx.init(getApplicationContext());
        //Task9999555-zhengpinhuang@tcl.com-Mobile data off-end
        return new ITelecomLoader.Stub() {
            @Override
            public ITelecomService createTelecomService(IInternalServiceRetriever retriever) {
                InternalServiceRetrieverAdapter adapter =
                        new InternalServiceRetrieverAdapter(retriever);
                initializeTelecomSystem(TelecomService.this, adapter);
                synchronized (getTelecomSystem().getLock()) {
                    return getTelecomSystem().getTelecomServiceImpl().getBinder();
                }
            }
        };
    }
}

接下去看下,TelecomLoaderService在ServiceConnected成功后做了什么?

    private class TelecomServiceConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // Normally, we would listen for death here, but since telecom runs in the same process
            // as this loader (process="system") that's redundant here.
            try {
                ITelecomLoader telecomLoader = ITelecomLoader.Stub.asInterface(service);
                ITelecomService telecomService = telecomLoader.createTelecomService(mServiceRepo);

                SmsApplication.getDefaultMmsApplication(mContext, false);
                ServiceManager.addService(Context.TELECOM_SERVICE, telecomService.asBinder());

                //......省略部分实现
               
            } catch (RemoteException e) {
                Slog.w(TAG, "Failed linking to death.");
            }
        }

可以看到在拿到service后,第一时间就是调用createTelecomService,真正的实现是在TelecomLoaderService的service端,就是上面提到的实现了ITelecomLoader.Stub的地方。

        return new ITelecomLoader.Stub() {
            @Override
            public ITelecomService createTelecomService(IInternalServiceRetriever retriever) {
                InternalServiceRetrieverAdapter adapter =
                        new InternalServiceRetrieverAdapter(retriever);
                initializeTelecomSystem(TelecomService.this, adapter);
                synchronized (getTelecomSystem().getLock()) {
                    return getTelecomSystem().getTelecomServiceImpl().getBinder();
                }
            }
        };

getTelecomServiceImpl的实现可以看到:

    public TelecomServiceImpl getTelecomServiceImpl() {
        return mTelecomServiceImpl;
    }

mTelecomServiceImpl是在TelecomSystem的构造方法里面new的。再看下getBinder的实现:

    public ITelecomService.Stub getBinder() {
        return mBinderImpl;
    }
    private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
        @Override
        public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme,
                String callingPackage, String callingFeatureId) {
}

可以看到这里是真正telecomservice的实现端,是一个匿名内部类。再一步步往回走,在拿到真正的telecomservice后,通过ServiceManager.addService将其加入到ServiceManager中。

方法总结

上面总结了很多系统service的启动和注册流程,那么对于这些系统的service,如何在看源码的时候快速定位到具体service的实现呢?在已经知道答案的情况下,我个人大致反推了一下,方便后续查看其它系统service时能够快速定位。
1、假设现在要Context.TELECOM_SERVICE的具体实现,从代码可以知道这个service对应的标识是:

    public static final String TELECOM_SERVICE = "telecom";

2、adb shell service list|grep -rin telecom 结果如下:

telecom: [com.android.internal.telecom.ITelecomService]
看到对应的aidl接口是ITelecomService.aidl

3、代码全局搜索"extends ITelecomService.stub" ,如果没有再搜索 "new ITelecomService.stub" ,因为有部分service端是匿名的类,telcom service就是这样的。

完成上面3步,这些系统service的真正实现的地方基本就定位到了。

参考内容

如何实现服务器端调用应用端的例子。
https://cloud.tencent.com/developer/article/1600478
解析telephonymanager和telecom的文章,里面的很多时序图很好。
https://blog.csdn.net/jason_wzn/article/details/58164251
https://blog.csdn.net/ZhongGuoRenMei/article/details/97037870

本文经用户投稿或网站收集转载,如有侵权请联系本站。

发表评论

0条回复

    作者信息

    标签TAG

    相关文章