1 /* 2 * Copyright (C) 2017 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 com.googlecode.android_scripting.facade.telephony; 18 19 import java.util.ArrayList; 20 import java.util.HashMap; 21 import java.util.List; 22 import java.util.Set; 23 24 import android.telecom.Call; 25 import android.telecom.Call.Details; 26 import android.telecom.CallAudioState; 27 import android.telecom.Connection; 28 import android.telecom.InCallService; 29 import android.telecom.Phone; 30 import android.telecom.TelecomManager; 31 import android.telecom.VideoProfile; 32 import android.telecom.VideoProfile.CameraCapabilities; 33 34 import com.googlecode.android_scripting.Log; 35 36 import com.googlecode.android_scripting.facade.EventFacade; 37 38 public class InCallServiceImpl extends InCallService { 39 40 private static InCallServiceImpl sService = null; 41 getService()42 public static InCallServiceImpl getService() { 43 return sService; 44 } 45 46 public static class CallListener { 47 48 public static final int LISTEN_CALL_ADDED = 1 << 0; 49 public static final int LISTEN_CALL_REMOVED = 1 << 1; 50 public static final int LISTEN_ALL = LISTEN_CALL_ADDED | LISTEN_CALL_REMOVED; 51 52 private static int sListenedEvents = 0; 53 startListeningForEvent( int event )54 public static void startListeningForEvent( int event ) { 55 sListenedEvents |= event & LISTEN_ALL; 56 } 57 stopListeningForEvent( int event )58 public static void stopListeningForEvent( int event ) { 59 sListenedEvents &= ~(event & LISTEN_ALL); 60 } 61 onCallAdded(String callId, Call call)62 public static void onCallAdded(String callId, Call call) { 63 Log.d("CallListener:onCallAdded()"); 64 if ((sListenedEvents & LISTEN_CALL_ADDED) 65 == LISTEN_CALL_ADDED) { 66 servicePostEvent(TelephonyConstants.EventTelecomCallAdded, 67 new CallEvent<Call>(callId, call)); 68 } 69 } 70 onCallRemoved(String callId, Call call)71 public static void onCallRemoved(String callId, Call call) { 72 Log.d("CallListener:onCallRemoved()"); 73 if ((sListenedEvents & LISTEN_CALL_REMOVED) 74 == LISTEN_CALL_REMOVED) { 75 servicePostEvent(TelephonyConstants.EventTelecomCallRemoved, 76 new CallEvent<Call>(callId, call)); 77 } 78 } 79 }; 80 81 82 private static Object mLock = new Object(); 83 84 // Provides a return value for getCallState when no call is active 85 public static final int STATE_INVALID = -1; 86 87 // Provides a return value for getCallQuality when input is invalid 88 public static final int QUALITY_INVALID = -1; 89 90 // Provides a return value for getAudioRoute when input is invalid 91 public static final int INVALID_AUDIO_ROUTE = -1; 92 93 public static final int VIDEO_STATE_AUDIO_ONLY = VideoProfile.STATE_AUDIO_ONLY; 94 95 public static final int VIDEO_STATE_TX_ENABLED = VideoProfile.STATE_TX_ENABLED; 96 97 public static final int VIDEO_STATE_RX_ENABLED = VideoProfile.STATE_RX_ENABLED; 98 99 public static final int VIDEO_STATE_BIDIRECTIONAL = VideoProfile.STATE_BIDIRECTIONAL; 100 101 public static final int VIDEO_STATE_TX_PAUSED = 102 VideoProfile.STATE_TX_ENABLED | VideoProfile.STATE_PAUSED; 103 104 public static final int VIDEO_STATE_RX_PAUSED = 105 VideoProfile.STATE_RX_ENABLED | VideoProfile.STATE_PAUSED; 106 107 public static final int VIDEO_STATE_BIDIRECTIONAL_PAUSED = 108 VideoProfile.STATE_BIDIRECTIONAL | VideoProfile.STATE_PAUSED; 109 110 // Container class to return the call ID along with the event 111 public static class CallEvent<EventType> { 112 113 private final String mCallId; 114 private final EventType mEvent; 115 CallEvent(String callId, EventType event)116 CallEvent(String callId, EventType event) { 117 mCallId = callId; 118 mEvent = event; 119 } 120 getCallId()121 public String getCallId() { 122 return mCallId; 123 } 124 getEvent()125 public EventType getEvent() { 126 return mEvent; 127 } 128 } 129 130 // Currently the same as a call event... here for future use 131 public static class VideoCallEvent<EventType> extends CallEvent<EventType> { VideoCallEvent(String callId, EventType event)132 VideoCallEvent(String callId, EventType event) { 133 super(callId, event); 134 } 135 } 136 137 private class CallCallback extends Call.Callback { 138 139 // Invalid video state (valid >= 0) 140 public static final int STATE_INVALID = InCallServiceImpl.STATE_INVALID; 141 142 public static final int EVENT_INVALID = -1; 143 public static final int EVENT_NONE = 0; 144 public static final int EVENT_STATE_CHANGED = 1 << 0; 145 public static final int EVENT_PARENT_CHANGED = 1 << 1; 146 public static final int EVENT_CHILDREN_CHANGED = 1 << 2; 147 public static final int EVENT_DETAILS_CHANGED = 1 << 3; 148 public static final int EVENT_CANNED_TEXT_RESPONSES_LOADED = 1 << 4; 149 public static final int EVENT_POST_DIAL_WAIT = 1 << 5; 150 public static final int EVENT_VIDEO_CALL_CHANGED = 1 << 6; 151 public static final int EVENT_CALL_DESTROYED = 1 << 7; 152 public static final int EVENT_CONFERENCABLE_CALLS_CHANGED = 1 << 8; 153 154 public static final int EVENT_ALL = EVENT_STATE_CHANGED | 155 EVENT_PARENT_CHANGED | 156 EVENT_CHILDREN_CHANGED | 157 EVENT_DETAILS_CHANGED | 158 EVENT_CANNED_TEXT_RESPONSES_LOADED | 159 EVENT_POST_DIAL_WAIT | 160 EVENT_VIDEO_CALL_CHANGED | 161 EVENT_DETAILS_CHANGED | 162 EVENT_CALL_DESTROYED | 163 EVENT_CONFERENCABLE_CALLS_CHANGED; 164 165 private int mEvents; 166 private String mCallId; 167 CallCallback(String callId, int events)168 public CallCallback(String callId, int events) { 169 super(); 170 mEvents = events & EVENT_ALL; 171 mCallId = callId; 172 } 173 startListeningForEvents(int events)174 public void startListeningForEvents(int events) { 175 mEvents |= events & EVENT_ALL; 176 } 177 stopListeningForEvents(int events)178 public void stopListeningForEvents(int events) { 179 mEvents &= ~(events & EVENT_ALL); 180 } 181 182 @Override onStateChanged( Call call, int state)183 public void onStateChanged( 184 Call call, int state) { 185 Log.d("CallCallback:onStateChanged()"); 186 if ((mEvents & EVENT_STATE_CHANGED) 187 == EVENT_STATE_CHANGED) { 188 servicePostEvent(TelephonyConstants.EventTelecomCallStateChanged, 189 new CallEvent<String>(mCallId, getCallStateString(state))); 190 } 191 } 192 193 @Override onParentChanged( Call call, Call parent)194 public void onParentChanged( 195 Call call, Call parent) { 196 Log.d("CallCallback:onParentChanged()"); 197 if ((mEvents & EVENT_PARENT_CHANGED) 198 == EVENT_PARENT_CHANGED) { 199 servicePostEvent(TelephonyConstants.EventTelecomCallParentChanged, 200 new CallEvent<String>(mCallId, getCallId(parent))); 201 } 202 } 203 204 @Override onChildrenChanged( Call call, List<Call> children)205 public void onChildrenChanged( 206 Call call, List<Call> children) { 207 Log.d("CallCallback:onChildrenChanged()"); 208 209 if ((mEvents & EVENT_CHILDREN_CHANGED) 210 == EVENT_CHILDREN_CHANGED) { 211 List<String> childList = new ArrayList<String>(); 212 213 for (Call child : children) { 214 childList.add(getCallId(child)); 215 } 216 servicePostEvent(TelephonyConstants.EventTelecomCallChildrenChanged, 217 new CallEvent<List<String>>(mCallId, childList)); 218 } 219 } 220 221 @Override onDetailsChanged( Call call, Details details)222 public void onDetailsChanged( 223 Call call, Details details) { 224 Log.d("CallCallback:onDetailsChanged()"); 225 226 if ((mEvents & EVENT_DETAILS_CHANGED) 227 == EVENT_DETAILS_CHANGED) { 228 servicePostEvent(TelephonyConstants.EventTelecomCallDetailsChanged, 229 new CallEvent<Details>(mCallId, details)); 230 } 231 } 232 233 @Override onCannedTextResponsesLoaded( Call call, List<String> cannedTextResponses)234 public void onCannedTextResponsesLoaded( 235 Call call, List<String> cannedTextResponses) { 236 Log.d("CallCallback:onCannedTextResponsesLoaded()"); 237 if ((mEvents & EVENT_CANNED_TEXT_RESPONSES_LOADED) 238 == EVENT_CANNED_TEXT_RESPONSES_LOADED) { 239 servicePostEvent(TelephonyConstants.EventTelecomCallCannedTextResponsesLoaded, 240 new CallEvent<List<String>>(mCallId, cannedTextResponses)); 241 } 242 } 243 244 @Override onPostDialWait( Call call, String remainingPostDialSequence)245 public void onPostDialWait( 246 Call call, String remainingPostDialSequence) { 247 Log.d("CallCallback:onPostDialWait()"); 248 if ((mEvents & EVENT_POST_DIAL_WAIT) 249 == EVENT_POST_DIAL_WAIT) { 250 servicePostEvent(TelephonyConstants.EventTelecomCallPostDialWait, 251 new CallEvent<String>(mCallId, remainingPostDialSequence)); 252 } 253 } 254 255 @Override onVideoCallChanged( Call call, InCallService.VideoCall videoCall)256 public void onVideoCallChanged( 257 Call call, InCallService.VideoCall videoCall) { 258 259 /* 260 * There is a race condition such that the lifetime of the VideoCall is not aligned with 261 * the lifetime of the underlying call object. We are using the onVideoCallChanged 262 * method as a way of determining the lifetime of the VideoCall object rather than 263 * onCallAdded/onCallRemoved. 264 */ 265 Log.d("CallCallback:onVideoCallChanged()"); 266 267 if (call != null) { 268 String callId = getCallId(call); 269 CallContainer cc = mCallContainerMap.get(callId); 270 if (cc == null) { 271 Log.d(String.format("Call container returned null for callId %s", callId)); 272 } 273 else { 274 synchronized (mLock) { 275 if (videoCall == null) { 276 Log.d("Yo dawg, I heard you like null video calls."); 277 // Try and see if the videoCall has been added/changed after firing the 278 // callback 279 // This probably won't work. 280 videoCall = call.getVideoCall(); 281 } 282 if (cc.getVideoCall() != videoCall) { 283 if (videoCall == null) { 284 // VideoCall object deleted 285 cc.updateVideoCall(null, null); 286 Log.d("Removing video call from call."); 287 } 288 else if (cc.getVideoCall() != null) { 289 // Somehow we have a mismatched VideoCall ID! 290 Log.d("Mismatched video calls for same call ID."); 291 } 292 else { 293 Log.d("Huzzah, we have a video call!"); 294 295 VideoCallCallback videoCallCallback = 296 new VideoCallCallback(callId, VideoCallCallback.EVENT_NONE); 297 298 videoCall.registerCallback(videoCallCallback); 299 300 cc.updateVideoCall( 301 videoCall, 302 videoCallCallback); 303 } 304 } 305 else { 306 Log.d("Change to existing video call."); 307 } 308 309 } 310 } 311 } 312 else { 313 Log.d("passed null call pointer to call callback"); 314 } 315 316 if ((mEvents & EVENT_VIDEO_CALL_CHANGED) 317 == EVENT_VIDEO_CALL_CHANGED) { 318 // TODO: b/26273778 Need to determine what to return; 319 // probably not the whole video call 320 servicePostEvent(TelephonyConstants.EventTelecomCallVideoCallChanged, 321 new CallEvent<String>(mCallId, videoCall.toString())); 322 } 323 } 324 325 @Override onCallDestroyed(Call call)326 public void onCallDestroyed(Call call) { 327 Log.d("CallCallback:onCallDestroyed()"); 328 329 if ((mEvents & EVENT_CALL_DESTROYED) 330 == EVENT_CALL_DESTROYED) { 331 servicePostEvent(TelephonyConstants.EventTelecomCallDestroyed, 332 new CallEvent<Call>(mCallId, call)); 333 } 334 } 335 336 @Override onConferenceableCallsChanged( Call call, List<Call> conferenceableCalls)337 public void onConferenceableCallsChanged( 338 Call call, List<Call> conferenceableCalls) { 339 Log.d("CallCallback:onConferenceableCallsChanged()"); 340 341 if ((mEvents & EVENT_CONFERENCABLE_CALLS_CHANGED) 342 == EVENT_CONFERENCABLE_CALLS_CHANGED) { 343 List<String> confCallList = new ArrayList<String>(); 344 for (Call cc : conferenceableCalls) { 345 confCallList.add(getCallId(cc)); 346 } 347 servicePostEvent(TelephonyConstants.EventTelecomCallConferenceableCallsChanged, 348 new CallEvent<List<String>>(mCallId, confCallList)); 349 } 350 } 351 } 352 353 private class VideoCallCallback extends InCallService.VideoCall.Callback { 354 355 public static final int EVENT_INVALID = -1; 356 public static final int EVENT_NONE = 0; 357 public static final int EVENT_SESSION_MODIFY_REQUEST_RECEIVED = 1 << 0; 358 public static final int EVENT_SESSION_MODIFY_RESPONSE_RECEIVED = 1 << 1; 359 public static final int EVENT_SESSION_EVENT = 1 << 2; 360 public static final int EVENT_PEER_DIMENSIONS_CHANGED = 1 << 3; 361 public static final int EVENT_VIDEO_QUALITY_CHANGED = 1 << 4; 362 public static final int EVENT_DATA_USAGE_CHANGED = 1 << 5; 363 public static final int EVENT_CAMERA_CAPABILITIES_CHANGED = 1 << 6; 364 public static final int EVENT_ALL = 365 EVENT_SESSION_MODIFY_REQUEST_RECEIVED | 366 EVENT_SESSION_MODIFY_RESPONSE_RECEIVED | 367 EVENT_SESSION_EVENT | 368 EVENT_PEER_DIMENSIONS_CHANGED | 369 EVENT_VIDEO_QUALITY_CHANGED | 370 EVENT_DATA_USAGE_CHANGED | 371 EVENT_CAMERA_CAPABILITIES_CHANGED; 372 373 private String mCallId; 374 private int mEvents; 375 VideoCallCallback(String callId, int listeners)376 public VideoCallCallback(String callId, int listeners) { 377 378 mCallId = callId; 379 mEvents = listeners & EVENT_ALL; 380 } 381 startListeningForEvents(int events)382 public void startListeningForEvents(int events) { 383 Log.d(String.format( 384 "VideoCallCallback(%s):startListeningForEvents(%x): events:%x", 385 mCallId, events, mEvents)); 386 387 mEvents |= events & EVENT_ALL; 388 389 } 390 stopListeningForEvents(int events)391 public void stopListeningForEvents(int events) { 392 mEvents &= ~(events & EVENT_ALL); 393 } 394 395 @Override onSessionModifyRequestReceived(VideoProfile videoProfile)396 public void onSessionModifyRequestReceived(VideoProfile videoProfile) { 397 Log.d(String.format("VideoCallCallback(%s):onSessionModifyRequestReceived()", mCallId)); 398 399 if ((mEvents & EVENT_SESSION_MODIFY_REQUEST_RECEIVED) 400 == EVENT_SESSION_MODIFY_REQUEST_RECEIVED) { 401 servicePostEvent(TelephonyConstants.EventTelecomVideoCallSessionModifyRequestReceived, 402 new VideoCallEvent<VideoProfile>(mCallId, videoProfile)); 403 } 404 405 } 406 407 @Override onSessionModifyResponseReceived(int status, VideoProfile requestedProfile, VideoProfile responseProfile)408 public void onSessionModifyResponseReceived(int status, 409 VideoProfile requestedProfile, VideoProfile responseProfile) { 410 Log.d("VideoCallCallback:onSessionModifyResponseReceived()"); 411 412 if ((mEvents & EVENT_SESSION_MODIFY_RESPONSE_RECEIVED) 413 == EVENT_SESSION_MODIFY_RESPONSE_RECEIVED) { 414 415 HashMap<String, VideoProfile> smrrInfo = new HashMap<String, VideoProfile>(); 416 417 smrrInfo.put("RequestedProfile", requestedProfile); 418 smrrInfo.put("ResponseProfile", responseProfile); 419 420 servicePostEvent(TelephonyConstants.EventTelecomVideoCallSessionModifyResponseReceived, 421 new VideoCallEvent<HashMap<String, VideoProfile>>(mCallId, smrrInfo)); 422 } 423 } 424 425 @Override onCallSessionEvent(int event)426 public void onCallSessionEvent(int event) { 427 Log.d("VideoCallCallback:onCallSessionEvent()"); 428 429 String eventString = getVideoCallSessionEventString(event); 430 431 if ((mEvents & EVENT_SESSION_EVENT) 432 == EVENT_SESSION_EVENT) { 433 servicePostEvent(TelephonyConstants.EventTelecomVideoCallSessionEvent, 434 new VideoCallEvent<String>(mCallId, eventString)); 435 } 436 } 437 438 @Override onPeerDimensionsChanged(int width, int height)439 public void onPeerDimensionsChanged(int width, int height) { 440 Log.d("VideoCallCallback:onPeerDimensionsChanged()"); 441 442 if ((mEvents & EVENT_PEER_DIMENSIONS_CHANGED) 443 == EVENT_PEER_DIMENSIONS_CHANGED) { 444 445 HashMap<String, Integer> temp = new HashMap<String, Integer>(); 446 temp.put("Width", width); 447 temp.put("Height", height); 448 449 servicePostEvent(TelephonyConstants.EventTelecomVideoCallPeerDimensionsChanged, 450 new VideoCallEvent<HashMap<String, Integer>>(mCallId, temp)); 451 } 452 } 453 454 @Override onVideoQualityChanged(int videoQuality)455 public void onVideoQualityChanged(int videoQuality) { 456 Log.d("VideoCallCallback:onVideoQualityChanged()"); 457 458 if ((mEvents & EVENT_VIDEO_QUALITY_CHANGED) 459 == EVENT_VIDEO_QUALITY_CHANGED) { 460 servicePostEvent(TelephonyConstants.EventTelecomVideoCallVideoQualityChanged, 461 new VideoCallEvent<String>(mCallId, 462 getVideoCallQualityString(videoQuality))); 463 } 464 } 465 466 @Override onCallDataUsageChanged(long dataUsage)467 public void onCallDataUsageChanged(long dataUsage) { 468 Log.d("VideoCallCallback:onCallDataUsageChanged()"); 469 470 if ((mEvents & EVENT_DATA_USAGE_CHANGED) 471 == EVENT_DATA_USAGE_CHANGED) { 472 servicePostEvent(TelephonyConstants.EventTelecomVideoCallDataUsageChanged, 473 new VideoCallEvent<Long>(mCallId, dataUsage)); 474 } 475 } 476 477 @Override onCameraCapabilitiesChanged( CameraCapabilities cameraCapabilities)478 public void onCameraCapabilitiesChanged( 479 CameraCapabilities cameraCapabilities) { 480 Log.d("VideoCallCallback:onCallDataUsageChanged()"); 481 482 if ((mEvents & EVENT_DATA_USAGE_CHANGED) 483 == EVENT_DATA_USAGE_CHANGED) { 484 servicePostEvent(TelephonyConstants.EventTelecomVideoCallCameraCapabilities, 485 new VideoCallEvent<CameraCapabilities>(mCallId, cameraCapabilities)); 486 } 487 488 } 489 } 490 491 /* 492 * Container Class for Call and CallCallback Objects 493 */ 494 private class CallContainer { 495 496 /* 497 * Call Container Members 498 */ 499 500 private Call mCall; 501 private CallCallback mCallCallback; 502 private VideoCall mVideoCall; 503 private VideoCallCallback mVideoCallCallback; 504 505 /* 506 * Call Container Functions 507 */ 508 CallContainer(Call call, CallCallback callback, VideoCall videoCall, VideoCallCallback videoCallCallback)509 public CallContainer(Call call, 510 CallCallback callback, 511 VideoCall videoCall, 512 VideoCallCallback videoCallCallback) { 513 mCall = call; 514 mCallCallback = callback; 515 mVideoCall = videoCall; 516 mVideoCallCallback = videoCallCallback; 517 } 518 getCall()519 public Call getCall() { 520 return mCall; 521 } 522 getCallback()523 public CallCallback getCallback() { 524 return mCallCallback; 525 } 526 getVideoCall()527 public InCallService.VideoCall getVideoCall() { 528 return mVideoCall; 529 } 530 getVideoCallCallback()531 public VideoCallCallback getVideoCallCallback() { 532 return mVideoCallCallback; 533 } 534 updateVideoCall(VideoCall videoCall, VideoCallCallback videoCallCallback)535 public void updateVideoCall(VideoCall videoCall, VideoCallCallback videoCallCallback) { 536 if (videoCall == null && videoCallCallback != null) { 537 Log.d("UpdateVideoCall: videoCall and videoCallCallback are null."); 538 return; 539 } 540 mVideoCall = videoCall; 541 mVideoCallCallback = videoCallCallback; 542 } 543 } 544 545 /* 546 * TODO: b/26272583 Refactor so that these are instance members of the 547 * incallservice. Then we can perform null checks using the design pattern 548 * of the "manager" classes. 549 */ 550 551 private static EventFacade mEventFacade = null; 552 private static HashMap<String, CallContainer> mCallContainerMap = 553 new HashMap<String, CallContainer>(); 554 555 @Override onCallAdded(Call call)556 public void onCallAdded(Call call) { 557 Log.d("onCallAdded: " + call.toString()); 558 String id = getCallId(call); 559 Log.d("Adding " + id); 560 CallCallback callCallback = new CallCallback(id, CallCallback.EVENT_NONE); 561 562 call.registerCallback(callCallback); 563 564 VideoCall videoCall = call.getVideoCall(); 565 VideoCallCallback videoCallCallback = null; 566 567 if (videoCall != null) { 568 synchronized (mLock) { 569 if (getVideoCallById(id) == null) { 570 videoCallCallback = new VideoCallCallback(id, VideoCallCallback.EVENT_NONE); 571 videoCall.registerCallback(videoCallCallback); 572 } 573 } 574 } 575 else { 576 // No valid video object 577 Log.d("No Video Call provided to InCallService."); 578 } 579 580 mCallContainerMap.put(id, 581 new CallContainer(call, 582 callCallback, 583 videoCall, 584 videoCallCallback)); 585 586 /* 587 * Once we have a call active, anchor the inCallService instance as a psuedo-singleton. 588 * Because object lifetime is not guaranteed we shouldn't do this in the 589 * constructor/destructor. 590 */ 591 if (sService == null) { 592 sService = this; 593 } 594 else if (sService != this) { 595 Log.e("Multiple InCall Services Active in SL4A!"); 596 } 597 598 CallListener.onCallAdded(id, call); 599 } 600 601 @Override onCallRemoved(Call call)602 public void onCallRemoved(Call call) { 603 Log.d("onCallRemoved: " + call.toString()); 604 String id = getCallId(call); 605 Log.d("Removing " + id); 606 607 mCallContainerMap.remove(id); 608 609 CallListener.onCallRemoved(id, call); 610 611 if (mCallContainerMap.size() == 0) { 612 sService = null; 613 } 614 } 615 setEventFacade(EventFacade facade)616 public static void setEventFacade(EventFacade facade) { 617 Log.d(String.format("setEventFacade(): Settings SL4A event facade to %s", 618 (facade != null) ? facade.toString() : "null")); 619 mEventFacade = facade; 620 } 621 servicePostEvent(String eventName, Object event)622 private static boolean servicePostEvent(String eventName, Object event) { 623 624 if (mEventFacade == null) { 625 Log.d("servicePostEvent():SL4A eventFacade Is Null!!"); 626 return false; 627 } 628 629 mEventFacade.postEvent(eventName, event); 630 631 return true; 632 } 633 getCallId(Call call)634 public static String getCallId(Call call) { 635 if (call != null) { 636 return "Call:" + call.hashCode(); 637 } 638 else 639 return ""; 640 } 641 getVideoCallId(InCallServiceImpl.VideoCall videoCall)642 public static String getVideoCallId(InCallServiceImpl.VideoCall videoCall) { 643 if (videoCall != null) 644 return "VideoCall:" + videoCall.hashCode(); 645 else 646 return ""; 647 } 648 getCallById(String callId)649 public static Call getCallById(String callId) { 650 651 CallContainer cc = mCallContainerMap.get(callId); 652 653 if (cc != null) { 654 return cc.getCall(); 655 } 656 657 return null; 658 } 659 getCallCallbackById(String callId)660 private static CallCallback getCallCallbackById(String callId) { 661 662 CallContainer cc = mCallContainerMap.get(callId); 663 664 if (cc != null) { 665 return cc.getCallback(); 666 } 667 668 return null; 669 } 670 getVideoCallById(String callId)671 private static InCallService.VideoCall getVideoCallById(String callId) { 672 673 CallContainer cc = mCallContainerMap.get(callId); 674 675 if (cc != null) { 676 return cc.getVideoCall(); 677 678 } 679 680 return null; 681 } 682 683 private static VideoCallCallback getVideoCallListenerById(String callId)684 getVideoCallListenerById(String callId) { 685 686 CallContainer cc = mCallContainerMap.get(callId); 687 688 if (cc != null) { 689 return cc.getVideoCallCallback(); 690 } 691 692 return null; 693 } 694 695 /* 696 * Public Call/Phone Functions 697 */ 698 callDisconnect(String callId)699 public static void callDisconnect(String callId) { 700 Call c = getCallById(callId); 701 if (c == null) { 702 Log.d("callDisconnect: callId is null"); 703 return; 704 } 705 706 c.disconnect(); 707 } 708 holdCall(String callId)709 public static void holdCall(String callId) { 710 Call c = getCallById(callId); 711 if (c == null) { 712 Log.d("holdCall: callId is null"); 713 return; 714 } 715 c.hold(); 716 } 717 muteCall(Boolean shouldMute)718 public static void muteCall(Boolean shouldMute) { 719 InCallServiceImpl svc = getService(); 720 721 if (svc == null) { 722 Log.d("muteCall: InCallServiceImpl is null."); 723 return; 724 } 725 726 svc.setMuted(shouldMute); 727 } 728 mergeCallsInConference(String callId)729 public static void mergeCallsInConference(String callId) { 730 Call c = getCallById(callId); 731 if (c == null) { 732 Log.d("mergeCallsInConference: callId is null"); 733 return; 734 } 735 c.mergeConference(); 736 } 737 splitCallFromConf(String callId)738 public static void splitCallFromConf(String callId) { 739 Call c = getCallById(callId); 740 if (c == null) { 741 Log.d("splitCallFromConf: callId is null"); 742 return; 743 } 744 c.splitFromConference(); 745 } 746 unholdCall(String callId)747 public static void unholdCall(String callId) { 748 Call c = getCallById(callId); 749 if (c == null) { 750 Log.d("unholdCall: callId is null"); 751 return; 752 } 753 c.unhold(); 754 } 755 joinCallsInConf(String callIdOne, String callIdTwo)756 public static void joinCallsInConf(String callIdOne, String callIdTwo) { 757 Call callOne = getCallById(callIdOne); 758 Call callTwo = getCallById(callIdTwo); 759 760 if (callOne == null || callTwo == null) { 761 Log.d("joinCallsInConf: callOne or CallTwo is null"); 762 return; 763 } 764 765 callOne.conference(callTwo); 766 } 767 getCallIdList()768 public static Set<String> getCallIdList() { 769 return mCallContainerMap.keySet(); 770 } 771 clearCallList()772 public static void clearCallList() { 773 mCallContainerMap.clear(); 774 } 775 callGetState(String callId)776 public static String callGetState(String callId) { 777 Call c = getCallById(callId); 778 if (c == null) { 779 return getCallStateString(STATE_INVALID); 780 } 781 782 return getCallStateString(c.getState()); 783 } 784 callGetDetails(String callId)785 public static Call.Details callGetDetails(String callId) { 786 Call c = getCallById(callId); 787 if (c == null) { 788 Log.d(String.format("Couldn't find an active call with ID:%s", callId)); 789 return null; 790 } 791 792 return c.getDetails(); 793 } 794 callGetCallProperties(String callId)795 public static List<String> callGetCallProperties(String callId) { 796 Call.Details details = callGetDetails(callId); 797 798 if (details == null) { 799 return null; 800 } 801 802 return getCallPropertiesString(details.getCallProperties()); 803 } 804 callGetCallCapabilities(String callId)805 public static List<String> callGetCallCapabilities(String callId) { 806 Call.Details details = callGetDetails(callId); 807 808 if (details == null) { 809 return null; 810 } 811 812 return getCallCapabilitiesString(details.getCallCapabilities()); 813 } 814 815 @SuppressWarnings("deprecation") overrideProximitySensor(Boolean screenOn)816 public static void overrideProximitySensor(Boolean screenOn) { 817 InCallServiceImpl svc = getService(); 818 if (svc == null) { 819 Log.d("overrideProximitySensor: InCallServiceImpl is null."); 820 return; 821 } 822 823 Phone phone = svc.getPhone(); 824 if (phone == null) { 825 Log.d("overrideProximitySensor: phone is null."); 826 return; 827 } 828 829 phone.setProximitySensorOff(screenOn); 830 } 831 serviceGetCallAudioState()832 public static CallAudioState serviceGetCallAudioState() { 833 InCallServiceImpl svc = getService(); 834 835 if (svc != null) { 836 return svc.getCallAudioState(); 837 } 838 else { 839 return null; 840 } 841 } 842 843 // Wonky name due to conflict with internal function serviceSetAudioRoute(String route)844 public static void serviceSetAudioRoute(String route) { 845 InCallServiceImpl svc = getService(); 846 847 if (svc == null) { 848 Log.d("serviceSetAudioRoute: InCallServiceImpl is null."); 849 return; 850 } 851 852 int r = getAudioRoute(route); 853 854 Log.d(String.format("Setting Audio Route to %s:%d", route, r)); 855 856 if (r == INVALID_AUDIO_ROUTE) { 857 Log.d(String.format("Invalid Audio route %s:%d", route, r)); 858 return; 859 } 860 svc.setAudioRoute(r); 861 } 862 callStartListeningForEvent(String callId, String strEvent)863 public static void callStartListeningForEvent(String callId, String strEvent) { 864 865 CallCallback cl = getCallCallbackById(callId); 866 867 if (cl == null) { 868 Log.d("callStartListeningForEvent: CallCallback is null."); 869 return; 870 } 871 872 int event = getCallCallbackEvent(strEvent); 873 874 if (event == CallCallback.EVENT_INVALID) { 875 Log.d("callStartListeningForEvent: event is invalid."); 876 return; 877 } 878 879 cl.startListeningForEvents(event); 880 } 881 callStopListeningForEvent(String callId, String strEvent)882 public static void callStopListeningForEvent(String callId, String strEvent) { 883 CallCallback cl = getCallCallbackById(callId); 884 885 if (cl == null) { 886 Log.d("callStopListeningForEvent: CallCallback is null."); 887 return; 888 } 889 890 int event = getCallCallbackEvent(strEvent); 891 892 if (event == CallCallback.EVENT_INVALID) { 893 Log.d("callStopListeningForEvent: event is invalid."); 894 return; 895 } 896 897 cl.stopListeningForEvents(event); 898 } 899 videoCallStartListeningForEvent(String callId, String strEvent)900 public static void videoCallStartListeningForEvent(String callId, String strEvent) { 901 VideoCallCallback cl = getVideoCallListenerById(callId); 902 903 if (cl == null) { 904 Log.d(String.format("Couldn't find a call with call id:%s", callId)); 905 return; 906 } 907 908 int event = getVideoCallCallbackEvent(strEvent); 909 910 if (event == VideoCallCallback.EVENT_INVALID) { 911 Log.d(String.format("Failed to find a valid event:[%s]", strEvent)); 912 return; 913 } 914 915 cl.startListeningForEvents(event); 916 } 917 videoCallStopListeningForEvent(String callId, String strEvent)918 public static void videoCallStopListeningForEvent(String callId, String strEvent) { 919 VideoCallCallback cl = getVideoCallListenerById(callId); 920 921 if (cl == null) { 922 Log.d("videoCallStopListeningForEvent: CallCallback is null."); 923 return; 924 } 925 926 int event = getVideoCallCallbackEvent(strEvent); 927 928 if (event == VideoCallCallback.EVENT_INVALID) { 929 Log.d("getVideoCallCallbackEvent: event is invalid."); 930 return; 931 } 932 933 cl.stopListeningForEvents(event); 934 } 935 videoCallGetState(String callId)936 public static String videoCallGetState(String callId) { 937 Call c = getCallById(callId); 938 939 int state = CallCallback.STATE_INVALID; 940 941 if (c == null) { 942 Log.d("videoCallGetState: call is null."); 943 } 944 else { 945 state = c.getDetails().getVideoState(); 946 } 947 948 return getVideoCallStateString(state); 949 } 950 videoCallSendSessionModifyRequest( String callId, String videoStateString, String videoQualityString)951 public static void videoCallSendSessionModifyRequest( 952 String callId, String videoStateString, String videoQualityString) { 953 VideoCall vc = getVideoCallById(callId); 954 955 if (vc == null) { 956 Log.d("Invalid video call for call ID"); 957 return; 958 } 959 960 int videoState = getVideoCallState(videoStateString); 961 int videoQuality = getVideoCallQuality(videoQualityString); 962 963 Log.d(String.format("Sending Modify request for %s:%d, %s:%d", 964 videoStateString, videoState, videoQualityString, videoQuality)); 965 966 if (videoState == CallCallback.STATE_INVALID || 967 videoQuality == QUALITY_INVALID || videoQuality == VideoProfile.QUALITY_UNKNOWN) { 968 Log.d("Invalid session modify request!"); 969 return; 970 } 971 972 vc.sendSessionModifyRequest(new VideoProfile(videoState, videoQuality)); 973 } 974 videoCallSendSessionModifyResponse( String callId, String videoStateString, String videoQualityString)975 public static void videoCallSendSessionModifyResponse( 976 String callId, String videoStateString, String videoQualityString) { 977 VideoCall vc = getVideoCallById(callId); 978 979 if (vc == null) { 980 Log.d("Invalid video call for call ID"); 981 return; 982 } 983 984 int videoState = getVideoCallState(videoStateString); 985 int videoQuality = getVideoCallQuality(videoQualityString); 986 987 Log.d(String.format("Sending Modify request for %s:%d, %s:%d", 988 videoStateString, videoState, videoQualityString, videoQuality)); 989 990 if (videoState == CallCallback.STATE_INVALID || 991 videoQuality == QUALITY_INVALID || videoQuality == VideoProfile.QUALITY_UNKNOWN) { 992 Log.d("Invalid session modify request!"); 993 return; 994 } 995 996 vc.sendSessionModifyResponse(new VideoProfile(videoState, videoQuality)); 997 } 998 callAnswer(String callId, String videoState)999 public static void callAnswer(String callId, String videoState) { 1000 Call c = getCallById(callId); 1001 1002 if (c == null) { 1003 Log.d("callAnswer: call is null."); 1004 } 1005 1006 int state = getVideoCallState(videoState); 1007 1008 if (state == CallCallback.STATE_INVALID) { 1009 Log.d("callAnswer: video state is invalid."); 1010 state = VideoProfile.STATE_AUDIO_ONLY; 1011 } 1012 1013 c.answer(state); 1014 } 1015 callReject(String callId, String message)1016 public static void callReject(String callId, String message) { 1017 Call c = getCallById(callId); 1018 1019 if (c == null) { 1020 Log.d("callReject: call is null."); 1021 } 1022 1023 c.reject((message != null) ? true : false, message); 1024 } 1025 getCallParent(String callId)1026 public static String getCallParent(String callId) { 1027 Call c = getCallById(callId); 1028 1029 if (c == null) { 1030 Log.d("getCallParent: call is null."); 1031 return null; 1032 } 1033 Call callParent = c.getParent(); 1034 return getCallId(callParent); 1035 } 1036 getCallChildren(String callId)1037 public static List<String> getCallChildren(String callId) { 1038 Call c = getCallById(callId); 1039 1040 if (c == null) { 1041 Log.d("getCallChildren: call is null."); 1042 return null; 1043 } 1044 List<String> childrenList = new ArrayList<String>(); 1045 List<Call> callChildren = c.getChildren(); 1046 for (Call call : callChildren) { 1047 childrenList.add(getCallId(call)); 1048 } 1049 return childrenList; 1050 } 1051 swapCallsInConference(String callId)1052 public static void swapCallsInConference(String callId) { 1053 Call c = getCallById(callId); 1054 if (c == null) { 1055 Log.d("swapCallsInConference: call is null."); 1056 return; 1057 } 1058 c.swapConference(); 1059 } 1060 callPlayDtmfTone(String callId, char digit)1061 public static void callPlayDtmfTone(String callId, char digit) { 1062 Call c = getCallById(callId); 1063 if (c == null) { 1064 Log.d("callPlayDtmfTone: call is null."); 1065 return; 1066 } 1067 c.playDtmfTone(digit); 1068 } 1069 callStopDtmfTone(String callId)1070 public static void callStopDtmfTone(String callId) { 1071 Call c = getCallById(callId); 1072 if (c == null) { 1073 Log.d("callStopDtmfTone: call is null."); 1074 return; 1075 } 1076 c.stopDtmfTone(); 1077 } 1078 callGetCannedTextResponses(String callId)1079 public static List<String> callGetCannedTextResponses(String callId) { 1080 Call c = getCallById(callId); 1081 if (c == null) { 1082 return null; 1083 } 1084 1085 return c.getCannedTextResponses(); 1086 } 1087 1088 /* 1089 * String Mapping Functions for Facade Parameter Translation 1090 */ 1091 getVideoCallStateString(int state)1092 public static String getVideoCallStateString(int state) { 1093 switch (state) { 1094 case VIDEO_STATE_AUDIO_ONLY: 1095 return TelephonyConstants.VT_STATE_AUDIO_ONLY; 1096 case VIDEO_STATE_TX_ENABLED: 1097 return TelephonyConstants.VT_STATE_TX_ENABLED; 1098 case VIDEO_STATE_RX_ENABLED: 1099 return TelephonyConstants.VT_STATE_RX_ENABLED; 1100 case VIDEO_STATE_BIDIRECTIONAL: 1101 return TelephonyConstants.VT_STATE_BIDIRECTIONAL; 1102 case VIDEO_STATE_TX_PAUSED: 1103 return TelephonyConstants.VT_STATE_TX_PAUSED; 1104 case VIDEO_STATE_RX_PAUSED: 1105 return TelephonyConstants.VT_STATE_RX_PAUSED; 1106 case VIDEO_STATE_BIDIRECTIONAL_PAUSED: 1107 return TelephonyConstants.VT_STATE_BIDIRECTIONAL_PAUSED; 1108 default: 1109 } 1110 Log.d("getVideoCallStateString: state is invalid."); 1111 return TelephonyConstants.VT_STATE_STATE_INVALID; 1112 } 1113 getVideoCallState(String state)1114 public static int getVideoCallState(String state) { 1115 switch (state.toUpperCase()) { 1116 case TelephonyConstants.VT_STATE_AUDIO_ONLY: 1117 return VIDEO_STATE_AUDIO_ONLY; 1118 case TelephonyConstants.VT_STATE_TX_ENABLED: 1119 return VIDEO_STATE_TX_ENABLED; 1120 case TelephonyConstants.VT_STATE_RX_ENABLED: 1121 return VIDEO_STATE_RX_ENABLED; 1122 case TelephonyConstants.VT_STATE_BIDIRECTIONAL: 1123 return VIDEO_STATE_BIDIRECTIONAL; 1124 case TelephonyConstants.VT_STATE_TX_PAUSED: 1125 return VIDEO_STATE_TX_PAUSED; 1126 case TelephonyConstants.VT_STATE_RX_PAUSED: 1127 return VIDEO_STATE_RX_PAUSED; 1128 case TelephonyConstants.VT_STATE_BIDIRECTIONAL_PAUSED: 1129 return VIDEO_STATE_BIDIRECTIONAL_PAUSED; 1130 1131 default: 1132 } 1133 Log.d("getVideoCallState: state is invalid."); 1134 return CallCallback.STATE_INVALID; 1135 } 1136 getVideoCallQuality(String quality)1137 private static int getVideoCallQuality(String quality) { 1138 1139 switch (quality.toUpperCase()) { 1140 case TelephonyConstants.VT_VIDEO_QUALITY_UNKNOWN: 1141 return VideoProfile.QUALITY_UNKNOWN; 1142 case TelephonyConstants.VT_VIDEO_QUALITY_HIGH: 1143 return VideoProfile.QUALITY_HIGH; 1144 case TelephonyConstants.VT_VIDEO_QUALITY_MEDIUM: 1145 return VideoProfile.QUALITY_MEDIUM; 1146 case TelephonyConstants.VT_VIDEO_QUALITY_LOW: 1147 return VideoProfile.QUALITY_LOW; 1148 case TelephonyConstants.VT_VIDEO_QUALITY_DEFAULT: 1149 return VideoProfile.QUALITY_DEFAULT; 1150 default: 1151 } 1152 Log.d("getVideoCallQuality: quality is invalid."); 1153 return QUALITY_INVALID; 1154 } 1155 getVideoCallQualityString(int quality)1156 public static String getVideoCallQualityString(int quality) { 1157 switch (quality) { 1158 case VideoProfile.QUALITY_UNKNOWN: 1159 return TelephonyConstants.VT_VIDEO_QUALITY_UNKNOWN; 1160 case VideoProfile.QUALITY_HIGH: 1161 return TelephonyConstants.VT_VIDEO_QUALITY_HIGH; 1162 case VideoProfile.QUALITY_MEDIUM: 1163 return TelephonyConstants.VT_VIDEO_QUALITY_MEDIUM; 1164 case VideoProfile.QUALITY_LOW: 1165 return TelephonyConstants.VT_VIDEO_QUALITY_LOW; 1166 case VideoProfile.QUALITY_DEFAULT: 1167 return TelephonyConstants.VT_VIDEO_QUALITY_DEFAULT; 1168 default: 1169 } 1170 Log.d("getVideoCallQualityString: quality is invalid."); 1171 return TelephonyConstants.VT_VIDEO_QUALITY_INVALID; 1172 } 1173 getCallCallbackEvent(String event)1174 private static int getCallCallbackEvent(String event) { 1175 1176 switch (event.toUpperCase()) { 1177 case "EVENT_STATE_CHANGED": 1178 return CallCallback.EVENT_STATE_CHANGED; 1179 case "EVENT_PARENT_CHANGED": 1180 return CallCallback.EVENT_PARENT_CHANGED; 1181 case "EVENT_CHILDREN_CHANGED": 1182 return CallCallback.EVENT_CHILDREN_CHANGED; 1183 case "EVENT_DETAILS_CHANGED": 1184 return CallCallback.EVENT_DETAILS_CHANGED; 1185 case "EVENT_CANNED_TEXT_RESPONSES_LOADED": 1186 return CallCallback.EVENT_CANNED_TEXT_RESPONSES_LOADED; 1187 case "EVENT_POST_DIAL_WAIT": 1188 return CallCallback.EVENT_POST_DIAL_WAIT; 1189 case "EVENT_VIDEO_CALL_CHANGED": 1190 return CallCallback.EVENT_VIDEO_CALL_CHANGED; 1191 case "EVENT_CALL_DESTROYED": 1192 return CallCallback.EVENT_CALL_DESTROYED; 1193 case "EVENT_CONFERENCABLE_CALLS_CHANGED": 1194 return CallCallback.EVENT_CONFERENCABLE_CALLS_CHANGED; 1195 } 1196 Log.d("getCallCallbackEvent: event is invalid."); 1197 return CallCallback.EVENT_INVALID; 1198 } 1199 getCallCallbackEventString(int event)1200 public static String getCallCallbackEventString(int event) { 1201 1202 switch (event) { 1203 case CallCallback.EVENT_STATE_CHANGED: 1204 return "EVENT_STATE_CHANGED"; 1205 case CallCallback.EVENT_PARENT_CHANGED: 1206 return "EVENT_PARENT_CHANGED"; 1207 case CallCallback.EVENT_CHILDREN_CHANGED: 1208 return "EVENT_CHILDREN_CHANGED"; 1209 case CallCallback.EVENT_DETAILS_CHANGED: 1210 return "EVENT_DETAILS_CHANGED"; 1211 case CallCallback.EVENT_CANNED_TEXT_RESPONSES_LOADED: 1212 return "EVENT_CANNED_TEXT_RESPONSES_LOADED"; 1213 case CallCallback.EVENT_POST_DIAL_WAIT: 1214 return "EVENT_POST_DIAL_WAIT"; 1215 case CallCallback.EVENT_VIDEO_CALL_CHANGED: 1216 return "EVENT_VIDEO_CALL_CHANGED"; 1217 case CallCallback.EVENT_CALL_DESTROYED: 1218 return "EVENT_CALL_DESTROYED"; 1219 case CallCallback.EVENT_CONFERENCABLE_CALLS_CHANGED: 1220 return "EVENT_CONFERENCABLE_CALLS_CHANGED"; 1221 } 1222 Log.d("getCallCallbackEventString: event is invalid."); 1223 return "EVENT_INVALID"; 1224 } 1225 getVideoCallCallbackEvent(String event)1226 private static int getVideoCallCallbackEvent(String event) { 1227 1228 switch (event) { 1229 case TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED: 1230 return VideoCallCallback.EVENT_SESSION_MODIFY_REQUEST_RECEIVED; 1231 case TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED: 1232 return VideoCallCallback.EVENT_SESSION_MODIFY_RESPONSE_RECEIVED; 1233 case TelephonyConstants.EVENT_VIDEO_SESSION_EVENT: 1234 return VideoCallCallback.EVENT_SESSION_EVENT; 1235 case TelephonyConstants.EVENT_VIDEO_PEER_DIMENSIONS_CHANGED: 1236 return VideoCallCallback.EVENT_PEER_DIMENSIONS_CHANGED; 1237 case TelephonyConstants.EVENT_VIDEO_QUALITY_CHANGED: 1238 return VideoCallCallback.EVENT_VIDEO_QUALITY_CHANGED; 1239 case TelephonyConstants.EVENT_VIDEO_DATA_USAGE_CHANGED: 1240 return VideoCallCallback.EVENT_DATA_USAGE_CHANGED; 1241 case TelephonyConstants.EVENT_VIDEO_CAMERA_CAPABILITIES_CHANGED: 1242 return VideoCallCallback.EVENT_CAMERA_CAPABILITIES_CHANGED; 1243 } 1244 Log.d("getVideoCallCallbackEvent: event is invalid."); 1245 return CallCallback.EVENT_INVALID; 1246 } 1247 getVideoCallCallbackEventString(int event)1248 public static String getVideoCallCallbackEventString(int event) { 1249 1250 switch (event) { 1251 case VideoCallCallback.EVENT_SESSION_MODIFY_REQUEST_RECEIVED: 1252 return TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED; 1253 case VideoCallCallback.EVENT_SESSION_MODIFY_RESPONSE_RECEIVED: 1254 return TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED; 1255 case VideoCallCallback.EVENT_SESSION_EVENT: 1256 return TelephonyConstants.EVENT_VIDEO_SESSION_EVENT; 1257 case VideoCallCallback.EVENT_PEER_DIMENSIONS_CHANGED: 1258 return TelephonyConstants.EVENT_VIDEO_PEER_DIMENSIONS_CHANGED; 1259 case VideoCallCallback.EVENT_VIDEO_QUALITY_CHANGED: 1260 return TelephonyConstants.EVENT_VIDEO_QUALITY_CHANGED; 1261 case VideoCallCallback.EVENT_DATA_USAGE_CHANGED: 1262 return TelephonyConstants.EVENT_VIDEO_DATA_USAGE_CHANGED; 1263 case VideoCallCallback.EVENT_CAMERA_CAPABILITIES_CHANGED: 1264 return TelephonyConstants.EVENT_VIDEO_CAMERA_CAPABILITIES_CHANGED; 1265 } 1266 Log.d("getVideoCallCallbackEventString: event is invalid."); 1267 return TelephonyConstants.EVENT_VIDEO_INVALID; 1268 } 1269 getCallStateString(int state)1270 public static String getCallStateString(int state) { 1271 switch (state) { 1272 case Call.STATE_NEW: 1273 return TelephonyConstants.CALL_STATE_NEW; 1274 case Call.STATE_DIALING: 1275 return TelephonyConstants.CALL_STATE_DIALING; 1276 case Call.STATE_RINGING: 1277 return TelephonyConstants.CALL_STATE_RINGING; 1278 case Call.STATE_HOLDING: 1279 return TelephonyConstants.CALL_STATE_HOLDING; 1280 case Call.STATE_ACTIVE: 1281 return TelephonyConstants.CALL_STATE_ACTIVE; 1282 case Call.STATE_DISCONNECTED: 1283 return TelephonyConstants.CALL_STATE_DISCONNECTED; 1284 case Call.STATE_PRE_DIAL_WAIT: 1285 return TelephonyConstants.CALL_STATE_PRE_DIAL_WAIT; 1286 case Call.STATE_CONNECTING: 1287 return TelephonyConstants.CALL_STATE_CONNECTING; 1288 case Call.STATE_DISCONNECTING: 1289 return TelephonyConstants.CALL_STATE_DISCONNECTING; 1290 case STATE_INVALID: 1291 return TelephonyConstants.CALL_STATE_INVALID; 1292 default: 1293 return TelephonyConstants.CALL_STATE_UNKNOWN; 1294 } 1295 } 1296 getAudioRoute(String audioRoute)1297 private static int getAudioRoute(String audioRoute) { 1298 switch (audioRoute.toUpperCase()) { 1299 case TelephonyConstants.AUDIO_ROUTE_BLUETOOTH: 1300 return CallAudioState.ROUTE_BLUETOOTH; 1301 case TelephonyConstants.AUDIO_ROUTE_EARPIECE: 1302 return CallAudioState.ROUTE_EARPIECE; 1303 case TelephonyConstants.AUDIO_ROUTE_SPEAKER: 1304 return CallAudioState.ROUTE_SPEAKER; 1305 case TelephonyConstants.AUDIO_ROUTE_WIRED_HEADSET: 1306 return CallAudioState.ROUTE_WIRED_HEADSET; 1307 case TelephonyConstants.AUDIO_ROUTE_WIRED_OR_EARPIECE: 1308 return CallAudioState.ROUTE_WIRED_OR_EARPIECE; 1309 default: 1310 return INVALID_AUDIO_ROUTE; 1311 } 1312 } 1313 getAudioRouteString(int audioRoute)1314 public static String getAudioRouteString(int audioRoute) { 1315 return CallAudioState.audioRouteToString(audioRoute); 1316 } 1317 getVideoCallSessionEventString(int event)1318 public static String getVideoCallSessionEventString(int event) { 1319 1320 switch (event) { 1321 case Connection.VideoProvider.SESSION_EVENT_RX_PAUSE: 1322 return TelephonyConstants.SESSION_EVENT_RX_PAUSE; 1323 case Connection.VideoProvider.SESSION_EVENT_RX_RESUME: 1324 return TelephonyConstants.SESSION_EVENT_RX_RESUME; 1325 case Connection.VideoProvider.SESSION_EVENT_TX_START: 1326 return TelephonyConstants.SESSION_EVENT_TX_START; 1327 case Connection.VideoProvider.SESSION_EVENT_TX_STOP: 1328 return TelephonyConstants.SESSION_EVENT_TX_STOP; 1329 case Connection.VideoProvider.SESSION_EVENT_CAMERA_FAILURE: 1330 return TelephonyConstants.SESSION_EVENT_CAMERA_FAILURE; 1331 case Connection.VideoProvider.SESSION_EVENT_CAMERA_READY: 1332 return TelephonyConstants.SESSION_EVENT_CAMERA_READY; 1333 default: 1334 return TelephonyConstants.SESSION_EVENT_UNKNOWN; 1335 } 1336 } 1337 getCallCapabilityString(int capability)1338 public static String getCallCapabilityString(int capability) { 1339 switch (capability) { 1340 case Call.Details.CAPABILITY_HOLD: 1341 return TelephonyConstants.CALL_CAPABILITY_HOLD; 1342 case Call.Details.CAPABILITY_SUPPORT_HOLD: 1343 return TelephonyConstants.CALL_CAPABILITY_SUPPORT_HOLD; 1344 case Call.Details.CAPABILITY_MERGE_CONFERENCE: 1345 return TelephonyConstants.CALL_CAPABILITY_MERGE_CONFERENCE; 1346 case Call.Details.CAPABILITY_SWAP_CONFERENCE: 1347 return TelephonyConstants.CALL_CAPABILITY_SWAP_CONFERENCE; 1348 case Call.Details.CAPABILITY_UNUSED_1: 1349 return TelephonyConstants.CALL_CAPABILITY_UNUSED_1; 1350 case Call.Details.CAPABILITY_RESPOND_VIA_TEXT: 1351 return TelephonyConstants.CALL_CAPABILITY_RESPOND_VIA_TEXT; 1352 case Call.Details.CAPABILITY_MUTE: 1353 return TelephonyConstants.CALL_CAPABILITY_MUTE; 1354 case Call.Details.CAPABILITY_MANAGE_CONFERENCE: 1355 return TelephonyConstants.CALL_CAPABILITY_MANAGE_CONFERENCE; 1356 case Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_RX: 1357 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_LOCAL_RX; 1358 case Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX: 1359 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_LOCAL_TX; 1360 case Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL: 1361 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL; 1362 case Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX: 1363 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_REMOTE_RX; 1364 case Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_TX: 1365 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_REMOTE_TX; 1366 case Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL: 1367 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL; 1368 case Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE: 1369 return TelephonyConstants.CALL_CAPABILITY_SEPARATE_FROM_CONFERENCE; 1370 case Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE: 1371 return TelephonyConstants.CALL_CAPABILITY_DISCONNECT_FROM_CONFERENCE; 1372 case Call.Details.CAPABILITY_SPEED_UP_MT_AUDIO: 1373 return TelephonyConstants.CALL_CAPABILITY_SPEED_UP_MT_AUDIO; 1374 case Call.Details.CAPABILITY_CAN_UPGRADE_TO_VIDEO: 1375 return TelephonyConstants.CALL_CAPABILITY_CAN_UPGRADE_TO_VIDEO; 1376 case Call.Details.CAPABILITY_CAN_PAUSE_VIDEO: 1377 return TelephonyConstants.CALL_CAPABILITY_CAN_PAUSE_VIDEO; 1378 } 1379 return TelephonyConstants.CALL_CAPABILITY_UNKOWN; 1380 } 1381 getCallCapabilitiesString(int capabilities)1382 public static List<String> getCallCapabilitiesString(int capabilities) { 1383 final int[] capabilityConstants = new int[] { 1384 Call.Details.CAPABILITY_HOLD, 1385 Call.Details.CAPABILITY_SUPPORT_HOLD, 1386 Call.Details.CAPABILITY_MERGE_CONFERENCE, 1387 Call.Details.CAPABILITY_SWAP_CONFERENCE, 1388 Call.Details.CAPABILITY_UNUSED_1, 1389 Call.Details.CAPABILITY_RESPOND_VIA_TEXT, 1390 Call.Details.CAPABILITY_MUTE, 1391 Call.Details.CAPABILITY_MANAGE_CONFERENCE, 1392 Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_RX, 1393 Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX, 1394 Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL, 1395 Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX, 1396 Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_TX, 1397 Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL, 1398 Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE, 1399 Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE, 1400 Call.Details.CAPABILITY_SPEED_UP_MT_AUDIO, 1401 Call.Details.CAPABILITY_CAN_UPGRADE_TO_VIDEO, 1402 Call.Details.CAPABILITY_CAN_PAUSE_VIDEO 1403 }; 1404 1405 List<String> capabilityList = new ArrayList<String>(); 1406 1407 for (int capability : capabilityConstants) { 1408 if ((capabilities & capability) == capability) { 1409 capabilityList.add(getCallCapabilityString(capability)); 1410 } 1411 } 1412 return capabilityList; 1413 } 1414 getCallPropertyString(int property)1415 public static String getCallPropertyString(int property) { 1416 1417 switch (property) { 1418 case Call.Details.PROPERTY_CONFERENCE: 1419 return TelephonyConstants.CALL_PROPERTY_CONFERENCE; 1420 case Call.Details.PROPERTY_GENERIC_CONFERENCE: 1421 return TelephonyConstants.CALL_PROPERTY_GENERIC_CONFERENCE; 1422 case Call.Details.PROPERTY_EMERGENCY_CALLBACK_MODE: 1423 return TelephonyConstants.CALL_PROPERTY_EMERGENCY_CALLBACK_MODE; 1424 case Call.Details.PROPERTY_WIFI: 1425 return TelephonyConstants.CALL_PROPERTY_WIFI; 1426 case Call.Details.PROPERTY_HIGH_DEF_AUDIO: 1427 return TelephonyConstants.CALL_PROPERTY_HIGH_DEF_AUDIO; 1428 default: 1429 return TelephonyConstants.CALL_PROPERTY_UNKNOWN; 1430 } 1431 } 1432 getCallPropertiesString(int properties)1433 public static List<String> getCallPropertiesString(int properties) { 1434 final int[] propertyConstants = new int[] { 1435 Call.Details.PROPERTY_CONFERENCE, 1436 Call.Details.PROPERTY_GENERIC_CONFERENCE, 1437 Call.Details.PROPERTY_EMERGENCY_CALLBACK_MODE, 1438 Call.Details.PROPERTY_WIFI, 1439 Call.Details.PROPERTY_HIGH_DEF_AUDIO 1440 }; 1441 1442 List<String> propertyList = new ArrayList<String>(); 1443 1444 for (int property : propertyConstants) { 1445 if ((properties & property) == property) { 1446 propertyList.add(getCallPropertyString(property)); 1447 } 1448 } 1449 1450 return propertyList; 1451 } 1452 getCallPresentationInfoString(int presentation)1453 public static String getCallPresentationInfoString(int presentation) { 1454 switch (presentation) { 1455 case TelecomManager.PRESENTATION_ALLOWED: 1456 return TelephonyConstants.CALL_PRESENTATION_ALLOWED; 1457 case TelecomManager.PRESENTATION_RESTRICTED: 1458 return TelephonyConstants.CALL_PRESENTATION_RESTRICTED; 1459 case TelecomManager.PRESENTATION_PAYPHONE: 1460 return TelephonyConstants.CALL_PRESENTATION_PAYPHONE; 1461 default: 1462 return TelephonyConstants.CALL_PRESENTATION_UNKNOWN; 1463 } 1464 } 1465 } 1466