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