您的位置:首页 > 其它

(O)Telephony分析之通话流程分析(一) TelecomManager的getTelecomService方法解析

2018-01-11 15:43 423 查看
这段时间,在研究Telephony相关的通话流程,虽然从书上看到通话流程,但是自己在分析Google 8.0的代码的时候,发现依旧有些复杂,现在就将自己的研究成果记录一下,以备后续查阅。

一.TelecomLoaderService的初始化
在此前的Android机器启动的流程中,分析过,SystemServer中启动系统的所有服务和进程,而在此文件中,我们会发现,TelecomLoaderService的初始化

private void startOtherServices() {
......
mSystemServiceManager.startService(TelecomLoaderService.class);
......
mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
......
}

从上面的代码中,可以看到,在SystemServer中做了如下的事情

1)调用SystemServiceManager的startService方法,传入的参数就是TelecomLoaderService的class,而这个startService方法,此前也分析过,就是先调用传入class参数的有参构造方法(参数为Context),然后将传入的class参数加入到SystemServiceManager的mService中

进行管理,最后调用传入参数的onStart方法

2)调用SystemServiceManager的startBootPhase方法,传入的参数为SystemService.PHASE_ACTIVITY_MANAGER_READY,而此方法主要是调用加入SystemServiceManager的mService中的所有service的onBootPhase方法,即会调用TelecomLoaderService的onBootPhase方法

接下来,我们就查看一下

(一)TelecomLoaderService的构造方法

public TelecomLoaderService(Context context) {
super(context);
mContext = context;
registerDefaultAppProviders();
}

调用了registerDefaultAppProviders方法
private void registerDefaultAppProviders() {
final PackageManagerInternal packageManagerInternal = LocalServices.getService(
PackageManagerInternal.class);

// Set a callback for the package manager to query the default sms app.
packageManagerInternal.setSmsAppPackagesProvider(...);

// Set a callback for the package manager to query the default dialer app.
packageManagerInternal.setDialerAppPackagesProvider(...);

// Set a callback for the package manager to query the default sim call manager.
packageManagerInternal.setSimCallManagerPackagesProvider(...);
}

从这个方法可以看出,此方法设置系统默认的SMS应用,拨号应用和默认SIM卡通话管理,并加入到PackageManagerService中进行管理

我们从代码中可以看到,在TelecomLoaderService的onStart方法中没有做任何操作,因此不讨论

(二)TelecomLoaderService的onBootPhase方法
public void onBootPhase(int phase) {
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
registerDefaultAppNotifier();
registerCarrierConfigChangedReceiver();
connectToTelecom();
}
}

当Phase匹配的时候,会调用三个方法,主要是做了下述功能

1)registerDefaultAppNotifier方法主要是注册了默认SMS应用和默认拨号应用的ContentObserver,用于监听默认应用的变化,并进行相应的处理

2)registerCarrierConfigChangedReceiver方法主要是注册监听运营商变化的广播,此处不关注

3)connectToTelecom方法,这个方法是我们需要主要分析的,继续分析其代码
private void connectToTelecom() {
synchronized (mLock) {
......
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;
}
}
}

从这部分代码,我们可以看出,将Intent和serviceConnection进行绑定,即将TelecomManager和serviceConnection进行关联

而serviceConnection是什么呢?
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") thats redundant here.
try {
......
ServiceManager.addService(Context.TELECOM_SERVICE, service);
......
} catch (RemoteException e) {
Slog.w(TAG, "Failed linking to death.");
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
connectToTelecom();
}
}

这个部分,调用了ServiceManager的addService方法将TelecomService加入到服务管理器中,并绑定了TelecomManager和TelecomService,且注册TelecomService

自此,就将TelecomManager和TelecomService进行绑定了

二.TelecomService分析

当TelecomManager和TelecomService绑定完成后,就会进入TelecomService

先看看其onBind方法
public IBinder onBind(Intent intent) {
Log.d(this, "onBind");
initializeTelecomSystem(this);
synchronized (getTelecomSystem().getLock()) {
// Leo, 绑定TelecomServiceImpl对象
return getTelecomSystem().getTelecomServiceImpl().getBinder();
}
}

主要是调用了initializeTelecomSystem方法,并且调用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(......));
}
......
}

从这段代码中可以看到,这个方法主要是初始化了一个TelecomSystem对象,并且设置,此处我们不做分析,待后续遇到具体问题,具体再看

然后就是返回的是getTelecomSystem().getTelecomServiceImpl().getBinder()
public TelecomSystem getTelecomSystem() {
return TelecomSystem.getInstance();
}

返回的是刚刚新建的TelecomSystem对象

public TelecomServiceImpl getTelecomServiceImpl() {
return mTelecomServiceImpl;
}

TelecomSystem的getTelecomServiceImpl方法,返回的是mTelecomServicesImpl对象,那么其是什么?

public TelecomSystem(
Context context,
MissedCallNotifierImplFactory missedCallNotifierImplFactory,
CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory,
HeadsetMediaButtonFactory headsetMediaButtonFactory,
ProximitySensorManagerFactory proximitySensorManagerFactory,
InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
AudioServiceFactory audioServiceFactory,
BluetoothPhoneServiceImplFactory
bluetoothPhoneServiceImplFactory,
Timeouts.Adapter timeoutsAdapter,
AsyncRingtonePlayer asyncRingtonePlayer,
PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
InterruptionFilterProxy interruptionFilterProxy,
IncomingCallNotifier incomingCallNotifier) {
......
mTelecomServiceImpl = new TelecomServiceImpl(
mContext, mCallsManager, mPhoneAccountRegistrar,
new CallIntentProcessor.AdapterImpl(),
new UserCallIntentProcessorFactory() {
@Override
public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
return new UserCallIntentProcessor(context, userHandle);
}
},
defaultDialerCache,
new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
mLock);
......
}

可以看到,这个对象是在TelecomSystem的构造函数中定义的,并且重写了create方法

所以,TelecomService的onBind方法返回的是TelecomServiceImpl的getBinder方法所返回的ITelecomService.Stub对象

即TelecomServiceImpl中的mBinderImpl对象

因此,从上面的分析中,可以知道,TelecomManager和TelecomService进行绑定了,而TelecomService和TelecomServiceImpl的mBinderImpl进行绑定

(三)TelecomManager的getTelecomService方法

先来看看这个方法的代码
private ITelecomService getTelecomService() {
if (mTelecomServiceOverride != null) {
return mTelecomServiceOverride;
}
// 这个ITelecomService为TelecomService对象,其中跟TelecomServiceImpl进行绑定了
return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE));
}

ServiceManager.getService(Context.TELECOM_SERVICE)方法,我们知道,是TelecomService对象

那么其返回的应该是

ITelecomService.Stub.asInterface(TelecomService.class)

那么从此前的分析,我们就知道,其返回的也就是TelecomServiceImpl的mBinderImpl了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息