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

Commit 1c9a1eb3 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4796401 from 36ec1642 to pi-release

Change-Id: I8c20e6146b6d8ac06c2c56b456d3134e664f2c75
parents 673560e5 36ec1642
Loading
Loading
Loading
Loading
+86 −53
Original line number Diff line number Diff line
@@ -80,13 +80,15 @@ class PhonePolicy {
    private static final int MESSAGE_ADAPTER_STATE_TURNED_ON = 4;

    // Timeouts
    private static final int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s
    @VisibleForTesting
    static int sConnectOtherProfilesTimeoutMillis = 6000; // 6s

    private final AdapterService mAdapterService;
    private final ServiceFactory mFactory;
    private final Handler mHandler;
    private final HashSet<BluetoothDevice> mHeadsetRetrySet = new HashSet<>();
    private final HashSet<BluetoothDevice> mA2dpRetrySet = new HashSet<>();
    private final HashSet<BluetoothDevice> mConnectOtherProfilesDeviceSet = new HashSet<>();

    // Broadcast receiver for all changes to states of various profiles
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -167,12 +169,14 @@ class PhonePolicy {
                }
                break;

                case MESSAGE_CONNECT_OTHER_PROFILES:
                case MESSAGE_CONNECT_OTHER_PROFILES: {
                    // Called when we try connect some profiles in processConnectOtherProfiles but
                    // we send a delayed message to try connecting the remaining profiles
                    processConnectOtherProfiles((BluetoothDevice) msg.obj);
                    BluetoothDevice device = (BluetoothDevice) msg.obj;
                    processConnectOtherProfiles(device);
                    mConnectOtherProfilesDeviceSet.remove(device);
                    break;

                }
                case MESSAGE_ADAPTER_STATE_TURNED_ON:
                    // Call auto connect when adapter switches state to ON
                    resetStates();
@@ -254,8 +258,8 @@ class PhonePolicy {
            int prevState) {
        debugLog("processProfileStateChanged, device=" + device + ", profile=" + profileId + ", "
                + prevState + " -> " + nextState);
        if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET)) && (
                nextState == BluetoothProfile.STATE_CONNECTED)) {
        if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET))) {
            if (nextState == BluetoothProfile.STATE_CONNECTED) {
                switch (profileId) {
                    case BluetoothProfile.A2DP:
                        mA2dpRetrySet.remove(device);
@@ -265,7 +269,13 @@ class PhonePolicy {
                        break;
                }
                connectOtherProfile(device);
            setProfileAutoConnectionPriority(device, profileId);
                setProfileAutoConnectionPriority(device, profileId, true);
            }
            if (prevState == BluetoothProfile.STATE_CONNECTING
                    && nextState == BluetoothProfile.STATE_DISCONNECTED) {
                setProfileAutoConnectionPriority(device, profileId, false);
            }

        }
    }

@@ -341,12 +351,18 @@ class PhonePolicy {
    }

    private void connectOtherProfile(BluetoothDevice device) {
        if ((!mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES))
                && (!mAdapterService.isQuietModeEnabled())) {
        if (mAdapterService.isQuietModeEnabled()) {
            debugLog("connectOtherProfile: in quiet mode, skip connect other profile " + device);
            return;
        }
        if (mConnectOtherProfilesDeviceSet.contains(device)) {
            debugLog("connectOtherProfile: already scheduled callback for " + device);
            return;
        }
        mConnectOtherProfilesDeviceSet.add(device);
        Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES);
        m.obj = device;
            mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT);
        }
        mHandler.sendMessageDelayed(m, sConnectOtherProfilesTimeoutMillis);
    }

    // This function is called whenever a profile is connected.  This allows any other bluetooth
@@ -363,6 +379,7 @@ class PhonePolicy {
        A2dpService a2dpService = mFactory.getA2dpService();
        PanService panService = mFactory.getPanService();

        boolean atLeastOneProfileConnectedForDevice = false;
        boolean allProfilesEmpty = true;
        List<BluetoothDevice> a2dpConnDevList = null;
        List<BluetoothDevice> hsConnDevList = null;
@@ -370,38 +387,45 @@ class PhonePolicy {

        if (hsService != null) {
            hsConnDevList = hsService.getConnectedDevices();
            allProfilesEmpty = allProfilesEmpty && hsConnDevList.isEmpty();
            allProfilesEmpty &= hsConnDevList.isEmpty();
            atLeastOneProfileConnectedForDevice |= hsConnDevList.contains(device);
        }
        if (a2dpService != null) {
            a2dpConnDevList = a2dpService.getConnectedDevices();
            allProfilesEmpty = allProfilesEmpty && a2dpConnDevList.isEmpty();
            allProfilesEmpty &= a2dpConnDevList.isEmpty();
            atLeastOneProfileConnectedForDevice |= a2dpConnDevList.contains(device);
        }
        if (panService != null) {
            panConnDevList = panService.getConnectedDevices();
            allProfilesEmpty = allProfilesEmpty && panConnDevList.isEmpty();
            allProfilesEmpty &= panConnDevList.isEmpty();
            atLeastOneProfileConnectedForDevice |= panConnDevList.contains(device);
        }

        if (allProfilesEmpty) {
            // considered as fully disconnected, don't bother connecting others.
        if (!atLeastOneProfileConnectedForDevice) {
            // Consider this device as fully disconnected, don't bother connecting others
            debugLog("processConnectOtherProfiles, all profiles disconnected for " + device);
            // reset retry status so that in the next round we can start retrying connections again
            mHeadsetRetrySet.remove(device);
            mA2dpRetrySet.remove(device);
            if (allProfilesEmpty) {
                debugLog("processConnectOtherProfiles, all profiles disconnected for all devices");
                // reset retry status so that in the next round we can start retrying connections
                resetStates();
            }
            return;
        }

        if (hsService != null) {
            if (!mHeadsetRetrySet.contains(device) && (
                    hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (
                    hsService.getConnectionState(device) == BluetoothProfile.STATE_DISCONNECTED)) {
            if (!mHeadsetRetrySet.contains(device) && (hsService.getPriority(device)
                    >= BluetoothProfile.PRIORITY_ON) && (hsService.getConnectionState(device)
                    == BluetoothProfile.STATE_DISCONNECTED)) {
                debugLog("Retrying connection to Headset with device " + device);
                mHeadsetRetrySet.add(device);
                hsService.connect(device);
            }
        }
        if (a2dpService != null) {
            if (!mA2dpRetrySet.contains(device) && (
                    a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON) && (
                    a2dpService.getConnectionState(device)
            if (!mA2dpRetrySet.contains(device) && (a2dpService.getPriority(device)
                    >= BluetoothProfile.PRIORITY_ON) && (a2dpService.getConnectionState(device)
                    == BluetoothProfile.STATE_DISCONNECTED)) {
                debugLog("Retrying connection to A2DP with device " + device);
                mA2dpRetrySet.add(device);
@@ -420,51 +444,60 @@ class PhonePolicy {
        }
    }

    private void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) {
    private void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId,
            boolean autoConnect) {
        debugLog("setProfileAutoConnectionPriority: device=" + device + ", profile=" + profileId
                + ", autoConnect=" + autoConnect);
        switch (profileId) {
            case BluetoothProfile.HEADSET:
            case BluetoothProfile.HEADSET: {
                HeadsetService hsService = mFactory.getHeadsetService();
                if ((hsService != null) && (BluetoothProfile.PRIORITY_AUTO_CONNECT
                        != hsService.getPriority(device))) {
                    List<BluetoothDevice> deviceList = hsService.getConnectedDevices();
                    adjustOtherHeadsetPriorities(hsService, deviceList);
                if (hsService == null) {
                    warnLog("setProfileAutoConnectionPriority: HEADSET service is null");
                    break;
                }
                removeAutoConnectFromDisconnectedHeadsets(hsService);
                if (autoConnect) {
                    hsService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT);
                }
                break;

            case BluetoothProfile.A2DP:
            }
            case BluetoothProfile.A2DP: {
                A2dpService a2dpService = mFactory.getA2dpService();
                if ((a2dpService != null) && (BluetoothProfile.PRIORITY_AUTO_CONNECT
                        != a2dpService.getPriority(device))) {
                    List<BluetoothDevice> deviceList = a2dpService.getConnectedDevices();
                    adjustOtherSinkPriorities(a2dpService, deviceList);
                if (a2dpService == null) {
                    warnLog("setProfileAutoConnectionPriority: A2DP service is null");
                    break;
                }
                removeAutoConnectFromDisconnectedA2dpSinks(a2dpService);
                if (autoConnect) {
                    a2dpService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT);
                }
                break;

            }
            default:
                Log.w(TAG, "Tried to set AutoConnect priority on invalid profile " + profileId);
                break;
        }
    }

    private void adjustOtherHeadsetPriorities(HeadsetService hsService,
            List<BluetoothDevice> connectedDeviceList) {
    private void removeAutoConnectFromDisconnectedHeadsets(HeadsetService hsService) {
        List<BluetoothDevice> connectedDeviceList = hsService.getConnectedDevices();
        for (BluetoothDevice device : mAdapterService.getBondedDevices()) {
            if (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT
                    && !connectedDeviceList.contains(device)) {
                debugLog("adjustOtherHeadsetPriorities, device " + device + " PRIORITY_ON");
                debugLog("removeAutoConnectFromDisconnectedHeadsets, device " + device
                        + " PRIORITY_ON");
                hsService.setPriority(device, BluetoothProfile.PRIORITY_ON);
            }
        }
    }

    private void adjustOtherSinkPriorities(A2dpService a2dpService,
            List<BluetoothDevice> connectedDeviceList) {
    private void removeAutoConnectFromDisconnectedA2dpSinks(A2dpService a2dpService) {
        List<BluetoothDevice> connectedDeviceList = a2dpService.getConnectedDevices();
        for (BluetoothDevice device : mAdapterService.getBondedDevices()) {
            if (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT
                    && !connectedDeviceList.contains(device)) {
                debugLog("adjustOtherSinkPriorities, device " + device + " PRIORITY_ON");
                debugLog("removeAutoConnectFromDisconnectedA2dpSinks, device " + device
                        + " PRIORITY_ON");
                a2dpService.setPriority(device, BluetoothProfile.PRIORITY_ON);
            }
        }
+2 −0
Original line number Diff line number Diff line
@@ -119,11 +119,13 @@ public class AtPhonebook {
                Calls.TYPE + "=" + Calls.OUTGOING_TYPE, null,
                Calls.DEFAULT_SORT_ORDER + " LIMIT 1");
        if (cursor == null) {
            Log.w(TAG, "getLastDialledNumber, cursor is null");
            return null;
        }

        if (cursor.getCount() < 1) {
            cursor.close();
            Log.w(TAG, "getLastDialledNumber, cursor.getCount is 0");
            return null;
        }
        cursor.moveToNext();
+9 −2
Original line number Diff line number Diff line
@@ -1274,7 +1274,8 @@ public class HeadsetService extends ProfileService {
     * @param dialNumber number to dial
     * @return true on successful dial out
     */
    boolean dialOutgoingCall(BluetoothDevice fromDevice, String dialNumber) {
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public boolean dialOutgoingCall(BluetoothDevice fromDevice, String dialNumber) {
        synchronized (mStateMachines) {
            Log.i(TAG, "dialOutgoingCall: from " + fromDevice);
            if (!isOnStateMachineThread()) {
@@ -1306,7 +1307,13 @@ public class HeadsetService extends ProfileService {
        }
    }

    boolean hasDeviceInitiatedDialingOut() {
    /**
     * Check if any connected headset has started dialing calls
     *
     * @return true if some device has started dialing calls
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public boolean hasDeviceInitiatedDialingOut() {
        synchronized (mStateMachines) {
            return mDialingOutTimeoutEvent != null;
        }
+10 −9
Original line number Diff line number Diff line
@@ -1826,20 +1826,21 @@ public class HeadsetStateMachine extends StateMachine {

    // HSP +CKPD command
    private void processKeyPressed(BluetoothDevice device) {
        final HeadsetPhoneState phoneState = mSystemInterface.getHeadsetPhoneState();
        if (phoneState.getCallState() == HeadsetHalConstants.CALL_STATE_INCOMING) {
        if (mSystemInterface.isRinging()) {
            mSystemInterface.answerCall(device);
        } else if (phoneState.getNumActiveCall() > 0) {
            if (getAudioState() != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
                mHeadsetService.setActiveDevice(mDevice);
                mSystemInterface.getAudioManager().setParameters("A2dpSuspended=true");
                if (!mNativeInterface.connectAudio(mDevice)) {
                    mSystemInterface.getAudioManager().setParameters("A2dpSuspended=false");
                    Log.w(TAG, "processKeyPressed: failed to connectAudio to " + mDevice);
        } else if (mSystemInterface.isInCall()) {
            if (getAudioState() == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
                // Should connect audio as well
                if (!mHeadsetService.setActiveDevice(mDevice)) {
                    Log.w(TAG, "processKeyPressed, failed to set active device to " + mDevice);
                }
            } else {
                mSystemInterface.hangupCall(device);
            }
        } else if (getAudioState() != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
            if (!mNativeInterface.disconnectAudio(mDevice)) {
                Log.w(TAG, "processKeyPressed, failed to disconnect audio from " + mDevice);
            }
        } else {
            // We have already replied OK to this HSP command, no feedback is needed
            if (mHeadsetService.hasDeviceInitiatedDialingOut()) {
+31 −25
Original line number Diff line number Diff line
@@ -278,9 +278,36 @@ class MediaPlayerWrapper {
        d("Controller for " + mPackageName + " was updated.");
    }

    private void sendMediaUpdate() {
        MediaData newData = new MediaData(
                Util.toMetadata(getMetadata()),
                getPlaybackState(),
                Util.toMetadataList(getQueue()));

        if (newData.equals(mCurrentData)) {
            // This may happen if the controller is fully synced by the time the
            // first update is completed
            Log.v(TAG, "Trying to update with last sent metadata");
            return;
        }

        synchronized (mCallbackLock) {
            if (mRegisteredCallback == null) {
                Log.e(TAG, mPackageName
                        + "Trying to send an update with no registered callback");
                return;
            }

            Log.v(TAG, "trySendMediaUpdate(): Metadata has been updated for " + mPackageName);
            mRegisteredCallback.mediaUpdatedCallback(newData);
        }

        mCurrentData = newData;
    }

    class TimeoutHandler extends Handler {
        private static final int MSG_TIMEOUT = 0;
        private static final long CALLBACK_TIMEOUT_MS = 1000;
        private static final long CALLBACK_TIMEOUT_MS = 2000;

        TimeoutHandler(Looper looper) {
            super(looper);
@@ -301,6 +328,8 @@ class MediaPlayerWrapper {
                Log.e(TAG, "  └ QueueItem(" + i + "): " + current_queue.get(i));
            }

            sendMediaUpdate();

            // TODO(apanicke): Add metric collection here.

            if (sTesting) Log.wtfStack(TAG, "Crashing the stack");
@@ -342,30 +371,7 @@ class MediaPlayerWrapper {
                }
            }

            MediaData newData = new MediaData(
                    Util.toMetadata(getMetadata()),
                    getPlaybackState(),
                    Util.toMetadataList(getQueue()));

            if (newData.equals(mCurrentData)) {
                // This may happen if the controller is fully synced by the time the
                // first update is completed
                Log.v(TAG, "Trying to update with last sent metadata");
                return;
            }

            synchronized (mCallbackLock) {
                if (mRegisteredCallback == null) {
                    Log.e(TAG, mPackageName
                            + "Trying to send an update with no registered callback");
                    return;
                }

                Log.v(TAG, "trySendMediaUpdate(): Metadata has been updated for " + mPackageName);
                mRegisteredCallback.mediaUpdatedCallback(newData);
            }

            mCurrentData = newData;
            sendMediaUpdate();
        }

        @Override
Loading