Home | History | Annotate | Download | only in server
      1 /*
      2  * Copyright (C) 2007 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 com.android.server;
     18 
     19 import android.app.ActivityManager;
     20 import android.content.BroadcastReceiver;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.IntentFilter;
     24 import android.content.pm.PackageManager;
     25 import android.net.LinkProperties;
     26 import android.net.NetworkCapabilities;
     27 import android.os.Binder;
     28 import android.os.Bundle;
     29 import android.os.Handler;
     30 import android.os.IBinder;
     31 import android.os.Message;
     32 import android.os.RemoteException;
     33 import android.os.UserHandle;
     34 import android.telephony.CellLocation;
     35 import android.telephony.DataConnectionRealTimeInfo;
     36 import android.telephony.Rlog;
     37 import android.telephony.TelephonyManager;
     38 import android.telephony.SubscriptionManager;
     39 import android.telephony.PhoneStateListener;
     40 import android.telephony.ServiceState;
     41 import android.telephony.SignalStrength;
     42 import android.telephony.CellInfo;
     43 import android.telephony.VoLteServiceState;
     44 import android.telephony.DisconnectCause;
     45 import android.telephony.PreciseCallState;
     46 import android.telephony.PreciseDataConnectionState;
     47 import android.telephony.PreciseDisconnectCause;
     48 import android.text.TextUtils;
     49 import android.text.format.Time;
     50 
     51 import java.util.ArrayList;
     52 import java.util.List;
     53 import java.io.FileDescriptor;
     54 import java.io.PrintWriter;
     55 
     56 import com.android.internal.app.IBatteryStats;
     57 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
     58 import com.android.internal.telephony.ITelephonyRegistry;
     59 import com.android.internal.telephony.IPhoneStateListener;
     60 import com.android.internal.telephony.DefaultPhoneNotifier;
     61 import com.android.internal.telephony.PhoneConstants;
     62 import com.android.internal.telephony.ServiceStateTracker;
     63 import com.android.internal.telephony.TelephonyIntents;
     64 import com.android.server.am.BatteryStatsService;
     65 
     66 /**
     67  * Since phone process can be restarted, this class provides a centralized place
     68  * that applications can register and be called back from.
     69  *
     70  * Change-Id: I450c968bda93767554b5188ee63e10c9f43c5aa4 fixes bugs 16148026
     71  * and 15973975 by saving the phoneId of the registrant and then using the
     72  * phoneId when deciding to to make a callback. This is necessary because
     73  * a subId changes from to a dummy value when a SIM is removed and thus won't
     74  * compare properly. Because SubscriptionManager.getPhoneId(int subId) handles
     75  * the dummy value conversion we properly do the callbacks.
     76  *
     77  * Eventually we may want to remove the notion of dummy value but for now this
     78  * looks like the best approach.
     79  */
     80 class TelephonyRegistry extends ITelephonyRegistry.Stub {
     81     private static final String TAG = "TelephonyRegistry";
     82     private static final boolean DBG = false; // STOPSHIP if true
     83     private static final boolean DBG_LOC = false; // STOPSHIP if true
     84     private static final boolean VDBG = false; // STOPSHIP if true
     85 
     86     private static class Record {
     87         String pkgForDebug;
     88 
     89         IBinder binder;
     90 
     91         IPhoneStateListener callback;
     92         IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
     93 
     94         int callerUid;
     95 
     96         int events;
     97 
     98         int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
     99 
    100         int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;
    101 
    102         boolean matchPhoneStateListenerEvent(int events) {
    103             return (callback != null) && ((events & this.events) != 0);
    104         }
    105 
    106         boolean matchOnSubscriptionsChangedListener() {
    107             return (onSubscriptionsChangedListenerCallback != null);
    108         }
    109 
    110         @Override
    111         public String toString() {
    112             return "{pkgForDebug=" + pkgForDebug + " binder=" + binder + " callback=" + callback
    113                     + " onSubscriptionsChangedListenererCallback="
    114                                             + onSubscriptionsChangedListenerCallback
    115                     + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
    116                     + " events=" + Integer.toHexString(events) + "}";
    117         }
    118     }
    119 
    120     private final Context mContext;
    121 
    122     // access should be inside synchronized (mRecords) for these two fields
    123     private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>();
    124     private final ArrayList<Record> mRecords = new ArrayList<Record>();
    125 
    126     private final IBatteryStats mBatteryStats;
    127 
    128     private boolean hasNotifySubscriptionInfoChangedOccurred = false;
    129 
    130     private int mNumPhones;
    131 
    132     private int[] mCallState;
    133 
    134     private String[] mCallIncomingNumber;
    135 
    136     private ServiceState[] mServiceState;
    137 
    138     private SignalStrength[] mSignalStrength;
    139 
    140     private boolean[] mMessageWaiting;
    141 
    142     private boolean[] mCallForwarding;
    143 
    144     private int[] mDataActivity;
    145 
    146     private int[] mDataConnectionState;
    147 
    148     private boolean[] mDataConnectionPossible;
    149 
    150     private String[] mDataConnectionReason;
    151 
    152     private String[] mDataConnectionApn;
    153 
    154     private ArrayList<String> mConnectedApns;
    155 
    156     private LinkProperties[] mDataConnectionLinkProperties;
    157 
    158     private NetworkCapabilities[] mDataConnectionNetworkCapabilities;
    159 
    160     private Bundle[] mCellLocation;
    161 
    162     private int[] mDataConnectionNetworkType;
    163 
    164     private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN;
    165 
    166     private ArrayList<List<CellInfo>> mCellInfo = null;
    167 
    168     private VoLteServiceState mVoLteServiceState = new VoLteServiceState();
    169 
    170     private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    171 
    172     private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
    173 
    174     private DataConnectionRealTimeInfo mDcRtInfo = new DataConnectionRealTimeInfo();
    175 
    176     private int mRingingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
    177 
    178     private int mForegroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
    179 
    180     private int mBackgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
    181 
    182     private PreciseCallState mPreciseCallState = new PreciseCallState();
    183 
    184     private PreciseDataConnectionState mPreciseDataConnectionState =
    185                 new PreciseDataConnectionState();
    186 
    187     static final int PHONE_STATE_PERMISSION_MASK =
    188                 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
    189                 PhoneStateListener.LISTEN_CALL_STATE |
    190                 PhoneStateListener.LISTEN_DATA_ACTIVITY |
    191                 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
    192                 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR |
    193                 PhoneStateListener.LISTEN_VOLTE_STATE;;
    194 
    195     static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
    196                 PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
    197                 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE;
    198 
    199     private static final int MSG_USER_SWITCHED = 1;
    200     private static final int MSG_UPDATE_DEFAULT_SUB = 2;
    201 
    202     private final Handler mHandler = new Handler() {
    203         @Override
    204         public void handleMessage(Message msg) {
    205             switch (msg.what) {
    206                 case MSG_USER_SWITCHED: {
    207                     if (VDBG) log("MSG_USER_SWITCHED userId=" + msg.arg1);
    208                     int numPhones = TelephonyManager.getDefault().getPhoneCount();
    209                     for (int sub = 0; sub < numPhones; sub++) {
    210                         TelephonyRegistry.this.notifyCellLocationForSubscriber(sub,
    211                                 mCellLocation[sub]);
    212                     }
    213                     break;
    214                 }
    215                 case MSG_UPDATE_DEFAULT_SUB: {
    216                     int newDefaultPhoneId = msg.arg1;
    217                     int newDefaultSubId = (Integer)(msg.obj);
    218                     if (VDBG) {
    219                         log("MSG_UPDATE_DEFAULT_SUB:current mDefaultSubId=" + mDefaultSubId
    220                             + " current mDefaultPhoneId=" + mDefaultPhoneId + " newDefaultSubId= "
    221                             + newDefaultSubId + " newDefaultPhoneId=" + newDefaultPhoneId);
    222                     }
    223 
    224                     //Due to possible risk condition,(notify call back using the new
    225                     //defaultSubId comes before new defaultSubId update) we need to recall all
    226                     //possible missed notify callback
    227                     synchronized (mRecords) {
    228                         for (Record r : mRecords) {
    229                             if(r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
    230                                 checkPossibleMissNotify(r, newDefaultPhoneId);
    231                             }
    232                         }
    233                         handleRemoveListLocked();
    234                     }
    235                     mDefaultSubId = newDefaultSubId;
    236                     mDefaultPhoneId = newDefaultPhoneId;
    237                 }
    238             }
    239         }
    240     };
    241 
    242     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    243         @Override
    244         public void onReceive(Context context, Intent intent) {
    245             String action = intent.getAction();
    246             if (VDBG) log("mBroadcastReceiver: action=" + action);
    247             if (Intent.ACTION_USER_SWITCHED.equals(action)) {
    248                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
    249                 if (DBG) log("onReceive: userHandle=" + userHandle);
    250                 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED, userHandle, 0));
    251             } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED)) {
    252                 Integer newDefaultSubIdObj = new Integer(intent.getIntExtra(
    253                         PhoneConstants.SUBSCRIPTION_KEY, SubscriptionManager.getDefaultSubId()));
    254                 int newDefaultPhoneId = intent.getIntExtra(PhoneConstants.SLOT_KEY,
    255                     SubscriptionManager.getPhoneId(mDefaultSubId));
    256                 if (DBG) {
    257                     log("onReceive:current mDefaultSubId=" + mDefaultSubId
    258                         + " current mDefaultPhoneId=" + mDefaultPhoneId + " newDefaultSubId= "
    259                         + newDefaultSubIdObj + " newDefaultPhoneId=" + newDefaultPhoneId);
    260                 }
    261 
    262                 if(validatePhoneId(newDefaultPhoneId) && (newDefaultSubIdObj.equals(mDefaultSubId)
    263                         || (newDefaultPhoneId != mDefaultPhoneId))) {
    264                     mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_DEFAULT_SUB,
    265                             newDefaultPhoneId, 0, newDefaultSubIdObj));
    266                 }
    267             }
    268         }
    269     };
    270 
    271     // we keep a copy of all of the state so we can send it out when folks
    272     // register for it
    273     //
    274     // In these calls we call with the lock held. This is safe becasuse remote
    275     // calls go through a oneway interface and local calls going through a
    276     // handler before they get to app code.
    277 
    278     TelephonyRegistry(Context context) {
    279         CellLocation  location = CellLocation.getEmpty();
    280 
    281         mContext = context;
    282         mBatteryStats = BatteryStatsService.getService();
    283         mConnectedApns = new ArrayList<String>();
    284 
    285         int numPhones = TelephonyManager.getDefault().getPhoneCount();
    286         if (DBG) log("TelephonyRegistor: ctor numPhones=" + numPhones);
    287         mNumPhones = numPhones;
    288         mCallState = new int[numPhones];
    289         mDataActivity = new int[numPhones];
    290         mDataConnectionState = new int[numPhones];
    291         mDataConnectionNetworkType = new int[numPhones];
    292         mCallIncomingNumber = new String[numPhones];
    293         mServiceState = new ServiceState[numPhones];
    294         mSignalStrength = new SignalStrength[numPhones];
    295         mMessageWaiting = new boolean[numPhones];
    296         mDataConnectionPossible = new boolean[numPhones];
    297         mDataConnectionReason = new String[numPhones];
    298         mDataConnectionApn = new String[numPhones];
    299         mCallForwarding = new boolean[numPhones];
    300         mCellLocation = new Bundle[numPhones];
    301         mDataConnectionLinkProperties = new LinkProperties[numPhones];
    302         mDataConnectionNetworkCapabilities = new NetworkCapabilities[numPhones];
    303         mCellInfo = new ArrayList<List<CellInfo>>();
    304         for (int i = 0; i < numPhones; i++) {
    305             mCallState[i] =  TelephonyManager.CALL_STATE_IDLE;
    306             mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
    307             mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN;
    308             mCallIncomingNumber[i] =  "";
    309             mServiceState[i] =  new ServiceState();
    310             mSignalStrength[i] =  new SignalStrength();
    311             mMessageWaiting[i] =  false;
    312             mCallForwarding[i] =  false;
    313             mDataConnectionPossible[i] = false;
    314             mDataConnectionReason[i] =  "";
    315             mDataConnectionApn[i] =  "";
    316             mCellLocation[i] = new Bundle();
    317             mCellInfo.add(i, null);
    318         }
    319 
    320         // Note that location can be null for non-phone builds like
    321         // like the generic one.
    322         if (location != null) {
    323             for (int i = 0; i < numPhones; i++) {
    324                 location.fillInNotifierBundle(mCellLocation[i]);
    325             }
    326         }
    327         mConnectedApns = new ArrayList<String>();
    328     }
    329 
    330     public void systemRunning() {
    331         // Watch for interesting updates
    332         final IntentFilter filter = new IntentFilter();
    333         filter.addAction(Intent.ACTION_USER_SWITCHED);
    334         filter.addAction(Intent.ACTION_USER_REMOVED);
    335         filter.addAction(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
    336         log("systemRunning register for intents");
    337         mContext.registerReceiver(mBroadcastReceiver, filter);
    338     }
    339 
    340     @Override
    341     public void addOnSubscriptionsChangedListener(String pkgForDebug,
    342             IOnSubscriptionsChangedListener callback) {
    343         int callerUid = UserHandle.getCallingUserId();
    344         int myUid = UserHandle.myUserId();
    345         if (VDBG) {
    346             log("listen oscl: E pkg=" + pkgForDebug + " myUid=" + myUid
    347                 + " callerUid="  + callerUid + " callback=" + callback
    348                 + " callback.asBinder=" + callback.asBinder());
    349         }
    350 
    351         /* Checks permission and throws Security exception */
    352         checkOnSubscriptionsChangedListenerPermission();
    353         Record r = null;
    354 
    355         synchronized (mRecords) {
    356             // register
    357             find_and_add: {
    358                 IBinder b = callback.asBinder();
    359                 final int N = mRecords.size();
    360                 for (int i = 0; i < N; i++) {
    361                     r = mRecords.get(i);
    362                     if (b == r.binder) {
    363                         break find_and_add;
    364                     }
    365                 }
    366                 r = new Record();
    367                 r.binder = b;
    368                 mRecords.add(r);
    369                 if (DBG) log("listen oscl: add new record");
    370             }
    371 
    372             r.onSubscriptionsChangedListenerCallback = callback;
    373             r.pkgForDebug = pkgForDebug;
    374             r.callerUid = callerUid;
    375             r.events = 0;
    376             if (DBG) {
    377                 log("listen oscl:  Register r=" + r);
    378             }
    379             // Always notify when registration occurs if there has been a notification.
    380             if (hasNotifySubscriptionInfoChangedOccurred) {
    381                 try {
    382                     if (VDBG) log("listen oscl: send to r=" + r);
    383                     r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged();
    384                     if (VDBG) log("listen oscl: sent to r=" + r);
    385                 } catch (RemoteException e) {
    386                     if (VDBG) log("listen oscl: remote exception sending to r=" + r + " e=" + e);
    387                     remove(r.binder);
    388                 }
    389             } else {
    390                 log("listen oscl: hasNotifySubscriptionInfoChangedOccurred==false no callback");
    391             }
    392         }
    393     }
    394 
    395     @Override
    396     public void removeOnSubscriptionsChangedListener(String pkgForDebug,
    397             IOnSubscriptionsChangedListener callback) {
    398         if (DBG) log("listen oscl: Unregister");
    399         remove(callback.asBinder());
    400     }
    401 
    402     private void checkOnSubscriptionsChangedListenerPermission() {
    403         mContext.enforceCallingOrSelfPermission(
    404                 SubscriptionManager.OnSubscriptionsChangedListener
    405                     .PERMISSION_ON_SUBSCRIPTIONS_CHANGED, null);
    406     }
    407 
    408     @Override
    409     public void notifySubscriptionInfoChanged() {
    410         if (VDBG) log("notifySubscriptionInfoChanged:");
    411         synchronized (mRecords) {
    412             if (!hasNotifySubscriptionInfoChangedOccurred) {
    413                 log("notifySubscriptionInfoChanged: first invocation mRecords.size="
    414                         + mRecords.size());
    415             }
    416             hasNotifySubscriptionInfoChangedOccurred = true;
    417             mRemoveList.clear();
    418             for (Record r : mRecords) {
    419                 if (r.matchOnSubscriptionsChangedListener()) {
    420                     try {
    421                         if (VDBG) log("notifySubscriptionInfoChanged: call osc to r=" + r);
    422                         r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged();
    423                         if (VDBG) log("notifySubscriptionInfoChanged: done osc to r=" + r);
    424                     } catch (RemoteException ex) {
    425                         if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r);
    426                         mRemoveList.add(r.binder);
    427                     }
    428                 }
    429             }
    430             handleRemoveListLocked();
    431         }
    432     }
    433 
    434     @Override
    435     public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
    436             boolean notifyNow) {
    437         listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, pkgForDebug, callback,
    438                 events, notifyNow);
    439     }
    440 
    441     @Override
    442     public void listenForSubscriber(int subId, String pkgForDebug, IPhoneStateListener callback,
    443             int events, boolean notifyNow) {
    444         listen(pkgForDebug, callback, events, notifyNow, subId);
    445     }
    446 
    447     private void listen(String pkgForDebug, IPhoneStateListener callback, int events,
    448             boolean notifyNow, int subId) {
    449         int callerUid = UserHandle.getCallingUserId();
    450         int myUid = UserHandle.myUserId();
    451         if (VDBG) {
    452             log("listen: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events)
    453                 + " notifyNow=" + notifyNow + " subId=" + subId + " myUid=" + myUid
    454                 + " callerUid=" + callerUid);
    455         }
    456 
    457         if (events != PhoneStateListener.LISTEN_NONE) {
    458             /* Checks permission and throws Security exception */
    459             checkListenerPermission(events);
    460             synchronized (mRecords) {
    461                 // register
    462                 Record r = null;
    463                 find_and_add: {
    464                     IBinder b = callback.asBinder();
    465                     final int N = mRecords.size();
    466                     for (int i = 0; i < N; i++) {
    467                         r = mRecords.get(i);
    468                         if (b == r.binder) {
    469                             break find_and_add;
    470                         }
    471                     }
    472                     r = new Record();
    473                     r.binder = b;
    474                     mRecords.add(r);
    475                     if (DBG) log("listen: add new record");
    476                 }
    477 
    478                 r.callback = callback;
    479                 r.pkgForDebug = pkgForDebug;
    480                 r.callerUid = callerUid;
    481                 // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
    482                 // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
    483                 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
    484                     r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
    485                  } else {//APP specify subID
    486                     r.subId = subId;
    487                 }
    488                 r.phoneId = SubscriptionManager.getPhoneId(r.subId);
    489 
    490                 int phoneId = r.phoneId;
    491                 r.events = events;
    492                 if (DBG) {
    493                     log("listen:  Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId);
    494                 }
    495                 if (VDBG) toStringLogSSC("listen");
    496                 if (notifyNow && validatePhoneId(phoneId)) {
    497                     if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
    498                         try {
    499                             if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]);
    500                             r.callback.onServiceStateChanged(
    501                                     new ServiceState(mServiceState[phoneId]));
    502                         } catch (RemoteException ex) {
    503                             remove(r.binder);
    504                         }
    505                     }
    506                     if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
    507                         try {
    508                             int gsmSignalStrength = mSignalStrength[phoneId]
    509                                     .getGsmSignalStrength();
    510                             r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
    511                                     : gsmSignalStrength));
    512                         } catch (RemoteException ex) {
    513                             remove(r.binder);
    514                         }
    515                     }
    516                     if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
    517                         try {
    518                             r.callback.onMessageWaitingIndicatorChanged(
    519                                     mMessageWaiting[phoneId]);
    520                         } catch (RemoteException ex) {
    521                             remove(r.binder);
    522                         }
    523                     }
    524                     if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
    525                         try {
    526                             r.callback.onCallForwardingIndicatorChanged(
    527                                     mCallForwarding[phoneId]);
    528                         } catch (RemoteException ex) {
    529                             remove(r.binder);
    530                         }
    531                     }
    532                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
    533                         try {
    534                             if (DBG_LOC) log("listen: mCellLocation = "
    535                                     + mCellLocation[phoneId]);
    536                             r.callback.onCellLocationChanged(
    537                                     new Bundle(mCellLocation[phoneId]));
    538                         } catch (RemoteException ex) {
    539                             remove(r.binder);
    540                         }
    541                     }
    542                     if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
    543                         try {
    544                             r.callback.onCallStateChanged(mCallState[phoneId],
    545                                      mCallIncomingNumber[phoneId]);
    546                         } catch (RemoteException ex) {
    547                             remove(r.binder);
    548                         }
    549                     }
    550                     if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
    551                         try {
    552                             r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
    553                                 mDataConnectionNetworkType[phoneId]);
    554                         } catch (RemoteException ex) {
    555                             remove(r.binder);
    556                         }
    557                     }
    558                     if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
    559                         try {
    560                             r.callback.onDataActivity(mDataActivity[phoneId]);
    561                         } catch (RemoteException ex) {
    562                             remove(r.binder);
    563                         }
    564                     }
    565                     if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
    566                         try {
    567                             r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
    568                         } catch (RemoteException ex) {
    569                             remove(r.binder);
    570                         }
    571                     }
    572                     if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
    573                         try {
    574                             r.callback.onOtaspChanged(mOtaspMode);
    575                         } catch (RemoteException ex) {
    576                             remove(r.binder);
    577                         }
    578                     }
    579                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
    580                         try {
    581                             if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = "
    582                                     + mCellInfo.get(phoneId));
    583                             r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
    584                         } catch (RemoteException ex) {
    585                             remove(r.binder);
    586                         }
    587                     }
    588                     if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) {
    589                         try {
    590                             r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo);
    591                         } catch (RemoteException ex) {
    592                             remove(r.binder);
    593                         }
    594                     }
    595                     if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
    596                         try {
    597                             r.callback.onPreciseCallStateChanged(mPreciseCallState);
    598                         } catch (RemoteException ex) {
    599                             remove(r.binder);
    600                         }
    601                     }
    602                     if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
    603                         try {
    604                             r.callback.onPreciseDataConnectionStateChanged(
    605                                     mPreciseDataConnectionState);
    606                         } catch (RemoteException ex) {
    607                             remove(r.binder);
    608                         }
    609                     }
    610                 }
    611             }
    612         } else {
    613             if(DBG) log("listen: Unregister");
    614             remove(callback.asBinder());
    615         }
    616     }
    617 
    618     private void remove(IBinder binder) {
    619         synchronized (mRecords) {
    620             final int recordCount = mRecords.size();
    621             for (int i = 0; i < recordCount; i++) {
    622                 if (mRecords.get(i).binder == binder) {
    623                     if (DBG) {
    624                         Record r = mRecords.get(i);
    625                         log("remove: binder=" + binder + "r.pkgForDebug" + r.pkgForDebug
    626                                 + "r.callback" + r.callback);
    627                     }
    628                     mRecords.remove(i);
    629                     return;
    630                 }
    631             }
    632         }
    633     }
    634 
    635     public void notifyCallState(int state, String incomingNumber) {
    636         if (!checkNotifyPermission("notifyCallState()")) {
    637             return;
    638         }
    639 
    640         if (VDBG) {
    641             log("notifyCallState: state=" + state + " incomingNumber=" + incomingNumber);
    642         }
    643 
    644         synchronized (mRecords) {
    645             for (Record r : mRecords) {
    646                 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
    647                         (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
    648                     try {
    649                         r.callback.onCallStateChanged(state, incomingNumber);
    650                     } catch (RemoteException ex) {
    651                         mRemoveList.add(r.binder);
    652                     }
    653                 }
    654             }
    655             handleRemoveListLocked();
    656         }
    657         broadcastCallStateChanged(state, incomingNumber,
    658                 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
    659     }
    660 
    661     public void notifyCallStateForSubscriber(int subId, int state, String incomingNumber) {
    662         if (!checkNotifyPermission("notifyCallState()")) {
    663             return;
    664         }
    665         if (VDBG) {
    666             log("notifyCallStateForSubscriber: subId=" + subId
    667                 + " state=" + state + " incomingNumber=" + incomingNumber);
    668         }
    669         synchronized (mRecords) {
    670             int phoneId = SubscriptionManager.getPhoneId(subId);
    671             if (validatePhoneId(phoneId)) {
    672                 mCallState[phoneId] = state;
    673                 mCallIncomingNumber[phoneId] = incomingNumber;
    674                 for (Record r : mRecords) {
    675                     if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
    676                             (r.subId == subId) &&
    677                             (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
    678                         try {
    679                             r.callback.onCallStateChanged(state, incomingNumber);
    680                         } catch (RemoteException ex) {
    681                             mRemoveList.add(r.binder);
    682                         }
    683                     }
    684                 }
    685             }
    686             handleRemoveListLocked();
    687         }
    688         broadcastCallStateChanged(state, incomingNumber, subId);
    689     }
    690 
    691     public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) {
    692         if (!checkNotifyPermission("notifyServiceState()")){
    693             return;
    694         }
    695 
    696         synchronized (mRecords) {
    697             if (VDBG) {
    698                 log("notifyServiceStateForSubscriber: subId=" + subId + " phoneId=" + phoneId
    699                     + " state=" + state);
    700             }
    701             if (validatePhoneId(phoneId)) {
    702                 mServiceState[phoneId] = state;
    703                 logServiceStateChanged("notifyServiceStateForSubscriber", subId, phoneId, state);
    704                 if (VDBG) toStringLogSSC("notifyServiceStateForSubscriber");
    705 
    706                 for (Record r : mRecords) {
    707                     if (VDBG) {
    708                         log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId
    709                                 + " phoneId=" + phoneId + " state=" + state);
    710                     }
    711                     if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) &&
    712                             idMatch(r.subId, subId, phoneId)) {
    713                         try {
    714                             if (DBG) {
    715                                 log("notifyServiceStateForSubscriber: callback.onSSC r=" + r
    716                                         + " subId=" + subId + " phoneId=" + phoneId
    717                                         + " state=" + state);
    718                             }
    719                             r.callback.onServiceStateChanged(new ServiceState(state));
    720                         } catch (RemoteException ex) {
    721                             mRemoveList.add(r.binder);
    722                         }
    723                     }
    724                 }
    725             } else {
    726                 log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId);
    727             }
    728             handleRemoveListLocked();
    729         }
    730         broadcastServiceStateChanged(state, subId);
    731     }
    732 
    733     public void notifySignalStrength(SignalStrength signalStrength) {
    734         notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
    735                 signalStrength);
    736     }
    737 
    738     public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) {
    739         if (!checkNotifyPermission("notifySignalStrength()")) {
    740             return;
    741         }
    742         if (VDBG) {
    743             log("notifySignalStrengthForSubscriber: subId=" + subId
    744                 + " signalStrength=" + signalStrength);
    745             toStringLogSSC("notifySignalStrengthForSubscriber");
    746         }
    747         synchronized (mRecords) {
    748             int phoneId = SubscriptionManager.getPhoneId(subId);
    749             if (validatePhoneId(phoneId)) {
    750                 if (VDBG) log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId);
    751                 mSignalStrength[phoneId] = signalStrength;
    752                 for (Record r : mRecords) {
    753                     if (VDBG) {
    754                         log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId
    755                                 + " phoneId=" + phoneId + " ss=" + signalStrength);
    756                     }
    757                     if (r.matchPhoneStateListenerEvent(
    758                                 PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) &&
    759                             idMatch(r.subId, subId, phoneId)) {
    760                         try {
    761                             if (DBG) {
    762                                 log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r
    763                                         + " subId=" + subId + " phoneId=" + phoneId
    764                                         + " ss=" + signalStrength);
    765                             }
    766                             r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
    767                         } catch (RemoteException ex) {
    768                             mRemoveList.add(r.binder);
    769                         }
    770                     }
    771                     if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) &&
    772                             idMatch(r.subId, subId, phoneId)){
    773                         try {
    774                             int gsmSignalStrength = signalStrength.getGsmSignalStrength();
    775                             int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
    776                             if (DBG) {
    777                                 log("notifySignalStrengthForSubscriber: callback.onSS r=" + r
    778                                         + " subId=" + subId + " phoneId=" + phoneId
    779                                         + " gsmSS=" + gsmSignalStrength + " ss=" + ss);
    780                             }
    781                             r.callback.onSignalStrengthChanged(ss);
    782                         } catch (RemoteException ex) {
    783                             mRemoveList.add(r.binder);
    784                         }
    785                     }
    786                 }
    787             } else {
    788                 log("notifySignalStrengthForSubscriber: invalid phoneId=" + phoneId);
    789             }
    790             handleRemoveListLocked();
    791         }
    792         broadcastSignalStrengthChanged(signalStrength, subId);
    793     }
    794 
    795     public void notifyCellInfo(List<CellInfo> cellInfo) {
    796          notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellInfo);
    797     }
    798 
    799     public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) {
    800         if (!checkNotifyPermission("notifyCellInfo()")) {
    801             return;
    802         }
    803         if (VDBG) {
    804             log("notifyCellInfoForSubscriber: subId=" + subId
    805                 + " cellInfo=" + cellInfo);
    806         }
    807 
    808         synchronized (mRecords) {
    809             int phoneId = SubscriptionManager.getPhoneId(subId);
    810             if (validatePhoneId(phoneId)) {
    811                 mCellInfo.set(phoneId, cellInfo);
    812                 for (Record r : mRecords) {
    813                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) &&
    814                             idMatch(r.subId, subId, phoneId)) {
    815                         try {
    816                             if (DBG_LOC) {
    817                                 log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r);
    818                             }
    819                             r.callback.onCellInfoChanged(cellInfo);
    820                         } catch (RemoteException ex) {
    821                             mRemoveList.add(r.binder);
    822                         }
    823                     }
    824                 }
    825             }
    826             handleRemoveListLocked();
    827         }
    828     }
    829 
    830     public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) {
    831         if (!checkNotifyPermission("notifyDataConnectionRealTimeInfo()")) {
    832             return;
    833         }
    834 
    835         synchronized (mRecords) {
    836             mDcRtInfo = dcRtInfo;
    837             for (Record r : mRecords) {
    838                 if (validateEventsAndUserLocked(r,
    839                         PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO)) {
    840                     try {
    841                         if (DBG_LOC) {
    842                             log("notifyDataConnectionRealTimeInfo: mDcRtInfo="
    843                                     + mDcRtInfo + " r=" + r);
    844                         }
    845                         r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo);
    846                     } catch (RemoteException ex) {
    847                         mRemoveList.add(r.binder);
    848                     }
    849                 }
    850             }
    851             handleRemoveListLocked();
    852         }
    853     }
    854 
    855     @Override
    856     public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) {
    857         if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
    858             return;
    859         }
    860         if (VDBG) {
    861             log("notifyMessageWaitingChangedForSubscriberPhoneID: subId=" + phoneId
    862                 + " mwi=" + mwi);
    863         }
    864         synchronized (mRecords) {
    865             if (validatePhoneId(phoneId)) {
    866                 mMessageWaiting[phoneId] = mwi;
    867                 for (Record r : mRecords) {
    868                     if (r.matchPhoneStateListenerEvent(
    869                             PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) &&
    870                             idMatch(r.subId, subId, phoneId)) {
    871                         try {
    872                             r.callback.onMessageWaitingIndicatorChanged(mwi);
    873                         } catch (RemoteException ex) {
    874                             mRemoveList.add(r.binder);
    875                         }
    876                     }
    877                 }
    878             }
    879             handleRemoveListLocked();
    880         }
    881     }
    882 
    883     public void notifyCallForwardingChanged(boolean cfi) {
    884         notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cfi);
    885     }
    886 
    887     public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) {
    888         if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
    889             return;
    890         }
    891         if (VDBG) {
    892             log("notifyCallForwardingChangedForSubscriber: subId=" + subId
    893                 + " cfi=" + cfi);
    894         }
    895         synchronized (mRecords) {
    896             int phoneId = SubscriptionManager.getPhoneId(subId);
    897             if (validatePhoneId(phoneId)) {
    898                 mCallForwarding[phoneId] = cfi;
    899                 for (Record r : mRecords) {
    900                     if (r.matchPhoneStateListenerEvent(
    901                             PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) &&
    902                             idMatch(r.subId, subId, phoneId)) {
    903                         try {
    904                             r.callback.onCallForwardingIndicatorChanged(cfi);
    905                         } catch (RemoteException ex) {
    906                             mRemoveList.add(r.binder);
    907                         }
    908                     }
    909                 }
    910             }
    911             handleRemoveListLocked();
    912         }
    913     }
    914 
    915     public void notifyDataActivity(int state) {
    916         notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state);
    917     }
    918 
    919     public void notifyDataActivityForSubscriber(int subId, int state) {
    920         if (!checkNotifyPermission("notifyDataActivity()" )) {
    921             return;
    922         }
    923         synchronized (mRecords) {
    924             int phoneId = SubscriptionManager.getPhoneId(subId);
    925             if (validatePhoneId(phoneId)) {
    926                 mDataActivity[phoneId] = state;
    927                 for (Record r : mRecords) {
    928                     if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) {
    929                         try {
    930                             r.callback.onDataActivity(state);
    931                         } catch (RemoteException ex) {
    932                             mRemoveList.add(r.binder);
    933                         }
    934                     }
    935                 }
    936             }
    937             handleRemoveListLocked();
    938         }
    939     }
    940 
    941     public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
    942             String reason, String apn, String apnType, LinkProperties linkProperties,
    943             NetworkCapabilities networkCapabilities, int networkType, boolean roaming) {
    944         notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state,
    945             isDataConnectivityPossible,reason, apn, apnType, linkProperties,
    946             networkCapabilities, networkType, roaming);
    947     }
    948 
    949     public void notifyDataConnectionForSubscriber(int subId, int state,
    950             boolean isDataConnectivityPossible, String reason, String apn, String apnType,
    951             LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
    952             int networkType, boolean roaming) {
    953         if (!checkNotifyPermission("notifyDataConnection()" )) {
    954             return;
    955         }
    956         if (VDBG) {
    957             log("notifyDataConnectionForSubscriber: subId=" + subId
    958                 + " state=" + state + " isDataConnectivityPossible=" + isDataConnectivityPossible
    959                 + " reason='" + reason
    960                 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType
    961                 + " mRecords.size()=" + mRecords.size());
    962         }
    963         synchronized (mRecords) {
    964             int phoneId = SubscriptionManager.getPhoneId(subId);
    965             if (validatePhoneId(phoneId)) {
    966                 boolean modified = false;
    967                 if (state == TelephonyManager.DATA_CONNECTED) {
    968                     if (!mConnectedApns.contains(apnType)) {
    969                         mConnectedApns.add(apnType);
    970                         if (mDataConnectionState[phoneId] != state) {
    971                             mDataConnectionState[phoneId] = state;
    972                             modified = true;
    973                         }
    974                     }
    975                 } else {
    976                     if (mConnectedApns.remove(apnType)) {
    977                         if (mConnectedApns.isEmpty()) {
    978                             mDataConnectionState[phoneId] = state;
    979                             modified = true;
    980                         } else {
    981                             // leave mDataConnectionState as is and
    982                             // send out the new status for the APN in question.
    983                         }
    984                     }
    985                 }
    986                 mDataConnectionPossible[phoneId] = isDataConnectivityPossible;
    987                 mDataConnectionReason[phoneId] = reason;
    988                 mDataConnectionLinkProperties[phoneId] = linkProperties;
    989                 mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities;
    990                 if (mDataConnectionNetworkType[phoneId] != networkType) {
    991                     mDataConnectionNetworkType[phoneId] = networkType;
    992                     // need to tell registered listeners about the new network type
    993                     modified = true;
    994                 }
    995                 if (modified) {
    996                     if (DBG) {
    997                         log("onDataConnectionStateChanged(" + mDataConnectionState[phoneId]
    998                             + ", " + mDataConnectionNetworkType[phoneId] + ")");
    999                     }
   1000                     for (Record r : mRecords) {
   1001                         if (r.matchPhoneStateListenerEvent(
   1002                                 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) &&
   1003                                 idMatch(r.subId, subId, phoneId)) {
   1004                             try {
   1005                                 log("Notify data connection state changed on sub: " +
   1006                                         subId);
   1007                                 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
   1008                                         mDataConnectionNetworkType[phoneId]);
   1009                             } catch (RemoteException ex) {
   1010                                 mRemoveList.add(r.binder);
   1011                             }
   1012                         }
   1013                     }
   1014                     handleRemoveListLocked();
   1015                 }
   1016                 mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType,
   1017                         apnType, apn, reason, linkProperties, "");
   1018                 for (Record r : mRecords) {
   1019                     if (r.matchPhoneStateListenerEvent(
   1020                             PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
   1021                         try {
   1022                             r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
   1023                         } catch (RemoteException ex) {
   1024                             mRemoveList.add(r.binder);
   1025                         }
   1026                     }
   1027                 }
   1028             }
   1029             handleRemoveListLocked();
   1030         }
   1031         broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
   1032                 apnType, linkProperties, networkCapabilities, roaming, subId);
   1033         broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason,
   1034                 linkProperties, "");
   1035     }
   1036 
   1037     public void notifyDataConnectionFailed(String reason, String apnType) {
   1038          notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
   1039                  reason, apnType);
   1040     }
   1041 
   1042     public void notifyDataConnectionFailedForSubscriber(int subId,
   1043             String reason, String apnType) {
   1044         if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
   1045             return;
   1046         }
   1047         if (VDBG) {
   1048             log("notifyDataConnectionFailedForSubscriber: subId=" + subId
   1049                 + " reason=" + reason + " apnType=" + apnType);
   1050         }
   1051         synchronized (mRecords) {
   1052             mPreciseDataConnectionState = new PreciseDataConnectionState(
   1053                     TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN,
   1054                     apnType, "", reason, null, "");
   1055             for (Record r : mRecords) {
   1056                 if (r.matchPhoneStateListenerEvent(
   1057                         PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
   1058                     try {
   1059                         r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
   1060                     } catch (RemoteException ex) {
   1061                         mRemoveList.add(r.binder);
   1062                     }
   1063                 }
   1064             }
   1065             handleRemoveListLocked();
   1066         }
   1067         broadcastDataConnectionFailed(reason, apnType, subId);
   1068         broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
   1069                 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, "");
   1070     }
   1071 
   1072     public void notifyCellLocation(Bundle cellLocation) {
   1073          notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation);
   1074     }
   1075 
   1076     public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) {
   1077         log("notifyCellLocationForSubscriber: subId=" + subId
   1078                 + " cellLocation=" + cellLocation);
   1079         if (!checkNotifyPermission("notifyCellLocation()")) {
   1080             return;
   1081         }
   1082         if (VDBG) {
   1083             log("notifyCellLocationForSubscriber: subId=" + subId
   1084                 + " cellLocation=" + cellLocation);
   1085         }
   1086         synchronized (mRecords) {
   1087             int phoneId = SubscriptionManager.getPhoneId(subId);
   1088             if (validatePhoneId(phoneId)) {
   1089                 mCellLocation[phoneId] = cellLocation;
   1090                 for (Record r : mRecords) {
   1091                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) &&
   1092                             idMatch(r.subId, subId, phoneId)) {
   1093                         try {
   1094                             if (DBG_LOC) {
   1095                                 log("notifyCellLocation: cellLocation=" + cellLocation
   1096                                         + " r=" + r);
   1097                             }
   1098                             r.callback.onCellLocationChanged(new Bundle(cellLocation));
   1099                         } catch (RemoteException ex) {
   1100                             mRemoveList.add(r.binder);
   1101                         }
   1102                     }
   1103                 }
   1104             }
   1105             handleRemoveListLocked();
   1106         }
   1107     }
   1108 
   1109     public void notifyOtaspChanged(int otaspMode) {
   1110         if (!checkNotifyPermission("notifyOtaspChanged()" )) {
   1111             return;
   1112         }
   1113         synchronized (mRecords) {
   1114             mOtaspMode = otaspMode;
   1115             for (Record r : mRecords) {
   1116                 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_OTASP_CHANGED)) {
   1117                     try {
   1118                         r.callback.onOtaspChanged(otaspMode);
   1119                     } catch (RemoteException ex) {
   1120                         mRemoveList.add(r.binder);
   1121                     }
   1122                 }
   1123             }
   1124             handleRemoveListLocked();
   1125         }
   1126     }
   1127 
   1128     public void notifyPreciseCallState(int ringingCallState, int foregroundCallState,
   1129             int backgroundCallState) {
   1130         if (!checkNotifyPermission("notifyPreciseCallState()")) {
   1131             return;
   1132         }
   1133         synchronized (mRecords) {
   1134             mRingingCallState = ringingCallState;
   1135             mForegroundCallState = foregroundCallState;
   1136             mBackgroundCallState = backgroundCallState;
   1137             mPreciseCallState = new PreciseCallState(ringingCallState, foregroundCallState,
   1138                     backgroundCallState,
   1139                     DisconnectCause.NOT_VALID,
   1140                     PreciseDisconnectCause.NOT_VALID);
   1141             for (Record r : mRecords) {
   1142                 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) {
   1143                     try {
   1144                         r.callback.onPreciseCallStateChanged(mPreciseCallState);
   1145                     } catch (RemoteException ex) {
   1146                         mRemoveList.add(r.binder);
   1147                     }
   1148                 }
   1149             }
   1150             handleRemoveListLocked();
   1151         }
   1152         broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState,
   1153                 DisconnectCause.NOT_VALID,
   1154                 PreciseDisconnectCause.NOT_VALID);
   1155     }
   1156 
   1157     public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) {
   1158         if (!checkNotifyPermission("notifyDisconnectCause()")) {
   1159             return;
   1160         }
   1161         synchronized (mRecords) {
   1162             mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState,
   1163                     mBackgroundCallState, disconnectCause, preciseDisconnectCause);
   1164             for (Record r : mRecords) {
   1165                 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) {
   1166                     try {
   1167                         r.callback.onPreciseCallStateChanged(mPreciseCallState);
   1168                     } catch (RemoteException ex) {
   1169                         mRemoveList.add(r.binder);
   1170                     }
   1171                 }
   1172             }
   1173             handleRemoveListLocked();
   1174         }
   1175         broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState,
   1176                 mBackgroundCallState, disconnectCause, preciseDisconnectCause);
   1177     }
   1178 
   1179     public void notifyPreciseDataConnectionFailed(String reason, String apnType,
   1180             String apn, String failCause) {
   1181         if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) {
   1182             return;
   1183         }
   1184         synchronized (mRecords) {
   1185             mPreciseDataConnectionState = new PreciseDataConnectionState(
   1186                     TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN,
   1187                     apnType, apn, reason, null, failCause);
   1188             for (Record r : mRecords) {
   1189                 if (r.matchPhoneStateListenerEvent(
   1190                         PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) {
   1191                     try {
   1192                         r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState);
   1193                     } catch (RemoteException ex) {
   1194                         mRemoveList.add(r.binder);
   1195                     }
   1196                 }
   1197             }
   1198             handleRemoveListLocked();
   1199         }
   1200         broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN,
   1201                 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause);
   1202     }
   1203 
   1204     public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) {
   1205         if (!checkNotifyPermission("notifyVoLteServiceStateChanged()")) {
   1206             return;
   1207         }
   1208         synchronized (mRecords) {
   1209             mVoLteServiceState = lteState;
   1210             for (Record r : mRecords) {
   1211                 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_VOLTE_STATE)) {
   1212                     try {
   1213                         r.callback.onVoLteServiceStateChanged(
   1214                                 new VoLteServiceState(mVoLteServiceState));
   1215                     } catch (RemoteException ex) {
   1216                         mRemoveList.add(r.binder);
   1217                     }
   1218                 }
   1219             }
   1220             handleRemoveListLocked();
   1221         }
   1222     }
   1223 
   1224     public void notifyOemHookRawEventForSubscriber(int subId, byte[] rawData) {
   1225         if (!checkNotifyPermission("notifyOemHookRawEventForSubscriber")) {
   1226             return;
   1227         }
   1228 
   1229         synchronized (mRecords) {
   1230             for (Record r : mRecords) {
   1231                 if (VDBG) {
   1232                     log("notifyOemHookRawEventForSubscriber:  r=" + r + " subId=" + subId);
   1233                 }
   1234                 if ((r.matchPhoneStateListenerEvent(
   1235                         PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) &&
   1236                         ((r.subId == subId) ||
   1237                         (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID))) {
   1238                     try {
   1239                         r.callback.onOemHookRawEvent(rawData);
   1240                     } catch (RemoteException ex) {
   1241                         mRemoveList.add(r.binder);
   1242                     }
   1243                 }
   1244             }
   1245             handleRemoveListLocked();
   1246         }
   1247     }
   1248 
   1249     @Override
   1250     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1251         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
   1252                 != PackageManager.PERMISSION_GRANTED) {
   1253             pw.println("Permission Denial: can't dump telephony.registry from from pid="
   1254                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
   1255             return;
   1256         }
   1257         synchronized (mRecords) {
   1258             final int recordCount = mRecords.size();
   1259             pw.println("last known state:");
   1260             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
   1261                 pw.println("  Phone Id=" + i);
   1262                 pw.println("  mCallState=" + mCallState[i]);
   1263                 pw.println("  mCallIncomingNumber=" + mCallIncomingNumber[i]);
   1264                 pw.println("  mServiceState=" + mServiceState[i]);
   1265                 pw.println("  mSignalStrength=" + mSignalStrength[i]);
   1266                 pw.println("  mMessageWaiting=" + mMessageWaiting[i]);
   1267                 pw.println("  mCallForwarding=" + mCallForwarding[i]);
   1268                 pw.println("  mDataActivity=" + mDataActivity[i]);
   1269                 pw.println("  mDataConnectionState=" + mDataConnectionState[i]);
   1270                 pw.println("  mDataConnectionPossible=" + mDataConnectionPossible[i]);
   1271                 pw.println("  mDataConnectionReason=" + mDataConnectionReason[i]);
   1272                 pw.println("  mDataConnectionApn=" + mDataConnectionApn[i]);
   1273                 pw.println("  mDataConnectionLinkProperties=" + mDataConnectionLinkProperties[i]);
   1274                 pw.println("  mDataConnectionNetworkCapabilities=" +
   1275                         mDataConnectionNetworkCapabilities[i]);
   1276                 pw.println("  mCellLocation=" + mCellLocation[i]);
   1277                 pw.println("  mCellInfo=" + mCellInfo.get(i));
   1278             }
   1279             pw.println("  mDcRtInfo=" + mDcRtInfo);
   1280             pw.println("registrations: count=" + recordCount);
   1281             for (Record r : mRecords) {
   1282                 pw.println("  " + r);
   1283             }
   1284         }
   1285     }
   1286 
   1287     //
   1288     // the legacy intent broadcasting
   1289     //
   1290 
   1291     private void broadcastServiceStateChanged(ServiceState state, int subId) {
   1292         long ident = Binder.clearCallingIdentity();
   1293         try {
   1294             mBatteryStats.notePhoneState(state.getState());
   1295         } catch (RemoteException re) {
   1296             // Can't do much
   1297         } finally {
   1298             Binder.restoreCallingIdentity(ident);
   1299         }
   1300 
   1301         Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
   1302         Bundle data = new Bundle();
   1303         state.fillInNotifierBundle(data);
   1304         intent.putExtras(data);
   1305         // Pass the subscription along with the intent.
   1306         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
   1307         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
   1308     }
   1309 
   1310     private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int subId) {
   1311         long ident = Binder.clearCallingIdentity();
   1312         try {
   1313             mBatteryStats.notePhoneSignalStrength(signalStrength);
   1314         } catch (RemoteException e) {
   1315             /* The remote entity disappeared, we can safely ignore the exception. */
   1316         } finally {
   1317             Binder.restoreCallingIdentity(ident);
   1318         }
   1319 
   1320         Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
   1321         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
   1322         Bundle data = new Bundle();
   1323         signalStrength.fillInNotifierBundle(data);
   1324         intent.putExtras(data);
   1325         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
   1326         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
   1327     }
   1328 
   1329     private void broadcastCallStateChanged(int state, String incomingNumber, int subId) {
   1330         long ident = Binder.clearCallingIdentity();
   1331         try {
   1332             if (state == TelephonyManager.CALL_STATE_IDLE) {
   1333                 mBatteryStats.notePhoneOff();
   1334             } else {
   1335                 mBatteryStats.notePhoneOn();
   1336             }
   1337         } catch (RemoteException e) {
   1338             /* The remote entity disappeared, we can safely ignore the exception. */
   1339         } finally {
   1340             Binder.restoreCallingIdentity(ident);
   1341         }
   1342 
   1343         Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
   1344         intent.putExtra(PhoneConstants.STATE_KEY,
   1345                 DefaultPhoneNotifier.convertCallState(state).toString());
   1346         if (!TextUtils.isEmpty(incomingNumber)) {
   1347             intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
   1348         }
   1349         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
   1350         mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
   1351                 android.Manifest.permission.READ_PHONE_STATE);
   1352     }
   1353 
   1354     private void broadcastDataConnectionStateChanged(int state,
   1355             boolean isDataConnectivityPossible,
   1356             String reason, String apn, String apnType, LinkProperties linkProperties,
   1357             NetworkCapabilities networkCapabilities, boolean roaming, int subId) {
   1358         // Note: not reporting to the battery stats service here, because the
   1359         // status bar takes care of that after taking into account all of the
   1360         // required info.
   1361         Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
   1362         intent.putExtra(PhoneConstants.STATE_KEY,
   1363                 DefaultPhoneNotifier.convertDataState(state).toString());
   1364         if (!isDataConnectivityPossible) {
   1365             intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true);
   1366         }
   1367         if (reason != null) {
   1368             intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
   1369         }
   1370         if (linkProperties != null) {
   1371             intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
   1372             String iface = linkProperties.getInterfaceName();
   1373             if (iface != null) {
   1374                 intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
   1375             }
   1376         }
   1377         if (networkCapabilities != null) {
   1378             intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY, networkCapabilities);
   1379         }
   1380         if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true);
   1381 
   1382         intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
   1383         intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
   1384         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
   1385         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
   1386     }
   1387 
   1388     private void broadcastDataConnectionFailed(String reason, String apnType,
   1389             int subId) {
   1390         Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
   1391         intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason);
   1392         intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
   1393         intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
   1394         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
   1395     }
   1396 
   1397     private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState,
   1398             int backgroundCallState, int disconnectCause, int preciseDisconnectCause) {
   1399         Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED);
   1400         intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState);
   1401         intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState);
   1402         intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState);
   1403         intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause);
   1404         intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause);
   1405         mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
   1406                 android.Manifest.permission.READ_PRECISE_PHONE_STATE);
   1407     }
   1408 
   1409     private void broadcastPreciseDataConnectionStateChanged(int state, int networkType,
   1410             String apnType, String apn, String reason, LinkProperties linkProperties,
   1411             String failCause) {
   1412         Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED);
   1413         intent.putExtra(PhoneConstants.STATE_KEY, state);
   1414         intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType);
   1415         if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason);
   1416         if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);
   1417         if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
   1418         if (linkProperties != null) {
   1419             intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY,linkProperties);
   1420         }
   1421         if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause);
   1422 
   1423         mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
   1424                 android.Manifest.permission.READ_PRECISE_PHONE_STATE);
   1425     }
   1426 
   1427     private boolean checkNotifyPermission(String method) {
   1428         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
   1429                 == PackageManager.PERMISSION_GRANTED) {
   1430             return true;
   1431         }
   1432         String msg = "Modify Phone State Permission Denial: " + method + " from pid="
   1433                 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
   1434         if (DBG) log(msg);
   1435         return false;
   1436     }
   1437 
   1438     private void checkListenerPermission(int events) {
   1439         if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
   1440             mContext.enforceCallingOrSelfPermission(
   1441                     android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
   1442 
   1443         }
   1444 
   1445         if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
   1446             mContext.enforceCallingOrSelfPermission(
   1447                     android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
   1448 
   1449         }
   1450 
   1451         if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
   1452             mContext.enforceCallingOrSelfPermission(
   1453                     android.Manifest.permission.READ_PHONE_STATE, null);
   1454         }
   1455 
   1456         if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) {
   1457             mContext.enforceCallingOrSelfPermission(
   1458                     android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
   1459 
   1460         }
   1461 
   1462         if ((events & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) {
   1463             mContext.enforceCallingOrSelfPermission(
   1464                     android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
   1465         }
   1466     }
   1467 
   1468     private void handleRemoveListLocked() {
   1469         int size = mRemoveList.size();
   1470         if (VDBG) log("handleRemoveListLocked: mRemoveList.size()=" + size);
   1471         if (size > 0) {
   1472             for (IBinder b: mRemoveList) {
   1473                 remove(b);
   1474             }
   1475             mRemoveList.clear();
   1476         }
   1477     }
   1478 
   1479     private boolean validateEventsAndUserLocked(Record r, int events) {
   1480         int foregroundUser;
   1481         long callingIdentity = Binder.clearCallingIdentity();
   1482         boolean valid = false;
   1483         try {
   1484             foregroundUser = ActivityManager.getCurrentUser();
   1485             valid = r.callerUid ==  foregroundUser && r.matchPhoneStateListenerEvent(events);
   1486             if (DBG | DBG_LOC) {
   1487                 log("validateEventsAndUserLocked: valid=" + valid
   1488                         + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser
   1489                         + " r.events=" + r.events + " events=" + events);
   1490             }
   1491         } finally {
   1492             Binder.restoreCallingIdentity(callingIdentity);
   1493         }
   1494         return valid;
   1495     }
   1496 
   1497     private boolean validatePhoneId(int phoneId) {
   1498         boolean valid = (phoneId >= 0) && (phoneId < mNumPhones);
   1499         if (VDBG) log("validatePhoneId: " + valid);
   1500         return valid;
   1501     }
   1502 
   1503     private static void log(String s) {
   1504         Rlog.d(TAG, s);
   1505     }
   1506 
   1507     private static class LogSSC {
   1508         private Time mTime;
   1509         private String mS;
   1510         private int mSubId;
   1511         private int mPhoneId;
   1512         private ServiceState mState;
   1513 
   1514         public void set(Time t, String s, int subId, int phoneId, ServiceState state) {
   1515             mTime = t; mS = s; mSubId = subId; mPhoneId = phoneId; mState = state;
   1516         }
   1517 
   1518         @Override
   1519         public String toString() {
   1520             return mS + " Time " + mTime.toString() + " mSubId " + mSubId + " mPhoneId "
   1521                     + mPhoneId + "  mState " + mState;
   1522         }
   1523     }
   1524 
   1525     private LogSSC logSSC [] = new LogSSC[10];
   1526     private int next = 0;
   1527 
   1528     private void logServiceStateChanged(String s, int subId, int phoneId, ServiceState state) {
   1529         if (logSSC == null || logSSC.length == 0) {
   1530             return;
   1531         }
   1532         if (logSSC[next] == null) {
   1533             logSSC[next] = new LogSSC();
   1534         }
   1535         Time t = new Time();
   1536         t.setToNow();
   1537         logSSC[next].set(t, s, subId, phoneId, state);
   1538         if (++next >= logSSC.length) {
   1539             next = 0;
   1540         }
   1541     }
   1542 
   1543     private void toStringLogSSC(String prompt) {
   1544         if (logSSC == null || logSSC.length == 0 || (next == 0 && logSSC[next] == null)) {
   1545             log(prompt + ": logSSC is empty");
   1546         } else {
   1547             // There is at least one element
   1548             log(prompt + ": logSSC.length=" + logSSC.length + " next=" + next);
   1549             int i = next;
   1550             if (logSSC[i] == null) {
   1551                 // logSSC is not full so back to the beginning
   1552                 i = 0;
   1553             }
   1554             do {
   1555                 log(logSSC[i].toString());
   1556                 if (++i >= logSSC.length) {
   1557                     i = 0;
   1558                 }
   1559             } while (i != next);
   1560             log(prompt + ": ----------------");
   1561         }
   1562     }
   1563 
   1564     boolean idMatch(int rSubId, int subId, int phoneId) {
   1565 
   1566         if(subId < 0) {
   1567             // Invalid case, we need compare phoneId with default one.
   1568             return (mDefaultPhoneId == phoneId);
   1569         }
   1570         if(rSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
   1571             return (subId == mDefaultSubId);
   1572         } else {
   1573             return (rSubId == subId);
   1574         }
   1575     }
   1576 
   1577     private void checkPossibleMissNotify(Record r, int phoneId) {
   1578         int events = r.events;
   1579 
   1580         if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
   1581             try {
   1582                 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" +
   1583                         mServiceState[phoneId]);
   1584                 r.callback.onServiceStateChanged(
   1585                         new ServiceState(mServiceState[phoneId]));
   1586             } catch (RemoteException ex) {
   1587                 mRemoveList.add(r.binder);
   1588             }
   1589         }
   1590 
   1591         if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
   1592             try {
   1593                 SignalStrength signalStrength = mSignalStrength[phoneId];
   1594                 if (DBG) {
   1595                     log("checkPossibleMissNotify: onSignalStrengthsChanged SS=" + signalStrength);
   1596                 }
   1597                 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
   1598             } catch (RemoteException ex) {
   1599                 mRemoveList.add(r.binder);
   1600             }
   1601         }
   1602 
   1603         if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
   1604             try {
   1605                 int gsmSignalStrength = mSignalStrength[phoneId]
   1606                         .getGsmSignalStrength();
   1607                 if (DBG) {
   1608                     log("checkPossibleMissNotify: onSignalStrengthChanged SS=" +
   1609                             gsmSignalStrength);
   1610                 }
   1611                 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
   1612                         : gsmSignalStrength));
   1613             } catch (RemoteException ex) {
   1614                 mRemoveList.add(r.binder);
   1615             }
   1616         }
   1617 
   1618         if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
   1619             try {
   1620                 if (DBG_LOC) {
   1621                     log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = "
   1622                             + mCellInfo.get(phoneId));
   1623                 }
   1624                 r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
   1625             } catch (RemoteException ex) {
   1626                 mRemoveList.add(r.binder);
   1627             }
   1628         }
   1629 
   1630         if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
   1631             try {
   1632                 if (VDBG) {
   1633                     log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId="
   1634                             + phoneId + " mwi=" + mMessageWaiting[phoneId]);
   1635                 }
   1636                 r.callback.onMessageWaitingIndicatorChanged(
   1637                         mMessageWaiting[phoneId]);
   1638             } catch (RemoteException ex) {
   1639                 mRemoveList.add(r.binder);
   1640             }
   1641         }
   1642 
   1643         if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
   1644             try {
   1645                 if (VDBG) {
   1646                     log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId="
   1647                         + phoneId + " cfi=" + mCallForwarding[phoneId]);
   1648                 }
   1649                 r.callback.onCallForwardingIndicatorChanged(
   1650                         mCallForwarding[phoneId]);
   1651             } catch (RemoteException ex) {
   1652                 mRemoveList.add(r.binder);
   1653             }
   1654         }
   1655 
   1656         if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
   1657             try {
   1658                 if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = "
   1659                         + mCellLocation[phoneId]);
   1660                 r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId]));
   1661             } catch (RemoteException ex) {
   1662                 mRemoveList.add(r.binder);
   1663             }
   1664         }
   1665 
   1666         if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
   1667             try {
   1668                 if (DBG) {
   1669                     log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState"
   1670                             + "=" + mDataConnectionState[phoneId]
   1671                             + ", mDataConnectionNetworkType=" + mDataConnectionNetworkType[phoneId]
   1672                             + ")");
   1673                 }
   1674                 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
   1675                         mDataConnectionNetworkType[phoneId]);
   1676             } catch (RemoteException ex) {
   1677                 mRemoveList.add(r.binder);
   1678             }
   1679         }
   1680     }
   1681 }
   1682