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