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