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