1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.telecom; 18 19 import android.annotation.SdkConstant; 20 import android.annotation.SystemApi; 21 import android.app.Service; 22 import android.content.Intent; 23 import android.hardware.camera2.CameraManager; 24 import android.net.Uri; 25 import android.os.Bundle; 26 import android.os.Handler; 27 import android.os.IBinder; 28 import android.os.Looper; 29 import android.os.Message; 30 import android.view.Surface; 31 32 import com.android.internal.os.SomeArgs; 33 import com.android.internal.telecom.IInCallAdapter; 34 import com.android.internal.telecom.IInCallService; 35 36 import java.lang.String; 37 import java.util.Collections; 38 import java.util.List; 39 40 /** 41 * This service is implemented by any app that wishes to provide the user-interface for managing 42 * phone calls. Telecom binds to this service while there exists a live (active or incoming) call, 43 * and uses it to notify the in-call app of any live and recently disconnected calls. An app must 44 * first be set as the default phone app (See {@link TelecomManager#getDefaultDialerPackage()}) 45 * before the telecom service will bind to its {@code InCallService} implementation. 46 * <p> 47 * Below is an example manifest registration for an {@code InCallService}. The meta-data 48 * ({@link TelecomManager#METADATA_IN_CALL_SERVICE_UI}) indicates that this particular 49 * {@code InCallService} implementation intends to replace the built-in in-call UI. 50 * <pre> 51 * {@code 52 * <service android:name="your.package.YourInCallServiceImplementation" 53 * android:permission="android.permission.BIND_INCALL_SERVICE"> 54 * <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" /> 55 * <intent-filter> 56 * <action android:name="android.telecom.InCallService"/> 57 * </intent-filter> 58 * </service> 59 * } 60 * </pre> 61 */ 62 public abstract class InCallService extends Service { 63 64 /** 65 * The {@link Intent} that must be declared as handled by the service. 66 */ 67 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 68 public static final String SERVICE_INTERFACE = "android.telecom.InCallService"; 69 70 private static final int MSG_SET_IN_CALL_ADAPTER = 1; 71 private static final int MSG_ADD_CALL = 2; 72 private static final int MSG_UPDATE_CALL = 3; 73 private static final int MSG_SET_POST_DIAL_WAIT = 4; 74 private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 5; 75 private static final int MSG_BRING_TO_FOREGROUND = 6; 76 private static final int MSG_ON_CAN_ADD_CALL_CHANGED = 7; 77 private static final int MSG_SILENCE_RINGER = 8; 78 private static final int MSG_ON_CONNECTION_EVENT = 9; 79 private static final int MSG_ON_RTT_UPGRADE_REQUEST = 10; 80 private static final int MSG_ON_RTT_INITIATION_FAILURE = 11; 81 82 /** Default Handler used to consolidate binder method calls onto a single thread. */ 83 private final Handler mHandler = new Handler(Looper.getMainLooper()) { 84 @Override 85 public void handleMessage(Message msg) { 86 if (mPhone == null && msg.what != MSG_SET_IN_CALL_ADAPTER) { 87 return; 88 } 89 90 switch (msg.what) { 91 case MSG_SET_IN_CALL_ADAPTER: 92 String callingPackage = getApplicationContext().getOpPackageName(); 93 mPhone = new Phone(new InCallAdapter((IInCallAdapter) msg.obj), callingPackage, 94 getApplicationContext().getApplicationInfo().targetSdkVersion); 95 mPhone.addListener(mPhoneListener); 96 onPhoneCreated(mPhone); 97 break; 98 case MSG_ADD_CALL: 99 mPhone.internalAddCall((ParcelableCall) msg.obj); 100 break; 101 case MSG_UPDATE_CALL: 102 mPhone.internalUpdateCall((ParcelableCall) msg.obj); 103 break; 104 case MSG_SET_POST_DIAL_WAIT: { 105 SomeArgs args = (SomeArgs) msg.obj; 106 try { 107 String callId = (String) args.arg1; 108 String remaining = (String) args.arg2; 109 mPhone.internalSetPostDialWait(callId, remaining); 110 } finally { 111 args.recycle(); 112 } 113 break; 114 } 115 case MSG_ON_CALL_AUDIO_STATE_CHANGED: 116 mPhone.internalCallAudioStateChanged((CallAudioState) msg.obj); 117 break; 118 case MSG_BRING_TO_FOREGROUND: 119 mPhone.internalBringToForeground(msg.arg1 == 1); 120 break; 121 case MSG_ON_CAN_ADD_CALL_CHANGED: 122 mPhone.internalSetCanAddCall(msg.arg1 == 1); 123 break; 124 case MSG_SILENCE_RINGER: 125 mPhone.internalSilenceRinger(); 126 break; 127 case MSG_ON_CONNECTION_EVENT: { 128 SomeArgs args = (SomeArgs) msg.obj; 129 try { 130 String callId = (String) args.arg1; 131 String event = (String) args.arg2; 132 Bundle extras = (Bundle) args.arg3; 133 mPhone.internalOnConnectionEvent(callId, event, extras); 134 } finally { 135 args.recycle(); 136 } 137 break; 138 } 139 case MSG_ON_RTT_UPGRADE_REQUEST: { 140 String callId = (String) msg.obj; 141 int requestId = msg.arg1; 142 mPhone.internalOnRttUpgradeRequest(callId, requestId); 143 break; 144 } 145 case MSG_ON_RTT_INITIATION_FAILURE: { 146 String callId = (String) msg.obj; 147 int reason = msg.arg1; 148 mPhone.internalOnRttInitiationFailure(callId, reason); 149 break; 150 } 151 default: 152 break; 153 } 154 } 155 }; 156 157 /** Manages the binder calls so that the implementor does not need to deal with it. */ 158 private final class InCallServiceBinder extends IInCallService.Stub { 159 @Override setInCallAdapter(IInCallAdapter inCallAdapter)160 public void setInCallAdapter(IInCallAdapter inCallAdapter) { 161 mHandler.obtainMessage(MSG_SET_IN_CALL_ADAPTER, inCallAdapter).sendToTarget(); 162 } 163 164 @Override addCall(ParcelableCall call)165 public void addCall(ParcelableCall call) { 166 mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget(); 167 } 168 169 @Override updateCall(ParcelableCall call)170 public void updateCall(ParcelableCall call) { 171 mHandler.obtainMessage(MSG_UPDATE_CALL, call).sendToTarget(); 172 } 173 174 @Override setPostDial(String callId, String remaining)175 public void setPostDial(String callId, String remaining) { 176 // TODO: Unused 177 } 178 179 @Override setPostDialWait(String callId, String remaining)180 public void setPostDialWait(String callId, String remaining) { 181 SomeArgs args = SomeArgs.obtain(); 182 args.arg1 = callId; 183 args.arg2 = remaining; 184 mHandler.obtainMessage(MSG_SET_POST_DIAL_WAIT, args).sendToTarget(); 185 } 186 187 @Override onCallAudioStateChanged(CallAudioState callAudioState)188 public void onCallAudioStateChanged(CallAudioState callAudioState) { 189 mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, callAudioState).sendToTarget(); 190 } 191 192 @Override bringToForeground(boolean showDialpad)193 public void bringToForeground(boolean showDialpad) { 194 mHandler.obtainMessage(MSG_BRING_TO_FOREGROUND, showDialpad ? 1 : 0, 0).sendToTarget(); 195 } 196 197 @Override onCanAddCallChanged(boolean canAddCall)198 public void onCanAddCallChanged(boolean canAddCall) { 199 mHandler.obtainMessage(MSG_ON_CAN_ADD_CALL_CHANGED, canAddCall ? 1 : 0, 0) 200 .sendToTarget(); 201 } 202 203 @Override silenceRinger()204 public void silenceRinger() { 205 mHandler.obtainMessage(MSG_SILENCE_RINGER).sendToTarget(); 206 } 207 208 @Override onConnectionEvent(String callId, String event, Bundle extras)209 public void onConnectionEvent(String callId, String event, Bundle extras) { 210 SomeArgs args = SomeArgs.obtain(); 211 args.arg1 = callId; 212 args.arg2 = event; 213 args.arg3 = extras; 214 mHandler.obtainMessage(MSG_ON_CONNECTION_EVENT, args).sendToTarget(); 215 } 216 217 @Override onRttUpgradeRequest(String callId, int id)218 public void onRttUpgradeRequest(String callId, int id) { 219 mHandler.obtainMessage(MSG_ON_RTT_UPGRADE_REQUEST, id, 0, callId).sendToTarget(); 220 } 221 222 @Override onRttInitiationFailure(String callId, int reason)223 public void onRttInitiationFailure(String callId, int reason) { 224 mHandler.obtainMessage(MSG_ON_RTT_INITIATION_FAILURE, reason, 0, callId).sendToTarget(); 225 } 226 } 227 228 private Phone.Listener mPhoneListener = new Phone.Listener() { 229 /** ${inheritDoc} */ 230 @Override 231 public void onAudioStateChanged(Phone phone, AudioState audioState) { 232 InCallService.this.onAudioStateChanged(audioState); 233 } 234 235 public void onCallAudioStateChanged(Phone phone, CallAudioState callAudioState) { 236 InCallService.this.onCallAudioStateChanged(callAudioState); 237 }; 238 239 /** ${inheritDoc} */ 240 @Override 241 public void onBringToForeground(Phone phone, boolean showDialpad) { 242 InCallService.this.onBringToForeground(showDialpad); 243 } 244 245 /** ${inheritDoc} */ 246 @Override 247 public void onCallAdded(Phone phone, Call call) { 248 InCallService.this.onCallAdded(call); 249 } 250 251 /** ${inheritDoc} */ 252 @Override 253 public void onCallRemoved(Phone phone, Call call) { 254 InCallService.this.onCallRemoved(call); 255 } 256 257 /** ${inheritDoc} */ 258 @Override 259 public void onCanAddCallChanged(Phone phone, boolean canAddCall) { 260 InCallService.this.onCanAddCallChanged(canAddCall); 261 } 262 263 /** ${inheritDoc} */ 264 @Override 265 public void onSilenceRinger(Phone phone) { 266 InCallService.this.onSilenceRinger(); 267 } 268 269 }; 270 271 private Phone mPhone; 272 InCallService()273 public InCallService() { 274 } 275 276 @Override onBind(Intent intent)277 public IBinder onBind(Intent intent) { 278 return new InCallServiceBinder(); 279 } 280 281 @Override onUnbind(Intent intent)282 public boolean onUnbind(Intent intent) { 283 if (mPhone != null) { 284 Phone oldPhone = mPhone; 285 mPhone = null; 286 287 oldPhone.destroy(); 288 // destroy sets all the calls to disconnected if any live ones still exist. Therefore, 289 // it is important to remove the Listener *after* the call to destroy so that 290 // InCallService.on* callbacks are appropriately called. 291 oldPhone.removeListener(mPhoneListener); 292 293 onPhoneDestroyed(oldPhone); 294 } 295 296 return false; 297 } 298 299 /** 300 * Obtain the {@code Phone} associated with this {@code InCallService}. 301 * 302 * @return The {@code Phone} object associated with this {@code InCallService}, or {@code null} 303 * if the {@code InCallService} is not in a state where it has an associated 304 * {@code Phone}. 305 * @hide 306 * @deprecated Use direct methods on InCallService instead of {@link Phone}. 307 */ 308 @SystemApi 309 @Deprecated getPhone()310 public Phone getPhone() { 311 return mPhone; 312 } 313 314 /** 315 * Obtains the current list of {@code Call}s to be displayed by this in-call service. 316 * 317 * @return A list of the relevant {@code Call}s. 318 */ getCalls()319 public final List<Call> getCalls() { 320 return mPhone == null ? Collections.<Call>emptyList() : mPhone.getCalls(); 321 } 322 323 /** 324 * Returns if the device can support additional calls. 325 * 326 * @return Whether the phone supports adding more calls. 327 */ canAddCall()328 public final boolean canAddCall() { 329 return mPhone == null ? false : mPhone.canAddCall(); 330 } 331 332 /** 333 * Obtains the current phone call audio state. 334 * 335 * @return An object encapsulating the audio state. Returns null if the service is not 336 * fully initialized. 337 * @deprecated Use {@link #getCallAudioState()} instead. 338 * @hide 339 */ 340 @Deprecated getAudioState()341 public final AudioState getAudioState() { 342 return mPhone == null ? null : mPhone.getAudioState(); 343 } 344 345 /** 346 * Obtains the current phone call audio state. 347 * 348 * @return An object encapsulating the audio state. Returns null if the service is not 349 * fully initialized. 350 */ getCallAudioState()351 public final CallAudioState getCallAudioState() { 352 return mPhone == null ? null : mPhone.getCallAudioState(); 353 } 354 355 /** 356 * Sets the microphone mute state. When this request is honored, there will be change to 357 * the {@link #getCallAudioState()}. 358 * 359 * @param state {@code true} if the microphone should be muted; {@code false} otherwise. 360 */ setMuted(boolean state)361 public final void setMuted(boolean state) { 362 if (mPhone != null) { 363 mPhone.setMuted(state); 364 } 365 } 366 367 /** 368 * Sets the audio route (speaker, bluetooth, etc...). When this request is honored, there will 369 * be change to the {@link #getCallAudioState()}. 370 * 371 * @param route The audio route to use. 372 */ setAudioRoute(int route)373 public final void setAudioRoute(int route) { 374 if (mPhone != null) { 375 mPhone.setAudioRoute(route); 376 } 377 } 378 379 /** 380 * Invoked when the {@code Phone} has been created. This is a signal to the in-call experience 381 * to start displaying in-call information to the user. Each instance of {@code InCallService} 382 * will have only one {@code Phone}, and this method will be called exactly once in the lifetime 383 * of the {@code InCallService}. 384 * 385 * @param phone The {@code Phone} object associated with this {@code InCallService}. 386 * @hide 387 * @deprecated Use direct methods on InCallService instead of {@link Phone}. 388 */ 389 @SystemApi 390 @Deprecated onPhoneCreated(Phone phone)391 public void onPhoneCreated(Phone phone) { 392 } 393 394 /** 395 * Invoked when a {@code Phone} has been destroyed. This is a signal to the in-call experience 396 * to stop displaying in-call information to the user. This method will be called exactly once 397 * in the lifetime of the {@code InCallService}, and it will always be called after a previous 398 * call to {@link #onPhoneCreated(Phone)}. 399 * 400 * @param phone The {@code Phone} object associated with this {@code InCallService}. 401 * @hide 402 * @deprecated Use direct methods on InCallService instead of {@link Phone}. 403 */ 404 @SystemApi 405 @Deprecated onPhoneDestroyed(Phone phone)406 public void onPhoneDestroyed(Phone phone) { 407 } 408 409 /** 410 * Called when the audio state changes. 411 * 412 * @param audioState The new {@link AudioState}. 413 * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState) instead}. 414 * @hide 415 */ 416 @Deprecated onAudioStateChanged(AudioState audioState)417 public void onAudioStateChanged(AudioState audioState) { 418 } 419 420 /** 421 * Called when the audio state changes. 422 * 423 * @param audioState The new {@link CallAudioState}. 424 */ onCallAudioStateChanged(CallAudioState audioState)425 public void onCallAudioStateChanged(CallAudioState audioState) { 426 } 427 428 /** 429 * Called to bring the in-call screen to the foreground. The in-call experience should 430 * respond immediately by coming to the foreground to inform the user of the state of 431 * ongoing {@code Call}s. 432 * 433 * @param showDialpad If true, put up the dialpad when the screen is shown. 434 */ onBringToForeground(boolean showDialpad)435 public void onBringToForeground(boolean showDialpad) { 436 } 437 438 /** 439 * Called when a {@code Call} has been added to this in-call session. The in-call user 440 * experience should add necessary state listeners to the specified {@code Call} and 441 * immediately start to show the user information about the existence 442 * and nature of this {@code Call}. Subsequent invocations of {@link #getCalls()} will 443 * include this {@code Call}. 444 * 445 * @param call A newly added {@code Call}. 446 */ onCallAdded(Call call)447 public void onCallAdded(Call call) { 448 } 449 450 /** 451 * Called when a {@code Call} has been removed from this in-call session. The in-call user 452 * experience should remove any state listeners from the specified {@code Call} and 453 * immediately stop displaying any information about this {@code Call}. 454 * Subsequent invocations of {@link #getCalls()} will no longer include this {@code Call}. 455 * 456 * @param call A newly removed {@code Call}. 457 */ onCallRemoved(Call call)458 public void onCallRemoved(Call call) { 459 } 460 461 /** 462 * Called when the ability to add more calls changes. If the phone cannot 463 * support more calls then {@code canAddCall} is set to {@code false}. If it can, then it 464 * is set to {@code true}. This can be used to control the visibility of UI to add more calls. 465 * 466 * @param canAddCall Indicates whether an additional call can be added. 467 */ onCanAddCallChanged(boolean canAddCall)468 public void onCanAddCallChanged(boolean canAddCall) { 469 } 470 471 /** 472 * Called to silence the ringer if a ringing call exists. 473 */ onSilenceRinger()474 public void onSilenceRinger() { 475 } 476 477 /** 478 * Unused; to handle connection events issued by a {@link ConnectionService}, implement the 479 * {@link android.telecom.Call.Callback#onConnectionEvent(Call, String, Bundle)} callback. 480 * <p> 481 * See {@link Connection#sendConnectionEvent(String, Bundle)}. 482 * 483 * @param call The call the event is associated with. 484 * @param event The event. 485 * @param extras Any associated extras. 486 */ onConnectionEvent(Call call, String event, Bundle extras)487 public void onConnectionEvent(Call call, String event, Bundle extras) { 488 } 489 490 /** 491 * Used to issue commands to the {@link Connection.VideoProvider} associated with a 492 * {@link Call}. 493 */ 494 public static abstract class VideoCall { 495 496 /** @hide */ destroy()497 public abstract void destroy(); 498 499 /** 500 * Registers a callback to receive commands and state changes for video calls. 501 * 502 * @param callback The video call callback. 503 */ registerCallback(VideoCall.Callback callback)504 public abstract void registerCallback(VideoCall.Callback callback); 505 506 /** 507 * Registers a callback to receive commands and state changes for video calls. 508 * 509 * @param callback The video call callback. 510 * @param handler A handler which commands and status changes will be delivered to. 511 */ registerCallback(VideoCall.Callback callback, Handler handler)512 public abstract void registerCallback(VideoCall.Callback callback, Handler handler); 513 514 /** 515 * Clears the video call callback set via {@link #registerCallback}. 516 * 517 * @param callback The video call callback to clear. 518 */ unregisterCallback(VideoCall.Callback callback)519 public abstract void unregisterCallback(VideoCall.Callback callback); 520 521 /** 522 * Sets the camera to be used for the outgoing video. 523 * <p> 524 * Handled by {@link Connection.VideoProvider#onSetCamera(String)}. 525 * 526 * @param cameraId The id of the camera (use ids as reported by 527 * {@link CameraManager#getCameraIdList()}). 528 */ setCamera(String cameraId)529 public abstract void setCamera(String cameraId); 530 531 /** 532 * Sets the surface to be used for displaying a preview of what the user's camera is 533 * currently capturing. When video transmission is enabled, this is the video signal which 534 * is sent to the remote device. 535 * <p> 536 * Handled by {@link Connection.VideoProvider#onSetPreviewSurface(Surface)}. 537 * 538 * @param surface The {@link Surface}. 539 */ setPreviewSurface(Surface surface)540 public abstract void setPreviewSurface(Surface surface); 541 542 /** 543 * Sets the surface to be used for displaying the video received from the remote device. 544 * <p> 545 * Handled by {@link Connection.VideoProvider#onSetDisplaySurface(Surface)}. 546 * 547 * @param surface The {@link Surface}. 548 */ setDisplaySurface(Surface surface)549 public abstract void setDisplaySurface(Surface surface); 550 551 /** 552 * Sets the device orientation, in degrees. Assumes that a standard portrait orientation of 553 * the device is 0 degrees. 554 * <p> 555 * Handled by {@link Connection.VideoProvider#onSetDeviceOrientation(int)}. 556 * 557 * @param rotation The device orientation, in degrees. 558 */ setDeviceOrientation(int rotation)559 public abstract void setDeviceOrientation(int rotation); 560 561 /** 562 * Sets camera zoom ratio. 563 * <p> 564 * Handled by {@link Connection.VideoProvider#onSetZoom(float)}. 565 * 566 * @param value The camera zoom ratio. 567 */ setZoom(float value)568 public abstract void setZoom(float value); 569 570 /** 571 * Issues a request to modify the properties of the current video session. 572 * <p> 573 * Example scenarios include: requesting an audio-only call to be upgraded to a 574 * bi-directional video call, turning on or off the user's camera, sending a pause signal 575 * when the {@link InCallService} is no longer the foreground application. 576 * <p> 577 * Handled by 578 * {@link Connection.VideoProvider#onSendSessionModifyRequest(VideoProfile, VideoProfile)}. 579 * 580 * @param requestProfile The requested call video properties. 581 */ sendSessionModifyRequest(VideoProfile requestProfile)582 public abstract void sendSessionModifyRequest(VideoProfile requestProfile); 583 584 /** 585 * Provides a response to a request to change the current call video session 586 * properties. This should be called in response to a request the {@link InCallService} has 587 * received via {@link VideoCall.Callback#onSessionModifyRequestReceived}. 588 * <p> 589 * Handled by 590 * {@link Connection.VideoProvider#onSendSessionModifyResponse(VideoProfile)}. 591 * 592 * @param responseProfile The response call video properties. 593 */ sendSessionModifyResponse(VideoProfile responseProfile)594 public abstract void sendSessionModifyResponse(VideoProfile responseProfile); 595 596 /** 597 * Issues a request to the {@link Connection.VideoProvider} to retrieve the capabilities 598 * of the current camera. The current camera is selected using 599 * {@link VideoCall#setCamera(String)}. 600 * <p> 601 * Camera capabilities are reported to the caller via 602 * {@link VideoCall.Callback#onCameraCapabilitiesChanged(VideoProfile.CameraCapabilities)}. 603 * <p> 604 * Handled by {@link Connection.VideoProvider#onRequestCameraCapabilities()}. 605 */ requestCameraCapabilities()606 public abstract void requestCameraCapabilities(); 607 608 /** 609 * Issues a request to the {@link Connection.VideoProvider} to retrieve the cumulative data 610 * usage for the video component of the current call (in bytes). Data usage is reported 611 * to the caller via {@link VideoCall.Callback#onCallDataUsageChanged}. 612 * <p> 613 * Handled by {@link Connection.VideoProvider#onRequestConnectionDataUsage()}. 614 */ requestCallDataUsage()615 public abstract void requestCallDataUsage(); 616 617 /** 618 * Provides the {@link Connection.VideoProvider} with the {@link Uri} of an image to be 619 * displayed to the peer device when the video signal is paused. 620 * <p> 621 * Handled by {@link Connection.VideoProvider#onSetPauseImage(Uri)}. 622 * 623 * @param uri URI of image to display. 624 */ setPauseImage(Uri uri)625 public abstract void setPauseImage(Uri uri); 626 627 /** 628 * The {@link InCallService} extends this class to provide a means of receiving callbacks 629 * from the {@link Connection.VideoProvider}. 630 * <p> 631 * When the {@link InCallService} receives the 632 * {@link Call.Callback#onVideoCallChanged(Call, VideoCall)} callback, it should create an 633 * instance its {@link VideoCall.Callback} implementation and set it on the 634 * {@link VideoCall} using {@link VideoCall#registerCallback(Callback)}. 635 */ 636 public static abstract class Callback { 637 /** 638 * Called when the {@link Connection.VideoProvider} receives a session modification 639 * request from the peer device. 640 * <p> 641 * The {@link InCallService} may potentially prompt the user to confirm whether they 642 * wish to accept the request, or decide to automatically accept the request. In either 643 * case the {@link InCallService} should call 644 * {@link VideoCall#sendSessionModifyResponse(VideoProfile)} to indicate the video 645 * profile agreed upon. 646 * <p> 647 * Callback originates from 648 * {@link Connection.VideoProvider#receiveSessionModifyRequest(VideoProfile)}. 649 * 650 * @param videoProfile The requested video profile. 651 */ onSessionModifyRequestReceived(VideoProfile videoProfile)652 public abstract void onSessionModifyRequestReceived(VideoProfile videoProfile); 653 654 /** 655 * Called when the {@link Connection.VideoProvider} receives a response to a session 656 * modification request previously sent to the peer device. 657 * <p> 658 * The new video state should not be considered active by the {@link InCallService} 659 * until the {@link Call} video state changes (the 660 * {@link Call.Callback#onDetailsChanged(Call, Call.Details)} callback is triggered 661 * when the video state changes). 662 * <p> 663 * Callback originates from 664 * {@link Connection.VideoProvider#receiveSessionModifyResponse(int, VideoProfile, 665 * VideoProfile)}. 666 * 667 * @param status Status of the session modify request. Valid values are 668 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS}, 669 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_FAIL}, 670 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_INVALID}, 671 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_TIMED_OUT}, 672 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE}. 673 * @param requestedProfile The original request which was sent to the peer device. 674 * @param responseProfile The actual profile changes made by the peer device. 675 */ onSessionModifyResponseReceived(int status, VideoProfile requestedProfile, VideoProfile responseProfile)676 public abstract void onSessionModifyResponseReceived(int status, 677 VideoProfile requestedProfile, VideoProfile responseProfile); 678 679 /** 680 * Handles events related to the current video session which the {@link InCallService} 681 * may wish to handle. These are separate from requested changes to the session due to 682 * the underlying protocol or connection. 683 * <p> 684 * Callback originates from 685 * {@link Connection.VideoProvider#handleCallSessionEvent(int)}. 686 * 687 * @param event The event. Valid values are: 688 * {@link Connection.VideoProvider#SESSION_EVENT_RX_PAUSE}, 689 * {@link Connection.VideoProvider#SESSION_EVENT_RX_RESUME}, 690 * {@link Connection.VideoProvider#SESSION_EVENT_TX_START}, 691 * {@link Connection.VideoProvider#SESSION_EVENT_TX_STOP}, 692 * {@link Connection.VideoProvider#SESSION_EVENT_CAMERA_FAILURE}, 693 * {@link Connection.VideoProvider#SESSION_EVENT_CAMERA_READY}, 694 * {@link Connection.VideoProvider#SESSION_EVENT_CAMERA_PERMISSION_ERROR}. 695 */ onCallSessionEvent(int event)696 public abstract void onCallSessionEvent(int event); 697 698 /** 699 * Handles a change to the video dimensions from the peer device. This could happen if, 700 * for example, the peer changes orientation of their device, or switches cameras. 701 * <p> 702 * Callback originates from 703 * {@link Connection.VideoProvider#changePeerDimensions(int, int)}. 704 * 705 * @param width The updated peer video width. 706 * @param height The updated peer video height. 707 */ onPeerDimensionsChanged(int width, int height)708 public abstract void onPeerDimensionsChanged(int width, int height); 709 710 /** 711 * Handles a change to the video quality. 712 * <p> 713 * Callback originates from {@link Connection.VideoProvider#changeVideoQuality(int)}. 714 * 715 * @param videoQuality The updated peer video quality. Valid values: 716 * {@link VideoProfile#QUALITY_HIGH}, 717 * {@link VideoProfile#QUALITY_MEDIUM}, 718 * {@link VideoProfile#QUALITY_LOW}, 719 * {@link VideoProfile#QUALITY_DEFAULT}. 720 */ onVideoQualityChanged(int videoQuality)721 public abstract void onVideoQualityChanged(int videoQuality); 722 723 /** 724 * Handles an update to the total data used for the current video session. 725 * <p> 726 * Used by the {@link Connection.VideoProvider} in response to 727 * {@link VideoCall#requestCallDataUsage()}. May also be called periodically by the 728 * {@link Connection.VideoProvider}. 729 * <p> 730 * Callback originates from {@link Connection.VideoProvider#setCallDataUsage(long)}. 731 * 732 * @param dataUsage The updated data usage (in bytes). 733 */ onCallDataUsageChanged(long dataUsage)734 public abstract void onCallDataUsageChanged(long dataUsage); 735 736 /** 737 * Handles a change in the capabilities of the currently selected camera. 738 * <p> 739 * Used by the {@link Connection.VideoProvider} in response to 740 * {@link VideoCall#requestCameraCapabilities()}. The {@link Connection.VideoProvider} 741 * may also report the camera capabilities after a call to 742 * {@link VideoCall#setCamera(String)}. 743 * <p> 744 * Callback originates from 745 * {@link Connection.VideoProvider#changeCameraCapabilities( 746 * VideoProfile.CameraCapabilities)}. 747 * 748 * @param cameraCapabilities The changed camera capabilities. 749 */ onCameraCapabilitiesChanged( VideoProfile.CameraCapabilities cameraCapabilities)750 public abstract void onCameraCapabilitiesChanged( 751 VideoProfile.CameraCapabilities cameraCapabilities); 752 } 753 } 754 } 755