16c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie/*
2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project
3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License");
5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License.
6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at
7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *      http://www.apache.org/licenses/LICENSE-2.0
9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software
11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS,
12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and
14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License.
156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie */
166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xiepackage com.android.bluetooth.hfp;
186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.content.Context;
206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.telephony.PhoneStateListener;
216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.telephony.ServiceState;
226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.telephony.SignalStrength;
236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.telephony.TelephonyManager;
246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieimport android.util.Log;
256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie// Note:
276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie// All methods in this class are not thread safe, donot call them from
286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie// multiple threads. Call them from the HeadsetPhoneStateMachine message
296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie// handler only.
306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieclass HeadsetPhoneState {
316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private static final String TAG = "HeadsetPhoneState";
326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private HeadsetStateMachine mStateMachine;
346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private TelephonyManager mTelephonyManager;
356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private ServiceState mServiceState;
366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    // HFP 1.6 CIND service
386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private int mService = HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE;
396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    // Number of active (foreground) calls
416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private int mNumActive = 0;
426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
436c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    // Current Call Setup State
446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private int mCallState = HeadsetHalConstants.CALL_STATE_IDLE;
456c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
466c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    // Number of held (background) calls
476c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private int mNumHeld = 0;
486c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    // HFP 1.6 CIND signal
506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private int mSignal = 0;
516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    // HFP 1.6 CIND roam
536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private int mRoam = HeadsetHalConstants.SERVICE_TYPE_HOME;
546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    // HFP 1.6 CIND battchg
56f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    private int mBatteryCharge = 0;
57f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie
58f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    private int mSpeakerVolume = 0;
59bcbeaf69468424800a939b3e8678eaef21efa3d6Matthew Xie
60f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    private int mMicVolume = 0;
616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
626c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private boolean mListening = false;
636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    HeadsetPhoneState(Context context, HeadsetStateMachine stateMachine) {
656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mStateMachine = stateMachine;
6674ae04c73312403e89db0f8e9bd9601d403b4783fredc        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
6774ae04c73312403e89db0f8e9bd9601d403b4783fredc    }
6874ae04c73312403e89db0f8e9bd9601d403b4783fredc
6974ae04c73312403e89db0f8e9bd9601d403b4783fredc    public void cleanup() {
7074ae04c73312403e89db0f8e9bd9601d403b4783fredc        listenForPhoneState(false);
7174ae04c73312403e89db0f8e9bd9601d403b4783fredc        mTelephonyManager = null;
7274ae04c73312403e89db0f8e9bd9601d403b4783fredc        mStateMachine = null;
736c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
746c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    void listenForPhoneState(boolean start) {
766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        if (start) {
776c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            if (!mListening) {
786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                mTelephonyManager.listen(mPhoneStateListener,
796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                         PhoneStateListener.LISTEN_SERVICE_STATE |
806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                                         PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                mListening = true;
826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            }
836c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        } else {
846c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            if (mListening) {
856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                mListening = false;
876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            }
886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int getService() {
926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return mService;
936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int getNumActiveCall() {
966c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return mNumActive;
976c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    void setNumActiveCall(int numActive) {
1006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mNumActive = numActive;
1016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1026c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1036c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int getCallState() {
1046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return mCallState;
1056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    void setCallState(int callState) {
1086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mCallState = callState;
1096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int getNumHeldCall() {
1126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return mNumHeld;
1136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    void setNumHeldCall(int numHeldCall) {
1166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mNumHeld = numHeldCall;
1176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int getSignal() {
1206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return mSignal;
1216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int getRoam() {
1246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return mRoam;
1256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    void setRoam(int roam) {
1286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mRoam = roam;
1296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    void setBatteryCharge(int batteryLevel) {
1326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        if (mBatteryCharge != batteryLevel) {
1336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            mBatteryCharge = batteryLevel;
134a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan            sendDeviceStateChanged();
1356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
1366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int getBatteryCharge() {
1396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return mBatteryCharge;
1406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
142f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    void setSpeakerVolume(int volume) {
143f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie        mSpeakerVolume = volume;
144f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    }
145f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie
146f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    int getSpeakerVolume() {
147f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie        return mSpeakerVolume;
148f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    }
149f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie
150f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    void setMicVolume(int volume) {
151f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie        mMicVolume = volume;
152f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    }
153f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie
154f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    int getMicVolume() {
155f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie        return mMicVolume;
156f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie    }
157f0b6639617ce2245ffb88968e8a864d0fa99dd8cMatthew Xie
1586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    boolean isInCall() {
1596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        return (mNumActive >= 1);
1606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
1616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
162a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan    void sendDeviceStateChanged()
163a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan    {
164a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan        Log.d(TAG, "sendDeviceStateChanged. mService="+ mService +
165a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan                   " mSignal="+mSignal +" mRoam="+mRoam +
166a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan                   " mBatteryCharge=" + mBatteryCharge);
167a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan        HeadsetStateMachine sm = mStateMachine;
168a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan        if (sm != null) {
169a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan            sm.sendMessage(HeadsetStateMachine.DEVICE_STATE_CHANGED,
170a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan                new HeadsetDeviceState(mService, mRoam, mSignal, mBatteryCharge));
171a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan        }
172a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan    }
173a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan
1746c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
1756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        @Override
1766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        public void onServiceStateChanged(ServiceState serviceState) {
1776c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            mServiceState = serviceState;
1786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            mService = (serviceState.getState() == ServiceState.STATE_IN_SERVICE) ?
1796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                HeadsetHalConstants.NETWORK_STATE_AVAILABLE :
1806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE;
181fd0cb64aeb1f806a041a5881dd2ba846b0aa6a93Ravi Nagarajan            setRoam(serviceState.getRoaming() ? HeadsetHalConstants.SERVICE_TYPE_ROAMING
182fd0cb64aeb1f806a041a5881dd2ba846b0aa6a93Ravi Nagarajan                                              : HeadsetHalConstants.SERVICE_TYPE_HOME);
183a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan            sendDeviceStateChanged();
1846c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
1856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
1866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        @Override
1876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
188a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan            int prevSignal = mSignal;
1896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            if (signalStrength.isGsm()) {
1906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                mSignal = gsmAsuToSignal(signalStrength);
1916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            } else {
1926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                mSignal = cdmaDbmEcioToSignal(signalStrength);
1936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            }
194a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan            // network signal strength is scaled to BT 1-5 levels.
195a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan            // This results in a lot of duplicate messages, hence this check
196a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan            if (prevSignal != mSignal)
197a8e40f542287f047a8a2fda7f5ea2aea9607edfeRavi Nagarajan                sendDeviceStateChanged();
1986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
1996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        /* convert [0,31] ASU signal strength to the [0,5] expected by
2016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         * bluetooth devices. Scale is similar to status bar policy
2026c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         */
2036c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        private int gsmAsuToSignal(SignalStrength signalStrength) {
2046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            int asu = signalStrength.getGsmSignalStrength();
2056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            if      (asu >= 16) return 5;
2066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else if (asu >= 8)  return 4;
2076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else if (asu >= 4)  return 3;
2086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else if (asu >= 2)  return 2;
2096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else if (asu >= 1)  return 1;
2106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else                return 0;
2116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
2126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        /**
2146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         * Convert the cdma / evdo db levels to appropriate icon level.
2156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         * The scale is similar to the one used in status bar policy.
2166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         *
2176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         * @param signalStrength
2186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         * @return the icon level
2196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie         */
2206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        private int cdmaDbmEcioToSignal(SignalStrength signalStrength) {
2216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            int levelDbm = 0;
2226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            int levelEcio = 0;
2236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            int cdmaIconLevel = 0;
2246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            int evdoIconLevel = 0;
2256c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            int cdmaDbm = signalStrength.getCdmaDbm();
2266c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            int cdmaEcio = signalStrength.getCdmaEcio();
2276c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2286c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            if (cdmaDbm >= -75) levelDbm = 4;
2296c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else if (cdmaDbm >= -85) levelDbm = 3;
2306c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else if (cdmaDbm >= -95) levelDbm = 2;
2316c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else if (cdmaDbm >= -100) levelDbm = 1;
2326c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else levelDbm = 0;
2336c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2346c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            // Ec/Io are in dB*10
2356c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            if (cdmaEcio >= -90) levelEcio = 4;
2366c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else if (cdmaEcio >= -110) levelEcio = 3;
2376c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else if (cdmaEcio >= -130) levelEcio = 2;
2386c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else if (cdmaEcio >= -150) levelEcio = 1;
2396c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            else levelEcio = 0;
2406c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2416c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            cdmaIconLevel = (levelDbm < levelEcio) ? levelDbm : levelEcio;
2426c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
24361fa4903058a68538948d624271be96810defab4Matthew Xie            // STOPSHIP: Change back to getRilVoiceRadioTechnology
2446c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            if (mServiceState != null &&
24561fa4903058a68538948d624271be96810defab4Matthew Xie                  (mServiceState.getRadioTechnology() ==
246cae4f76797a8d32657eaa0fdc4294cc0ba944c9cWink Saville                      ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 ||
24761fa4903058a68538948d624271be96810defab4Matthew Xie                   mServiceState.getRadioTechnology() ==
248cae4f76797a8d32657eaa0fdc4294cc0ba944c9cWink Saville                       ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A)) {
2496c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  int evdoEcio = signalStrength.getEvdoEcio();
2506c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  int evdoSnr = signalStrength.getEvdoSnr();
2516c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  int levelEvdoEcio = 0;
2526c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  int levelEvdoSnr = 0;
2536c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2546c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  // Ec/Io are in dB*10
2556c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  if (evdoEcio >= -650) levelEvdoEcio = 4;
2566c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  else if (evdoEcio >= -750) levelEvdoEcio = 3;
2576c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  else if (evdoEcio >= -900) levelEvdoEcio = 2;
2586c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  else if (evdoEcio >= -1050) levelEvdoEcio = 1;
2596c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  else levelEvdoEcio = 0;
2606c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2616c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  if (evdoSnr > 7) levelEvdoSnr = 4;
2626c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  else if (evdoSnr > 5) levelEvdoSnr = 3;
2636c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  else if (evdoSnr > 3) levelEvdoSnr = 2;
2646c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  else if (evdoSnr > 1) levelEvdoSnr = 1;
2656c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  else levelEvdoSnr = 0;
2666c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2676c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                  evdoIconLevel = (levelEvdoEcio < levelEvdoSnr) ? levelEvdoEcio : levelEvdoSnr;
2686c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            }
2696c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            // TODO(): There is a bug open regarding what should be sent.
2706c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie            return (cdmaIconLevel > evdoIconLevel) ?  cdmaIconLevel : evdoIconLevel;
2716c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        }
2726c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    };
2736c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2746c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2756c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2766c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieclass HeadsetDeviceState {
2776c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mService;
2786c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mRoam;
2796c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mSignal;
2806c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mBatteryCharge;
2816c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2826c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    HeadsetDeviceState(int service, int roam, int signal, int batteryCharge) {
2836c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mService = service;
2846c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mRoam = roam;
2856c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mSignal = signal;
2866c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mBatteryCharge = batteryCharge;
2876c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
2886c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
2896c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2906c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieclass HeadsetCallState {
2916c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mNumActive;
2926c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mNumHeld;
2936c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mCallState;
2946c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    String mNumber;
2956c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mType;
2966c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
2976c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    public HeadsetCallState(int numActive, int numHeld, int callState, String number, int type) {
2986c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mNumActive = numActive;
2996c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mNumHeld = numHeld;
3006c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mCallState = callState;
3016c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mNumber = number;
3026c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mType = type;
3036c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
3046c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie}
3056c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
3066c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xieclass HeadsetClccResponse {
3076c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mIndex;
3086c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mDirection;
3096c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mStatus;
3106c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mMode;
3116c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    boolean mMpty;
3126c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    String mNumber;
3136c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    int mType;
3146c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie
3156c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    public HeadsetClccResponse(int index, int direction, int status, int mode, boolean mpty,
3166c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie                               String number, int type) {
3176c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mIndex = index;
3186c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mDirection = direction;
3196c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mStatus = status;
3206c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mMode = mode;
3216c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mMpty = mpty;
3226c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mNumber = number;
3236c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie        mType = type;
3246c91bc0a163cc7600c40d7fb979777fd911d1ef1Matthew Xie    }
325bcbeaf69468424800a939b3e8678eaef21efa3d6Matthew Xie}
326cdc8ec8d84c7f16b851238da0d80b51335c4ea07Edward Jee
327cdc8ec8d84c7f16b851238da0d80b51335c4ea07Edward Jeeclass HeadsetVendorSpecificResultCode {
328cdc8ec8d84c7f16b851238da0d80b51335c4ea07Edward Jee    String mCommand;
329cdc8ec8d84c7f16b851238da0d80b51335c4ea07Edward Jee    String mArg;
330cdc8ec8d84c7f16b851238da0d80b51335c4ea07Edward Jee
331cdc8ec8d84c7f16b851238da0d80b51335c4ea07Edward Jee    public HeadsetVendorSpecificResultCode(String command, String arg) {
332cdc8ec8d84c7f16b851238da0d80b51335c4ea07Edward Jee        mCommand = command;
333cdc8ec8d84c7f16b851238da0d80b51335c4ea07Edward Jee        mArg = arg;
334cdc8ec8d84c7f16b851238da0d80b51335c4ea07Edward Jee    }
335cdc8ec8d84c7f16b851238da0d80b51335c4ea07Edward Jee}
336