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