Android N 來電流程(MT)

本流程圖基於MTK平臺 Android 7.0,普通來電,本流程只作爲溝通學習使用

本篇文章寫作順序是從modem上報消息,一層一層上報到incallUI,讀者可以根據需求選擇閱讀順序。

frameworks/opt/telephony/

這裏寫圖片描述

當對方撥打電話後,運營商就會通過基站向含有特定SIM卡手機的modem發送指令,當手機modem收到這個指令後就會發生變化,並將變化信息通過AT指令集的方式傳送給RILC,RILC又會通過socket的方式將變化信息傳遞到RILJ,此時RILJ的RILReceiver就會處理這些消息,從而進入我們上圖的流程當中。

第一次其實是RIL_UNSOL_INCOMING_CALL_INDICATION這個事件,mIncomingCallIndicationRegistrant這個觀察者list是在BaseCommands中定義並實現了添加觀察者的方法,在GsmCdmaCallTracker初始化的時候往裏面加入了觀察者,觀察EVENT_INCOMING_CALL_INDICATION事件,所以,當RILC向RILJ傳送UNSOL_INCOMING_CALL_INDICATION事件時,通過
mIncomingCallIndicationRegistrant.notifyRegistrant(new AsyncResult(null, ret, null));這個方法,讓GsmCdmaCallTracker的 handleMessage 的 EVENT_INCOMING_CALL_INDICATION,這樣就把消息通過觀察者模式傳遞到了GsmCdmaCallTracker裏面去了,在這裏面做一些判斷,比如提高PhoneAPP的優先級、多個來電拒絕最新的來電等.

相關log信息

12-30 14:57:45.564 D/RILJ    ( 1452): [UNSL]< UNSOL_RESPONSE_CALL_STATE_CHANGED [SUB0]
12-30 14:57:45.565 D/GsmCallTrackerHelper( 1452): handle EVENT_CALL_STATE_CHANGE (slot 0)
12-30 14:57:45.565 D/RILJ    ( 1452): [4481]> GET_CURRENT_CALLS [SUB0]
12-30 14:57:45.584 D/RILJ    ( 1452): [4481]< GET_CURRENT_CALLS {[id=1,INCOMING,toa=129,norm,mt,0,voc,nonvid,noevp,,cli=1,,1] } [SUB0]
12-30 14:57:45.586 D/GsmCallTrackerHelper( 1452): handle EVENT_POLL_CALLS_RESULT (slot 0)
12-30 14:57:45.586 D/GsmCdmaCallTracker( 1452): Event EVENT_POLL_CALLS_RESULT Received 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

這部分流程主要是做一些狀態的上報,還有一些connection的初始化.

RIL和modem簡單交互圖

這裏寫圖片描述 這裏寫圖片描述

詳細的介紹可以參考滿哥的 http://blog.csdn.net/yihongyuelan/article/details/22044787 這篇文章,看完後應該會有個大致的瞭解,這裏就不再細說了。

packages/services/Telecomm

這裏寫圖片描述

這個流程圖主要介紹了Telecom這層對下面Telephony傳上來的數據處理,大概是一下幾步:

  1. 將telephony上傳的數據封裝成一個intent
  2. 創建一個call
  3. 創建一個鏈接,並建立起一個鏈接

重要的方法:

構造intent的額外信息

    /**
     * Sends the incoming call intent to telecom.
     */
    private void sendIncomingCallIntent(Connection connection) {
        /// M: ALPS02136977. Prints debug messages for telephony. @{
        if (connection != null) {
            FormattedLog formattedLog = new FormattedLog.Builder()
                    .setCategory("CC")
                    .setServiceName("Telephony")
                    .setOpType(FormattedLog.OpType.NOTIFY)
                    .setActionName("MT")
                    .setCallNumber(connection.getAddress())
                    .setCallId("")
                    .buildDebugMsg();
            if (formattedLog != null) {
                Log.d(this, formattedLog.toString());
            }
        }
        /// @}

        Bundle extras = new Bundle();
        if (connection.getNumberPresentation() == TelecomManager.PRESENTATION_ALLOWED &&
                !TextUtils.isEmpty(connection.getAddress())) {
            Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, connection.getAddress(), null);
            extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, uri);
            /// M: For one-key conference MT displayed as incoming conference call. @{
            boolean isIncomingMpty = connection.isIncomingCallMultiparty();
            Log.d(this, "isIncomingMpty: " + isIncomingMpty);
            extras.putBoolean(TelecomManagerEx.EXTRA_VOLTE_CONF_CALL_INCOMING, isIncomingMpty);
            /// @}
        }

        // Specifies the time the call was added. This is used by the dialer for analytics.
        extras.putLong(TelecomManager.EXTRA_CALL_CREATED_TIME_MILLIS,
                SystemClock.elapsedRealtime());

        PhoneAccountHandle handle = findCorrectPhoneAccountHandle();
        if (handle == null) {
            try {
                connection.hangup();
            } catch (CallStateException e) {
                // connection already disconnected. Do nothing
            }
        } else {
            TelecomManager.from(mPhone.getContext()).addNewIncomingCall(handle, extras);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

創建一個call

    /**
     * Starts the process to attach the call to a connection service.
     *
     * @param phoneAccountHandle The phone account which contains the component name of the
     *        connection service to use for this call.
     * @param extras The optional extras Bundle passed with the intent used for the incoming call.
     */
    void processIncomingCallIntent(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
        Log.d(this, "processIncomingCallIntent");
        Uri handle = extras.getParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS);
        if (handle == null) {
            // Required for backwards compatibility
            handle = extras.getParcelable(TelephonyManager.EXTRA_INCOMING_NUMBER);
        }
        Call call = new Call(
                getNextCallId(),
                mContext,
                this,
                mLock,
                mConnectionServiceRepository,
                mContactsAsyncHelper,
                mCallerInfoAsyncQueryFactory,
                handle,
                null /* gatewayInfo */,
                null /* connectionManagerPhoneAccount */,
                phoneAccountHandle,
                Call.CALL_DIRECTION_INCOMING /* callDirection */,
                false /* forceAttachToExistingConnection */,
                false /* isConference */
        ); //創建一個call

        call.initAnalytics();
        if (getForegroundCall() != null) {
            getForegroundCall().getAnalytics().setCallIsInterrupted(true);
            call.getAnalytics().setCallIsAdditional(true);
        }

        setIntentExtrasAndStartTime(call, extras);
        /// M: For VoLTE @{
        if (TelecomVolteUtils.isConferenceInvite(extras)) {
            call.setIsIncomingFromConfServer(true);
        }
        /// @}

        // TODO: Move this to be a part of addCall()
        call.addListener(this);
        call.startCreateConnection(mPhoneAccountRegistrar);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

創建鏈接

    /**
     * This can be used by telecom to either create a new outgoing call or attach to an existing
     * incoming call. In either case, telecom will cycle through a set of services and call
     * createConnection util a connection service cancels the process or completes it successfully.
     */
    private void createConnection(
            final PhoneAccountHandle callManagerAccount,
            final String callId,
            final ConnectionRequest request,
            boolean isIncoming,
            boolean isUnknown) {
        Log.d(this, "createConnection, callManagerAccount: %s, callId: %s, request: %s, " +
                        "isIncoming: %b, isUnknown: %b", callManagerAccount, callId, request,
                isIncoming,
                isUnknown);

        /// M: ALPS02136977. Prints debug messages for MO. @{
        if (!isIncoming) {
            String callNumber = null;
            if (request != null && request.getAddress() != null) {
                callNumber = request.getAddress().getSchemeSpecificPart();
            }
            FormattedLog formattedLog = new FormattedLog.Builder()
                    .setCategory("CC")
                    .setServiceName(getConnectionServiceName())
                    .setOpType(FormattedLog.OpType.OPERATION)
                    .setActionName("Dial")
                    .setCallNumber(callNumber)
                    .setCallId("")
                    .buildDebugMsg();
            if (formattedLog != null) {
                Log.d(this, formattedLog.toString());
            }
        }
        /// @}

        Connection connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
                : isIncoming ? onCreateIncomingConnection(callManagerAccount, request)
                : onCreateOutgoingConnection(callManagerAccount, request);//根據不同的狀態創建不同類型的鏈接
        Log.d(this, "createConnection, connection: %s", connection);
        if (connection == null) {
            connection = Connection.createFailedConnection(
                    new DisconnectCause(DisconnectCause.ERROR));
        }

        connection.setTelecomCallId(callId);
        if (connection.getState() != Connection.STATE_DISCONNECTED) {
            addConnection(callId, connection);
        }

        Uri address = connection.getAddress();
        String number = address == null ? "null" : address.getSchemeSpecificPart();
        Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s, properties: %s",
                Connection.toLogSafePhoneNumber(number),
                Connection.stateToString(connection.getState()),
                Connection.capabilitiesToString(connection.getConnectionCapabilities()),
                Connection.propertiesToString(connection.getConnectionProperties()));

        Log.d(this, "createConnection, calling handleCreateConnectionSuccessful %s", callId);
        /// M: CC: Set PhoneAccountHandle for ECC @{
        //[ALPS01794357]
        PhoneAccountHandle handle = connection.getAccountHandle();
        if (handle == null) {
            handle = request.getAccountHandle();
        } else {
            Log.d(this, "createConnection, set back phone account:%s", handle);
        }
        //// @}
        mAdapter.handleCreateConnectionComplete(
                callId,
                request,
                new ParcelableConnection(
                        handle,  /* M: CC: Set PhoneAccountHandle for ECC [ALPS01794357] */
                        connection.getState(),
                        connection.getConnectionCapabilities(),
                        connection.getConnectionProperties(),
                        connection.getAddress(),
                        connection.getAddressPresentation(),
                        connection.getCallerDisplayName(),
                        connection.getCallerDisplayNamePresentation(),
                        connection.getVideoProvider() == null ?
                                null : connection.getVideoProvider().getInterface(),
                        connection.getVideoState(),
                        connection.isRingbackRequested(),
                        connection.getAudioModeIsVoip(),
                        connection.getConnectTimeMillis(),
                        connection.getStatusHints(),
                        connection.getDisconnectCause(),
                        createIdList(connection.getConferenceables()),
                        connection.getExtras()));
        if (isUnknown) {
            triggerConferenceRecalculate();
        }

        /// M: CC: Proprietary CRSS handling @{
        // [ALPS01956888] For FailureSignalingConnection, CastException JE will happen.
        if (connection.getState() != Connection.STATE_DISCONNECTED) {
            forceSuppMessageUpdate(connection);
        }
        /// @}
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101

相關的log和步驟介紹

12-30 14:57:45.603 D/Telephony( 1452): PstnIncomingCallNotifier: handleNewRingingConnection
12-30 14:57:45.603 D/Telephony( 1452): PstnIncomingCallNotifier: [Debug][CC][Telephony][Notify][MT][13880118404][]
12-30 14:57:45.604 D/Telephony( 1452): PstnIncomingCallNotifier: isIncomingMpty: false   
//判斷來電是不是會議電話  這裏會構造intent的extras放入號碼、當前呼入時間、是否是會議通話,並且傳給telecom  PstnIncomingCallNotifier.sendIncomingCallIntent

12-30 14:57:45.608 V/Telecom (  936): Logging: START_SESSION: TSI.aNIC@ApY
12-30 14:57:45.608 I/Telecom (  936): : Adding new incoming call with phoneAccountHandle PhoneAccountHandle{TelephonyConnectionService, 89860115881029413909, UserHandle{0}}: TSI.aNIC@ApY
//這個方法裏面會檢查包名、檢查phoneaccount、然後構造完整的intent:ACTION_INCOMING_CALL、KEY_IS_INCOMING_CALL等等   TelecomServiceImpl.addNewIncomingCall

12-30 14:57:45.618 D/Telecom (  936): Telecom-LogUtils: [Debug][CC][Telecom][Notify][MT][][], Intent = Intent { act=android.telecom.action.INCOMING_CALL (has extras) }: TSI.aNIC@ApY 
12-30 14:57:45.619 D/Telecom (  936): Class: Processing incoming call from connection service [ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}]: TSI.aNIC@ApY 
//這裏會判斷intent的EXTRA_PHONE_ACCOUNT_HANDLE 和EXTRA_INCOMING_CALL_EXTRAS是否爲null    CallIntentProcessor.processIncomingCallIntent

12-30 14:57:45.619 D/Telecom (  936): CallsManager: processIncomingCallIntent: TSI.aNIC@ApY
//這裏會構造一個call ,並打斷前臺電話,設置當前時間爲telecom處理時間,CallsManager.processIncomingCallIntent

12-30 14:57:45.640 V/Telecom (  936): CreateConnectionProcessor: CreateConnectionProcessor created for Call = [TC@5, NEW, null, tel:13880118404, A, childs(0), has_parent(false), [Capabilities:], [Properties:]]: TSI.aNIC@ApY
//創建鏈接處理器   CreateConnectionProcessor.process

12-30 14:57:45.643 V/Telecom (  936): CreateConnectionProcessor: process: TSI.aNIC@ApY 
12-30 14:57:45.658 V/Telecom (  936): CreateConnectionProcessor: attemptNextPhoneAccount: TSI.aNIC@ApY
12-30 14:57:45.659 I/Telecom (  936): CreateConnectionProcessor: Trying attempt CallAttemptRecord(PhoneAccountHandle{TelephonyConnectionService, 89860115881029413909, UserHandle{0}},PhoneAccountHandle{TelephonyConnectionService, 89860115881029413909, UserHandle{0}}): TSI.aNIC@ApY
//設置call的connectionmanager、connectionservice、Timeout、phoneaccount、等信息    CreateConnectionProcessor.attemptNextPhoneAccount

12-30 14:57:45.660 D/Telecom (  936): ConnectionServiceWrapper: createConnection([TC@5, NEW, com.android.phone/com.android.services.telephony.TelephonyConnectionService, tel:13880118404, A, childs(0), has_parent(false), [Capabilities:], [Properties:]]) via ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}.: TSI.aNIC@ApY
12-30 14:57:45.681 D/TelecomFramework( 1452): : Enqueueing pre-init request TC@5 
12-30 14:57:45.697 D/TelecomFramework( 1452): TelephonyConnectionService: createConnection, callManagerAccount: PhoneAccountHandle{TelephonyConnectionService, 89860115881029413909, UserHandle{0}}, callId: TC@5, request: ConnectionRequest tel:13880118404 Bundle[mParcelledData.dataSize=584], isIncoming: true, isUnknown:
12-30 14:57:45.698 I/Telephony( 1452): TelephonyConnectionService: onCreateIncomingConnection, request: ConnectionRequest tel:13880118404 Bundle[mParcelledData.dataSize=584]
//真正的創建一個鏈接,根據類型的不同 有onCreateUnknownConnection、onCreateIncomingConnection、onCreateOutgoingConnection這些  ConnectionService.createConnection

12-30 14:57:45.712 V/TelecomFramework( 1452): TelephonyConnectionService: createConnection, number: 13880118404, state: RINGING, capabilities: [Capabilities: CAPABILITY_SUPPORT_HOLD CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO CAPABILITY_SPEED_UP_MT_AUDIO CAPABILITY_SEPARATE_FROM_CONFERENCE CAPABILITY_DISCONNECT_FROM_CONFERENCE], properties: [Properties:]
12-30 14:57:45.712 D/TelecomFramework( 1452): TelephonyConnectionService: createConnection, calling handleCreateConnectionSuccessful TC@5
12-30 14:57:45.715 D/Telecom (  936): Telecom-LogUtils: [Debug][CC][Telecom][Notify][CreateMtSuccess][13880118404][TC@5]ParcelableConnection [act:PhoneAccountHandle{TelephonyConnectionService, 89860115881029413909, UserHandle{0}}], state:2, capabilities:[Capabilities: CAPABILITY_SUPPORT_HOLD CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO CAPABILITY_SPEED_UP_MT_AUDIO CAPABILITY_SEPARATE_FROM_CONFERENCE CAPABILITY_DISCONNECT_FROM_CONFERENCE], properties:[Properties:], extras:Bundle[mParcelledData.dataSize=104]: CSW.hCCC@Apo
12-30 14:57:45.715 D/Telecom (  936): ConnectionServiceWrapper: ConnectionService -> Telecom: handleCreateConnectionComplete TC@5: CSW.hCCC@Apo 
//MT成功  ConnectionServiceWrapper.ParcelableConnection

12-30 14:57:45.719 V/Telecom (  936): Call: handleCreateConnectionSuccessful ParcelableConnection [act:PhoneAccountHandle{TelephonyConnectionService, 89860115881029413909, UserHandle{0}}], state:2, capabilities:[Capabilities: CAPABILITY_SUPPORT_HOLD CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO CAPABILITY_SPEED_UP_MT_AUDIO CAPABILITY_SEPARATE_FROM_CONFERENCE CAPABILITY_DISCONNECT_FROM_CONFERENCE], properties:[Properties:], extras:Bundle[mParcelledData.dataSize=104]: CSW.hCCC@Apo
//這裏會設置比較多的call的狀態和信息,Call.handleCreateConnectionSuccess

12-30 14:57:45.745 D/Telecom (  936): CallsManager: onSuccessfulIncomingCall: CSW.hCCC@Apo
//這裏會設置很多的過濾器,並執行過濾 CallsManager.onSuccessfulIncomingCall

12-30 14:57:45.746 D/Telecom (  936): IncomingCallFilter: [performFiltering], timeout = 5000: CSW.hCCC@Apo 
12-30 14:57:45.811 V/Telecom (  936): CallsManager: addCall([TC@5, RINGING, com.android.phone/com.android.services.telephony.TelephonyConnectionService, tel:13880118404, A, childs(0), has_parent(false), [Capabilities: CAPABILITY_SUPPORT_HOLD CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO CAPABILITY_SPEED_UP_MT_AUDIO CAPABILITY_SEPARATE_FROM_CONFERENCE CAPABILITY_DISCONNECT_FROM_CONFERENCE], [Properties:]])
12-30 14:57:45.831 I/Telecom (  936): EmergencyInCallServiceConnection: Attempting to bind to InCall ComponentInfo{com.android.dialer/com.android.incallui.InCallServiceImpl}, with Intent { act=android.telecom.InCallService cmp=com.android.dialer/com.android.incallui.InCallServiceImpl }
//EmergencyInCallServiceConnection繼承自InCallServiceBindingConnection 所以最終會回調到onServiceConnected

12-30 14:57:45.885 D/Telecom (  936): : onServiceConnected: ComponentInfo{com.android.dialer/com.android.incallui.InCallServiceImpl} false true: ICSBC.oSC@Ap4  //YT
12-30 14:57:45.885 I/Telecom (  936): InCallController: onConnected to ComponentInfo{com.android.dialer/com.android.incallui.InCallServiceImpl}: ICSBC.oSC@Ap4
12-30 14:57:45.886 I/Telecom (  936): InCallController: Adding 1 calls to InCallService after onConnected: ComponentInfo{com.android.dialer/com.android.incallui.InCallServiceImpl}: ICSBC.oSC@Ap4
//後面會通過InCallServiceImpl 的onCallAdded方法調用到上層界面incallUI裏面去
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

packages/apps/Dialer

這裏寫圖片描述

這裏主要是把來電的消息轉發到incallUI:

  1. 收到來電信息,改變關心此消息的變量的狀態
  2. 判斷當前手機狀態決定以全屏顯示來電界面還是以headsup的形式提示用戶

重要的方法:

確定是來電後的一些處理邏輯

    /**
     * Called when there is a new incoming call.
     *
     * @param call
     */
    @Override
    public void onIncomingCall(Call call) {
        /// M: for ALPS01945830. Force set theme colors. @{
        setThemeColors();
        /// @}
        InCallState newState = startOrFinishUi(InCallState.INCOMING);
        InCallState oldState = mInCallState;

        Log.i(this, "Phone switching state: " + oldState + " -> " + newState);
        mInCallState = newState;

        for (IncomingCallListener listener : mIncomingCallListeners) {
            listener.onIncomingCall(oldState, mInCallState, call);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

決定顯示HeadsUp還是AnswerFragment

    @Override
    public void addNotification(StatusBarNotification notification, RankingMap ranking,
            Entry oldEntry) {
        if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());

        mNotificationData.updateRanking(ranking);
        Entry shadeEntry = createNotificationViews(notification);
        if (shadeEntry == null) {
            return;
        }
        boolean isHeadsUped = shouldPeek(shadeEntry);
        Log.d("michael", "isHeadsUped: " +isHeadsUped);
        if (isHeadsUped) { //根據這個值確定是否顯示HeadsUp true顯示
            mHeadsUpManager.showNotification(shadeEntry);
            // Mark as seen immediately
            setNotificationShown(notification);
        }

        if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
            if (shouldSuppressFullScreenIntent(notification.getKey())) {
                if (DEBUG) {
                    Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + notification.getKey());
                }
            } else if (mNotificationData.getImportance(notification.getKey())
                    < NotificationListenerService.Ranking.IMPORTANCE_MAX) {
                if (DEBUG) {
                    Log.d(TAG, "No Fullscreen intent: not important enough: "
                            + notification.getKey());
                }
            } else {
                // Stop screensaver if the notification has a full-screen intent.
                // (like an incoming phone call)
                awakenDreams();

                // not immersive & a full-screen alert should be shown
                if (DEBUG)
                    Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
                try {
                    EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
                            notification.getKey());
                    notification.getNotification().fullScreenIntent.send();//顯示AnswerFragment
                    shadeEntry.notifyFullScreenIntentLaunched();
                    MetricsLogger.count(mContext, "note_fullscreen", 1);
                } catch (PendingIntent.CanceledException e) {
                }
            }
        }
        addNotificationViews(shadeEntry, ranking);
        // Recalculate the position of the sliding windows and the titles.
        setAreThereNotifications();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

相關的log信息

12-30 14:57:45.992 D/InCall  ( 3633): CallList - onCallAdded: callState=4, incallui call id=Call_1, telcom call id=TC@5
12-30 14:57:45.992 I/InCall  ( 3633): CallList - onIncoming - [Call_1, INCOMING, [Capabilities: CAPABILITY_SUPPORT_HOLD CAPABILITY_RESPOND_VIA_TEXT CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO CAPABILITY_SEPARATE_FROM_CONFERENCE CAPABILITY_DISCONNECT_FROM_CONFERENCE], children:[], parent:null, conferenceable:[], videoState:Audio Only, mSessionModificationState:0, VideoSettings:(CameraDir:-1)] 
//Called when a single call has changed. call已經發生改變,更新一些值的狀態 CallList.onIncoming
12-30 14:57:46.001 I/InCall  ( 3633): InCallPresenter - Start Full Screen in call UI  
12-30 14:57:46.105 I/InCall  ( 3633): StatusBarNotifier - Displaying notification for 2
12-30 14:57:46.110 V/NotificationService(  936): enqueueNotificationInternal: pkg=com.android.dialer id=2 notification=Notification(pri=1 contentView=null vibrate=null sound=null defaults=0x0 flags=0x82 color=0xff00796b category=call actions=2 vis=PRIVATE publicVersion=Notification(pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x0 color=0xff0288d1 vis=PRIVATE))
12-30 14:57:46.112 D/NotificationService(  936): EnqueueNotificationRunnable.run for: 0|com.android.dialer|2|null|10006
12-30 14:57:46.112 I/InCall  ( 3633): InCallPresenter - Phone switching state: NO_CALLS -> INCOMING
12-30 14:57:46.126 D/InCall  ( 3633): AnswerPresenter - onIncomingCall: com.android.incallui.AnswerPresenter@f23e1cd
12-30 14:57:46.136 D/StatusBar( 1190): onNotificationPosted: StatusBarNotification(pkg=com.android.dialer user=UserHandle{0} id=2 tag=null key=0|com.android.dialer|2|null|10006: Notification(pri=2 contentView=null vibrate=null sound=null defaults=0x0 flags=0x82 color=0xff00796b category=call actions=2 vis=PRIVATE publicVersion=Notification(pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x0 color=0xff0288d1 vis=PRIVATE)))
12-30 14:57:46.136 D/PhoneStatusBar( 1190): addNotification key=0|com.android.dialer|2|null|10006
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

完整流程圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章