Telephonyregistry in the framework

Source: Internet
Author: User
Tags constructor static class stub

First. Overview

This is a system service that mainly accomplishes two aspects of the notification task:

1. Monitor phone status, notify clients registering the service when new status is in progress。 Like what:
Notifycallstate: Notifies the change of the call status.
Notifysignalstrength: Change of notification signal.
Notifycallforwardingchanged: Notifies the change of the transfer status of the call.
Notifydataconnection: Notifies you of changes to the data connection.
2. Monitor the phone status and send the corresponding broadcast to the system when there is a new state。 Like what:
Broadcastservicestatechanged: Changes in broadcast service status.
Broadcastsignalstrengthchanged: Changes in broadcast signals.
Broadcastdataconnectionstatechanged: Changes in broadcast data connection status.


After the client obtains the service, it can register itself as a state listener through the unified listen method, and if the phone state changes, the system will traverse all the listeners and send messages to them and invoke the corresponding callback function.




Second. Service-to-system registration process 

since he is a service, he needs to go to ServiceManager to register himself. We found his registration process in the Systemserver initialization thread: [Java] view plain copy @SystemServer. java telephonyregistry = new Telephonyreg   Istry (context); Servicemanager.addservice ("Telephony.registry", telephonyregistry);



This shows that the service is loaded as a "telephony.registry" service. If you need to get the service, you will need to query the ServiceManager with the name "Telephony.registry".



Third, the client registers the monitoring process with the service side 3.1, the client needs to do the preparatory workthe process of registering is to add the client to a list called mrecords, and when the phone state changes, Telephonyregistry will traverse the client in Mrecords and invoke the callback function they originally registered.
Therefore, Mrecords is the list of telephonyregistry core maintenance, where each element is a record-type data structure that represents a client.
Let's first look at the data structure of the record:

[Java]


@ TelephonyRegistry.java
     private static class Record {
         // For debugging
         String pkgForDebug;
         // The IBinder object of the callback function
         IBinder binder;
         //Callback
         IPhoneStateListener callback;
         // client's uid, used to check permissions
         int callerUid;
         // Indicates which listener is registered by the client
         int events;
         // For debugging, don't care
         public String toString () {
         }
     }



  This data structure explains 3 important information:

 1, When the client registers the listener, it needs to provide an object of type Iphonestatelistener,

 2, the client needs to tell the server what messages it needs to listen to (events), 3, not all the clients have permission to listen to all the states (Calleruid decision).
Let's take a look at the data structure of Iphonestatelistener:

[Java]


@ IPhoneStateListener.aidl
     oneway interface IPhoneStateListener {
         // Service status changed
         void onServiceStateChanged (in ServiceState serviceState);
         // Signal changes
         void onSignalStrengthChanged (int asu);
         // Waiting for SMS changes, similar to voicemail reminding SMS
         void onMessageWaitingIndicatorChanged (boolean mwi);
         // Call transfer status changed
         void onCallForwardingIndicatorChanged (boolean cfi);
         void onCellLocationChanged (in Bundle location);
         // Call status changed
         void onCallStateChanged (int state, String incomingNumber);
         // Data connection status changed
         void onDataConnectionStateChanged (int state, int networkType);
         void onDataActivity (int direction);
         void onSignalStrengthsChanged (in SignalStrength signalStrength);
         void onOtaspChanged (in int otaspMode);
         void onCellInfoChanged (in List <CellInfo> cellInfo);
     }


     As seen above, the Iphonestatelistener interface defines a callback function for listeners for each state of the phone.
Let's look at what messages the client can listen to:

[Java]


        @PhoneStateListener.java
        LISTEN_SERVICE_STATE
        LISTEN_SIGNAL_STRENGTH
        LISTEN_MESSAGE_WAITING_INDICATOR
        LISTEN_CALL_FORWARDING_INDICATOR
        LISTEN_CELL_LOCATION
        LISTEN_CALL_STATE
        LISTEN_DATA_CONNECTION_STATE
        LISTEN_DATA_ACTIVITY
        LISTEN_SIGNAL_STRENGTHS
        LISTEN_OTASP_CHANGED
        LISTEN_CELL_INFO


 can see that these listening messages are and above the Iphonestateliste corresponding to the NER.
The client can specify its own state of interest and provide its own callback function for that state, and when the corresponding event occurs, Telephonyregistry invokes the client's callback function.
3.2, client registration monitoring process

As we have said in the framework of Telephonymanager, Telephonymanager also registered 3 Systemserver, And his client can initiate requests indirectly through Telephonymanager to 3 systemserver, and Telephonyregistry is one of them systemserver.
Therefore, the registration of Telephonyregistry by other clients can be implemented by Telephonymanager. The specific approach is:

[Java]


@ TelephonyManager.java
     public TelephonyManager (Context context) {
         // Get TelephonyRegistry service
         sRegistry = ITelephonyRegistry.Stub.asInterface (ServiceManager.getService ("telephony.registry"));
     }
     // Indirect registration of TelephonyRegistry via TelephonyManager:
     public void listen (PhoneStateListener listener, int events) {
         String pkgForDebug = sContext! = Null? SContext.getPackageName (): "<unknown>";
         try {
             Boolean notifyNow = (getITelephony ()! = Null);
             sRegistry.listen (pkgForDebug, listener.callback, events, notifyNow);
         } catch (RemoteException ex) {
         } catch (NullPointerException ex) {
         }
     }


in other words,If the client wants to implement the TELEPHONYREGISTRY monitoring, it can get Telephonymanager service first, and then call its Listen method through this service to register the current client to Telephonyregistry. When the phone status changes, the notification is sent to the current client by Telephonyregistry

And we've covered in Telephonymanager in the framework that the benefit is that the client gets Telephonymanager whilenot only got the systemserver of Telephonyregistry, but also got the other two systemserver
Next we continue to look at the result of calling listen in Telephonymanager:[Java]


@TelephonyRegistry
    public void listen (String pkgForDebug, IPhoneStateListener callback, int events, boolean notifyNow) {
        int callerUid = UserHandle.getCallingUserId ();
        // Get the client's UID
        int myUid = UserHandle.myUserId ();
        // Check if the caller has permission to listen
        checkListenerPermission (events);
        IBinder b = callback.asBinder ();
        // First find out if the current applicant is already registered for listening
        final int N = mRecords.size ();
        for (int i = 0; i <N; i ++) {
            r = mRecords.get (i);
            if (b == r.binder) {
                break find_and_add;
            }
        }
        // Build a Record object
        r = new Record ();
        r.binder = b;
        r.callback = callback;
        r.pkgForDebug = pkgForDebug;
        r.callerUid = callerUid;
        // Write the current client information to the mRecords list
        mRecords.add (r);
        // Need to send notification immediately
        if (notifyNow) {
            if ((events & PhoneStateListener.LISTEN_SERVICE_STATE)! = 0) {
                r.callback.onServiceStateChanged (new ServiceState (mServiceState));
            }
            ........
        }
    }
     


   The code above shows that there are 3 main tasks to complete in listen:
1, check whether the client has permission to listen;
2. Build a record of the client and add it to the Mrecords list


3, determine whether you need to send a notification immediately .



Fourth. service-side notification client process

The procedure for client registration is described in the third section above, which focuses on how the server notifies the client when the corresponding event occurs.
4.1, from Ril to Telephonyregistry of the notice distanceThis service is very special, and his notification to the client is initiated by another client. The specific situation is:A class called Defaultphonenotifier in its own constructor, get the "telephony.registry" of the system services, that is, telephonyregistry service, and Defaultphonenotifier at the same time and registered to Rilj, we know, when the modem has news report, is to send the message to Rilj, at this time Rilj will notify Defaultphonenotifier, Defaultphonenotifier get notified, and then according to different messages, to call Telephonyregistry corresponding notification method, within the Telephonyregistry notification method, and all registered clients for the message distribution
Other wordsTelephonyregistry acts as a mediator, where one of the clients passes telephonyregistry to all other clients for message dispatch .
We know that the generation of the Gsmphone object is like this:[Java]


    @PhoneFactory.java
    sPhoneNotifier = new DefaultPhoneNotifier();
    new GSMPhone(context,sCommandsInterface, sPhoneNotifier)


in other words, sphonenotifier in Gsmphone is Defaultphonenotifier object, we Take a look at the constructor of this object:[Java]


    @DefaultPhoneNotifier.java
    DefaultPhoneNotifier() {
        mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry"));
    }


This shows that Defaultphonenotifier is the "client" of Telephonyregistry and gets the remote Telephonyregistry object. When a message with the phone in Rilj needs to be escalated, it will take the following form:[Java]


    @PhoneFactory.java
    sPhoneNotifier = new DefaultPhoneNotifier();
    new GSMPhone(context,sCommandsInterface, sPhoneNotifier)    @GSMPhone.java
    void notifyPhoneStateChanged() {
        mNotifier.notifyPhoneState(this);
    }


The mnotifier here is the sphonenotifier that was passed when the Gsmphone was built, the Defaultphonenotifier object, and his Notifyphonestate method will be called:[Java] 


@ DefaultPhoneNotifier.java
     public void notifyPhoneState (Phone sender) {
         Call ringingCall = sender.getRingingCall ();
         String incomingNumber = "";
         if (ringingCall! = null && ringingCall.getEarliestConnection ()! = null) {
             incomingNumber = ringingCall.getEarliestConnection (). getAddress ();
         }
         try {
             // Here is the call to notifyCallState of TelephonyRegistry to notify all other clients
             mRegistry.notifyCallState (convertCallState (sender.getState ()), incomingNumber);
         } catch (RemoteException ex) {
         }
     }


     through the above steps, System from the modem sent about the phone, network state changes, after Ril and Gsmphone passed to Defaultphonenotifier, and then passed to the Telephonyregistry, It is up to him to distribute the current message to all clients registered for listening.
4.2, Telephonyregistry to send the message to the client's journey

the above analysis, RIL will eventually call to Telephonyregistry in the Notifyxxx method to do a variety of message notification, we analyze a typical Callstate message method:
That is Telephonyregistry's Notifycallstate method:[Java]


@ TelephonyRegistry.java
    public void notifyCallState (int state, String incomingNumber) {
        for (Record r: mRecords) {
            if ((r.events & PhoneStateListener.LISTEN_CALL_STATE)! = 0) {
                try {
                    // Notify all clients and call their onCallStateChanged method
                    r.callback.onCallStateChanged (state, incomingNumber);
                } catch (RemoteException ex) {
                }
            }
        }
        // Send broadcast message at the same time
        broadcastCallStateChanged (state, incomingNumber);
    }
    private void broadcastServiceStateChanged (ServiceState state) {
        long ident = Binder.clearCallingIdentity ();
        mBatteryStats.notePhoneState (state.getState ());
        // Send broadcast of ACTION_SERVICE_STATE_CHANGED
        Intent intent = new Intent (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
        Bundle data = new Bundle ();
        state.fillInNotifierBundle (data);
        intent.putExtras (data);
        //send
        mContext.sendStickyBroadcastAsUser (intent, UserHandle.ALL);
    }
          as can be seen from the above, in the process of notifycallstate, we see that the distribution of messages is achieved through two channels:
1, traversal mrecords, call the original registration of the current message listening to all the client's callback method, a one-to-one notification



2. Send the broadcast through the Broadcastcallstatechanged method .




Fifth, flowchart



We now use a flowchart to end this section of learning:





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.