Telephony Call

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 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.
 *


 * 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.
 *

 
  
 * {@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>
 * }
 *

 */


如果服务已经绑定好了,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);

你可能感兴趣的:(Telephony)