[go: nahoru, domu]

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
17package com.android.server;
18
19import android.Manifest;
20import android.app.ActivityManager;
21import android.app.AppOpsManager;
22import android.content.BroadcastReceiver;
23import android.content.Context;
24import android.content.Intent;
25import android.content.IntentFilter;
26import android.content.pm.PackageManager;
27import android.net.LinkProperties;
28import android.net.NetworkCapabilities;
29import android.os.Binder;
30import android.os.Bundle;
31import android.os.Handler;
32import android.os.IBinder;
33import android.os.Message;
34import android.os.RemoteException;
35import android.os.UserHandle;
36import android.telephony.CellLocation;
37import android.telephony.Rlog;
38import android.telephony.TelephonyManager;
39import android.telephony.SubscriptionManager;
40import android.telephony.PhoneStateListener;
41import android.telephony.ServiceState;
42import android.telephony.SignalStrength;
43import android.telephony.CellInfo;
44import android.telephony.VoLteServiceState;
45import android.telephony.DisconnectCause;
46import android.telephony.PreciseCallState;
47import android.telephony.PreciseDataConnectionState;
48import android.telephony.PreciseDisconnectCause;
49import android.text.TextUtils;
50import android.text.format.Time;
51
52import java.util.ArrayList;
53import java.util.List;
54import java.io.FileDescriptor;
55import java.io.PrintWriter;
56
57import com.android.internal.app.IBatteryStats;
58import com.android.internal.telephony.IOnSubscriptionsChangedListener;
59import com.android.internal.telephony.ITelephonyRegistry;
60import com.android.internal.telephony.IPhoneStateListener;
61import com.android.internal.telephony.DefaultPhoneNotifier;
62import com.android.internal.telephony.PhoneConstants;
63import com.android.internal.telephony.ServiceStateTracker;
64import com.android.internal.telephony.TelephonyIntents;
65import 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 */
81class 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
105        boolean matchPhoneStateListenerEvent(int events) {
106            return (callback != null) && ((events & this.events) != 0);
107        }
108
109        boolean matchOnSubscriptionsChangedListener() {
110            return (onSubscriptionsChangedListenerCallback != null);
111        }
112
113        @Override
114        public String toString() {
115            return "{callingPackage=" + callingPackage + " binder=" + binder
116                    + " callback=" + callback
117                    + " l" name="118" href="#118">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
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
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
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
422    public void removeOnSubscriptionsChangedListener(String pkgForDebug,
423            IOnSubscriptionsChangedListener callback) {
424        if (DBG) log("listen oscl: Unregister");
425        remove(callback.asBinder());
426    }
427
428    @Override
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
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
462    public void listenForSubscriber(int subId, String pkgForDebug, IPhoneStateListener callback,
463            int events, boolean notifyNow) {
464        listen(pkgForDebug, callback, events, notifyNow, subId);
465    }
466
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
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
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
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
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
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
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
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
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
880    public void notifyCellInfo(List<CellInfo> cellInfo) {
881         notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellInfo);
882    }
883
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
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
943    public void notifyCallForwardingChanged(boolean cfi) {
944        notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cfi);
945    }
946
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
975    public void notifyDataActivity(int state) {
976        notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state);
977    }
978
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
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
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
1097    public void notifyDataConnectionFailed(String reason, String apnType) {
1098         notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
1099                 reason, apnType);
1100    }
1101
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
1132    public void notifyCellLocation(Bundle cellLocation) {
1133         notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation);
1134    }
1135
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
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
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
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
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
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
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
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
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
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     */
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
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
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
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
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
1512    private void enforceNotifyPermissionOrCarrierPrivilege(String method) {
1513        if  (checkNotifyPermission()) {
1514            return;
1515        }
1516
1517        enforceCarrierPrivilege();
1518    }
1519
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
1530    private boolean checkNotifyPermission() {
1531        return mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
1532                == PackageManager.PERMISSION_GRANTED;
1533    }
1534
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
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
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
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
1617    private boolean validatePhoneId(int phoneId) {
1618        boolean valid = (phoneId >= 0) && (phoneId < mNumPhones);
1619        if (VDBG) log("validatePhoneId: " + valid);
1620        return valid;
1621    }
1622
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
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
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
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
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
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
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