安卓在5.0之后在TeleService和IncallUI之间多加了一层TeleComm,个人感觉是不想让IncallUI和Phone进程联系过于紧密,也便于其他通话方式的添加(不仅仅局限于通过电信运营商拨打传统电话),好了话不多说,开始分析,本文基于安卓7.1分析.
1.首先SystemServer在startOtherServices函数里会拉起TelecomLoaderService
mSystemServiceManager.startService(TelecomLoaderService.class);
2.然后TelecomLoaderService回去连接TelecomService
private static final ComponentName SERVICE_COMPONENT = new ComponentName(
"com.android.server.telecom",
"com.android.server.telecom.components.TelecomService");
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;
}
}
}
此处要注意,绑定服务后TelecomLoaderService会把返回的binder对象进行ServiceManager.addService的操作
ServiceManager.addService(Context.TELECOM_SERVICE, service);
所以我们通过context.getSystemService()获取到的TelecomManager对象实质调用的是该处绑定的服务在onBind中返回的Binder对象,该服务的类名为:com.android.server.telecom.components.TelecomService.
3.进入TelecomService的onBind方法
@Override
public IBinder onBind(Intent intent) {
Log.d(this, "onBind");
initializeTelecomSystem(this);
synchronized (getTelecomSystem().getLock()) {
return getTelecomSystem().getTelecomServiceImpl().getBinder();
}
}
static void initializeTelecomSystem(Context context) {
if (TelecomSystem.getInstance() == null) {
final NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
TelecomSystem.setInstance(
new TelecomSystem(
context,