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