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