您的位置:首页 > 其它

Telephony Call

2016-04-19 14:49 851 查看
call对象

packages/services/Telecomm/src/com/android/server/telecom/Call.java

frameworks/base/telecomm/java/android/telecom/Call.java

packages/apps/InCallUI/src/com/android/incallui/Call.java

frameworks/opt/telephony/src/java/com/android/internal/telephony/Call.java

在不同包内的call的功能应该是不同的,但是它们标识的应该同一个call。那么这种一一对应的关系是怎么建立起来的?

packages/services/Telecomm/src/com/android/server/telecom/Call.java 首先被建立

代码在packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java

MO startOutgoingCall, MT processIncomingCallIntent

Call startOutgoingCall(Uri handle, PhoneAccountHandle phoneAccountHandle, Bundle extras)

{...

addCall(call);

return call;

}

/**

* Adds the specified call to the main list of live calls.

*

* @param call The call to add.

*/

private void addCall(Call call) {

Trace.beginSection("addCall");

Log.v(this, "addCall(%s)", call);

call.addListener(this);

mCalls.add(call);// 引用维护到本地

// TODO: Update mForegroundCall prior to invoking

// onCallAdded for calls which immediately take the foreground (like the first call).

for (CallsManagerListener listener : mListeners) {

if (Log.SYSTRACE_DEBUG) {

Trace.beginSection(listener.getClass().toString() + " addCall");

}

listener.onCallAdded(call);// 通知各个Listener

if (Log.SYSTRACE_DEBUG) {

Trace.endSection();

}

}

updateCallsManagerState();//更新状态

Trace.endSection();

}

packages/services/Telecomm/src/com/android/server/telecom/InCallController.java

listener.onCallAdded(call); 通知很多Listener,在构造函数里可以找到。和各个目录的call映射有关系应该是InCallController,看一下它的实现

@Override

public void onCallAdded(Call call) {

if (!isBoundToServices()) {

bindToServices(call);

} else {

adjustServiceBindingsForEmergency();

Log.i(this, "onCallAdded: %s", call);

// Track the call if we don't already know about it.

addCall(call);

for (Map.Entry<ComponentName, IInCallService> entry : mInCallServices.entrySet()) {

ComponentName componentName = entry.getKey();

IInCallService inCallService = entry.getValue();

ParcelableCall parcelableCall = toParcelableCall(call,

true /* includeVideoProvider */);

try {

inCallService.addCall(parcelableCall);

} catch (RemoteException ignored) {

}

}

}

}

bindToServices(call);看一下这个函数的注释,代码就不看了。

/**

* Binds to all the UI-providing InCallService as well as system-implemented non-UI

* InCallServices. Method-invoker must check {@link #isBoundToServices()} before invoking.

*

* @param call The newly added call that triggered the binding to the in-call services.

*/

这个函数主要是用来绑定提供打电话界面UI的InCallService,这个InCallService是Framework的类,所以应该可以被很多app重写实现,所以,

绑定服务这个InCallService的时候会绑定很多,包括系统的实现(InCallUI)。

看一下InCallService的注释

frameworks/base/telecomm/java/android/telecom/InCallService.java

/**

* This service is implemented by any app that wishes to provide the user-interface for managing

* phone calls. Telecom binds to this service while there exists a live (active or incoming) call,

* and uses it to notify the in-call app of any live and recently disconnected calls. An app must

* first be set as the default phone app (See {@link TelecomManager#getDefaultDialerPackage()})

* before the telecom service will bind to its {@code InCallService} implementation.

* <p>

* Below is an example manifest registration for an {@code InCallService}. The meta-data

* ({@link TelecomManager#METADATA_IN_CALL_SERVICE_UI}) indicates that this particular

* {@code InCallService} implementation intends to replace the built-in in-call UI.

* <pre>

* {@code

* <service android:name="your.package.YourInCallServiceImplementation"

* android:permission="android.permission.BIND_IN_CALL_SERVICE">

* <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" />

* <intent-filter>

* <action android:name="android.telecom.InCallService"/>

* </intent-filter>

* </service>

* }

* </pre>

*/

如果服务已经绑定好了,addCall(call);//也把引用维护到本地

ParcelableCall parcelableCall = toParcelableCall(call, true /* includeVideoProvider */);//包装成ParcelableCall,通过aidl来传递的对象要实现parcelable?

inCallService.addCall(parcelableCall);//然后利用远程实例,通知各个service,添加call

->MSG_ADD_CALL

------------------------frameworks/base/telecomm/java/android/telecom/Call.java 来了~~~~~~----------------

->mPhone.internalAddCall((ParcelableCall) msg.obj);//这个mPhone是Telecom的Phone哦

final void internalAddCall(ParcelableCall parcelableCall) {

Call call = new Call(this, parcelableCall.getId(), mInCallAdapter,

parcelableCall.getState());

mCallByTelecomCallId.put(parcelableCall.getId(), call);//引用保存

mCalls.add(call);//引用保存

checkCallTree(parcelableCall);

call.internalUpdate(parcelableCall, mCallByTelecomCallId);

fireCallAdded(call);//这个fire该怎么理解

}

private void fireCallAdded(Call call) {

for (Listener listener : mListeners) {

listener.onCallAdded(this, call);//要找找都有哪些listener

}

}

正好InCallService在收到MSG_SET_IN_CALL_ADAPTER的时候会设置mPhone.addListener(mPhoneListener);

private Phone.Listener mPhoneListener = new Phone.Listener()

{...

public void onCallAdded(Phone phone, Call call) {

InCallService.this.onCallAdded(call);

}

...

}

InCallService.this.onCallAdded(call);// 这种写法总会让我感觉会调用父类方法,而不调用子类,是不是可以这样理解,因为new Phone.Listener()是

内部类的写法,InCallService.this只是标识是InCallService这个类方法,用来区别this。

现在掉到子类InCallService的onCallAdded,看一下系统实现的InCallService

packages/apps/InCallUI/src/com/android/incallui/InCallServiceImpl

public void onCallAdded(Call call) {

CallList.getInstance().onCallAdded(call);

InCallPresenter.getInstance().onCallAdded(call);

}

packages/apps/InCallUI/src/com/android/incallui/CallList

packages/apps/InCallUI/src/com/android/incallui/Call.java

public void onCallAdded(android.telecom.Call telecommCall) {

Trace.beginSection("onCallAdded");

Call call = new Call(telecommCall);

Log.d(this, "onCallAdded: callState=" + call.getState());

if (call.getState() == Call.State.INCOMING ||

call.getState() == Call.State.CALL_WAITING) {

onIncoming(call, call.getCannedSmsResponses());

} else {

onUpdate(call);

}

Trace.endSection();

}

->onUpdate(Call call)

->onUpdateCall(call)

->updateCallInMap(call)

{...

mCallById.put(call.getId(), call);

mCallByTelecommCall.put(call.getTelecommCall(), call);

...}

frameworks/opt/telephony/src/java/com/android/internal/telephony/Call.java

frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GsmCallTracker.java

在GsmCallTracker中new的

public GsmCall mRingingCall = new GsmCall(this);

// A call that is ringing or (call) waiting

public GsmCall mForegroundCall = new GsmCall(this);

public GsmCall mBackgroundCall = new GsmCall(this);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: