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