Android phone call Process

Source: Internet
Author: User

Part 1: Process of sending AT commands from Java.

Outbound call process:

1. Android: Process = "android. process. acore" in androidmanifest. xml of contacts indicates that the application is running in the acore process.

The action attribute of intent-filter of dialtactsactivity is set to main, and the catelog attribute is set to launcher. Therefore, this activity can appear in the main menu and is the first interface to click this application. Dialtactsactivity contains four tabs: twelvekeydialer and recentcallslistactivity.Activity-aliasDialtactscontactsentryactivity and dialtactsfavoritesentryactivity indicate contacts and add tabs respectively. However, contactslistactivity is responsible for the list of genuine contacts and favorites.

2. Enter The onclick method in twelvekeydialer, press and hold the button ID to R. Id. dialbutton, and execute the placecall () method:

Intent intent = new intent (intent. action_call_privileged, Uri. fromparts ("tel", number, null ));

Intent. setflags (intent. flag_activity_new_task );

Startactivity (intent );

3. The actual intert. action_call_privileged string is Android. Intent. Action. call_privileged. You can find out the androidmanifest. XML in packegs/phone.Activity-aliasIntent-filter is set, so you need to find its targetactivity as outgoingcallbroadcaster. So go to oncreate () of outgoingcallbroadcaster:

String action = intent. getaction ();
String number = phonenumberutils. getnumberfromintent (intent, this );
If (number! = NULL ){
Number = phonenumberutils. convertkeypadletterstodigits (number );
Number = phonenumberutils. stripseparators (number );
}
Final Boolean emergencynumber =
(Number! = NULL) & phonenumberutils. isemergencynumber (number );

Obtain the action and number, and determine the action and number type.

// If callnow = true, the incall interface is started:

Intent. setclass (this, incallscreen. Class );

Startactivity (intent );

And send the broadcast to outgoingcallreceiver:

Intent broadcastintent = new intent (intent. action_new_outgoing_call );

If (number! = NULL) broadcastintent. putextra (intent. extra_phone_number, number );

Broadcastintent. putextra (extra_already_called, callnow );

Broadcastintent. putextra (extra_original_uri, intent. getdata (). tostring ());

Sendorderedbroadcast (broadcastintent, permission,
New outgoingcallreceiver (), null, activity. result_ OK, number, null );

4. Intent. action_new_outgoing_call the actual string Android. Intent. Action. new_outgoing_call. You can find the androidmanifest. XML in packegs/phone to receive the intent message. Find the internal class outgoingcallreceiver in the outgoingcallbroadcaster class and execute the onreceive () function:

Execute doreceive (context, intent); method:

Obtain the sent number and obtain the phonetype according to the phoneapp instance. Finally, start the incall interface:

Intent newintent = new intent (intent. action_call, Uri );

Newintent. putextra (intent. extra_phone_number, number );

Newintent. setclass (context, incallscreen. Class );

Newintent. addflags (intent. flag_activity_new_task );

5. Java part of the request dialing process



6. Part of the C/C ++ request dialing process

6.1 initialize the event loop, start the serial port listener, and register the socket listener.

 

Rild. C-> main ()

 

(1) ril_starteventloop

 

// Create an event loop thread

 

Ret = pthread_create (& s_tid_dispatch, & ATTR, eventloop, null );

 

// Register the process to wake up Event Callback

 

Ril_event_set (& s_wakeupfd_event, s_fdwakeupread, true,

 

Processwakeupcallback, null );

 

Rileventaddwakeup (& s_wakeupfd_event );

 

// Create an event Loop

 

Ril_event_loop

 

For (;;){

 

...

 

N = select (NFDs, & rfds, null, null, PTV );

 

// Check for timeouts

 

Processtimeouts ();

 

// Check for read-ready

 

Processreadreadies (& rfds, N );

 

// Fire away

 

Firepending ();

 

}

 

(2), funcs = rilinit (& s_rilenv, argc, rilargv); // It is actually to execute ril_init in the reference-ril.c by dynamically loading the dynamic library

 

// Start a separate thread to read serial data

 

Ret = pthread_create (& s_tid_mainloop, & ATTR, mainloop, null );

 

FD = open (s_device_path, o_rdwr );

 

Ret = at_open (FD, onunsolicited );

 

Ret = pthread_create (& s_tid_reader, & ATTR, readerloop, & ATTR );

 

Ril_requesttimedcallback (initializecallback, null, & timeval_0 );

 

 

The Program executed in initializecallback:

 

Setradiostate (radio_state_off );

 

At_handshake ();

 

/* Note: We don't check errors here. Everything important will

 

Be handled in onattimeout and onatreaderclosed */

 

/* Atchannel is tolerant of ECHO but it must */

 

/* Have verbose result codes */

 

At_send_command ("ate0q0v1", null );

 

/* No auto-answer */

 

At_send_command ("ats0 = 0", null );

 

...

 

 

 

 

 

// Register the rild socket port event to listen to the event Loop

 

(3), ril_register (funcs );

 

S_fdlisten = android_get_control_socket (socket_name_ril );

 

Ret = listen (s_fdlisten, 4 );

 

Ril_event_set (& s_listen_event, s_fdlisten, false,

 

Listencallback, null); // Add this port to the event select queue

 

Rileventaddwakeup (& s_listen_event );

 

 

If there is data on the rild socket port, the listencallback function will be executed.

 

Listencallback

 

// Create a new listening handle for the client connection. s_fdlisten continues to listen for connections from other clients.

 

S_fdcommand = accept (s_fdlisten, (sockaddr *) & peeraddr, & socklen );

 

Ril_event_set (& s_commands_event, s_fdcommand, 1,

 

Processcommandscallback, p_rs); // Add this port to the event select queue

 

Rileventaddwakeup (& s_commands_event );

 

 

 

6.2 socket listening, receive the socket request of dial

 

Processcommandscallback

 

// Read data to p_record

 

Ret = record_stream_get_next (p_rs, & p_record, & recordlen );

 

Processcommandbuffer (p_record, recordlen );

 

P. setdata (uint8_t *) buffer, buflen );

 

// Status checked at end

 

Status = P. readint32 (& request );

 

Status = P. readint32 (& token); // the serial number in the Request queue

 

PRI = (requestinfo *) calloc (1, sizeof (requestinfo ));

 

Pri-> token = token;

 

 

/*

 

Contains the # include "ril_commands.h" statement. The struct is as follows:

 

Typedef struct {

 

Int requestnumber;

 

Void (* dispatchfunction) (parcel & P, struct requestinfo * Pri );

 

INT (* responsefunction) (parcel & P, void * response, size_t responselen );

 

} Commandinfo;

 

*/

 

Pri-> PCI = & (s_commands [request]);

 

Pri-> p_next = s_pendingrequests;

 

S_pendingrequests = PRI;

 

Pri-> PCI-> dispatchfunction (p, PRI );

 

 

// Assume that the dial command is received. pri-> PCI-> dispatchfunction (p, PRI) calls dispatchdial (p, PRI)

 

Dispatchdial (p, PRI)

 

S_callbacks.onrequest (PRI-> PCI-> requestnumber, & dial, sizeof (Dial), PRI );

 

In reference-ril.c onrequest ()

 

...

 

Switch (request ){

 

Case ril_request_dial:

 

Requestdial (data, datalen, t );

 

Asprintf (& cmd, "ATD % S % s;", p_dial-> address, clir );

 

Ret = at_send_command (CMD, null );

 

Err = at_send_command_full (command, no_result, null, null, 0, pp_outresponse );

 

Err = at_send_command_full_nolock (command, type, responseprefix, smspdu, timeoutmsec, sponse );

 

Err = writeline (command );

 

// Wait until a successful or failed response is received, such as OK, connect, and error CME.

 

Err = pthread_cond_wait (& s_commandcond, & s_commandmutex );

 

Waiting ....

 

Waiting ....

 

 

/* Success or failure is ignored by the upper layer here.

 

It will call get_current_cils and determine success that way */

 

Ril_onrequestcomplete (T, ril_e_success, null, 0 );

 

P. writeint32 (response_solicited );

 

P. writeint32 (PRI-> token );

 

Erroffset = P. dataposition ();

 

P. writeint32 (E );

 

If (E = ril_e_success ){

 

/* Process response on Success */

 

Ret = pri-> PCI-> responsefunction (p, response, responselen );

 

If (Ret! = 0 ){

 

P. setdataposition (erroroffset );

 

P. writeint32 (RET );

 

}

 

}

 

Sendresponse (P );

 

Sendresponseraw (P. Data (), P. datasize ());

 

Blockingwrite (FD, (void *) & header, sizeof (header ));

 

Blockingwrite (FD, Data, datasize );

 

 

 

6.4 The serial port listener receives the ATD command response "OK" or "No carrier", etc.

 

Readerloop ()

 

Line = Readline ();

 

Processline (line );

 

Handlefinalresponse (line );

 

Pthread_cond_signal (& s_commandcond); // at this point, the previous wait ends, and then execute the ril_onrequestcomplete Function

 

 

 

6.5. processing after the Java layer receives the response, taking dial as an example.

 

RIL. Java-> rilreceiver. Run ()

 

For (;;)

 

{

 

...

 

Length = readrilmessage (is, buffer );

 

P = parcel. Obtain ();

 

P. unmarshall (buffer, 0, length );

 

P. setdataposition (0 );

 

Processresponse (P );

 

Type = P. readint ();

 

If (type = response_solicited ){

 

Processsolicited (P );

 

Serial = P. readint ();

 

RR = findandremoverequestfromlist (Serial );

 

Rr. mresult. sendtotarget ();

 

......

 

}

 

 

 

Calltracker. Java-> handlemessage (Message MSG)

 

Switch (msg. What ){

 

Case event_operation_complete:

 

AR = (asyncresult) msg. OBJ;

 

Operationcomplete ();

 

Cm. getcurrentcils (lastrelevantpoll );

Part 2: the process of reporting unsolicited messages to Java from modem.

C ++:

Readerloop ()

Line = Readline ();

Processline (line );

Handleunsolicited (line );

If (s_unsolhandler! = NULL ){

S_unsolhandler (line1, line2); // The Void onunsolicited (const char * s, const char * sms_pdu) is actually executed)

If (strstartswith (S, "+ cring:") | strstartswith (S, "ring ")

| Strstartswith (S, "no carrier") | strstartswith (S, "+ ccwa "))

Ril_onunsolicitedresponse (ril_unsol_response_call_state_changed, null, 0 );

P. writeint32 (response_unsolicited );

P. writeint32 (unsolresponse );

Ret = s_unsolresponses [unsolresponseindex]. responsefunction (p, Data, datalen );

Ret = sendresponse (P );

Sendresponseraw (P. Data (), P. datasize ());

Ret = blockingwrite (FD, (void *) & header, sizeof (header ));

Blockingwrite (FD, Data, datasize );

Java:

RIL. Java-> rilreceiver. Run ()

For (;;)

{

...

Length = readrilmessage (is, buffer );

P = parcel. Obtain ();

P. unmarshall (buffer, 0, length );

P. setdataposition (0 );

Processresponse (P );

Processunsolicited (P );

Response = P. readint ();

Switch (response ){

...

Case ril_unsol_response_call_state_changed: ret = responsevoid (p); break;

...

}

Switch (response ){

Case ril_unsol_response_call_state_changed:

If (rilj_logd) unsljlog (response );

Mcallstateregistrants

. Notifyregistrants (New asyncresult (null, null, null ));

...

}

Part 3: monitoring and notification mechanisms for various statuses related to cats

Part 4: How call-related icons change.

 

A. register the listener



B. Event Notification Section



Note: All status change notifications are handled in telephonyregistry. For details, see the source code of this type.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.