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 17package android.telecom; 18 19import android.annotation.SdkConstant; 20import android.annotation.SystemApi; 21import android.app.Service; 22import android.content.Intent; 23import android.hardware.camera2.CameraManager; 24import android.net.Uri; 25import android.os.Bundle; 26import android.os.Handler; 27import android.os.IBinder; 28import android.os.Looper; 29import android.os.Message; 30import android.view.Surface; 31 32import com.android.internal.os.SomeArgs; 33import com.android.internal.telecom.IInCallAdapter; 34import com.android.internal.telecom.IInCallService; 35 36import java.lang.String; 37import java.util.Collections; 38import 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 */ 62public 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 144 public void setInCallAdapter(IInCallAdapter inCallAdapter) { 145 mHandler.obtainMessage(MSG_SET_IN_CALL_ADAPTER, inCallAdapter).sendToTarget(); 146 } 147 148 @Override 149 public void addCall(ParcelableCall call) { 150 mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget(); 151 } 152 153 @Override 154 public void updateCall(ParcelableCall call) { 155 mHandler.obtainMessage(MSG_UPDATE_CALL, call).sendToTarget(); 156 } 157 158 @Override 159 public void setPostDial(String callId, String remaining) { 160 // TODO: Unused 161 } 162 163 @Override 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 172 public void onCallAudioStateChanged(CallAudioState callAudioState) { 173 mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, callAudioState).sendToTarget(); 174 } 175 176 @Override 177 public void bringToForeground(boolean showDialpad) { 178 mHandler.obtainMessage(MSG_BRING_TO_FOREGROUND, showDialpad ? 1 : 0, 0).sendToTarget(); 179 } 180 181 @Override 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 188 public void silenceRinger() { 189 mHandler.obtainMessage(MSG_SILENCE_RINGER).sendToTarget(); 190 } 191 192 @Override 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 247 public InCallService() { 248 } 249 250 @Override 251 public IBinder onBind(Intent intent) { 252 return new InCallServiceBinder(); 253 } 254 255 @Override 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 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 442 public void onCanAddCallChanged(boolean canAddCall) { 443 } 444 445 /** 446 * Called to silence the ringer if a ringing call exists. 447 */ 448 public void onSilenceRinger() { 449 } 450 451 /** 452 * Called when a {@link Call} has received a connection event issued by the 453 * {@link ConnectionService}. 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 * @hide 461 */ 462 public void onConnectionEvent(Call call, String event, Bundle extras) { 463 } 464 465 /** 466 * Used to issue commands to the {@link Connection.VideoProvider} associated with a 467 * {@link Call}. 468 */ 469 public static abstract class VideoCall { 470 471 /** @hide */ 472 public abstract void destroy(); 473 474 /** 475 * Registers a callback to receive commands and state changes for video calls. 476 * 477 * @param callback The video call callback. 478 */ 479 public abstract void registerCallback(VideoCall.Callback callback); 480 481 /** 482 * Registers a callback to receive commands and state changes for video calls. 483 * 484 * @param callback The video call callback. 485 * @param handler A handler which commands and status changes will be delivered to. 486 */ 487 public abstract void registerCallback(VideoCall.Callback callback, Handler handler); 488 489 /** 490 * Clears the video call callback set via {@link #registerCallback}. 491 * 492 * @param callback The video call callback to clear. 493 */ 494 public abstract void unregisterCallback(VideoCall.Callback callback); 495 496 /** 497 * Sets the camera to be used for the outgoing video. 498 * <p> 499 * Handled by {@link Connection.VideoProvider#onSetCamera(String)}. 500 * 501 * @param cameraId The id of the camera (use ids as reported by 502 * {@link CameraManager#getCameraIdList()}). 503 */ 504 public abstract void setCamera(String cameraId); 505 506 /** 507 * Sets the surface to be used for displaying a preview of what the user's camera is 508 * currently capturing. When video transmission is enabled, this is the video signal which 509 * is sent to the remote device. 510 * <p> 511 * Handled by {@link Connection.VideoProvider#onSetPreviewSurface(Surface)}. 512 * 513 * @param surface The {@link Surface}. 514 */ 515 public abstract void setPreviewSurface(Surface surface); 516 517 /** 518 * Sets the surface to be used for displaying the video received from the remote device. 519 * <p> 520 * Handled by {@link Connection.VideoProvider#onSetDisplaySurface(Surface)}. 521 * 522 * @param surface The {@link Surface}. 523 */ 524 public abstract void setDisplaySurface(Surface surface); 525 526 /** 527 * Sets the device orientation, in degrees. Assumes that a standard portrait orientation of 528 * the device is 0 degrees. 529 * <p> 530 * Handled by {@link Connection.VideoProvider#onSetDeviceOrientation(int)}. 531 * 532 * @param rotation The device orientation, in degrees. 533 */ 534 public abstract void setDeviceOrientation(int rotation); 535 536 /** 537 * Sets camera zoom ratio. 538 * <p> 539 * Handled by {@link Connection.VideoProvider#onSetZoom(float)}. 540 * 541 * @param value The camera zoom ratio. 542 */ 543 public abstract void setZoom(float value); 544 545 /** 546 * Issues a request to modify the properties of the current video session. 547 * <p> 548 * Example scenarios include: requesting an audio-only call to be upgraded to a 549 * bi-directional video call, turning on or off the user's camera, sending a pause signal 550 * when the {@link InCallService} is no longer the foreground application. 551 * <p> 552 * Handled by 553 * {@link Connection.VideoProvider#onSendSessionModifyRequest(VideoProfile, VideoProfile)}. 554 * 555 * @param requestProfile The requested call video properties. 556 */ 557 public abstract void sendSessionModifyRequest(VideoProfile requestProfile); 558 559 /** 560 * Provides a response to a request to change the current call video session 561 * properties. This should be called in response to a request the {@link InCallService} has 562 * received via {@link VideoCall.Callback#onSessionModifyRequestReceived}. 563 * <p> 564 * Handled by 565 * {@link Connection.VideoProvider#onSendSessionModifyResponse(VideoProfile)}. 566 * 567 * @param responseProfile The response call video properties. 568 */ 569 public abstract void sendSessionModifyResponse(VideoProfile responseProfile); 570 571 /** 572 * Issues a request to the {@link Connection.VideoProvider} to retrieve the capabilities 573 * of the current camera. The current camera is selected using 574 * {@link VideoCall#setCamera(String)}. 575 * <p> 576 * Camera capabilities are reported to the caller via 577 * {@link VideoCall.Callback#onCameraCapabilitiesChanged(VideoProfile.CameraCapabilities)}. 578 * <p> 579 * Handled by {@link Connection.VideoProvider#onRequestCameraCapabilities()}. 580 */ 581 public abstract void requestCameraCapabilities(); 582 583 /** 584 * Issues a request to the {@link Connection.VideoProvider} to retrieve the cumulative data 585 * usage for the video component of the current call (in bytes). Data usage is reported 586 * to the caller via {@link VideoCall.Callback#onCallDataUsageChanged}. 587 * <p> 588 * Handled by {@link Connection.VideoProvider#onRequestConnectionDataUsage()}. 589 */ 590 public abstract void requestCallDataUsage(); 591 592 /** 593 * Provides the {@link Connection.VideoProvider} with the {@link Uri} of an image to be 594 * displayed to the peer device when the video signal is paused. 595 * <p> 596 * Handled by {@link Connection.VideoProvider#onSetPauseImage(Uri)}. 597 * 598 * @param uri URI of image to display. 599 */ 600 public abstract void setPauseImage(Uri uri); 601 602 /** 603 * The {@link InCallService} extends this class to provide a means of receiving callbacks 604 * from the {@link Connection.VideoProvider}. 605 * <p> 606 * When the {@link InCallService} receives the 607 * {@link Call.Callback#onVideoCallChanged(Call, VideoCall)} callback, it should create an 608 * instance its {@link VideoCall.Callback} implementation and set it on the 609 * {@link VideoCall} using {@link VideoCall#registerCallback(Callback)}. 610 */ 611 public static abstract class Callback { 612 /** 613 * Called when the {@link Connection.VideoProvider} receives a session modification 614 * request from the peer device. 615 * <p> 616 * The {@link InCallService} may potentially prompt the user to confirm whether they 617 * wish to accept the request, or decide to automatically accept the request. In either 618 * case the {@link InCallService} should call 619 * {@link VideoCall#sendSessionModifyResponse(VideoProfile)} to indicate the video 620 * profile agreed upon. 621 * <p> 622 * Callback originates from 623 * {@link Connection.VideoProvider#receiveSessionModifyRequest(VideoProfile)}. 624 * 625 * @param videoProfile The requested video profile. 626 */ 627 public abstract void onSessionModifyRequestReceived(VideoProfile videoProfile); 628 629 /** 630 * Called when the {@link Connection.VideoProvider} receives a response to a session 631 * modification request previously sent to the peer device. 632 * <p> 633 * The new video state should not be considered active by the {@link InCallService} 634 * until the {@link Call} video state changes (the 635 * {@link Call.Callback#onDetailsChanged(Call, Call.Details)} callback is triggered 636 * when the video state changes). 637 * <p> 638 * Callback originates from 639 * {@link Connection.VideoProvider#receiveSessionModifyResponse(int, VideoProfile, 640 * VideoProfile)}. 641 * 642 * @param status Status of the session modify request. Valid values are 643 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS}, 644 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_FAIL}, 645 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_INVALID}, 646 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_TIMED_OUT}, 647 * {@link Connection.VideoProvider#SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE}. 648 * @param requestedProfile The original request which was sent to the peer device. 649 * @param responseProfile The actual profile changes made by the peer device. 650 */ 651 public abstract void onSessionModifyResponseReceived(int status, 652 VideoProfile requestedProfile, VideoProfile responseProfile); 653 654 /** 655 * Handles events related to the current video session which the {@link InCallService} 656 * may wish to handle. These are separate from requested changes to the session due to 657 * the underlying protocol or connection. 658 * <p> 659 * Callback originates from 660 * {@link Connection.VideoProvider#handleCallSessionEvent(int)}. 661 * 662 * @param event The event. Valid values are: 663 * {@link Connection.VideoProvider#SESSION_EVENT_RX_PAUSE}, 664 * {@link Connection.VideoProvider#SESSION_EVENT_RX_RESUME}, 665 * {@link Connection.VideoProvider#SESSION_EVENT_TX_START}, 666 * {@link Connection.VideoProvider#SESSION_EVENT_TX_STOP}, 667 * {@link Connection.VideoProvider#SESSION_EVENT_CAMERA_FAILURE}, 668 * {@link Connection.VideoProvider#SESSION_EVENT_CAMERA_READY}. 669 */ 670 public abstract void onCallSessionEvent(int event); 671 672 /** 673 * Handles a change to the video dimensions from the peer device. This could happen if, 674 * for example, the peer changes orientation of their device, or switches cameras. 675 * <p> 676 * Callback originates from 677 * {@link Connection.VideoProvider#changePeerDimensions(int, int)}. 678 * 679 * @param width The updated peer video width. 680 * @param height The updated peer video height. 681 */ 682 public abstract void onPeerDimensionsChanged(int width, int height); 683 684 /** 685 * Handles a change to the video quality. 686 * <p> 687 * Callback originates from {@link Connection.VideoProvider#changeVideoQuality(int)}. 688 * 689 * @param videoQuality The updated peer video quality. Valid values: 690 * {@link VideoProfile#QUALITY_HIGH}, 691 * {@link VideoProfile#QUALITY_MEDIUM}, 692 * {@link VideoProfile#QUALITY_LOW}, 693 * {@link VideoProfile#QUALITY_DEFAULT}. 694 */ 695 public abstract void onVideoQualityChanged(int videoQuality); 696 697 /** 698 * Handles an update to the total data used for the current video session. 699 * <p> 700 * Used by the {@link Connection.VideoProvider} in response to 701 * {@link VideoCall#requestCallDataUsage()}. May also be called periodically by the 702 * {@link Connection.VideoProvider}. 703 * <p> 704 * Callback originates from {@link Connection.VideoProvider#setCallDataUsage(long)}. 705 * 706 * @param dataUsage The updated data usage (in bytes). 707 */ 708 public abstract void onCallDataUsageChanged(long dataUsage); 709 710 /** 711 * Handles a change in the capabilities of the currently selected camera. 712 * <p> 713 * Used by the {@link Connection.VideoProvider} in response to 714 * {@link VideoCall#requestCameraCapabilities()}. The {@link Connection.VideoProvider} 715 * may also report the camera capabilities after a call to 716 * {@link VideoCall#setCamera(String)}. 717 * <p> 718 * Callback originates from 719 * {@link Connection.VideoProvider#changeCameraCapabilities( 720 * VideoProfile.CameraCapabilities)}. 721 * 722 * @param cameraCapabilities The changed camera capabilities. 723 */ 724 public abstract void onCameraCapabilitiesChanged( 725 VideoProfile.CameraCapabilities cameraCapabilities); 726 } 727 } 728} 729