19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.CellLocation;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.PhoneStateListener;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.ServiceState;
29e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Savilleimport android.telephony.SignalStrength;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.TelephonyManager;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils;
328a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.app.IBatteryStats;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.telephony.ITelephonyRegistry;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.telephony.IPhoneStateListener;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.telephony.DefaultPhoneNotifier;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.telephony.Phone;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.telephony.TelephonyIntents;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.am.BatteryStatsService;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
47e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville * Since phone process can be restarted, this class provides a centralized place
48e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville * that applications can register and be called back from.
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass TelephonyRegistry extends ITelephonyRegistry.Stub {
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "TelephonyRegistry";
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class Record {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String pkgForDebug;
55e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IBinder binder;
57e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IPhoneStateListener callback;
59e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int events;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Context mContext;
64e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final ArrayList<Record> mRecords = new ArrayList();
66e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final IBatteryStats mBatteryStats;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mCallState = TelephonyManager.CALL_STATE_IDLE;
70e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mCallIncomingNumber = "";
72e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ServiceState mServiceState = new ServiceState();
74e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
75e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    private SignalStrength mSignalStrength = new SignalStrength();
76e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mMessageWaiting = false;
78e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mCallForwarding = false;
80e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
82e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mDataConnectionState = TelephonyManager.DATA_CONNECTED;
84e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mDataConnectionPossible = false;
86e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mDataConnectionReason = "";
88e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mDataConnectionApn = "";
90e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
9142acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private String[] mDataConnectionApnTypes = null;
9242acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mDataConnectionInterfaceName = "";
94e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Bundle mCellLocation = new Bundle();
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9798e0b146b80670b52805b4b210ef5582dad6bb68Robert Greenwalt    private int mDataConnectionNetworkType;
9898e0b146b80670b52805b4b210ef5582dad6bb68Robert Greenwalt
9945515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh    static final int PHONE_STATE_PERMISSION_MASK =
10045515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh                PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
10145515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh                PhoneStateListener.LISTEN_CALL_STATE |
10245515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh                PhoneStateListener.LISTEN_DATA_ACTIVITY |
10345515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh                PhoneStateListener.LISTEN_DATA_CONNECTION_STATE |
10445515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh                PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
10545515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh
106e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    // we keep a copy of all of the state so we can send it out when folks
107e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    // register for it
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //
109e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    // In these calls we call with the lock held. This is safe becasuse remote
110e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    // calls go through a oneway interface and local calls going through a
111e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    // handler before they get to app code.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    TelephonyRegistry(Context context) {
1144ef8ec3a21da69091200aeebff80dbcde336709cDavid 'Digit' Turner        CellLocation  location = CellLocation.getEmpty();
1154ef8ec3a21da69091200aeebff80dbcde336709cDavid 'Digit' Turner
1164ef8ec3a21da69091200aeebff80dbcde336709cDavid 'Digit' Turner        // Note that location can be null for non-phone builds like
1174ef8ec3a21da69091200aeebff80dbcde336709cDavid 'Digit' Turner        // like the generic one.
1184ef8ec3a21da69091200aeebff80dbcde336709cDavid 'Digit' Turner        if (location != null) {
1194ef8ec3a21da69091200aeebff80dbcde336709cDavid 'Digit' Turner            location.fillInNotifierBundle(mCellLocation);
1204ef8ec3a21da69091200aeebff80dbcde336709cDavid 'Digit' Turner        }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBatteryStats = BatteryStatsService.getService();
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void listen(String pkgForDebug, IPhoneStateListener callback, int events,
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean notifyNow) {
1278a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        // Slog.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" +
128e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        // Integer.toHexString(events));
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (events != 0) {
13045515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh            /* Checks permission and throws Security exception */
13145515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh            checkListenerPermission(events);
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mRecords) {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // register
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = null;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                find_and_add: {
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    IBinder b = callback.asBinder();
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    final int N = mRecords.size();
139e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    for (int i = 0; i < N; i++) {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        r = mRecords.get(i);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (b == r.binder) {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break find_and_add;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r = new Record();
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r.binder = b;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r.callback = callback;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    r.pkgForDebug = pkgForDebug;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mRecords.add(r);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int send = events & (events ^ r.events);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                r.events = events;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (notifyNow) {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        sendServiceState(r, mServiceState);
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
159e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                            int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
160e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                            r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
161e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                                    : gsmSignalStrength));
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (RemoteException ex) {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            remove(r.binder);
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting);
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (RemoteException ex) {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            remove(r.binder);
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            r.callback.onCallForwardingIndicatorChanged(mCallForwarding);
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (RemoteException ex) {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            remove(r.binder);
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        sendCellLocation(r, mCellLocation);
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            r.callback.onCallStateChanged(mCallState, mCallIncomingNumber);
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (RemoteException ex) {
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            remove(r.binder);
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
19298e0b146b80670b52805b4b210ef5582dad6bb68Robert Greenwalt                            r.callback.onDataConnectionStateChanged(mDataConnectionState,
19398e0b146b80670b52805b4b210ef5582dad6bb68Robert Greenwalt                                mDataConnectionNetworkType);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (RemoteException ex) {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            remove(r.binder);
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        try {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            r.callback.onDataActivity(mDataActivity);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } catch (RemoteException ex) {
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            remove(r.binder);
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
205e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
206e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                        try {
207e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                            r.callback.onSignalStrengthsChanged(mSignalStrength);
208e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                        } catch (RemoteException ex) {
209e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                            remove(r.binder);
210e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                        }
211e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            remove(callback.asBinder());
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void remove(IBinder binder) {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
221e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            final int recordCount = mRecords.size();
222e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            for (int i = 0; i < recordCount; i++) {
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mRecords.get(i).binder == binder) {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mRecords.remove(i);
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void notifyCallState(int state, String incomingNumber) {
23245515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if (!checkNotifyPermission("notifyCallState()")) {
233ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            return;
234ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCallState = state;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCallIncomingNumber = incomingNumber;
238e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            for (int i = mRecords.size() - 1; i >= 0; i--) {
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = mRecords.get(i);
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        r.callback.onCallStateChanged(state, incomingNumber);
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (RemoteException ex) {
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        remove(r.binder);
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        broadcastCallStateChanged(state, incomingNumber);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void notifyServiceState(ServiceState state) {
25345515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if (!checkNotifyPermission("notifyServiceState()")){
254ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            return;
255e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mServiceState = state;
258e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            for (int i = mRecords.size() - 1; i >= 0; i--) {
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = mRecords.get(i);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sendServiceState(r, state);
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        broadcastServiceStateChanged(state);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
268e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    public void notifySignalStrength(SignalStrength signalStrength) {
26945515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if (!checkNotifyPermission("notifySignalStrength()")) {
270ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            return;
271e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        }
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
273e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            mSignalStrength = signalStrength;
274e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            for (int i = mRecords.size() - 1; i >= 0; i--) {
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = mRecords.get(i);
276e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
277e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    sendSignalStrength(r, signalStrength);
278e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
281e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                        int gsmSignalStrength = signalStrength.getGsmSignalStrength();
282e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                        r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
283e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                                : gsmSignalStrength));
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (RemoteException ex) {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        remove(r.binder);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
290e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        broadcastSignalStrengthChanged(signalStrength);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void notifyMessageWaitingChanged(boolean mwi) {
29445515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
295ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            return;
296e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMessageWaiting = mwi;
299e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            for (int i = mRecords.size() - 1; i >= 0; i--) {
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = mRecords.get(i);
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        r.callback.onMessageWaitingIndicatorChanged(mwi);
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (RemoteException ex) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        remove(r.binder);
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void notifyCallForwardingChanged(boolean cfi) {
31345515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
314ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            return;
315e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        }
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCallForwarding = cfi;
318e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            for (int i = mRecords.size() - 1; i >= 0; i--) {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = mRecords.get(i);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        r.callback.onCallForwardingIndicatorChanged(cfi);
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (RemoteException ex) {
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        remove(r.binder);
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void notifyDataActivity(int state) {
33245515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if (!checkNotifyPermission("notifyDataActivity()" )) {
333ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            return;
334e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        }
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataActivity = state;
337e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            for (int i = mRecords.size() - 1; i >= 0; i--) {
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = mRecords.get(i);
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        r.callback.onDataActivity(state);
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (RemoteException ex) {
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        remove(r.binder);
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35045515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh    public void notifyDataConnection(int state, boolean isDataConnectivityPossible,
35198e0b146b80670b52805b4b210ef5582dad6bb68Robert Greenwalt            String reason, String apn, String[] apnTypes, String interfaceName, int networkType) {
35245515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if (!checkNotifyPermission("notifyDataConnection()" )) {
353ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            return;
354e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        }
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataConnectionState = state;
357e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            mDataConnectionPossible = isDataConnectivityPossible;
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataConnectionReason = reason;
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataConnectionApn = apn;
36042acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            mDataConnectionApnTypes = apnTypes;
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataConnectionInterfaceName = interfaceName;
36298e0b146b80670b52805b4b210ef5582dad6bb68Robert Greenwalt            mDataConnectionNetworkType = networkType;
363e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            for (int i = mRecords.size() - 1; i >= 0; i--) {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = mRecords.get(i);
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
36798e0b146b80670b52805b4b210ef5582dad6bb68Robert Greenwalt                        r.callback.onDataConnectionStateChanged(state, networkType);
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (RemoteException ex) {
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        remove(r.binder);
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
374e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn,
37542acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt                apnTypes, interfaceName);
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void notifyDataConnectionFailed(String reason) {
37945515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if (!checkNotifyPermission("notifyDataConnectionFailed()")) {
380ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            return;
381e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        }
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This is commented out because there is on onDataConnectionFailed callback
384e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville         * on PhoneStateListener. There should be
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDataConnectionFailedReason = reason;
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int N = mRecords.size();
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i=N-1; i>=0; i--) {
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = mRecords.get(i);
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) {
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // XXX
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        */
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        broadcastDataConnectionFailed(reason);
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void notifyCellLocation(Bundle cellLocation) {
40045515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if (!checkNotifyPermission("notifyCellLocation()")) {
401ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            return;
402e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        }
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCellLocation = cellLocation;
405e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            for (int i = mRecords.size() - 1; i >= 0; i--) {
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = mRecords.get(i);
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sendCellLocation(r, cellLocation);
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
414e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    /**
415e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville     * Copy the service state object so they can't mess it up in the local calls
416e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville     */
41745515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh    public void sendServiceState(Record r, ServiceState state) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            r.callback.onServiceStateChanged(new ServiceState(state));
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException ex) {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            remove(r.binder);
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
425e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    private void sendCellLocation(Record r, Bundle cellLocation) {
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            r.callback.onCellLocationChanged(new Bundle(cellLocation));
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException ex) {
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            remove(r.binder);
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
433e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    private void sendSignalStrength(Record r, SignalStrength signalStrength) {
434e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        try {
435e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
436e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        } catch (RemoteException ex) {
437e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            remove(r.binder);
438e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        }
439e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    }
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                != PackageManager.PERMISSION_GRANTED) {
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("Permission Denial: can't dump telephony.registry from from pid="
446e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mRecords) {
450e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            final int recordCount = mRecords.size();
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("last known state:");
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mCallState=" + mCallState);
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mCallIncomingNumber=" + mCallIncomingNumber);
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mServiceState=" + mServiceState);
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mSignalStrength=" + mSignalStrength);
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mMessageWaiting=" + mMessageWaiting);
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mCallForwarding=" + mCallForwarding);
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mDataActivity=" + mDataActivity);
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mDataConnectionState=" + mDataConnectionState);
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mDataConnectionPossible=" + mDataConnectionPossible);
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mDataConnectionReason=" + mDataConnectionReason);
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mDataConnectionApn=" + mDataConnectionApn);
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mDataConnectionInterfaceName=" + mDataConnectionInterfaceName);
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("  mCellLocation=" + mCellLocation);
465e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            pw.println("registrations: count=" + recordCount);
466e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            for (int i = 0; i < recordCount; i++) {
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Record r = mRecords.get(i);
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pw.println("  " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events));
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // the legacy intent broadcasting
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void broadcastServiceStateChanged(ServiceState state) {
47832dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani        long ident = Binder.clearCallingIdentity();
47932dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani        try {
480f37447bad3773b62176baa837908daf6edb44273Amith Yamasani            mBatteryStats.notePhoneState(state.getState());
48132dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani        } catch (RemoteException re) {
48232dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani            // Can't do much
48332dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani        } finally {
48432dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani            Binder.restoreCallingIdentity(ident);
48532dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani        }
48632dbefda71c50bf848da21fb5d1255273439f90dAmith Yamasani
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
4881c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Bundle data = new Bundle();
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        state.fillInNotifierBundle(data);
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtras(data);
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.sendStickyBroadcast(intent);
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
495e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville    private void broadcastSignalStrengthChanged(SignalStrength signalStrength) {
496627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn        long ident = Binder.clearCallingIdentity();
497627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn        try {
498e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            mBatteryStats.notePhoneSignalStrength(signalStrength);
499627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn        } catch (RemoteException e) {
500e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            /* The remote entity disappeared, we can safely ignore the exception. */
501627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn        } finally {
502627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn            Binder.restoreCallingIdentity(ident);
503627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn        }
504e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED);
5061c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
507e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        Bundle data = new Bundle();
508e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        signalStrength.fillInNotifierBundle(data);
509e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        intent.putExtras(data);
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.sendStickyBroadcast(intent);
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void broadcastCallStateChanged(int state, String incomingNumber) {
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long ident = Binder.clearCallingIdentity();
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (state == TelephonyManager.CALL_STATE_IDLE) {
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mBatteryStats.notePhoneOff();
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mBatteryStats.notePhoneOn();
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
522e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville            /* The remote entity disappeared, we can safely ignore the exception. */
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Binder.restoreCallingIdentity(ident);
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
526e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
5281c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
529e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville        intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!TextUtils.isEmpty(incomingNumber)) {
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE);
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
53642acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt    private void broadcastDataConnectionStateChanged(int state,
53742acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            boolean isDataConnectivityPossible,
53842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt            String reason, String apn, String[] apnTypes, String interfaceName) {
539627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn        // Note: not reporting to the battery stats service here, because the
540627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn        // status bar takes care of that after taking into account all of the
541627bba736d022c39696b7c582a6af5592d2b8c33Dianne Hackborn        // required info.
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
5431c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtra(Phone.STATE_KEY, DefaultPhoneNotifier.convertDataState(state).toString());
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!isDataConnectivityPossible) {
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, true);
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (reason != null) {
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason);
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtra(Phone.DATA_APN_KEY, apn);
55275e1d3137cdcdb88783795d3f1fe735098330fa8Robert Greenwalt        String types = new String("");
55375e1d3137cdcdb88783795d3f1fe735098330fa8Robert Greenwalt        if (apnTypes.length > 0) {
55475e1d3137cdcdb88783795d3f1fe735098330fa8Robert Greenwalt            types = apnTypes[0];
55575e1d3137cdcdb88783795d3f1fe735098330fa8Robert Greenwalt            for (int i = 1; i < apnTypes.length; i++) {
55675e1d3137cdcdb88783795d3f1fe735098330fa8Robert Greenwalt                types = types+","+apnTypes[i];
55775e1d3137cdcdb88783795d3f1fe735098330fa8Robert Greenwalt            }
55842acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        }
55942acef37339afe6ac608c842f1637870ee9c4f6cRobert Greenwalt        intent.putExtra(Phone.DATA_APN_TYPES_KEY, types);
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName);
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.sendStickyBroadcast(intent);
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void broadcastDataConnectionFailed(String reason) {
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
5661c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        intent.putExtra(Phone.FAILURE_REASON_KEY, reason);
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.sendStickyBroadcast(intent);
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
570e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville
57145515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh    private boolean checkNotifyPermission(String method) {
572ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
573ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project                == PackageManager.PERMISSION_GRANTED) {
574ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project            return true;
575ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        }
576ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        String msg = "Modify Phone State Permission Denial: " + method + " from pid="
577e9b06d754af03faf27012fbed1e7559ec1ba7c79Wink Saville                + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
5788a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        Slog.w(TAG, msg);
579ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project        return false;
580ba87e3e6c985e7175152993b5efcc7dd2f0e1c93The Android Open Source Project    }
58145515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh
58245515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh    private void checkListenerPermission(int events) {
58345515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
58445515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh            mContext.enforceCallingOrSelfPermission(
58545515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh                    android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
58645515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh
58745515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        }
58845515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh
58945515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        if ((events & PHONE_STATE_PERMISSION_MASK) != 0) {
59045515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh            mContext.enforceCallingOrSelfPermission(
59145515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh                    android.Manifest.permission.READ_PHONE_STATE, null);
59245515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh        }
59345515659438964ec47f4feac247f0e9dce587c86Jaikumar Ganesh    }
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
595