Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c553a80 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4507345 from fbeb78bc to pi-release

Change-Id: I104e5eb267d4aedb9cad0f7af4b6043e05eabf51
parents ff1acbaa fbeb78bc
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -104,11 +104,8 @@ public class AtPhonebook {
        mPhonebooks.put("RC", new PhonebookResult());  // received calls
        mPhonebooks.put("MC", new PhonebookResult());  // missed calls
        mPhonebooks.put("ME", new PhonebookResult());  // mobile phonebook

        mCurrentPhonebook = "ME";  // default to mobile phonebook

        mCpbrIndex1 = mCpbrIndex2 = -1;
        mCheckingAccessPermission = false;
    }

    public void cleanup() {
@@ -172,7 +169,7 @@ public class AtPhonebook {
            case TYPE_SET: // Set
                log("handleCscsCommand - Set Command");
                String[] args = atString.split("=");
                if (args.length < 2 || !(args[1] instanceof String)) {
                if (args.length < 2 || args[1] == null) {
                    mNativeInterface.atResponseCode(device, atCommandResult, atCommandErrorCode);
                    break;
                }
@@ -234,7 +231,7 @@ public class AtPhonebook {
                log("handleCpbsCommand - set command");
                String[] args = atString.split("=");
                // Select phonebook memory
                if (args.length < 2 || !(args[1] instanceof String)) {
                if (args.length < 2 || args[1] == null) {
                    atCommandErrorCode = BluetoothCmeError.OPERATION_NOT_SUPPORTED;
                    break;
                }
@@ -266,7 +263,7 @@ public class AtPhonebook {
        mNativeInterface.atResponseCode(device, atCommandResult, atCommandErrorCode);
    }

    public void handleCpbrCommand(String atString, int type, BluetoothDevice remoteDevice) {
    void handleCpbrCommand(String atString, int type, BluetoothDevice remoteDevice) {
        log("handleCpbrCommand - atString = " + atString);
        int atCommandResult = HeadsetHalConstants.AT_RESPONSE_ERROR;
        int atCommandErrorCode = -1;
+255 −293
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Looper;
import android.support.annotation.VisibleForTesting;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
@@ -33,6 +34,8 @@ import android.util.Log;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;

import java.util.Objects;


/**
 * Class that manages Telephony states
@@ -45,142 +48,106 @@ import com.android.internal.telephony.TelephonyIntents;
public class HeadsetPhoneState {
    private static final String TAG = "HeadsetPhoneState";

    private final Context mContext;
    private final HeadsetStateMachine mStateMachine;
    private final HeadsetService mHeadsetService;
    private final TelephonyManager mTelephonyManager;
    private final SubscriptionManager mSubMgr;
    private final SubscriptionManager mSubscriptionManager;

    private ServiceState mServiceState;

    // HFP 1.6 CIND service value
    private int mService = HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE;

    private int mCindService = HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE;
    // Check this before sending out service state to the device -- if the SIM isn't fully
    // loaded, don't expose that the network is available.
    private boolean mIsSimStateLoaded;

    // Number of active (foreground) calls
    private int mNumActive;

    // Current Call Setup State
    private int mCallState = HeadsetHalConstants.CALL_STATE_IDLE;

    // Number of held (background) calls
    private int mNumHeld;

    // HFP 1.6 CIND signal
    private int mSignal;

    // HFP 1.6 CIND roam
    private int mRoam = HeadsetHalConstants.SERVICE_TYPE_HOME;

    // HFP 1.6 CIND battchg
    private int mBatteryCharge;

    private int mSpeakerVolume;

    private int mMicVolume;
    // HFP 1.6 CIND signal value
    private int mCindSignal;
    // HFP 1.6 CIND roam value
    private int mCindRoam = HeadsetHalConstants.SERVICE_TYPE_HOME;
    // HFP 1.6 CIND battchg value
    private int mCindBatteryCharge;

    private boolean mListening;

    // when HFP Service Level Connection is established
    private boolean mSlcReady;

    private PhoneStateListener mPhoneStateListener;

    private OnSubscriptionsChangedListener mOnSubscriptionsChangedListener;

    private class HeadsetPhoneStateOnSubscriptionChangedListener
            extends OnSubscriptionsChangedListener {
        HeadsetPhoneStateOnSubscriptionChangedListener(Looper looper) {
            super(looper);
        }

        @Override
        public void onSubscriptionsChanged() {
            listenForPhoneState(false);
            listenForPhoneState(true);
        }
    }

    HeadsetPhoneState(Context context, HeadsetStateMachine stateMachine) {
        mStateMachine = stateMachine;
        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (mTelephonyManager == null) {
            Log.e(TAG, "getSystemService(Context.TELEPHONY_SERVICE) failed, "
                    + "cannot register for SubscriptionInfo changes");
        }
        mContext = context;

        // Register for SubscriptionInfo list changes which is guaranteed
        // to invoke onSubscriptionInfoChanged and which in turns calls
        // loadInBackgroud.
        mSubMgr = SubscriptionManager.from(mContext);
    private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener;

    HeadsetPhoneState(HeadsetService headsetService) {
        Objects.requireNonNull(headsetService, "headsetService is null");
        mHeadsetService = headsetService;
        mTelephonyManager =
                (TelephonyManager) mHeadsetService.getSystemService(Context.TELEPHONY_SERVICE);
        Objects.requireNonNull(mTelephonyManager, "TELEPHONY_SERVICE is null");
        // Register for SubscriptionInfo list changes which is guaranteed to invoke
        // onSubscriptionInfoChanged and which in turns calls loadInBackgroud.
        mSubscriptionManager = SubscriptionManager.from(mHeadsetService);
        Objects.requireNonNull(mSubscriptionManager, "TELEPHONY_SUBSCRIPTION_SERVICE is null");
        // Initialize subscription on the handler thread
        mOnSubscriptionsChangedListener = new HeadsetPhoneStateOnSubscriptionChangedListener(
                stateMachine.getHandler().getLooper());
        mSubMgr.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
                headsetService.getStateMachinesThreadLooper());
        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
    }

    /**
     * Cleanup this instance. Instance can no longer be used after calling this method.
     */
    public void cleanup() {
        listenForPhoneState(false);
        if (mOnSubscriptionsChangedListener != null) {
            mSubMgr.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
            mOnSubscriptionsChangedListener = null;
        }
        mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
    }

    @Override
    public String toString() {
        return "HeadsetPhoneState [mService=" + mService + ", mNumActive=" + mNumActive
                + ", mCallState=" + mCallState + ", mNumHeld=" + mNumHeld + ", mSignal=" + mSignal
                + ", mRoam=" + mRoam + ", mBatteryCharge=" + mBatteryCharge + ", mSpeakerVolume="
                + mSpeakerVolume + ", mMicVolume=" + mMicVolume + ", mListening=" + mListening
                + ", mSlcReady=" + mSlcReady + "]";
        return "HeadsetPhoneState [mTelephonyServiceAvailability=" + mCindService + ", mNumActive="
                + mNumActive + ", mCallState=" + mCallState + ", mNumHeld=" + mNumHeld
                + ", mSignal=" + mCindSignal + ", mRoam=" + mCindRoam + ", mBatteryCharge="
                + mCindBatteryCharge + ", mListening=" + mListening + "]";
    }

    void listenForPhoneState(boolean start) {
        mSlcReady = start;
    /**
     * Start or stop listening for phone state change
     * @param start True to start, False to stop
     */
    @VisibleForTesting
    public void listenForPhoneState(boolean start) {
        synchronized (mTelephonyManager) {
            if (start) {
                startListenForPhoneState();
            } else {
                stopListenForPhoneState();
            }
        }
    }

    private void startListenForPhoneState() {
        if (!mListening && mSlcReady && mTelephonyManager != null) {
        if (!mListening) {
            int subId = SubscriptionManager.getDefaultSubscriptionId();
            if (SubscriptionManager.isValidSubscriptionId(subId)) {
                mPhoneStateListener = getPhoneStateListener(subId);
                if (mTelephonyManager == null) {
                    Log.e(TAG, "mTelephonyManager is null, "
                            + "cannot start listening for phone state changes");
                } else {
                mPhoneStateListener = new HeadsetPhoneStateListener(subId,
                        mHeadsetService.getStateMachinesThreadLooper());
                mTelephonyManager.listen(mPhoneStateListener,
                        PhoneStateListener.LISTEN_SERVICE_STATE
                                | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
                mListening = true;
                }
            } else {
                Log.w(TAG, "startListenForPhoneState, invalid subscription ID " + subId);
            }
        }
    }

    private void stopListenForPhoneState() {
        if (mListening && mTelephonyManager != null) {

            if (mTelephonyManager == null) {
                Log.e(TAG, "mTelephonyManager is null, "
                        + "cannot send request to stop listening for phone state changes");
            } else {
        if (mListening) {
            mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
            mListening = false;
        }
    }
    }

    int getService() {
        return mService;
    int getCindService() {
        return mCindService;
    }

    int getNumActiveCall() {
@@ -207,97 +174,94 @@ public class HeadsetPhoneState {
        mNumHeld = numHeldCall;
    }

    int getSignal() {
        return mSignal;
    int getCindSignal() {
        return mCindSignal;
    }

    int getRoam() {
        return mRoam;
    int getCindRoam() {
        return mCindRoam;
    }

    void setRoam(int roam) {
        if (mRoam != roam) {
            mRoam = roam;
    void setCindRoam(int cindRoam) {
        if (mCindRoam != cindRoam) {
            mCindRoam = cindRoam;
            sendDeviceStateChanged();
        }
    }

    void setBatteryCharge(int batteryLevel) {
        if (mBatteryCharge != batteryLevel) {
            mBatteryCharge = batteryLevel;
    void setCindBatteryCharge(int batteryLevel) {
        if (mCindBatteryCharge != batteryLevel) {
            mCindBatteryCharge = batteryLevel;
            sendDeviceStateChanged();
        }
    }

    int getBatteryCharge() {
        return mBatteryCharge;
    }

    void setSpeakerVolume(int volume) {
        mSpeakerVolume = volume;
    }

    int getSpeakerVolume() {
        return mSpeakerVolume;
    }

    void setMicVolume(int volume) {
        mMicVolume = volume;
    }

    int getMicVolume() {
        return mMicVolume;
    int getCindBatteryCharge() {
        return mCindBatteryCharge;
    }

    boolean isInCall() {
        return (mNumActive >= 1);
    }

    void sendDeviceStateChanged() {
    private void sendDeviceStateChanged() {
        int service =
                mIsSimStateLoaded ? mService : HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE;
                mIsSimStateLoaded ? mCindService : HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE;
        // When out of service, send signal strength as 0. Some devices don't
        // use the service indicator, but only the signal indicator
        int signal = service == HeadsetHalConstants.NETWORK_STATE_AVAILABLE ? mSignal : 0;
        int signal = service == HeadsetHalConstants.NETWORK_STATE_AVAILABLE ? mCindSignal : 0;

        Log.d(TAG, "sendDeviceStateChanged. mService=" + mService + " mIsSimStateLoaded="
                + mIsSimStateLoaded + " mSignal=" + signal + " mRoam=" + mRoam + " mBatteryCharge="
                + mBatteryCharge);
        HeadsetStateMachine sm = mStateMachine;
        if (sm != null) {
            sm.sendMessage(HeadsetStateMachine.DEVICE_STATE_CHANGED,
                    new HeadsetDeviceState(service, mRoam, signal, mBatteryCharge));
        Log.d(TAG, "sendDeviceStateChanged. mService=" + mCindService + " mIsSimStateLoaded="
                + mIsSimStateLoaded + " mSignal=" + signal + " mRoam=" + mCindRoam
                + " mBatteryCharge=" + mCindBatteryCharge);
        mHeadsetService.onDeviceStateChanged(
                new HeadsetDeviceState(service, mCindRoam, signal, mCindBatteryCharge));
    }

    private class HeadsetPhoneStateOnSubscriptionChangedListener
            extends OnSubscriptionsChangedListener {
        HeadsetPhoneStateOnSubscriptionChangedListener(Looper looper) {
            super(looper);
        }

        @Override
        public void onSubscriptionsChanged() {
            listenForPhoneState(false);
            listenForPhoneState(true);
        }
    }

    private PhoneStateListener getPhoneStateListener(int subId) {
        PhoneStateListener mPhoneStateListener = new PhoneStateListener(subId) {
    private class HeadsetPhoneStateListener extends PhoneStateListener {
        HeadsetPhoneStateListener(Integer subId, Looper looper) {
            super(subId, looper);
        }

        @Override
            public void onServiceStateChanged(ServiceState serviceState) {
        public synchronized void onServiceStateChanged(ServiceState serviceState) {
            mServiceState = serviceState;
                int newService = (serviceState.getState() == ServiceState.STATE_IN_SERVICE)
            int cindService = (serviceState.getState() == ServiceState.STATE_IN_SERVICE)
                    ? HeadsetHalConstants.NETWORK_STATE_AVAILABLE
                    : HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE;
            int newRoam = serviceState.getRoaming() ? HeadsetHalConstants.SERVICE_TYPE_ROAMING
                    : HeadsetHalConstants.SERVICE_TYPE_HOME;

                if (newService == mService && newRoam == mRoam) {
                    // Debounce the state change
            if (cindService == mCindService && newRoam == mCindRoam) {
                // De-bounce the state change
                return;
            }
                mService = newService;
                mRoam = newRoam;
            mCindService = cindService;
            mCindRoam = newRoam;

            // If this is due to a SIM insertion, we want to defer sending device state changed
            // until all the SIM config is loaded.
                if (newService == HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE) {
            if (cindService == HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE) {
                mIsSimStateLoaded = false;
                sendDeviceStateChanged();
                return;
            }
            IntentFilter simStateChangedFilter =
                    new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
                mContext.registerReceiver(new BroadcastReceiver() {
            mHeadsetService.registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
@@ -307,36 +271,37 @@ public class HeadsetPhoneState {
                                intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE))) {
                            mIsSimStateLoaded = true;
                            sendDeviceStateChanged();
                                mContext.unregisterReceiver(this);
                            mHeadsetService.unregisterReceiver(this);
                        }
                    }
                }
            }, simStateChangedFilter);

        }

        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {

                int prevSignal = mSignal;
                if (mService == HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE) {
                    mSignal = 0;
            int prevSignal = mCindSignal;
            if (mCindService == HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE) {
                mCindSignal = 0;
            } else if (signalStrength.isGsm()) {
                    mSignal = signalStrength.getLteLevel();
                    if (mSignal == SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
                        mSignal = gsmAsuToSignal(signalStrength);
                mCindSignal = signalStrength.getLteLevel();
                if (mCindSignal == SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
                    mCindSignal = gsmAsuToSignal(signalStrength);
                } else {
                    // SignalStrength#getLteLevel returns the scale from 0-4
                    // Bluetooth signal scales at 0-5
                    // Let's match up the larger side
                        mSignal++;
                    mCindSignal++;
                }
            } else {
                    mSignal = cdmaDbmEcioToSignal(signalStrength);
                mCindSignal = cdmaDbmEcioToSignal(signalStrength);
            }

            // network signal strength is scaled to BT 1-5 levels.
            // This results in a lot of duplicate messages, hence this check
                if (prevSignal != mSignal) {
            if (prevSignal != mCindSignal) {
                sendDeviceStateChanged();
            }
        }
@@ -367,8 +332,8 @@ public class HeadsetPhoneState {
         * Convert the cdma / evdo db levels to appropriate icon level.
         * The scale is similar to the one used in status bar policy.
         *
             * @param signalStrength
             * @return the icon level
         * @param signalStrength signal strength level
         * @return the icon level for remote device
         */
        private int cdmaDbmEcioToSignal(SignalStrength signalStrength) {
            int levelDbm = 0;
@@ -406,8 +371,8 @@ public class HeadsetPhoneState {
            cdmaIconLevel = (levelDbm < levelEcio) ? levelDbm : levelEcio;

            // STOPSHIP: Change back to getRilVoiceRadioTechnology
                if (mServiceState != null && (mServiceState.getRadioTechnology()
                        == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0
            if (mServiceState != null && (
                    mServiceState.getRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0
                            || mServiceState.getRadioTechnology()
                            == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A)) {
                int evdoEcio = signalStrength.getEvdoEcio();
@@ -445,10 +410,7 @@ public class HeadsetPhoneState {
            // TODO(): There is a bug open regarding what should be sent.
            return (cdmaIconLevel > evdoIconLevel) ? cdmaIconLevel : evdoIconLevel;
        }
        };
        return mPhoneStateListener;
    }

}

class HeadsetDeviceState {
+75 −19

File changed.

Preview size limit exceeded, changes collapsed.

+155 −366

File changed.

Preview size limit exceeded, changes collapsed.

+317 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading