diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ebac35fcd4044237a2ea495e07d1b44393cef67a..a0454375f6d94385d5cbeb93c5d91b666a54ef7d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -243,6 +243,7 @@ android:exported="false"> + diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/DataManager.java b/app/src/main/java/com/nynja/mobile/communicator/data/DataManager.java index d4fd29b4e66de6a007007f192e9be61cfe31019b..413ef431a8ece2750fce84267f3359855573e8b5 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/DataManager.java +++ b/app/src/main/java/com/nynja/mobile/communicator/data/DataManager.java @@ -5904,9 +5904,10 @@ public class DataManager { } catch (Exception ex) { Timber.e(ex); } - if (soundUri != null) { - mNynjaSoundManager.playCallRinging(soundUri); - } + getConferenceSDK().playIncomingRinging(soundUri); +// if (soundUri != null) { +// mNynjaSoundManager.playCallRinging(soundUri); +// } } public NynjaSoundManager.Mode getNynjaSoundManagerRingerMode() { diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/audio/NynjaSoundManager.kt b/app/src/main/java/com/nynja/mobile/communicator/data/audio/NynjaSoundManager.kt index b3a9ed2c02ef371419da755bbe62e3d73f4b0616..6049c72040f3f57bf87a59cdb39a46db47bc5fee 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/audio/NynjaSoundManager.kt +++ b/app/src/main/java/com/nynja/mobile/communicator/data/audio/NynjaSoundManager.kt @@ -110,8 +110,9 @@ class NynjaSoundManager(context: Context) { stopSound() mMediaPlayer.setDataSource(mContext, uri) - - setStream(stream) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + setStream(stream) + } mMediaPlayer.setLooping(loop) mMediaPlayer.prepare() diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/audio/headphones/HeadphoneEventsBroadcastReceiver.java b/app/src/main/java/com/nynja/mobile/communicator/data/audio/headphones/HeadphoneEventsBroadcastReceiver.java index 4e60648479f40f5ed26277f77543e9470b00245d..a98e29c7656d1ed435be45373f50eec116c729fe 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/audio/headphones/HeadphoneEventsBroadcastReceiver.java +++ b/app/src/main/java/com/nynja/mobile/communicator/data/audio/headphones/HeadphoneEventsBroadcastReceiver.java @@ -20,8 +20,6 @@ public class HeadphoneEventsBroadcastReceiver extends BroadcastReceiver { mBus = NynjaApp.getComponent().rxBus(); } - abortBroadcast(); - KeyEvent keyEvent = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); int keyCode = keyEvent.getKeyCode(); Timber.d("HeadphoneEventsBroadcastReceiver::onReceive(): " + diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/audio/headphones/HeadphoneStateBroadcastReceiver.java b/app/src/main/java/com/nynja/mobile/communicator/data/audio/headphones/HeadphoneStateBroadcastReceiver.java index 84b89cfbb6fabd34c92d193f7cc95c0221709644..d0492afed4040a0d470492869b900e3cc73bf9bb 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/audio/headphones/HeadphoneStateBroadcastReceiver.java +++ b/app/src/main/java/com/nynja/mobile/communicator/data/audio/headphones/HeadphoneStateBroadcastReceiver.java @@ -1,5 +1,6 @@ package com.nynja.mobile.communicator.data.audio.headphones; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; @@ -10,6 +11,8 @@ import com.nynja.mobile.communicator.NynjaApp; import com.nynja.mobile.communicator.data.RxBus; import com.nynja.mobile.communicator.data.audio.headphones.data.HeadphoneState; +import timber.log.Timber; + public class HeadphoneStateBroadcastReceiver extends BroadcastReceiver { @@ -19,27 +22,65 @@ public class HeadphoneStateBroadcastReceiver extends BroadcastReceiver { AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) { sendWireHeadsetConnectionState(am); - } else if ((intent.getAction().equals(BluetoothDevice.ACTION_ACL_CONNECTED) || (intent.getAction().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)))) { - sendBTHeadsetConnectionState(am); + } else if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) { + sendBluetoothDeviceConnectionState(intent, am); + } else if (intent.getAction().equals(BluetoothDevice.ACTION_ACL_CONNECTED)) { + sendBTHeadsetConnectionState(am, true); + } else if (intent.getAction().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) { + sendBTHeadsetConnectionState(am, false); + } + } + + private void sendBluetoothDeviceConnectionState(Intent intent, AudioManager am) { + BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1); + switch (state) { + case BluetoothDevice.BOND_NONE: + Timber.d("sendBluetoothDeviceConnectionState(): Remote Bluetoot device is not bonded. Device: "); + mBus.localEvent(HeadphoneState.Companion.disconnected()); + break; + case BluetoothDevice.BOND_BONDING: + Timber.d("sendBluetoothDeviceConnectionState(): Remote Bluetoot device is in bonding process"); + break; + case BluetoothDevice.BOND_BONDED: + { + Timber.d("sendBluetoothDeviceConnectionState(): Remote Bluetoot device is paired"); + if (am.isBluetoothA2dpOn()) { + mBus.localEvent(HeadphoneState.Companion.connected()); + } else { + mBus.localEvent(HeadphoneState.Companion.disconnected()); + } + } + break; } } private void sendWireHeadsetConnectionState(AudioManager am) { if (am != null) { if (am.isWiredHeadsetOn()) { + Timber.d("sendWireHeadsetConnectionState(): isWiredHeadsetOn: ON"); mBus.localEvent(HeadphoneState.Companion.connected()); } else { + Timber.d("sendWireHeadsetConnectionState(): isWiredHeadsetOn: OFF"); mBus.localEvent(HeadphoneState.Companion.disconnected()); } } } - private void sendBTHeadsetConnectionState(AudioManager am) { + private void sendBTHeadsetConnectionState(AudioManager am, boolean aclConnected) { if (am != null) { if (am.isBluetoothA2dpOn()) { + Timber.d("sendBTHeadsetConnectionState(): isBluetoothA2dpOn: ON"); mBus.localEvent(HeadphoneState.Companion.connected()); } else { - mBus.localEvent(HeadphoneState.Companion.disconnected()); + Timber.d("sendBTHeadsetConnectionState(): isBluetoothA2dpOn: OFF"); + if (aclConnected) { + Timber.d("sendBTHeadsetConnectionState(): aclConnected: ON"); + mBus.localEvent(HeadphoneState.Companion.connected()); + } else { + Timber.d("sendBTHeadsetConnectionState(): aclConnected: OFF"); + mBus.localEvent(HeadphoneState.Companion.disconnected()); + } } } } diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ActiveConferenceCall.java b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ActiveConferenceCall.java index 881a7088e044a52d1a879931dbd1fee3dbc1003c..38fafd114895a91900b752da08c4f35d9272c399 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ActiveConferenceCall.java +++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ActiveConferenceCall.java @@ -32,10 +32,11 @@ public class ActiveConferenceCall extends ActiveCallBase { public ActiveConferenceCall(NYNCall conference, String endPointId, - CallType callType, boolean isVideoEnabled, boolean outgoingCall) { + CallType callType, boolean isVideoEnabled, + boolean outgoingCall, CallStateData.AudioRouteType audioRouteType) { super(endPointId, callType, isVideoEnabled, outgoingCall); mData = new ConferenceCallData((callType == CallType.P2PCall)); - mState = new CallStateData(false, isVideoEnabled); + mState = new CallStateData(false, isVideoEnabled, audioRouteType); mConference = conference; mMembers = new ArrayList(); mMyDisplayName = ""; diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/CallStateData.java b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/CallStateData.java index a5c102e44d549d17abd69451452c809b1e14ce1c..1d4397ff6b451cad974eacc8a6e24e99b8f8742f 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/CallStateData.java +++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/CallStateData.java @@ -52,10 +52,12 @@ public class CallStateData { pauseRestoreState = new CallStateData(this); } - public CallStateData(boolean isOwnSSActive, boolean isOwnStreamActive) { + public CallStateData(boolean isOwnSSActive, boolean isOwnStreamActive, + AudioRouteType audioRouteType) { init(); this.isOwnSSActive = isOwnSSActive; this.isOwnStreamActive = isOwnStreamActive; + this.mAudioRouteType = audioRouteType; } private void init() { diff --git a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKModule.java b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKModule.java index c7eacc2658160776cddbd9d6adfd8a2cc93cfd3b..8c479d3823bc00f922a6c154df784ecc47cdb1e2 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKModule.java +++ b/app/src/main/java/com/nynja/mobile/communicator/data/sdk/calls/ConferenceSDKModule.java @@ -8,6 +8,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.media.AudioManager; +import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.CountDownTimer; @@ -133,7 +134,6 @@ public class ConferenceSDKModule extends BaseSDKModule { private NynjaSoundManager mNynjaSoundManager; private AppRTCAudioManager mConferenceAudioManager; private AudioManager mAudioManager; - private BroadcastReceiver incomingCallReceiver; private ProfileSyncManager mProfileSyncManager; public boolean isScreenShareAllowed = false; @@ -147,6 +147,9 @@ public class ConferenceSDKModule extends BaseSDKModule { private HashMap mConferenceWaitingRoomLNames = new HashMap<>(); //private HashMap mMyAcceptedElsewhereCalls = new HashMap<>(); private HashMap mMyAcceptedElsewhereCalls = new HashMap<>(); + public CallStateData.AudioRouteType mActiveAudioRouteType; + public CallStateData.AudioRouteType mAudioRouteBeforeBluetooth; + private enum States { Connecting, Connected, Disconnecting, Disconnected @@ -723,9 +726,12 @@ public class ConferenceSDKModule extends BaseSDKModule { break; case BLUETOOTH: + mAudioRouteBeforeBluetooth = mActiveAudioRouteType; + setSpeakerState(false, true, false); mConferenceAudioManager.selectAudioDevice(AppRTCAudioManager.AudioDevice.BLUETOOTH); break; } + mActiveAudioRouteType = routeType; if (updateWith && hasCreatedActiveCall()) { mActiveConference.mState.mAudioRouteType = routeType; } @@ -754,7 +760,10 @@ public class ConferenceSDKModule extends BaseSDKModule { mStateDevice = stateDevice; mNynjaSoundManager = nynjaSoundManager; mProfileSyncManager = profileSyncManager; - //////////////////////////////////////////////////////////////////////////////////////////////////////// + mActiveAudioRouteType = CallStateData.AudioRouteType.NOT_SET; + mAudioRouteBeforeBluetooth = mActiveAudioRouteType; + + //////////////////////////////////////////////////////////////////////////////////////////////////////// // REVISE FOR Multiple account services !!!!!!!!!!!!! //if (isWriteStorageAllowed()) { // mConferenceCommunicator = NynjaCommunicator.newInstanceWithConfig( @@ -2710,7 +2719,8 @@ public class ConferenceSDKModule extends BaseSDKModule { boolean isOutcomingConference, boolean isVideoEnabled, ActiveCallBase.CallType callType) { - ActiveConferenceCall activeConference = new ActiveConferenceCall(iConference, personId, callType, isVideoEnabled, isOutcomingConference); + ActiveConferenceCall activeConference = new ActiveConferenceCall(iConference, personId, callType, + isVideoEnabled, isOutcomingConference, mActiveAudioRouteType); ContextUtils.createRootEglBase(); return activeConference; } @@ -2833,13 +2843,13 @@ public class ConferenceSDKModule extends BaseSDKModule { if (mConferenceAudioManager != null) { mConferenceAudioManager.start(null); mActiveConference.mState.isSpeakerOn = mActiveConference.isReceivingVideo(); - if (!isSpeakerPhoneForced) { - if (mActiveConference.mState.isSpeakerOn) { - mConferenceAudioManager.setDefaultAudioDevice(AppRTCAudioManager.AudioDevice.SPEAKER_PHONE); - } else { - mConferenceAudioManager.setDefaultAudioDevice(AppRTCAudioManager.AudioDevice.EARPIECE); - } - } +// if (!isSpeakerPhoneForced) { +// if (mActiveConference.mState.isSpeakerOn) { +// mConferenceAudioManager.setDefaultAudioDevice(AppRTCAudioManager.AudioDevice.SPEAKER_PHONE); +// } else { +// mConferenceAudioManager.setDefaultAudioDevice(AppRTCAudioManager.AudioDevice.EARPIECE); +// } +// } } if (mActiveConference.isOutgoingCall) { if (mActiveConference.mCallType == ActiveCallBase.CallType.P2PCall) { @@ -3090,6 +3100,9 @@ public class ConferenceSDKModule extends BaseSDKModule { if (!hasCreatedActiveCall()) return false; mActiveConference.mState.isOwnStreamActive = false; initConferenceCall(startActivity); + new Handler(Looper.getMainLooper()).post(() -> { + mConferenceAudioManager.start(null); + }); Timber.d("createIncomingCallAndStartRinging with \'ConferenceId\'=\'" + callId + "; startActivity=" + (startActivity?"true": "false")); if (startActivity) { @@ -3646,11 +3659,19 @@ public class ConferenceSDKModule extends BaseSDKModule { return mActiveConference.mData.mParticipantsCountLimit; } + public void playIncomingRinging(Uri soundUri) { + if (!hasCreatedActiveCall()) return; + if (soundUri == null) return; + mConferenceAudioManager.start(null); + mNynjaSoundManager.playCallRinging(soundUri); + } + private void playConnecting() { mNynjaSoundManager.playCallConnecting(); } private void playRinging() { + if (!hasCreatedActiveCall()) return; setSpeakerState(false, false); mNynjaSoundManager.playCallRingBack(); } @@ -3938,7 +3959,7 @@ public class ConferenceSDKModule extends BaseSDKModule { } private void switchToBTDevice() { - setSpeakerState(false, true, false); +// setSpeakerState(false, true, false); setAudioRoute(CallStateData.AudioRouteType.BLUETOOTH, true, true); } @@ -3953,15 +3974,30 @@ public class ConferenceSDKModule extends BaseSDKModule { @Override public boolean onMediaButtonsLocalEvent(Context context, LocalEvent event) { if (event instanceof HeadphoneState) { + if (!hasCreatedActiveCall()) { + Timber.d("onMediaButtonsLocalEvent(): hasCreatedActiveCall() = false "); + } HeadphoneState hs = (HeadphoneState)event; switch (hs.getState()) { case Connected: - switchToBTDevice(); - onBluetoothConnectivityChanged(true); + if (hasCreatedActiveCall()) { + switchToBTDevice(); + } else { + switchToBTDevice(); + onBluetoothConnectivityChanged(true); + } break; case Disconnected: - setAudioRoute(CallStateData.AudioRouteType.EARPIECE, true, true); - onBluetoothConnectivityChanged(false); + if (hasCreatedActiveCall()) { + if (mAudioRouteBeforeBluetooth != CallStateData.AudioRouteType.NOT_SET) { + setAudioRoute(mAudioRouteBeforeBluetooth, true, true); + } else { + setAudioRoute(CallStateData.AudioRouteType.EARPIECE, true, true); + } + onBluetoothConnectivityChanged(false); + } else { + setAudioRoute(CallStateData.AudioRouteType.EARPIECE, true, true); + } break; case Play: case Pause: @@ -3969,23 +4005,24 @@ public class ConferenceSDKModule extends BaseSDKModule { case PlayPause: if (isCallRinging()) { String callId = getActiveConference().mConference.callId(); - Intent intent = new Intent(context, MainActivity.class); -// if (hs.getState() == HeadphoneState.States.Pause || hs.getState() == HeadphoneState.States.Stop) { -// intent.setAction(MainActivity.INTENT_NOTIFICATION_CALL_REJECT_ID); -// } else { - intent.setAction(MainActivity.INTENT_NOTIFICATION_CALL_ANSWER_ID); -// } - intent.putExtra(MainActivity.INTENT_NOTIFICATION_CALL_ID, callId); - intent.putExtra(MainActivity.INTENT_CALL_NOTIFICATION_ID, ActiveConferenceCall.ANDROID_10_PUSH_CALL_NTFN_ID); + setSpeakerState(false, false, false); + mConferenceAudioManager.selectAudioDevice(AppRTCAudioManager.AudioDevice.EARPIECE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { answerCall(callId); + setAudioRoute(CallStateData.AudioRouteType.EARPIECE, false); mNotificationHelper.clearCallPush(ActiveConferenceCall.ANDROID_10_PUSH_CALL_NTFN_ID); -// .setAudioRoute(ActiveCallBase.AudioRouteType.BLUETOOTH, true, true); } else { + Intent intent = new Intent(context, MainActivity.class); + intent.setAction(MainActivity.INTENT_NOTIFICATION_CALL_ANSWER_ID); + intent.putExtra(MainActivity.INTENT_NOTIFICATION_CALL_ID, callId); + intent.putExtra(MainActivity.INTENT_CALL_NOTIFICATION_ID, ActiveConferenceCall.ANDROID_10_PUSH_CALL_NTFN_ID); context.startActivity(intent); //getContext().startActivity(intent); } - switchToBTDevice(); + new Handler(Looper.getMainLooper()).postDelayed(() -> { + switchToBTDevice(); + }, Consts.DELAY_1000); } else if (hasCallInProgress()) { hangUp(); } diff --git a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallTapToSpeakPresenter.java b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallTapToSpeakPresenter.java index 9c1d86ff045d85313737b0593d9bcc575debb2b2..df498f83dcc4e80874dad2ca2c704fa3bfbd2fa0 100644 --- a/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallTapToSpeakPresenter.java +++ b/app/src/main/java/com/nynja/mobile/communicator/mvp/presenters/CallTapToSpeakPresenter.java @@ -74,6 +74,7 @@ public class CallTapToSpeakPresenter extends ConferenceSDKPresenter