Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 1 | /* |
Adrien Béraud | e552f69 | 2020-11-03 14:30:52 -0500 | [diff] [blame] | 2 | * Copyright (C) 2004-2020 Savoir-faire Linux Inc. |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 3 | * |
| 4 | * Author: Hadrien De Sousa <hadrien.desousa@savoirfairelinux.com> |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 5 | * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com> |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 3 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | * |
| 12 | * This program is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | * GNU General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public License |
| 18 | * along with this program; if not, write to the Free Software |
| 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 20 | */ |
| 21 | package cx.ring.call; |
| 22 | |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 23 | import java.util.ArrayList; |
| 24 | import java.util.List; |
| 25 | import java.util.Objects; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 26 | import java.util.concurrent.TimeUnit; |
| 27 | |
| 28 | import javax.inject.Inject; |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 29 | import javax.inject.Named; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 30 | |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 31 | import cx.ring.facades.ConversationFacade; |
| 32 | import cx.ring.model.Conference; |
| 33 | import cx.ring.model.Conversation; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 34 | import cx.ring.model.SipCall; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 35 | import cx.ring.model.Uri; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 36 | import cx.ring.mvp.RootPresenter; |
| 37 | import cx.ring.services.AccountService; |
| 38 | import cx.ring.services.CallService; |
Adrien Béraud | 8d71075 | 2019-02-20 13:53:59 -0500 | [diff] [blame] | 39 | import cx.ring.services.ContactService; |
Rayan Osseiran | 38206c6 | 2019-05-15 14:49:03 -0400 | [diff] [blame] | 40 | import cx.ring.services.DeviceRuntimeService; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 41 | import cx.ring.services.HardwareService; |
Amirhossein | 7bb77aa | 2020-12-18 16:30:44 -0500 | [diff] [blame^] | 42 | import cx.ring.services.PreferencesService; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 43 | import cx.ring.utils.Log; |
Hadrien De Sousa | c165e9b | 2017-11-24 12:33:32 -0500 | [diff] [blame] | 44 | import cx.ring.utils.StringUtils; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 45 | import io.reactivex.Maybe; |
Rayan Osseiran | ed9feeb | 2019-07-05 16:04:30 -0400 | [diff] [blame] | 46 | import io.reactivex.Observable; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 47 | import io.reactivex.Observer; |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 48 | import io.reactivex.Scheduler; |
Adrien Béraud | 3aeed5d | 2018-07-26 11:26:13 -0400 | [diff] [blame] | 49 | import io.reactivex.disposables.Disposable; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 50 | import io.reactivex.subjects.BehaviorSubject; |
| 51 | import io.reactivex.subjects.Subject; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 52 | |
AGS5 | ef482ce | 2020-06-12 13:28:51 -0400 | [diff] [blame] | 53 | import static cx.ring.daemon.Ringservice.listCallMediaHandlers; |
AGS5 | ef482ce | 2020-06-12 13:28:51 -0400 | [diff] [blame] | 54 | |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 55 | public class CallPresenter extends RootPresenter<CallView> { |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 56 | |
| 57 | public final static String TAG = CallPresenter.class.getSimpleName(); |
| 58 | |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 59 | private AccountService mAccountService; |
Adrien Béraud | 8d71075 | 2019-02-20 13:53:59 -0500 | [diff] [blame] | 60 | private ContactService mContactService; |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 61 | private HardwareService mHardwareService; |
| 62 | private CallService mCallService; |
Rayan Osseiran | 38206c6 | 2019-05-15 14:49:03 -0400 | [diff] [blame] | 63 | private DeviceRuntimeService mDeviceRuntimeService; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 64 | private ConversationFacade mConversationFacade; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 65 | |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 66 | private Conference mConference; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 67 | private final List<SipCall> mPendingCalls = new ArrayList<>(); |
| 68 | private final Subject<List<SipCall>> mPendingSubject = BehaviorSubject.createDefault(mPendingCalls); |
Amirhossein | 7bb77aa | 2020-12-18 16:30:44 -0500 | [diff] [blame^] | 69 | private final PreferencesService mPreferencesService; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 70 | |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 71 | private boolean mOnGoingCall = false; |
Hadrien De Sousa | 203164c | 2017-12-05 17:41:42 -0500 | [diff] [blame] | 72 | private boolean mAudioOnly = true; |
Adrien Béraud | 335d32e | 2019-05-31 09:31:40 -0400 | [diff] [blame] | 73 | private boolean permissionChanged = false; |
Rayan Osseiran | c1532d4 | 2019-06-05 13:17:53 -0400 | [diff] [blame] | 74 | private boolean pipIsActive = false; |
Rayan Osseiran | 3dd0466 | 2019-06-28 16:47:48 -0400 | [diff] [blame] | 75 | private boolean incomingIsFullIntent = true; |
Rayan Osseiran | ed9feeb | 2019-07-05 16:04:30 -0400 | [diff] [blame] | 76 | private boolean callInitialized = false; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 77 | |
| 78 | private int videoWidth = -1; |
| 79 | private int videoHeight = -1; |
| 80 | private int previewWidth = -1; |
| 81 | private int previewHeight = -1; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 82 | private String currentSurfaceId = null; |
AGS5 | ef482ce | 2020-06-12 13:28:51 -0400 | [diff] [blame] | 83 | private String currentPluginSurfaceId = null; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 84 | |
Adrien Béraud | 3aeed5d | 2018-07-26 11:26:13 -0400 | [diff] [blame] | 85 | private Disposable timeUpdateTask = null; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 86 | |
| 87 | @Inject |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 88 | @Named("UiScheduler") |
| 89 | protected Scheduler mUiScheduler; |
| 90 | |
| 91 | @Inject |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 92 | public CallPresenter(AccountService accountService, |
Adrien Béraud | 8d71075 | 2019-02-20 13:53:59 -0500 | [diff] [blame] | 93 | ContactService contactService, |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 94 | HardwareService hardwareService, |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 95 | CallService callService, |
| 96 | DeviceRuntimeService deviceRuntimeService, |
Amirhossein | 7bb77aa | 2020-12-18 16:30:44 -0500 | [diff] [blame^] | 97 | ConversationFacade conversationFacade, |
| 98 | PreferencesService preferencesService) { |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 99 | mAccountService = accountService; |
Adrien Béraud | 8d71075 | 2019-02-20 13:53:59 -0500 | [diff] [blame] | 100 | mContactService = contactService; |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 101 | mHardwareService = hardwareService; |
| 102 | mCallService = callService; |
Rayan Osseiran | 38206c6 | 2019-05-15 14:49:03 -0400 | [diff] [blame] | 103 | mDeviceRuntimeService = deviceRuntimeService; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 104 | mConversationFacade = conversationFacade; |
Amirhossein | 7bb77aa | 2020-12-18 16:30:44 -0500 | [diff] [blame^] | 105 | mPreferencesService = preferencesService; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 106 | } |
| 107 | |
Rayan Osseiran | 38206c6 | 2019-05-15 14:49:03 -0400 | [diff] [blame] | 108 | public void cameraPermissionChanged(boolean isGranted) { |
| 109 | if (isGranted && mHardwareService.isVideoAvailable()) { |
Adrien Béraud | 37fb52e | 2020-10-02 19:24:31 -0400 | [diff] [blame] | 110 | mHardwareService.initVideo() |
| 111 | .onErrorComplete() |
| 112 | .blockingAwait(); |
Adrien Béraud | 335d32e | 2019-05-31 09:31:40 -0400 | [diff] [blame] | 113 | permissionChanged = true; |
Rayan Osseiran | 38206c6 | 2019-05-15 14:49:03 -0400 | [diff] [blame] | 114 | } |
| 115 | } |
| 116 | |
| 117 | public void audioPermissionChanged(boolean isGranted) { |
Rayan Osseiran | db4667e | 2019-05-31 09:41:54 -0400 | [diff] [blame] | 118 | if (isGranted && mHardwareService.hasMicrophone()) { |
Adrien Béraud | 22ec8b8 | 2019-07-27 21:53:50 -0400 | [diff] [blame] | 119 | mCallService.restartAudioLayer(); |
Rayan Osseiran | 38206c6 | 2019-05-15 14:49:03 -0400 | [diff] [blame] | 120 | } |
| 121 | } |
| 122 | |
| 123 | |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 124 | @Override |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 125 | public void unbindView() { |
Hadrien De Sousa | 203164c | 2017-12-05 17:41:42 -0500 | [diff] [blame] | 126 | if (!mAudioOnly) { |
Adrien Béraud | 30532a5 | 2018-09-11 15:10:05 -0400 | [diff] [blame] | 127 | mHardwareService.endCapture(); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 128 | } |
Adrien Béraud | 99fd420 | 2018-12-13 13:02:21 -0500 | [diff] [blame] | 129 | super.unbindView(); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 130 | } |
| 131 | |
| 132 | @Override |
| 133 | public void bindView(CallView view) { |
| 134 | super.bindView(view); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 135 | /*mCompositeDisposable.add(mAccountService.getRegisteredNames() |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 136 | .observeOn(mUiScheduler) |
| 137 | .subscribe(r -> { |
| 138 | if (mSipCall != null && mSipCall.getContact() != null) { |
| 139 | getView().updateContactBubble(mSipCall.getContact()); |
| 140 | } |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 141 | }));*/ |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 142 | mCompositeDisposable.add(mHardwareService.getVideoEvents() |
| 143 | .observeOn(mUiScheduler) |
| 144 | .subscribe(this::onVideoEvent)); |
Adrien Béraud | 34a6fa2 | 2019-07-28 16:02:59 -0400 | [diff] [blame] | 145 | mCompositeDisposable.add(mHardwareService.getAudioState() |
| 146 | .observeOn(mUiScheduler) |
| 147 | .subscribe(state -> getView().updateAudioState(state))); |
| 148 | |
Adrien Béraud | 22ec8b8 | 2019-07-27 21:53:50 -0400 | [diff] [blame] | 149 | /*mCompositeDisposable.add(mHardwareService |
Adrien Béraud | 057e9a3 | 2018-09-30 17:48:55 -0400 | [diff] [blame] | 150 | .getBluetoothEvents() |
| 151 | .subscribe(event -> { |
Rayan Osseiran | 7f77c8a | 2019-07-17 16:40:50 -0400 | [diff] [blame] | 152 | if (!event.connected && mSipCall == null) { |
Adrien Béraud | 057e9a3 | 2018-09-30 17:48:55 -0400 | [diff] [blame] | 153 | hangupCall(); |
| 154 | } |
Adrien Béraud | 22ec8b8 | 2019-07-27 21:53:50 -0400 | [diff] [blame] | 155 | }));*/ |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 156 | } |
| 157 | |
Hadrien De Sousa | 203164c | 2017-12-05 17:41:42 -0500 | [diff] [blame] | 158 | public void initOutGoing(String accountId, String contactRingId, boolean audioOnly) { |
Adrien Béraud | 85683c2 | 2018-05-23 11:18:43 -0400 | [diff] [blame] | 159 | if (accountId == null || contactRingId == null) { |
| 160 | Log.e(TAG, "initOutGoing: null account or contact"); |
Rayan Osseiran | 106a474 | 2019-07-18 15:03:55 -0400 | [diff] [blame] | 161 | hangupCall(); |
Adrien Béraud | 85683c2 | 2018-05-23 11:18:43 -0400 | [diff] [blame] | 162 | return; |
| 163 | } |
Adrien Béraud | 7403f35 | 2019-11-22 16:30:55 -0500 | [diff] [blame] | 164 | if (!mHardwareService.hasCamera()) { |
Adrien Béraud | d3bf4e4 | 2018-02-14 14:44:41 +0100 | [diff] [blame] | 165 | audioOnly = true; |
Hadrien De Sousa | fcf2a99 | 2017-12-15 11:08:56 -0500 | [diff] [blame] | 166 | } |
Adrien Béraud | eb4bb00 | 2019-03-14 15:52:48 -0400 | [diff] [blame] | 167 | //getView().blockScreenRotation(); |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 168 | |
Adrien Béraud | 34915fb | 2020-08-24 17:12:03 -0400 | [diff] [blame] | 169 | Observable<Conference> callObservable = mCallService |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 170 | .placeCall(accountId, StringUtils.toNumber(contactRingId), audioOnly) |
| 171 | //.map(mCallService::getConference) |
| 172 | .flatMapObservable(call -> mCallService.getConfUpdates(call)) |
Adrien Béraud | 34915fb | 2020-08-24 17:12:03 -0400 | [diff] [blame] | 173 | .share(); |
| 174 | |
| 175 | mCompositeDisposable.add(callObservable |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 176 | .observeOn(mUiScheduler) |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 177 | .subscribe(conference -> { |
| 178 | contactUpdate(conference); |
| 179 | confUpdate(conference); |
Rayan Osseiran | db4667e | 2019-05-31 09:41:54 -0400 | [diff] [blame] | 180 | }, e -> { |
| 181 | hangupCall(); |
| 182 | Log.e(TAG, "Error with initOutgoing: " + e.getMessage()); |
| 183 | })); |
Adrien Béraud | 34915fb | 2020-08-24 17:12:03 -0400 | [diff] [blame] | 184 | |
| 185 | showConference(callObservable); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 186 | } |
| 187 | |
Rayan Osseiran | ed9feeb | 2019-07-05 16:04:30 -0400 | [diff] [blame] | 188 | /** |
| 189 | * Returns to or starts an incoming call |
| 190 | * |
| 191 | * @param confId the call id |
| 192 | * @param actionViewOnly true if only returning to call or if using full screen intent |
| 193 | */ |
| 194 | public void initIncomingCall(String confId, boolean actionViewOnly) { |
| 195 | //getView().blockScreenRotation(); |
| 196 | |
| 197 | // if the call is incoming through a full intent, this allows the incoming call to display |
| 198 | incomingIsFullIntent = actionViewOnly; |
| 199 | |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 200 | Observable<Conference> callObservable = mCallService.getConfUpdates(confId) |
| 201 | .observeOn(mUiScheduler) |
| 202 | .share(); |
Rayan Osseiran | ed9feeb | 2019-07-05 16:04:30 -0400 | [diff] [blame] | 203 | |
| 204 | // Handles the case where the call has been accepted, emits a single so as to only check for permissions and start the call once |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 205 | mCompositeDisposable.add(callObservable |
| 206 | .firstOrError() |
| 207 | .subscribe(call -> { |
| 208 | if (!actionViewOnly) { |
| 209 | contactUpdate(call); |
| 210 | confUpdate(call); |
| 211 | callInitialized = true; |
| 212 | getView().prepareCall(true); |
| 213 | } |
| 214 | }, e -> { |
| 215 | hangupCall(); |
| 216 | Log.e(TAG, "Error with initIncoming, preparing call flow :" , e); |
| 217 | })); |
Rayan Osseiran | ed9feeb | 2019-07-05 16:04:30 -0400 | [diff] [blame] | 218 | |
| 219 | // Handles retrieving call updates. Items emitted are only used if call is already in process or if user is returning to a call. |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 220 | mCompositeDisposable.add(callObservable |
| 221 | .subscribe(call -> { |
| 222 | if (callInitialized || actionViewOnly) { |
| 223 | contactUpdate(call); |
| 224 | confUpdate(call); |
| 225 | } |
| 226 | }, e -> { |
| 227 | hangupCall(); |
| 228 | Log.e(TAG, "Error with initIncoming, action view flow: ", e); |
| 229 | })); |
Adrien Béraud | 34915fb | 2020-08-24 17:12:03 -0400 | [diff] [blame] | 230 | |
| 231 | showConference(callObservable); |
| 232 | } |
| 233 | |
| 234 | private void showConference(Observable<Conference> conference) { |
| 235 | mCompositeDisposable.add(conference |
| 236 | .distinctUntilChanged() |
| 237 | .switchMap(Conference::getParticipantInfo) |
| 238 | .observeOn(mUiScheduler) |
| 239 | .subscribe(info -> getView().updateConfInfo(info), |
| 240 | e -> Log.e(TAG, "Error with initIncoming, action view flow: ", e))); |
Rayan Osseiran | 3dd0466 | 2019-06-28 16:47:48 -0400 | [diff] [blame] | 241 | } |
| 242 | |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 243 | public void prepareOptionMenu() { |
| 244 | boolean isSpeakerOn = mHardwareService.isSpeakerPhoneOn(); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 245 | //boolean hasContact = mSipCall != null && null != mSipCall.getContact() && mSipCall.getContact().isUnknown(); |
Amirhossein | 128eca4 | 2020-11-25 15:03:36 -0500 | [diff] [blame] | 246 | boolean canDial = mOnGoingCall && mConference != null; |
ayounes | c6c2c01 | 2019-11-11 11:09:51 -0500 | [diff] [blame] | 247 | // get the preferences |
| 248 | boolean displayPluginsButton = getView().displayPluginsButton(); |
| 249 | boolean showPluginBtn = displayPluginsButton && mOnGoingCall && mConference != null; |
Hadrien De Sousa | 203164c | 2017-12-05 17:41:42 -0500 | [diff] [blame] | 250 | boolean hasMultipleCamera = mHardwareService.getCameraCount() > 1 && mOnGoingCall && !mAudioOnly; |
ayounes | 47e9399 | 2019-10-28 12:09:53 -0400 | [diff] [blame] | 251 | getView().initMenu(isSpeakerOn, hasMultipleCamera, canDial, showPluginBtn, mOnGoingCall); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 252 | } |
| 253 | |
| 254 | public void chatClick() { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 255 | if (mConference == null || mConference.getParticipants().isEmpty()) { |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 256 | return; |
| 257 | } |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 258 | SipCall firstCall = mConference.getParticipants().get(0); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 259 | if (firstCall == null |
| 260 | || firstCall.getContact() == null |
| 261 | || firstCall.getContact().getIds() == null |
| 262 | || firstCall.getContact().getIds().isEmpty()) { |
| 263 | return; |
| 264 | } |
| 265 | getView().goToConversation(firstCall.getAccount(), firstCall.getContact().getIds().get(0)); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 266 | } |
| 267 | |
Adrien Béraud | bc0898e | 2018-08-23 14:31:11 -0400 | [diff] [blame] | 268 | public void speakerClick(boolean checked) { |
| 269 | mHardwareService.toggleSpeakerphone(checked); |
| 270 | } |
| 271 | |
| 272 | public void muteMicrophoneToggled(boolean checked) { |
| 273 | mCallService.setMuted(checked); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 274 | } |
| 275 | |
Rayan Osseiran | 38206c6 | 2019-05-15 14:49:03 -0400 | [diff] [blame] | 276 | |
Adrien Béraud | ec19fad | 2018-12-30 16:51:05 -0500 | [diff] [blame] | 277 | public boolean isMicrophoneMuted() { |
| 278 | return mCallService.isCaptureMuted(); |
| 279 | } |
| 280 | |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 281 | public void switchVideoInputClick() { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 282 | if(mConference == null) |
Rayan Osseiran | ca0436c | 2019-07-16 10:11:06 -0400 | [diff] [blame] | 283 | return; |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 284 | mHardwareService.switchInput(mConference.getId(), false); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 285 | getView().switchCameraIcon(mHardwareService.isPreviewFromFrontCamera()); |
| 286 | } |
| 287 | |
Adrien Béraud | eb4bb00 | 2019-03-14 15:52:48 -0400 | [diff] [blame] | 288 | public void configurationChanged(int rotation) { |
| 289 | mHardwareService.setDeviceOrientation(rotation); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 290 | } |
| 291 | |
| 292 | public void dialpadClick() { |
| 293 | getView().displayDialPadKeyboard(); |
| 294 | } |
| 295 | |
| 296 | public void acceptCall() { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 297 | if (mConference == null) { |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 298 | return; |
| 299 | } |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 300 | mCallService.accept(mConference.getId()); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 301 | } |
| 302 | |
| 303 | public void hangupCall() { |
AGS5 | ef482ce | 2020-06-12 13:28:51 -0400 | [diff] [blame] | 304 | List<String> callMediaHandlers = listCallMediaHandlers(); |
| 305 | |
| 306 | for (String callMediaHandler : callMediaHandlers) |
| 307 | { |
| 308 | toggleCallMediaHandler(callMediaHandler, false); |
| 309 | } |
| 310 | |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 311 | if (mConference != null) { |
| 312 | if (mConference.isConference()) |
| 313 | mCallService.hangUpConference(mConference.getId()); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 314 | else |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 315 | mCallService.hangUp(mConference.getId()); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 316 | } |
| 317 | for (SipCall call : mPendingCalls) { |
| 318 | mCallService.hangUp(call.getDaemonIdString()); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 319 | } |
| 320 | finish(); |
| 321 | } |
| 322 | |
| 323 | public void refuseCall() { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 324 | final Conference call = mConference; |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 325 | if (call != null) { |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 326 | mCallService.refuse(call.getId()); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 327 | } |
| 328 | finish(); |
| 329 | } |
| 330 | |
| 331 | public void videoSurfaceCreated(Object holder) { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 332 | if (mConference == null) { |
Alexandre Lision | e4d4026 | 2016-12-12 14:30:09 -0500 | [diff] [blame] | 333 | return; |
| 334 | } |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 335 | String newId = mConference.getId(); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 336 | if (!newId.equals(currentSurfaceId)) { |
| 337 | mHardwareService.removeVideoSurface(currentSurfaceId); |
| 338 | currentSurfaceId = newId; |
| 339 | } |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 340 | mHardwareService.addVideoSurface(mConference.getId(), holder); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 341 | getView().displayContactBubble(false); |
| 342 | } |
| 343 | |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 344 | public void videoSurfaceUpdateId(String newId) { |
| 345 | if (!Objects.equals(newId, currentSurfaceId)) { |
| 346 | mHardwareService.updateVideoSurfaceId(currentSurfaceId, newId); |
| 347 | currentSurfaceId = newId; |
| 348 | } |
| 349 | } |
| 350 | |
AGS5 | ef482ce | 2020-06-12 13:28:51 -0400 | [diff] [blame] | 351 | public void pluginSurfaceCreated(Object holder) { |
| 352 | if (mConference == null) { |
| 353 | return; |
| 354 | } |
| 355 | String newId = mConference.getPluginId(); |
| 356 | if (!newId.equals(currentPluginSurfaceId)) { |
| 357 | mHardwareService.removeVideoSurface(currentPluginSurfaceId); |
| 358 | currentPluginSurfaceId = newId; |
| 359 | } |
| 360 | mHardwareService.addVideoSurface(mConference.getPluginId(), holder); |
| 361 | getView().displayContactBubble(false); |
| 362 | } |
| 363 | |
| 364 | public void pluginSurfaceUpdateId(String newId) { |
| 365 | if (!Objects.equals(newId, currentPluginSurfaceId)) { |
| 366 | mHardwareService.updateVideoSurfaceId(currentPluginSurfaceId, newId); |
| 367 | currentPluginSurfaceId = newId; |
| 368 | } |
| 369 | } |
| 370 | |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 371 | public void previewVideoSurfaceCreated(Object holder) { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 372 | mHardwareService.addPreviewVideoSurface(holder, mConference); |
Adrien Béraud | 30532a5 | 2018-09-11 15:10:05 -0400 | [diff] [blame] | 373 | //mHardwareService.startCapture(null); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 374 | } |
| 375 | |
| 376 | public void videoSurfaceDestroyed() { |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 377 | if (currentSurfaceId != null) { |
| 378 | mHardwareService.removeVideoSurface(currentSurfaceId); |
| 379 | currentSurfaceId = null; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 380 | } |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 381 | } |
AGS5 | ef482ce | 2020-06-12 13:28:51 -0400 | [diff] [blame] | 382 | public void pluginSurfaceDestroyed() { |
| 383 | if (currentPluginSurfaceId != null) { |
| 384 | mHardwareService.removeVideoSurface(currentPluginSurfaceId); |
| 385 | currentPluginSurfaceId = null; |
| 386 | } |
| 387 | } |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 388 | public void previewVideoSurfaceDestroyed() { |
| 389 | mHardwareService.removePreviewVideoSurface(); |
Adrien Béraud | 30532a5 | 2018-09-11 15:10:05 -0400 | [diff] [blame] | 390 | mHardwareService.endCapture(); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 391 | } |
| 392 | |
| 393 | public void displayChanged() { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 394 | mHardwareService.switchInput(mConference.getId(), false); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 395 | } |
| 396 | |
| 397 | public void layoutChanged() { |
Adrien Béraud | de0d452 | 2018-12-12 12:11:02 -0500 | [diff] [blame] | 398 | //getView().resetVideoSize(videoWidth, videoHeight, previewWidth, previewHeight); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 399 | } |
| 400 | |
Rayan Osseiran | 38206c6 | 2019-05-15 14:49:03 -0400 | [diff] [blame] | 401 | |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 402 | public void uiVisibilityChanged(boolean displayed) { |
Adrien Béraud | 665faa2 | 2018-07-26 16:51:20 -0400 | [diff] [blame] | 403 | CallView view = getView(); |
| 404 | if (view != null) |
| 405 | view.displayHangupButton(mOnGoingCall && displayed); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 406 | } |
| 407 | |
| 408 | private void finish() { |
Adrien Béraud | 3aeed5d | 2018-07-26 11:26:13 -0400 | [diff] [blame] | 409 | if (timeUpdateTask != null && !timeUpdateTask.isDisposed()) { |
| 410 | timeUpdateTask.dispose(); |
| 411 | timeUpdateTask = null; |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 412 | } |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 413 | mConference = null; |
Adrien Béraud | 8d6baf3 | 2018-08-03 23:37:31 -0400 | [diff] [blame] | 414 | CallView view = getView(); |
| 415 | if (view != null) |
| 416 | view.finish(); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 417 | } |
| 418 | |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 419 | private Disposable contactDisposable = null; |
| 420 | |
| 421 | private void contactUpdate(final Conference conference) { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 422 | if (mConference != conference) { |
| 423 | mConference = conference; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 424 | if (contactDisposable != null && !contactDisposable.isDisposed()) { |
| 425 | contactDisposable.dispose(); |
| 426 | } |
| 427 | if (conference.getParticipants().isEmpty()) |
| 428 | return; |
| 429 | |
| 430 | // Updates of participant (and pending participant) list |
| 431 | Observable<List<SipCall>> callsObservable = mPendingSubject |
| 432 | .map(pendingList -> { |
| 433 | Log.w(TAG, "mPendingSubject onNext " + pendingList.size() + " " + conference.getParticipants().size()); |
| 434 | if (pendingList.isEmpty()) |
| 435 | return conference.getParticipants(); |
| 436 | List<SipCall> newList = new ArrayList<>(conference.getParticipants().size() + pendingList.size()); |
| 437 | newList.addAll(conference.getParticipants()); |
| 438 | newList.addAll(pendingList); |
| 439 | return newList; |
| 440 | }); |
| 441 | |
| 442 | // Updates of individual contacts |
| 443 | Observable<List<Observable<SipCall>>> contactsObservable = callsObservable |
| 444 | .flatMapSingle(calls -> Observable |
| 445 | .fromIterable(calls) |
Adrien Béraud | 2d8a8a8 | 2020-10-15 11:05:38 -0400 | [diff] [blame] | 446 | .map(call -> mContactService.observeContact(call.getAccount(), call.getContact(), false) |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 447 | .map(contact -> call)) |
| 448 | .toList(calls.size())); |
| 449 | |
| 450 | // Combined updates of contacts as participant list updates |
| 451 | Observable<List<SipCall>> contactUpdates = contactsObservable |
| 452 | .switchMap(list -> Observable |
| 453 | .combineLatest(list, objects -> { |
| 454 | Log.w(TAG, "flatMapObservable " + objects.length); |
| 455 | ArrayList<SipCall> calls = new ArrayList<>(objects.length); |
| 456 | for (Object call : objects) |
| 457 | calls.add((SipCall)call); |
| 458 | return (List<SipCall>)calls; |
| 459 | })) |
| 460 | .filter(list -> !list.isEmpty()); |
| 461 | |
| 462 | contactDisposable = contactUpdates |
Adrien Béraud | 2c378b3 | 2018-07-11 15:24:02 -0400 | [diff] [blame] | 463 | .observeOn(mUiScheduler) |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 464 | .subscribe(cs -> getView().updateContactBubble(cs), e -> Log.e(TAG, "Error updating contact data", e)); |
| 465 | mCompositeDisposable.add(contactDisposable); |
Adrien Béraud | 2c378b3 | 2018-07-11 15:24:02 -0400 | [diff] [blame] | 466 | } |
Adrien Béraud | 7c45b74 | 2019-11-15 14:30:11 -0500 | [diff] [blame] | 467 | mPendingSubject.onNext(mPendingCalls); |
Adrien Béraud | 2c378b3 | 2018-07-11 15:24:02 -0400 | [diff] [blame] | 468 | } |
| 469 | |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 470 | private void confUpdate(Conference call) { |
| 471 | Log.w(TAG, "confUpdate " + call.getId()); |
| 472 | |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 473 | mConference = call; |
Amirhossein | 063a5e2 | 2020-06-24 17:53:11 -0400 | [diff] [blame] | 474 | SipCall.CallStatus status = mConference.getState(); |
| 475 | if (status == SipCall.CallStatus.HOLD && mCallService.getConferenceList().size() == 1) { |
| 476 | mCallService.unhold(mConference.getId()); |
| 477 | } |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 478 | mAudioOnly = !call.hasVideo(); |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 479 | CallView view = getView(); |
Adrien Béraud | 99fd420 | 2018-12-13 13:02:21 -0500 | [diff] [blame] | 480 | if (view == null) |
| 481 | return; |
| 482 | view.updateMenu(); |
| 483 | if (call.isOnGoing()) { |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 484 | mOnGoingCall = true; |
Adrien Béraud | 34a6fa2 | 2019-07-28 16:02:59 -0400 | [diff] [blame] | 485 | view.initNormalStateDisplay(mAudioOnly, isMicrophoneMuted()); |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 486 | view.updateMenu(); |
Hadrien De Sousa | 203164c | 2017-12-05 17:41:42 -0500 | [diff] [blame] | 487 | if (!mAudioOnly) { |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 488 | mHardwareService.setPreviewSettings(); |
Adrien Béraud | 7403f35 | 2019-11-22 16:30:55 -0500 | [diff] [blame] | 489 | mHardwareService.updatePreviewVideoSurface(mConference); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 490 | videoSurfaceUpdateId(call.getId()); |
AGS5 | ef482ce | 2020-06-12 13:28:51 -0400 | [diff] [blame] | 491 | pluginSurfaceUpdateId(call.getPluginId()); |
Rayan Osseiran | c1532d4 | 2019-06-05 13:17:53 -0400 | [diff] [blame] | 492 | view.displayVideoSurface(true, mDeviceRuntimeService.hasVideoPermission()); |
Rayan Osseiran | 3dd0466 | 2019-06-28 16:47:48 -0400 | [diff] [blame] | 493 | if (permissionChanged) { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 494 | mHardwareService.switchInput(mConference.getId(), permissionChanged); |
Adrien Béraud | 335d32e | 2019-05-31 09:31:40 -0400 | [diff] [blame] | 495 | permissionChanged = false; |
Rayan Osseiran | 38206c6 | 2019-05-15 14:49:03 -0400 | [diff] [blame] | 496 | } |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 497 | } |
Adrien Béraud | 3aeed5d | 2018-07-26 11:26:13 -0400 | [diff] [blame] | 498 | if (timeUpdateTask != null) |
| 499 | timeUpdateTask.dispose(); |
Adrien Béraud | 99fd420 | 2018-12-13 13:02:21 -0500 | [diff] [blame] | 500 | timeUpdateTask = mUiScheduler.schedulePeriodicallyDirect(this::updateTime, 0, 1, TimeUnit.SECONDS); |
| 501 | } else if (call.isRinging()) { |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 502 | SipCall scall = call.getCall(); |
| 503 | |
Rayan Osseiran | de9ac14 | 2019-07-02 13:01:32 -0400 | [diff] [blame] | 504 | view.handleCallWakelock(mAudioOnly); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 505 | if (scall.isIncoming()) { |
| 506 | if (mAccountService.getAccount(scall.getAccount()).isAutoanswerEnabled()) { |
| 507 | mCallService.accept(scall.getDaemonIdString()); |
Rayan Osseiran | 3dd0466 | 2019-06-28 16:47:48 -0400 | [diff] [blame] | 508 | // only display the incoming call screen if the notification is a full screen intent |
| 509 | } else if (incomingIsFullIntent) { |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 510 | view.initIncomingCallDisplay(); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 511 | } |
| 512 | } else { |
| 513 | mOnGoingCall = false; |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 514 | view.updateCallStatus(scall.getCallStatus()); |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 515 | view.initOutGoingCallDisplay(); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 516 | } |
| 517 | } else { |
| 518 | finish(); |
| 519 | } |
| 520 | } |
| 521 | |
Adrien Béraud | 78c547f | 2020-09-08 16:01:17 -0400 | [diff] [blame] | 522 | public void maximizeParticipant(SipCall call) { |
| 523 | if (mConference.getMaximizedCall() == call) |
| 524 | call = null; |
| 525 | mConference.setMaximizedCall(call); |
| 526 | if (call != null) { |
| 527 | mCallService.setConfMaximizedParticipant(mConference.getConfId(), call.getDaemonIdString()); |
| 528 | } else { |
| 529 | mCallService.setConfGridLayout(mConference.getConfId()); |
| 530 | } |
| 531 | } |
| 532 | |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 533 | private void updateTime() { |
Adrien Béraud | 6325fad | 2018-08-15 15:34:11 -0400 | [diff] [blame] | 534 | CallView view = getView(); |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 535 | if (view != null && mConference != null) { |
| 536 | if (mConference.isOnGoing()) { |
| 537 | long start = mConference.getTimestampStart(); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 538 | if (start != Long.MAX_VALUE) { |
| 539 | view.updateTime((System.currentTimeMillis() - start) / 1000); |
| 540 | } else { |
| 541 | view.updateTime(-1); |
| 542 | } |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 543 | } |
| 544 | } |
| 545 | } |
| 546 | |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 547 | private void onVideoEvent(HardwareService.VideoEvent event) { |
Adrien Béraud | eb4bb00 | 2019-03-14 15:52:48 -0400 | [diff] [blame] | 548 | Log.d(TAG, "VIDEO_EVENT: " + event.start + " " + event.callId + " " + event.w + "x" + event.h); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 549 | |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 550 | if (event.start) { |
Rayan Osseiran | c1532d4 | 2019-06-05 13:17:53 -0400 | [diff] [blame] | 551 | getView().displayVideoSurface(true, !isPipMode() && mDeviceRuntimeService.hasVideoPermission()); |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 552 | } else if (mConference != null && mConference.getId().equals(event.callId)) { |
Rayan Osseiran | c1532d4 | 2019-06-05 13:17:53 -0400 | [diff] [blame] | 553 | getView().displayVideoSurface(event.started, event.started && !isPipMode() && mDeviceRuntimeService.hasVideoPermission()); |
Adrien Béraud | ace37a2 | 2018-06-22 14:58:36 -0400 | [diff] [blame] | 554 | if (event.started) { |
| 555 | videoWidth = event.w; |
| 556 | videoHeight = event.h; |
Adrien Béraud | eb4bb00 | 2019-03-14 15:52:48 -0400 | [diff] [blame] | 557 | getView().resetVideoSize(videoWidth, videoHeight); |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 558 | } |
Adrien Béraud | 30532a5 | 2018-09-11 15:10:05 -0400 | [diff] [blame] | 559 | } else if (event.callId == null) { |
| 560 | if (event.started) { |
| 561 | previewWidth = event.w; |
| 562 | previewHeight = event.h; |
Adrien Béraud | eb4bb00 | 2019-03-14 15:52:48 -0400 | [diff] [blame] | 563 | getView().resetPreviewVideoSize(previewWidth, previewHeight, event.rot); |
Adrien Béraud | 30532a5 | 2018-09-11 15:10:05 -0400 | [diff] [blame] | 564 | } |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 565 | } |
AGS5 | ef482ce | 2020-06-12 13:28:51 -0400 | [diff] [blame] | 566 | if (mConference != null && mConference.getPluginId().equals(event.callId)) { |
| 567 | if (event.started) { |
| 568 | previewWidth = event.w; |
| 569 | previewHeight = event.h; |
| 570 | getView().resetPluginPreviewVideoSize(previewWidth, previewHeight, event.rot); |
| 571 | } |
| 572 | } |
Adrien Béraud | eb4bb00 | 2019-03-14 15:52:48 -0400 | [diff] [blame] | 573 | /*if (event.started || event.start) { |
Adrien Béraud | de0d452 | 2018-12-12 12:11:02 -0500 | [diff] [blame] | 574 | getView().resetVideoSize(videoWidth, videoHeight, previewWidth, previewHeight); |
Adrien Béraud | eb4bb00 | 2019-03-14 15:52:48 -0400 | [diff] [blame] | 575 | }*/ |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 576 | } |
Pierre Duchemin | 8b2c1b5 | 2017-12-29 17:17:13 -0500 | [diff] [blame] | 577 | |
| 578 | public void positiveButtonClicked() { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 579 | if (mConference.isRinging() && mConference.isIncoming()) { |
Pierre Duchemin | 8b2c1b5 | 2017-12-29 17:17:13 -0500 | [diff] [blame] | 580 | acceptCall(); |
| 581 | } else { |
| 582 | hangupCall(); |
| 583 | } |
| 584 | } |
| 585 | |
| 586 | public void negativeButtonClicked() { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 587 | if (mConference.isRinging() && mConference.isIncoming()) { |
Pierre Duchemin | 8b2c1b5 | 2017-12-29 17:17:13 -0500 | [diff] [blame] | 588 | refuseCall(); |
| 589 | } else { |
| 590 | hangupCall(); |
| 591 | } |
| 592 | } |
| 593 | |
| 594 | public void toggleButtonClicked() { |
Amirhossein | 1cbc8df | 2020-08-14 11:48:30 -0400 | [diff] [blame] | 595 | if (mConference != null && !(mConference.isRinging() && mConference.isIncoming())) { |
Pierre Duchemin | 8b2c1b5 | 2017-12-29 17:17:13 -0500 | [diff] [blame] | 596 | hangupCall(); |
| 597 | } |
| 598 | } |
Adrien Béraud | 79808d0 | 2018-02-20 00:16:28 +0100 | [diff] [blame] | 599 | |
Rayan Osseiran | 38206c6 | 2019-05-15 14:49:03 -0400 | [diff] [blame] | 600 | public boolean isAudioOnly() { |
| 601 | return mAudioOnly; |
| 602 | } |
| 603 | |
Adrien Béraud | 79808d0 | 2018-02-20 00:16:28 +0100 | [diff] [blame] | 604 | public void requestPipMode() { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 605 | if (mConference != null && mConference.isOnGoing() && mConference.hasVideo()) { |
| 606 | getView().enterPipMode(mConference.getId()); |
Adrien Béraud | 79808d0 | 2018-02-20 00:16:28 +0100 | [diff] [blame] | 607 | } |
| 608 | } |
| 609 | |
Rayan Osseiran | c1532d4 | 2019-06-05 13:17:53 -0400 | [diff] [blame] | 610 | public boolean isPipMode() { |
| 611 | return pipIsActive; |
| 612 | } |
| 613 | |
Adrien Béraud | 79808d0 | 2018-02-20 00:16:28 +0100 | [diff] [blame] | 614 | public void pipModeChanged(boolean pip) { |
Rayan Osseiran | c1532d4 | 2019-06-05 13:17:53 -0400 | [diff] [blame] | 615 | pipIsActive = pip; |
Adrien Béraud | 79808d0 | 2018-02-20 00:16:28 +0100 | [diff] [blame] | 616 | if (pip) { |
| 617 | getView().displayHangupButton(false); |
| 618 | getView().displayPreviewSurface(false); |
Rayan Osseiran | c1532d4 | 2019-06-05 13:17:53 -0400 | [diff] [blame] | 619 | getView().displayVideoSurface(true, false); |
Adrien Béraud | 79808d0 | 2018-02-20 00:16:28 +0100 | [diff] [blame] | 620 | } else { |
| 621 | getView().displayPreviewSurface(true); |
Rayan Osseiran | c1532d4 | 2019-06-05 13:17:53 -0400 | [diff] [blame] | 622 | getView().displayVideoSurface(true, mDeviceRuntimeService.hasVideoPermission()); |
Adrien Béraud | 79808d0 | 2018-02-20 00:16:28 +0100 | [diff] [blame] | 623 | } |
| 624 | } |
Adrien Béraud | bc0898e | 2018-08-23 14:31:11 -0400 | [diff] [blame] | 625 | |
agsantos | 4f7b5a1 | 2020-07-08 16:18:07 -0400 | [diff] [blame] | 626 | public void toggleCallMediaHandler(String id, boolean toggle) |
| 627 | { |
| 628 | if (mConference != null && mConference.isOnGoing() && mConference.hasVideo()) { |
agsantos | 5f68e51 | 2020-10-26 11:48:52 -0400 | [diff] [blame] | 629 | getView().toggleCallMediaHandler(id, mConference.getId(), toggle); |
agsantos | 4f7b5a1 | 2020-07-08 16:18:07 -0400 | [diff] [blame] | 630 | } |
| 631 | } |
| 632 | |
Adrien Béraud | bc0898e | 2018-08-23 14:31:11 -0400 | [diff] [blame] | 633 | public boolean isSpeakerphoneOn() { |
| 634 | return mHardwareService.isSpeakerPhoneOn(); |
| 635 | } |
Adrien Béraud | bcbb4d4 | 2018-12-08 16:06:39 -0500 | [diff] [blame] | 636 | |
| 637 | public void sendDtmf(CharSequence s) { |
| 638 | mCallService.playDtmf(s.toString()); |
| 639 | } |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 640 | |
| 641 | public void addConferenceParticipant(String accountId, String contactId) { |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 642 | mCompositeDisposable.add(mConversationFacade.startConversation(accountId, new Uri(contactId)) |
| 643 | .map(Conversation::getCurrentCalls) |
Adrien Béraud | 94150a7 | 2019-11-18 16:41:28 -0500 | [diff] [blame] | 644 | .subscribe(confs -> { |
| 645 | if (confs.isEmpty()) { |
Adrien Béraud | 7c45b74 | 2019-11-15 14:30:11 -0500 | [diff] [blame] | 646 | final Observer<SipCall> pendingObserver = new Observer<SipCall>() { |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 647 | private SipCall call = null; |
| 648 | @Override |
| 649 | public void onSubscribe(Disposable d) {} |
| 650 | |
| 651 | @Override |
| 652 | public void onNext(SipCall sipCall) { |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 653 | if (call == null) { |
| 654 | call = sipCall; |
| 655 | mPendingCalls.add(sipCall); |
| 656 | } |
| 657 | mPendingSubject.onNext(mPendingCalls); |
| 658 | } |
| 659 | |
| 660 | @Override |
| 661 | public void onError(Throwable e) {} |
| 662 | |
| 663 | @Override |
| 664 | public void onComplete() { |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 665 | if (call != null) { |
| 666 | mPendingCalls.remove(call); |
| 667 | mPendingSubject.onNext(mPendingCalls); |
| 668 | call = null; |
| 669 | } |
| 670 | } |
| 671 | }; |
| 672 | |
| 673 | // Place new call, join to conference when answered |
| 674 | Maybe<SipCall> newCall = mCallService.placeCallObservable(accountId, contactId, mAudioOnly) |
| 675 | .doOnEach(pendingObserver) |
| 676 | .filter(SipCall::isOnGoing) |
| 677 | .firstElement() |
| 678 | .delay(1, TimeUnit.SECONDS) |
| 679 | .doOnEvent((v, e) -> pendingObserver.onComplete()); |
Adrien Béraud | 7c45b74 | 2019-11-15 14:30:11 -0500 | [diff] [blame] | 680 | mCompositeDisposable.add(newCall.subscribe(call -> { |
| 681 | String id = mConference.getId(); |
Adrien Béraud | 94150a7 | 2019-11-18 16:41:28 -0500 | [diff] [blame] | 682 | if (mConference.isConference()) { |
Adrien Béraud | 7c45b74 | 2019-11-15 14:30:11 -0500 | [diff] [blame] | 683 | mCallService.addParticipant(call.getDaemonIdString(), id); |
| 684 | } else { |
Adrien Béraud | 94150a7 | 2019-11-18 16:41:28 -0500 | [diff] [blame] | 685 | mCallService.joinParticipant(id, call.getDaemonIdString()).subscribe(); |
Adrien Béraud | 7c45b74 | 2019-11-15 14:30:11 -0500 | [diff] [blame] | 686 | } |
| 687 | })); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 688 | } else { |
| 689 | // Selected contact already in call or conference, join it to current conference |
Adrien Béraud | 94150a7 | 2019-11-18 16:41:28 -0500 | [diff] [blame] | 690 | Conference selectedConf = confs.get(0); |
| 691 | if (selectedConf != mConference) { |
| 692 | if (mConference.isConference()) { |
| 693 | if (selectedConf.isConference()) |
| 694 | mCallService.joinConference(mConference.getId(), selectedConf.getId()); |
| 695 | else |
| 696 | mCallService.addParticipant(selectedConf.getId(), mConference.getId()); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 697 | } else { |
Adrien Béraud | 94150a7 | 2019-11-18 16:41:28 -0500 | [diff] [blame] | 698 | if (selectedConf.isConference()) |
| 699 | mCallService.addParticipant(mConference.getId(), selectedConf.getId()); |
| 700 | else |
| 701 | mCallService.joinParticipant(mConference.getId(), selectedConf.getId()).subscribe(); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 702 | } |
| 703 | } |
| 704 | } |
| 705 | })); |
| 706 | } |
| 707 | |
| 708 | public void startAddParticipant() { |
Adrien Béraud | ac3de5a | 2019-11-06 11:36:01 -0500 | [diff] [blame] | 709 | getView().startAddParticipant(mConference.getId()); |
Adrien Béraud | e4f901a | 2019-10-25 17:26:30 -0400 | [diff] [blame] | 710 | } |
| 711 | |
| 712 | public void hangupParticipant(SipCall call) { |
| 713 | mCallService.hangUp(call.getDaemonIdString()); |
| 714 | } |
| 715 | |
| 716 | public void openParticipantContact(SipCall call) { |
| 717 | getView().goToContact(call.getAccount(), call.getContact()); |
| 718 | } |
Adrien Béraud | ade9bee | 2019-12-02 17:13:26 -0500 | [diff] [blame] | 719 | |
| 720 | public void stopCapture() { |
| 721 | mHardwareService.stopCapture(); |
| 722 | } |
| 723 | |
Adrien Béraud | 20bd723 | 2020-03-16 11:33:23 -0400 | [diff] [blame] | 724 | public boolean startScreenShare(Object mediaProjection) { |
| 725 | return mHardwareService.startScreenShare(mediaProjection); |
Adrien Béraud | ade9bee | 2019-12-02 17:13:26 -0500 | [diff] [blame] | 726 | } |
| 727 | |
| 728 | public void stopScreenShare() { |
| 729 | mHardwareService.stopScreenShare(); |
| 730 | } |
Adrien Béraud | 78c547f | 2020-09-08 16:01:17 -0400 | [diff] [blame] | 731 | |
| 732 | public boolean isMaximized(SipCall call) { |
| 733 | return mConference.getMaximizedCall() == call; |
| 734 | } |
agsantos | 4d495c9 | 2020-07-10 12:01:36 -0400 | [diff] [blame] | 735 | |
| 736 | public void startPlugin(String mediaHandlerId) { |
| 737 | mHardwareService.startMediaHandler(mediaHandlerId); |
| 738 | if(mConference == null) |
| 739 | return; |
| 740 | mHardwareService.switchInput(mConference.getId(), mHardwareService.isPreviewFromFrontCamera()); |
| 741 | } |
| 742 | |
| 743 | public void stopPlugin() { |
| 744 | mHardwareService.stopMediaHandler(); |
| 745 | if(mConference == null) |
| 746 | return; |
| 747 | mHardwareService.switchInput(mConference.getId(), mHardwareService.isPreviewFromFrontCamera()); |
| 748 | } |
Amirhossein | 7bb77aa | 2020-12-18 16:30:44 -0500 | [diff] [blame^] | 749 | |
| 750 | public boolean setBlockRecordStatus(){ |
| 751 | return mPreferencesService.getSettings().isRecordingBlocked(); |
| 752 | } |
| 753 | |
Hadrien De Sousa | ccc947d | 2017-04-12 14:26:52 -0400 | [diff] [blame] | 754 | } |