Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.telephony;
     18 
     19 import android.annotation.NonNull;
     20 import android.os.Bundle;
     21 import android.os.Handler;
     22 import android.os.Looper;
     23 import android.os.Message;
     24 
     25 import com.android.internal.telephony.IPhoneStateListener;
     26 
     27 import java.util.List;
     28 import java.lang.ref.WeakReference;
     29 
     30 /**
     31  * A listener class for monitoring changes in specific telephony states
     32  * on the device, including service state, signal strength, message
     33  * waiting indicator (voicemail), and others.
     34  * <p>
     35  * Override the methods for the state that you wish to receive updates for, and
     36  * pass your PhoneStateListener object, along with bitwise-or of the LISTEN_
     37  * flags to {@link TelephonyManager#listen TelephonyManager.listen()}.
     38  * <p>
     39  * Note that access to some telephony information is
     40  * permission-protected. Your application won't receive updates for protected
     41  * information unless it has the appropriate permissions declared in
     42  * its manifest file. Where permissions apply, they are noted in the
     43  * appropriate LISTEN_ flags.
     44  */
     45 public class PhoneStateListener {
     46     private static final String LOG_TAG = "PhoneStateListener";
     47     private static final boolean DBG = false; // STOPSHIP if true
     48 
     49     /**
     50      * Stop listening for updates.
     51      */
     52     public static final int LISTEN_NONE = 0;
     53 
     54     /**
     55      *  Listen for changes to the network service state (cellular).
     56      *
     57      *  @see #onServiceStateChanged
     58      *  @see ServiceState
     59      */
     60     public static final int LISTEN_SERVICE_STATE                            = 0x00000001;
     61 
     62     /**
     63      * Listen for changes to the network signal strength (cellular).
     64      * {@more}
     65      *
     66      * @see #onSignalStrengthChanged
     67      *
     68      * @deprecated by {@link #LISTEN_SIGNAL_STRENGTHS}
     69      */
     70     @Deprecated
     71     public static final int LISTEN_SIGNAL_STRENGTH                          = 0x00000002;
     72 
     73     /**
     74      * Listen for changes to the message-waiting indicator.
     75      * {@more}
     76      * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
     77      * READ_PHONE_STATE} or that the calling app has carrier privileges (see
     78      * {@link TelephonyManager#hasCarrierPrivileges}).
     79      * <p>
     80      * Example: The status bar uses this to determine when to display the
     81      * voicemail icon.
     82      *
     83      * @see #onMessageWaitingIndicatorChanged
     84      */
     85     public static final int LISTEN_MESSAGE_WAITING_INDICATOR                = 0x00000004;
     86 
     87     /**
     88      * Listen for changes to the call-forwarding indicator.
     89      * {@more}
     90      * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
     91      * READ_PHONE_STATE} or that the calling app has carrier privileges (see
     92      * {@link TelephonyManager#hasCarrierPrivileges}).
     93      *
     94      * @see #onCallForwardingIndicatorChanged
     95      */
     96     public static final int LISTEN_CALL_FORWARDING_INDICATOR                = 0x00000008;
     97 
     98     /**
     99      * Listen for changes to the device's cell location. Note that
    100      * this will result in frequent callbacks to the listener.
    101      * {@more}
    102      * Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION
    103      * ACCESS_COARSE_LOCATION}
    104      * <p>
    105      * If you need regular location updates but want more control over
    106      * the update interval or location precision, you can set up a listener
    107      * through the {@link android.location.LocationManager location manager}
    108      * instead.
    109      *
    110      * @see #onCellLocationChanged
    111      */
    112     public static final int LISTEN_CELL_LOCATION                            = 0x00000010;
    113 
    114     /**
    115      * Listen for changes to the device call state.
    116      * {@more}
    117      *
    118      * @see #onCallStateChanged
    119      */
    120     public static final int LISTEN_CALL_STATE                               = 0x00000020;
    121 
    122     /**
    123      * Listen for changes to the data connection state (cellular).
    124      *
    125      * @see #onDataConnectionStateChanged
    126      */
    127     public static final int LISTEN_DATA_CONNECTION_STATE                    = 0x00000040;
    128 
    129     /**
    130      * Listen for changes to the direction of data traffic on the data
    131      * connection (cellular).
    132      * {@more}
    133      * Example: The status bar uses this to display the appropriate
    134      * data-traffic icon.
    135      *
    136      * @see #onDataActivity
    137      */
    138     public static final int LISTEN_DATA_ACTIVITY                            = 0x00000080;
    139 
    140     /**
    141      * Listen for changes to the network signal strengths (cellular).
    142      * <p>
    143      * Example: The status bar uses this to control the signal-strength
    144      * icon.
    145      *
    146      * @see #onSignalStrengthsChanged
    147      */
    148     public static final int LISTEN_SIGNAL_STRENGTHS                         = 0x00000100;
    149 
    150     /**
    151      * Listen for changes to OTASP mode.
    152      *
    153      * @see #onOtaspChanged
    154      * @hide
    155      */
    156     public static final int LISTEN_OTASP_CHANGED                            = 0x00000200;
    157 
    158     /**
    159      * Listen for changes to observed cell info.
    160      *
    161      * @see #onCellInfoChanged
    162      */
    163     public static final int LISTEN_CELL_INFO = 0x00000400;
    164 
    165     /**
    166      * Listen for precise changes and fails to the device calls (cellular).
    167      * {@more}
    168      * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
    169      * READ_PRECISE_PHONE_STATE}
    170      *
    171      * @hide
    172      */
    173     public static final int LISTEN_PRECISE_CALL_STATE                       = 0x00000800;
    174 
    175     /**
    176      * Listen for precise changes and fails on the data connection (cellular).
    177      * {@more}
    178      * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
    179      * READ_PRECISE_PHONE_STATE}
    180      *
    181      * @see #onPreciseDataConnectionStateChanged
    182      * @hide
    183      */
    184     public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE            = 0x00001000;
    185 
    186     /**
    187      * Listen for real time info for all data connections (cellular)).
    188      * {@more}
    189      * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
    190      * READ_PRECISE_PHONE_STATE}
    191      * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo)
    192      *
    193      * @deprecated Use {@link TelephonyManager#getModemActivityInfo()}
    194      * @hide
    195      */
    196     @Deprecated
    197     public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO           = 0x00002000;
    198 
    199     /**
    200      * Listen for changes to LTE network state
    201      *
    202      * @see #onLteNetworkStateChanged
    203      * @hide
    204      */
    205     public static final int LISTEN_VOLTE_STATE                              = 0x00004000;
    206 
    207     /**
    208      * Listen for OEM hook raw event
    209      *
    210      * @see #onOemHookRawEvent
    211      * @hide
    212      * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
    213      */
    214     @Deprecated
    215     public static final int LISTEN_OEM_HOOK_RAW_EVENT                       = 0x00008000;
    216 
    217     /**
    218      * Listen for carrier network changes indicated by a carrier app.
    219      *
    220      * @see #onCarrierNetworkRequest
    221      * @see TelephonyManager#notifyCarrierNetworkChange(boolean)
    222      * @hide
    223      */
    224     public static final int LISTEN_CARRIER_NETWORK_CHANGE                   = 0x00010000;
    225 
    226     /**
    227      *  Listen for changes to the sim voice activation state
    228      *  @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
    229      *  @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
    230      *  @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
    231      *  @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
    232      *  @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
    233      *  {@more}
    234      *  Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been
    235      *  fully activated
    236      *
    237      *  @see #onVoiceActivationStateChanged
    238      *  @hide
    239      */
    240     public static final int LISTEN_VOICE_ACTIVATION_STATE                   = 0x00020000;
    241 
    242     /**
    243      *  Listen for changes to the sim data activation state
    244      *  @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
    245      *  @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
    246      *  @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
    247      *  @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
    248      *  @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN
    249      *  {@more}
    250      *  Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been
    251      *  fully activated
    252      *
    253      *  @see #onDataActivationStateChanged
    254      *  @hide
    255      */
    256     public static final int LISTEN_DATA_ACTIVATION_STATE                   = 0x00040000;
    257 
    258     /**
    259      *  Listen for changes to the user mobile data state
    260      *
    261      *  @see #onUserMobileDataStateChanged
    262      */
    263     public static final int LISTEN_USER_MOBILE_DATA_STATE                  = 0x00080000;
    264 
    265     /**
    266      *  Listen for changes to the physical channel configuration.
    267      *
    268      *  @see #onPhysicalChannelConfigurationChanged
    269      *  @hide
    270      */
    271     public static final int LISTEN_PHYSICAL_CHANNEL_CONFIGURATION          = 0x00100000;
    272 
    273     /*
    274      * Subscription used to listen to the phone state changes
    275      * @hide
    276      */
    277     /** @hide */
    278     protected Integer mSubId;
    279 
    280     private final Handler mHandler;
    281 
    282     /**
    283      * Create a PhoneStateListener for the Phone with the default subscription.
    284      * This class requires Looper.myLooper() not return null.
    285      */
    286     public PhoneStateListener() {
    287         this(null, Looper.myLooper());
    288     }
    289 
    290     /**
    291      * Create a PhoneStateListener for the Phone with the default subscription
    292      * using a particular non-null Looper.
    293      * @hide
    294      */
    295     public PhoneStateListener(Looper looper) {
    296         this(null, looper);
    297     }
    298 
    299     /**
    300      * Create a PhoneStateListener for the Phone using the specified subscription.
    301      * This class requires Looper.myLooper() not return null. To supply your
    302      * own non-null Looper use PhoneStateListener(int subId, Looper looper) below.
    303      * @hide
    304      */
    305     public PhoneStateListener(Integer subId) {
    306         this(subId, Looper.myLooper());
    307     }
    308 
    309     /**
    310      * Create a PhoneStateListener for the Phone using the specified subscription
    311      * and non-null Looper.
    312      * @hide
    313      */
    314     public PhoneStateListener(Integer subId, Looper looper) {
    315         if (DBG) log("ctor: subId=" + subId + " looper=" + looper);
    316         mSubId = subId;
    317         mHandler = new Handler(looper) {
    318             public void handleMessage(Message msg) {
    319                 if (DBG) {
    320                     log("mSubId=" + mSubId + " what=0x" + Integer.toHexString(msg.what)
    321                             + " msg=" + msg);
    322                 }
    323                 switch (msg.what) {
    324                     case LISTEN_SERVICE_STATE:
    325                         PhoneStateListener.this.onServiceStateChanged((ServiceState)msg.obj);
    326                         break;
    327                     case LISTEN_SIGNAL_STRENGTH:
    328                         PhoneStateListener.this.onSignalStrengthChanged(msg.arg1);
    329                         break;
    330                     case LISTEN_MESSAGE_WAITING_INDICATOR:
    331                         PhoneStateListener.this.onMessageWaitingIndicatorChanged(msg.arg1 != 0);
    332                         break;
    333                     case LISTEN_CALL_FORWARDING_INDICATOR:
    334                         PhoneStateListener.this.onCallForwardingIndicatorChanged(msg.arg1 != 0);
    335                         break;
    336                     case LISTEN_CELL_LOCATION:
    337                         PhoneStateListener.this.onCellLocationChanged((CellLocation)msg.obj);
    338                         break;
    339                     case LISTEN_CALL_STATE:
    340                         PhoneStateListener.this.onCallStateChanged(msg.arg1, (String)msg.obj);
    341                         break;
    342                     case LISTEN_DATA_CONNECTION_STATE:
    343                         PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1, msg.arg2);
    344                         PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1);
    345                         break;
    346                     case LISTEN_DATA_ACTIVITY:
    347                         PhoneStateListener.this.onDataActivity(msg.arg1);
    348                         break;
    349                     case LISTEN_SIGNAL_STRENGTHS:
    350                         PhoneStateListener.this.onSignalStrengthsChanged((SignalStrength)msg.obj);
    351                         break;
    352                     case LISTEN_OTASP_CHANGED:
    353                         PhoneStateListener.this.onOtaspChanged(msg.arg1);
    354                         break;
    355                     case LISTEN_CELL_INFO:
    356                         PhoneStateListener.this.onCellInfoChanged((List<CellInfo>)msg.obj);
    357                         break;
    358                     case LISTEN_PRECISE_CALL_STATE:
    359                         PhoneStateListener.this.onPreciseCallStateChanged((PreciseCallState)msg.obj);
    360                         break;
    361                     case LISTEN_PRECISE_DATA_CONNECTION_STATE:
    362                         PhoneStateListener.this.onPreciseDataConnectionStateChanged(
    363                                 (PreciseDataConnectionState)msg.obj);
    364                         break;
    365                     case LISTEN_DATA_CONNECTION_REAL_TIME_INFO:
    366                         PhoneStateListener.this.onDataConnectionRealTimeInfoChanged(
    367                                 (DataConnectionRealTimeInfo)msg.obj);
    368                         break;
    369                     case LISTEN_VOLTE_STATE:
    370                         PhoneStateListener.this.onVoLteServiceStateChanged((VoLteServiceState)msg.obj);
    371                         break;
    372                     case LISTEN_VOICE_ACTIVATION_STATE:
    373                         PhoneStateListener.this.onVoiceActivationStateChanged((int)msg.obj);
    374                         break;
    375                     case LISTEN_DATA_ACTIVATION_STATE:
    376                         PhoneStateListener.this.onDataActivationStateChanged((int)msg.obj);
    377                         break;
    378                     case LISTEN_USER_MOBILE_DATA_STATE:
    379                         PhoneStateListener.this.onUserMobileDataStateChanged((boolean)msg.obj);
    380                         break;
    381                     case LISTEN_OEM_HOOK_RAW_EVENT:
    382                         PhoneStateListener.this.onOemHookRawEvent((byte[])msg.obj);
    383                         break;
    384                     case LISTEN_CARRIER_NETWORK_CHANGE:
    385                         PhoneStateListener.this.onCarrierNetworkChange((boolean)msg.obj);
    386                         break;
    387                     case LISTEN_PHYSICAL_CHANNEL_CONFIGURATION:
    388                         PhoneStateListener.this.onPhysicalChannelConfigurationChanged(
    389                                 (List<PhysicalChannelConfig>)msg.obj);
    390                         break;
    391                 }
    392             }
    393         };
    394     }
    395 
    396     /**
    397      * Callback invoked when device service state changes.
    398      *
    399      * @see ServiceState#STATE_EMERGENCY_ONLY
    400      * @see ServiceState#STATE_IN_SERVICE
    401      * @see ServiceState#STATE_OUT_OF_SERVICE
    402      * @see ServiceState#STATE_POWER_OFF
    403      */
    404     public void onServiceStateChanged(ServiceState serviceState) {
    405         // default implementation empty
    406     }
    407 
    408     /**
    409      * Callback invoked when network signal strength changes.
    410      *
    411      * @see ServiceState#STATE_EMERGENCY_ONLY
    412      * @see ServiceState#STATE_IN_SERVICE
    413      * @see ServiceState#STATE_OUT_OF_SERVICE
    414      * @see ServiceState#STATE_POWER_OFF
    415      * @deprecated Use {@link #onSignalStrengthsChanged(SignalStrength)}
    416      */
    417     @Deprecated
    418     public void onSignalStrengthChanged(int asu) {
    419         // default implementation empty
    420     }
    421 
    422     /**
    423      * Callback invoked when the message-waiting indicator changes.
    424      */
    425     public void onMessageWaitingIndicatorChanged(boolean mwi) {
    426         // default implementation empty
    427     }
    428 
    429     /**
    430      * Callback invoked when the call-forwarding indicator changes.
    431      */
    432     public void onCallForwardingIndicatorChanged(boolean cfi) {
    433         // default implementation empty
    434     }
    435 
    436     /**
    437      * Callback invoked when device cell location changes.
    438      */
    439     public void onCellLocationChanged(CellLocation location) {
    440         // default implementation empty
    441     }
    442 
    443     /**
    444      * Callback invoked when device call state changes.
    445      * @param state call state
    446      * @param phoneNumber call phone number. If application does not have
    447      * {@link android.Manifest.permission#READ_CALL_LOG READ_CALL_LOG} permission or carrier
    448      * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be
    449      * passed as an argument.
    450      *
    451      * @see TelephonyManager#CALL_STATE_IDLE
    452      * @see TelephonyManager#CALL_STATE_RINGING
    453      * @see TelephonyManager#CALL_STATE_OFFHOOK
    454      */
    455     public void onCallStateChanged(int state, String phoneNumber) {
    456         // default implementation empty
    457     }
    458 
    459     /**
    460      * Callback invoked when connection state changes.
    461      *
    462      * @see TelephonyManager#DATA_DISCONNECTED
    463      * @see TelephonyManager#DATA_CONNECTING
    464      * @see TelephonyManager#DATA_CONNECTED
    465      * @see TelephonyManager#DATA_SUSPENDED
    466      */
    467     public void onDataConnectionStateChanged(int state) {
    468         // default implementation empty
    469     }
    470 
    471     /**
    472      * same as above, but with the network type.  Both called.
    473      */
    474     public void onDataConnectionStateChanged(int state, int networkType) {
    475     }
    476 
    477     /**
    478      * Callback invoked when data activity state changes.
    479      *
    480      * @see TelephonyManager#DATA_ACTIVITY_NONE
    481      * @see TelephonyManager#DATA_ACTIVITY_IN
    482      * @see TelephonyManager#DATA_ACTIVITY_OUT
    483      * @see TelephonyManager#DATA_ACTIVITY_INOUT
    484      * @see TelephonyManager#DATA_ACTIVITY_DORMANT
    485      */
    486     public void onDataActivity(int direction) {
    487         // default implementation empty
    488     }
    489 
    490     /**
    491      * Callback invoked when network signal strengths changes.
    492      *
    493      * @see ServiceState#STATE_EMERGENCY_ONLY
    494      * @see ServiceState#STATE_IN_SERVICE
    495      * @see ServiceState#STATE_OUT_OF_SERVICE
    496      * @see ServiceState#STATE_POWER_OFF
    497      */
    498     public void onSignalStrengthsChanged(SignalStrength signalStrength) {
    499         // default implementation empty
    500     }
    501 
    502 
    503     /**
    504      * The Over The Air Service Provisioning (OTASP) has changed. Requires
    505      * the READ_PHONE_STATE permission.
    506      * @param otaspMode is integer <code>OTASP_UNKNOWN=1<code>
    507      *   means the value is currently unknown and the system should wait until
    508      *   <code>OTASP_NEEDED=2<code> or <code>OTASP_NOT_NEEDED=3<code> is received before
    509      *   making the decision to perform OTASP or not.
    510      *
    511      * @hide
    512      */
    513     public void onOtaspChanged(int otaspMode) {
    514         // default implementation empty
    515     }
    516 
    517     /**
    518      * Callback invoked when a observed cell info has changed,
    519      * or new cells have been added or removed.
    520      * @param cellInfo is the list of currently visible cells.
    521      */
    522     public void onCellInfoChanged(List<CellInfo> cellInfo) {
    523     }
    524 
    525     /**
    526      * Callback invoked when precise device call state changes.
    527      *
    528      * @hide
    529      */
    530     public void onPreciseCallStateChanged(PreciseCallState callState) {
    531         // default implementation empty
    532     }
    533 
    534     /**
    535      * Callback invoked when data connection state changes with precise information.
    536      *
    537      * @hide
    538      */
    539     public void onPreciseDataConnectionStateChanged(
    540             PreciseDataConnectionState dataConnectionState) {
    541         // default implementation empty
    542     }
    543 
    544     /**
    545      * Callback invoked when data connection state changes with precise information.
    546      *
    547      * @hide
    548      */
    549     public void onDataConnectionRealTimeInfoChanged(
    550             DataConnectionRealTimeInfo dcRtInfo) {
    551         // default implementation empty
    552     }
    553 
    554     /**
    555      * Callback invoked when the service state of LTE network
    556      * related to the VoLTE service has changed.
    557      * @param stateInfo is the current LTE network information
    558      * @hide
    559      */
    560     public void onVoLteServiceStateChanged(VoLteServiceState stateInfo) {
    561     }
    562 
    563     /**
    564      * Callback invoked when the SIM voice activation state has changed
    565      * @param state is the current SIM voice activation state
    566      * @hide
    567      */
    568     public void onVoiceActivationStateChanged(int state) {
    569 
    570     }
    571 
    572     /**
    573      * Callback invoked when the SIM data activation state has changed
    574      * @param state is the current SIM data activation state
    575      * @hide
    576      */
    577     public void onDataActivationStateChanged(int state) {
    578 
    579     }
    580 
    581     /**
    582      * Callback invoked when the user mobile data state has changed
    583      * @param enabled indicates whether the current user mobile data state is enabled or disabled.
    584      */
    585     public void onUserMobileDataStateChanged(boolean enabled) {
    586         // default implementation empty
    587     }
    588 
    589     /**
    590      * Callback invoked when the current physical channel configuration has changed
    591      *
    592      * @param configs List of the current {@link PhysicalChannelConfig}s
    593      * @hide
    594      */
    595     public void onPhysicalChannelConfigurationChanged(
    596             @NonNull List<PhysicalChannelConfig> configs) {
    597         // default implementation empty
    598     }
    599 
    600     /**
    601      * Callback invoked when OEM hook raw event is received. Requires
    602      * the READ_PRIVILEGED_PHONE_STATE permission.
    603      * @param rawData is the byte array of the OEM hook raw data.
    604      * @hide
    605      */
    606     public void onOemHookRawEvent(byte[] rawData) {
    607         // default implementation empty
    608     }
    609 
    610     /**
    611      * Callback invoked when telephony has received notice from a carrier
    612      * app that a network action that could result in connectivity loss
    613      * has been requested by an app using
    614      * {@link android.telephony.TelephonyManager#notifyCarrierNetworkChange(boolean)}
    615      *
    616      * @param active Whether the carrier network change is or shortly
    617      *               will be active. This value is true to indicate
    618      *               showing alternative UI and false to stop.
    619      *
    620      * @hide
    621      */
    622     public void onCarrierNetworkChange(boolean active) {
    623         // default implementation empty
    624     }
    625 
    626     /**
    627      * The callback methods need to be called on the handler thread where
    628      * this object was created.  If the binder did that for us it'd be nice.
    629      *
    630      * Using a static class and weak reference here to avoid memory leak caused by the
    631      * IPhoneStateListener.Stub callback retaining references to the outside PhoneStateListeners:
    632      * even caller has been destroyed and "un-registered" the PhoneStateListener, it is still not
    633      * eligible for GC given the references coming from:
    634      * Native Stack --> PhoneStateListener --> Context (Activity).
    635      * memory of caller's context will be collected after GC from service side get triggered
    636      */
    637     private static class IPhoneStateListenerStub extends IPhoneStateListener.Stub {
    638         private WeakReference<PhoneStateListener> mPhoneStateListenerWeakRef;
    639 
    640         public IPhoneStateListenerStub(PhoneStateListener phoneStateListener) {
    641             mPhoneStateListenerWeakRef = new WeakReference<PhoneStateListener>(phoneStateListener);
    642         }
    643 
    644         private void send(int what, int arg1, int arg2, Object obj) {
    645             PhoneStateListener listener = mPhoneStateListenerWeakRef.get();
    646             if (listener != null) {
    647                 Message.obtain(listener.mHandler, what, arg1, arg2, obj).sendToTarget();
    648             }
    649         }
    650 
    651         public void onServiceStateChanged(ServiceState serviceState) {
    652             send(LISTEN_SERVICE_STATE, 0, 0, serviceState);
    653         }
    654 
    655         public void onSignalStrengthChanged(int asu) {
    656             send(LISTEN_SIGNAL_STRENGTH, asu, 0, null);
    657         }
    658 
    659         public void onMessageWaitingIndicatorChanged(boolean mwi) {
    660             send(LISTEN_MESSAGE_WAITING_INDICATOR, mwi ? 1 : 0, 0, null);
    661         }
    662 
    663         public void onCallForwardingIndicatorChanged(boolean cfi) {
    664             send(LISTEN_CALL_FORWARDING_INDICATOR, cfi ? 1 : 0, 0, null);
    665         }
    666 
    667         public void onCellLocationChanged(Bundle bundle) {
    668             CellLocation location = CellLocation.newFromBundle(bundle);
    669             send(LISTEN_CELL_LOCATION, 0, 0, location);
    670         }
    671 
    672         public void onCallStateChanged(int state, String incomingNumber) {
    673             send(LISTEN_CALL_STATE, state, 0, incomingNumber);
    674         }
    675 
    676         public void onDataConnectionStateChanged(int state, int networkType) {
    677             send(LISTEN_DATA_CONNECTION_STATE, state, networkType, null);
    678         }
    679 
    680         public void onDataActivity(int direction) {
    681             send(LISTEN_DATA_ACTIVITY, direction, 0, null);
    682         }
    683 
    684         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
    685             send(LISTEN_SIGNAL_STRENGTHS, 0, 0, signalStrength);
    686         }
    687 
    688         public void onOtaspChanged(int otaspMode) {
    689             send(LISTEN_OTASP_CHANGED, otaspMode, 0, null);
    690         }
    691 
    692         public void onCellInfoChanged(List<CellInfo> cellInfo) {
    693             send(LISTEN_CELL_INFO, 0, 0, cellInfo);
    694         }
    695 
    696         public void onPreciseCallStateChanged(PreciseCallState callState) {
    697             send(LISTEN_PRECISE_CALL_STATE, 0, 0, callState);
    698         }
    699 
    700         public void onPreciseDataConnectionStateChanged(
    701                 PreciseDataConnectionState dataConnectionState) {
    702             send(LISTEN_PRECISE_DATA_CONNECTION_STATE, 0, 0, dataConnectionState);
    703         }
    704 
    705         public void onDataConnectionRealTimeInfoChanged(
    706                 DataConnectionRealTimeInfo dcRtInfo) {
    707             send(LISTEN_DATA_CONNECTION_REAL_TIME_INFO, 0, 0, dcRtInfo);
    708         }
    709 
    710         public void onVoLteServiceStateChanged(VoLteServiceState lteState) {
    711             send(LISTEN_VOLTE_STATE, 0, 0, lteState);
    712         }
    713 
    714         public void onVoiceActivationStateChanged(int activationState) {
    715             send(LISTEN_VOICE_ACTIVATION_STATE, 0, 0, activationState);
    716         }
    717 
    718         public void onDataActivationStateChanged(int activationState) {
    719             send(LISTEN_DATA_ACTIVATION_STATE, 0, 0, activationState);
    720         }
    721 
    722         public void onUserMobileDataStateChanged(boolean enabled) {
    723             send(LISTEN_USER_MOBILE_DATA_STATE, 0, 0, enabled);
    724         }
    725 
    726         public void onOemHookRawEvent(byte[] rawData) {
    727             send(LISTEN_OEM_HOOK_RAW_EVENT, 0, 0, rawData);
    728         }
    729 
    730         public void onCarrierNetworkChange(boolean active) {
    731             send(LISTEN_CARRIER_NETWORK_CHANGE, 0, 0, active);
    732         }
    733 
    734         public void onPhysicalChannelConfigurationChanged(List<PhysicalChannelConfig> configs) {
    735             send(LISTEN_PHYSICAL_CHANNEL_CONFIGURATION, 0, 0, configs);
    736         }
    737     }
    738 
    739     IPhoneStateListener callback = new IPhoneStateListenerStub(this);
    740 
    741     private void log(String s) {
    742         Rlog.d(LOG_TAG, s);
    743     }
    744 }
    745