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