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 mergeCallsInConference(String callId)718 public static void mergeCallsInConference(String callId) { 719 Call c = getCallById(callId); 720 if (c == null) { 721 Log.d("mergeCallsInConference: callId is null"); 722 return; 723 } 724 c.mergeConference(); 725 } 726 splitCallFromConf(String callId)727 public static void splitCallFromConf(String callId) { 728 Call c = getCallById(callId); 729 if (c == null) { 730 Log.d("splitCallFromConf: callId is null"); 731 return; 732 } 733 c.splitFromConference(); 734 } 735 unholdCall(String callId)736 public static void unholdCall(String callId) { 737 Call c = getCallById(callId); 738 if (c == null) { 739 Log.d("unholdCall: callId is null"); 740 return; 741 } 742 c.unhold(); 743 } 744 joinCallsInConf(String callIdOne, String callIdTwo)745 public static void joinCallsInConf(String callIdOne, String callIdTwo) { 746 Call callOne = getCallById(callIdOne); 747 Call callTwo = getCallById(callIdTwo); 748 749 if (callOne == null || callTwo == null) { 750 Log.d("joinCallsInConf: callOne or CallTwo is null"); 751 return; 752 } 753 754 callOne.conference(callTwo); 755 } 756 getCallIdList()757 public static Set<String> getCallIdList() { 758 return mCallContainerMap.keySet(); 759 } 760 clearCallList()761 public static void clearCallList() { 762 mCallContainerMap.clear(); 763 } 764 callGetState(String callId)765 public static String callGetState(String callId) { 766 Call c = getCallById(callId); 767 if (c == null) { 768 return getCallStateString(STATE_INVALID); 769 } 770 771 return getCallStateString(c.getState()); 772 } 773 callGetDetails(String callId)774 public static Call.Details callGetDetails(String callId) { 775 Call c = getCallById(callId); 776 if (c == null) { 777 Log.d(String.format("Couldn't find an active call with ID:%s", callId)); 778 return null; 779 } 780 781 return c.getDetails(); 782 } 783 callGetCallProperties(String callId)784 public static List<String> callGetCallProperties(String callId) { 785 Call.Details details = callGetDetails(callId); 786 787 if (details == null) { 788 return null; 789 } 790 791 return getCallPropertiesString(details.getCallProperties()); 792 } 793 callGetCallCapabilities(String callId)794 public static List<String> callGetCallCapabilities(String callId) { 795 Call.Details details = callGetDetails(callId); 796 797 if (details == null) { 798 return null; 799 } 800 801 return getCallCapabilitiesString(details.getCallCapabilities()); 802 } 803 804 @SuppressWarnings("deprecation") overrideProximitySensor(Boolean screenOn)805 public static void overrideProximitySensor(Boolean screenOn) { 806 InCallServiceImpl svc = getService(); 807 if (svc == null) { 808 Log.d("overrideProximitySensor: InCallServiceImpl is null."); 809 return; 810 } 811 812 Phone phone = svc.getPhone(); 813 if (phone == null) { 814 Log.d("overrideProximitySensor: phone is null."); 815 return; 816 } 817 818 phone.setProximitySensorOff(screenOn); 819 } 820 serviceGetCallAudioState()821 public static CallAudioState serviceGetCallAudioState() { 822 InCallServiceImpl svc = getService(); 823 824 if (svc != null) { 825 return svc.getCallAudioState(); 826 } 827 else { 828 return null; 829 } 830 } 831 832 // Wonky name due to conflict with internal function serviceSetAudioRoute(String route)833 public static void serviceSetAudioRoute(String route) { 834 InCallServiceImpl svc = getService(); 835 836 if (svc == null) { 837 Log.d("serviceSetAudioRoute: InCallServiceImpl is null."); 838 return; 839 } 840 841 int r = getAudioRoute(route); 842 843 Log.d(String.format("Setting Audio Route to %s:%d", route, r)); 844 845 if (r == INVALID_AUDIO_ROUTE) { 846 Log.d(String.format("Invalid Audio route %s:%d", route, r)); 847 return; 848 } 849 svc.setAudioRoute(r); 850 } 851 callStartListeningForEvent(String callId, String strEvent)852 public static void callStartListeningForEvent(String callId, String strEvent) { 853 854 CallCallback cl = getCallCallbackById(callId); 855 856 if (cl == null) { 857 Log.d("callStartListeningForEvent: CallCallback is null."); 858 return; 859 } 860 861 int event = getCallCallbackEvent(strEvent); 862 863 if (event == CallCallback.EVENT_INVALID) { 864 Log.d("callStartListeningForEvent: event is invalid."); 865 return; 866 } 867 868 cl.startListeningForEvents(event); 869 } 870 callStopListeningForEvent(String callId, String strEvent)871 public static void callStopListeningForEvent(String callId, String strEvent) { 872 CallCallback cl = getCallCallbackById(callId); 873 874 if (cl == null) { 875 Log.d("callStopListeningForEvent: CallCallback is null."); 876 return; 877 } 878 879 int event = getCallCallbackEvent(strEvent); 880 881 if (event == CallCallback.EVENT_INVALID) { 882 Log.d("callStopListeningForEvent: event is invalid."); 883 return; 884 } 885 886 cl.stopListeningForEvents(event); 887 } 888 videoCallStartListeningForEvent(String callId, String strEvent)889 public static void videoCallStartListeningForEvent(String callId, String strEvent) { 890 VideoCallCallback cl = getVideoCallListenerById(callId); 891 892 if (cl == null) { 893 Log.d(String.format("Couldn't find a call with call id:%s", callId)); 894 return; 895 } 896 897 int event = getVideoCallCallbackEvent(strEvent); 898 899 if (event == VideoCallCallback.EVENT_INVALID) { 900 Log.d(String.format("Failed to find a valid event:[%s]", strEvent)); 901 return; 902 } 903 904 cl.startListeningForEvents(event); 905 } 906 videoCallStopListeningForEvent(String callId, String strEvent)907 public static void videoCallStopListeningForEvent(String callId, String strEvent) { 908 VideoCallCallback cl = getVideoCallListenerById(callId); 909 910 if (cl == null) { 911 Log.d("videoCallStopListeningForEvent: CallCallback is null."); 912 return; 913 } 914 915 int event = getVideoCallCallbackEvent(strEvent); 916 917 if (event == VideoCallCallback.EVENT_INVALID) { 918 Log.d("getVideoCallCallbackEvent: event is invalid."); 919 return; 920 } 921 922 cl.stopListeningForEvents(event); 923 } 924 videoCallGetState(String callId)925 public static String videoCallGetState(String callId) { 926 Call c = getCallById(callId); 927 928 int state = CallCallback.STATE_INVALID; 929 930 if (c == null) { 931 Log.d("videoCallGetState: call is null."); 932 } 933 else { 934 state = c.getDetails().getVideoState(); 935 } 936 937 return getVideoCallStateString(state); 938 } 939 videoCallSendSessionModifyRequest( String callId, String videoStateString, String videoQualityString)940 public static void videoCallSendSessionModifyRequest( 941 String callId, String videoStateString, String videoQualityString) { 942 VideoCall vc = getVideoCallById(callId); 943 944 if (vc == null) { 945 Log.d("Invalid video call for call ID"); 946 return; 947 } 948 949 int videoState = getVideoCallState(videoStateString); 950 int videoQuality = getVideoCallQuality(videoQualityString); 951 952 Log.d(String.format("Sending Modify request for %s:%d, %s:%d", 953 videoStateString, videoState, videoQualityString, videoQuality)); 954 955 if (videoState == CallCallback.STATE_INVALID || 956 videoQuality == QUALITY_INVALID || videoQuality == VideoProfile.QUALITY_UNKNOWN) { 957 Log.d("Invalid session modify request!"); 958 return; 959 } 960 961 vc.sendSessionModifyRequest(new VideoProfile(videoState, videoQuality)); 962 } 963 videoCallSendSessionModifyResponse( String callId, String videoStateString, String videoQualityString)964 public static void videoCallSendSessionModifyResponse( 965 String callId, String videoStateString, String videoQualityString) { 966 VideoCall vc = getVideoCallById(callId); 967 968 if (vc == null) { 969 Log.d("Invalid video call for call ID"); 970 return; 971 } 972 973 int videoState = getVideoCallState(videoStateString); 974 int videoQuality = getVideoCallQuality(videoQualityString); 975 976 Log.d(String.format("Sending Modify request for %s:%d, %s:%d", 977 videoStateString, videoState, videoQualityString, videoQuality)); 978 979 if (videoState == CallCallback.STATE_INVALID || 980 videoQuality == QUALITY_INVALID || videoQuality == VideoProfile.QUALITY_UNKNOWN) { 981 Log.d("Invalid session modify request!"); 982 return; 983 } 984 985 vc.sendSessionModifyResponse(new VideoProfile(videoState, videoQuality)); 986 } 987 callAnswer(String callId, String videoState)988 public static void callAnswer(String callId, String videoState) { 989 Call c = getCallById(callId); 990 991 if (c == null) { 992 Log.d("callAnswer: call is null."); 993 } 994 995 int state = getVideoCallState(videoState); 996 997 if (state == CallCallback.STATE_INVALID) { 998 Log.d("callAnswer: video state is invalid."); 999 state = VideoProfile.STATE_AUDIO_ONLY; 1000 } 1001 1002 c.answer(state); 1003 } 1004 callReject(String callId, String message)1005 public static void callReject(String callId, String message) { 1006 Call c = getCallById(callId); 1007 1008 if (c == null) { 1009 Log.d("callReject: call is null."); 1010 } 1011 1012 c.reject((message != null) ? true : false, message); 1013 } 1014 getCallParent(String callId)1015 public static String getCallParent(String callId) { 1016 Call c = getCallById(callId); 1017 1018 if (c == null) { 1019 Log.d("getCallParent: call is null."); 1020 return null; 1021 } 1022 Call callParent = c.getParent(); 1023 return getCallId(callParent); 1024 } 1025 getCallChildren(String callId)1026 public static List<String> getCallChildren(String callId) { 1027 Call c = getCallById(callId); 1028 1029 if (c == null) { 1030 Log.d("getCallChildren: call is null."); 1031 return null; 1032 } 1033 List<String> childrenList = new ArrayList<String>(); 1034 List<Call> callChildren = c.getChildren(); 1035 for (Call call : callChildren) { 1036 childrenList.add(getCallId(call)); 1037 } 1038 return childrenList; 1039 } 1040 swapCallsInConference(String callId)1041 public static void swapCallsInConference(String callId) { 1042 Call c = getCallById(callId); 1043 if (c == null) { 1044 Log.d("swapCallsInConference: call is null."); 1045 return; 1046 } 1047 c.swapConference(); 1048 } 1049 callPlayDtmfTone(String callId, char digit)1050 public static void callPlayDtmfTone(String callId, char digit) { 1051 Call c = getCallById(callId); 1052 if (c == null) { 1053 Log.d("callPlayDtmfTone: call is null."); 1054 return; 1055 } 1056 c.playDtmfTone(digit); 1057 } 1058 callStopDtmfTone(String callId)1059 public static void callStopDtmfTone(String callId) { 1060 Call c = getCallById(callId); 1061 if (c == null) { 1062 Log.d("callStopDtmfTone: call is null."); 1063 return; 1064 } 1065 c.stopDtmfTone(); 1066 } 1067 callGetCannedTextResponses(String callId)1068 public static List<String> callGetCannedTextResponses(String callId) { 1069 Call c = getCallById(callId); 1070 if (c == null) { 1071 return null; 1072 } 1073 1074 return c.getCannedTextResponses(); 1075 } 1076 1077 /* 1078 * String Mapping Functions for Facade Parameter Translation 1079 */ 1080 getVideoCallStateString(int state)1081 public static String getVideoCallStateString(int state) { 1082 switch (state) { 1083 case VIDEO_STATE_AUDIO_ONLY: 1084 return TelephonyConstants.VT_STATE_AUDIO_ONLY; 1085 case VIDEO_STATE_TX_ENABLED: 1086 return TelephonyConstants.VT_STATE_TX_ENABLED; 1087 case VIDEO_STATE_RX_ENABLED: 1088 return TelephonyConstants.VT_STATE_RX_ENABLED; 1089 case VIDEO_STATE_BIDIRECTIONAL: 1090 return TelephonyConstants.VT_STATE_BIDIRECTIONAL; 1091 case VIDEO_STATE_TX_PAUSED: 1092 return TelephonyConstants.VT_STATE_TX_PAUSED; 1093 case VIDEO_STATE_RX_PAUSED: 1094 return TelephonyConstants.VT_STATE_RX_PAUSED; 1095 case VIDEO_STATE_BIDIRECTIONAL_PAUSED: 1096 return TelephonyConstants.VT_STATE_BIDIRECTIONAL_PAUSED; 1097 default: 1098 } 1099 Log.d("getVideoCallStateString: state is invalid."); 1100 return TelephonyConstants.VT_STATE_STATE_INVALID; 1101 } 1102 getVideoCallState(String state)1103 public static int getVideoCallState(String state) { 1104 switch (state.toUpperCase()) { 1105 case TelephonyConstants.VT_STATE_AUDIO_ONLY: 1106 return VIDEO_STATE_AUDIO_ONLY; 1107 case TelephonyConstants.VT_STATE_TX_ENABLED: 1108 return VIDEO_STATE_TX_ENABLED; 1109 case TelephonyConstants.VT_STATE_RX_ENABLED: 1110 return VIDEO_STATE_RX_ENABLED; 1111 case TelephonyConstants.VT_STATE_BIDIRECTIONAL: 1112 return VIDEO_STATE_BIDIRECTIONAL; 1113 case TelephonyConstants.VT_STATE_TX_PAUSED: 1114 return VIDEO_STATE_TX_PAUSED; 1115 case TelephonyConstants.VT_STATE_RX_PAUSED: 1116 return VIDEO_STATE_RX_PAUSED; 1117 case TelephonyConstants.VT_STATE_BIDIRECTIONAL_PAUSED: 1118 return VIDEO_STATE_BIDIRECTIONAL_PAUSED; 1119 1120 default: 1121 } 1122 Log.d("getVideoCallState: state is invalid."); 1123 return CallCallback.STATE_INVALID; 1124 } 1125 getVideoCallQuality(String quality)1126 private static int getVideoCallQuality(String quality) { 1127 1128 switch (quality.toUpperCase()) { 1129 case TelephonyConstants.VT_VIDEO_QUALITY_UNKNOWN: 1130 return VideoProfile.QUALITY_UNKNOWN; 1131 case TelephonyConstants.VT_VIDEO_QUALITY_HIGH: 1132 return VideoProfile.QUALITY_HIGH; 1133 case TelephonyConstants.VT_VIDEO_QUALITY_MEDIUM: 1134 return VideoProfile.QUALITY_MEDIUM; 1135 case TelephonyConstants.VT_VIDEO_QUALITY_LOW: 1136 return VideoProfile.QUALITY_LOW; 1137 case TelephonyConstants.VT_VIDEO_QUALITY_DEFAULT: 1138 return VideoProfile.QUALITY_DEFAULT; 1139 default: 1140 } 1141 Log.d("getVideoCallQuality: quality is invalid."); 1142 return QUALITY_INVALID; 1143 } 1144 getVideoCallQualityString(int quality)1145 public static String getVideoCallQualityString(int quality) { 1146 switch (quality) { 1147 case VideoProfile.QUALITY_UNKNOWN: 1148 return TelephonyConstants.VT_VIDEO_QUALITY_UNKNOWN; 1149 case VideoProfile.QUALITY_HIGH: 1150 return TelephonyConstants.VT_VIDEO_QUALITY_HIGH; 1151 case VideoProfile.QUALITY_MEDIUM: 1152 return TelephonyConstants.VT_VIDEO_QUALITY_MEDIUM; 1153 case VideoProfile.QUALITY_LOW: 1154 return TelephonyConstants.VT_VIDEO_QUALITY_LOW; 1155 case VideoProfile.QUALITY_DEFAULT: 1156 return TelephonyConstants.VT_VIDEO_QUALITY_DEFAULT; 1157 default: 1158 } 1159 Log.d("getVideoCallQualityString: quality is invalid."); 1160 return TelephonyConstants.VT_VIDEO_QUALITY_INVALID; 1161 } 1162 getCallCallbackEvent(String event)1163 private static int getCallCallbackEvent(String event) { 1164 1165 switch (event.toUpperCase()) { 1166 case "EVENT_STATE_CHANGED": 1167 return CallCallback.EVENT_STATE_CHANGED; 1168 case "EVENT_PARENT_CHANGED": 1169 return CallCallback.EVENT_PARENT_CHANGED; 1170 case "EVENT_CHILDREN_CHANGED": 1171 return CallCallback.EVENT_CHILDREN_CHANGED; 1172 case "EVENT_DETAILS_CHANGED": 1173 return CallCallback.EVENT_DETAILS_CHANGED; 1174 case "EVENT_CANNED_TEXT_RESPONSES_LOADED": 1175 return CallCallback.EVENT_CANNED_TEXT_RESPONSES_LOADED; 1176 case "EVENT_POST_DIAL_WAIT": 1177 return CallCallback.EVENT_POST_DIAL_WAIT; 1178 case "EVENT_VIDEO_CALL_CHANGED": 1179 return CallCallback.EVENT_VIDEO_CALL_CHANGED; 1180 case "EVENT_CALL_DESTROYED": 1181 return CallCallback.EVENT_CALL_DESTROYED; 1182 case "EVENT_CONFERENCABLE_CALLS_CHANGED": 1183 return CallCallback.EVENT_CONFERENCABLE_CALLS_CHANGED; 1184 } 1185 Log.d("getCallCallbackEvent: event is invalid."); 1186 return CallCallback.EVENT_INVALID; 1187 } 1188 getCallCallbackEventString(int event)1189 public static String getCallCallbackEventString(int event) { 1190 1191 switch (event) { 1192 case CallCallback.EVENT_STATE_CHANGED: 1193 return "EVENT_STATE_CHANGED"; 1194 case CallCallback.EVENT_PARENT_CHANGED: 1195 return "EVENT_PARENT_CHANGED"; 1196 case CallCallback.EVENT_CHILDREN_CHANGED: 1197 return "EVENT_CHILDREN_CHANGED"; 1198 case CallCallback.EVENT_DETAILS_CHANGED: 1199 return "EVENT_DETAILS_CHANGED"; 1200 case CallCallback.EVENT_CANNED_TEXT_RESPONSES_LOADED: 1201 return "EVENT_CANNED_TEXT_RESPONSES_LOADED"; 1202 case CallCallback.EVENT_POST_DIAL_WAIT: 1203 return "EVENT_POST_DIAL_WAIT"; 1204 case CallCallback.EVENT_VIDEO_CALL_CHANGED: 1205 return "EVENT_VIDEO_CALL_CHANGED"; 1206 case CallCallback.EVENT_CALL_DESTROYED: 1207 return "EVENT_CALL_DESTROYED"; 1208 case CallCallback.EVENT_CONFERENCABLE_CALLS_CHANGED: 1209 return "EVENT_CONFERENCABLE_CALLS_CHANGED"; 1210 } 1211 Log.d("getCallCallbackEventString: event is invalid."); 1212 return "EVENT_INVALID"; 1213 } 1214 getVideoCallCallbackEvent(String event)1215 private static int getVideoCallCallbackEvent(String event) { 1216 1217 switch (event) { 1218 case TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED: 1219 return VideoCallCallback.EVENT_SESSION_MODIFY_REQUEST_RECEIVED; 1220 case TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED: 1221 return VideoCallCallback.EVENT_SESSION_MODIFY_RESPONSE_RECEIVED; 1222 case TelephonyConstants.EVENT_VIDEO_SESSION_EVENT: 1223 return VideoCallCallback.EVENT_SESSION_EVENT; 1224 case TelephonyConstants.EVENT_VIDEO_PEER_DIMENSIONS_CHANGED: 1225 return VideoCallCallback.EVENT_PEER_DIMENSIONS_CHANGED; 1226 case TelephonyConstants.EVENT_VIDEO_QUALITY_CHANGED: 1227 return VideoCallCallback.EVENT_VIDEO_QUALITY_CHANGED; 1228 case TelephonyConstants.EVENT_VIDEO_DATA_USAGE_CHANGED: 1229 return VideoCallCallback.EVENT_DATA_USAGE_CHANGED; 1230 case TelephonyConstants.EVENT_VIDEO_CAMERA_CAPABILITIES_CHANGED: 1231 return VideoCallCallback.EVENT_CAMERA_CAPABILITIES_CHANGED; 1232 } 1233 Log.d("getVideoCallCallbackEvent: event is invalid."); 1234 return CallCallback.EVENT_INVALID; 1235 } 1236 getVideoCallCallbackEventString(int event)1237 public static String getVideoCallCallbackEventString(int event) { 1238 1239 switch (event) { 1240 case VideoCallCallback.EVENT_SESSION_MODIFY_REQUEST_RECEIVED: 1241 return TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED; 1242 case VideoCallCallback.EVENT_SESSION_MODIFY_RESPONSE_RECEIVED: 1243 return TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED; 1244 case VideoCallCallback.EVENT_SESSION_EVENT: 1245 return TelephonyConstants.EVENT_VIDEO_SESSION_EVENT; 1246 case VideoCallCallback.EVENT_PEER_DIMENSIONS_CHANGED: 1247 return TelephonyConstants.EVENT_VIDEO_PEER_DIMENSIONS_CHANGED; 1248 case VideoCallCallback.EVENT_VIDEO_QUALITY_CHANGED: 1249 return TelephonyConstants.EVENT_VIDEO_QUALITY_CHANGED; 1250 case VideoCallCallback.EVENT_DATA_USAGE_CHANGED: 1251 return TelephonyConstants.EVENT_VIDEO_DATA_USAGE_CHANGED; 1252 case VideoCallCallback.EVENT_CAMERA_CAPABILITIES_CHANGED: 1253 return TelephonyConstants.EVENT_VIDEO_CAMERA_CAPABILITIES_CHANGED; 1254 } 1255 Log.d("getVideoCallCallbackEventString: event is invalid."); 1256 return TelephonyConstants.EVENT_VIDEO_INVALID; 1257 } 1258 getCallStateString(int state)1259 public static String getCallStateString(int state) { 1260 switch (state) { 1261 case Call.STATE_NEW: 1262 return TelephonyConstants.CALL_STATE_NEW; 1263 case Call.STATE_DIALING: 1264 return TelephonyConstants.CALL_STATE_DIALING; 1265 case Call.STATE_RINGING: 1266 return TelephonyConstants.CALL_STATE_RINGING; 1267 case Call.STATE_HOLDING: 1268 return TelephonyConstants.CALL_STATE_HOLDING; 1269 case Call.STATE_ACTIVE: 1270 return TelephonyConstants.CALL_STATE_ACTIVE; 1271 case Call.STATE_DISCONNECTED: 1272 return TelephonyConstants.CALL_STATE_DISCONNECTED; 1273 case Call.STATE_PRE_DIAL_WAIT: 1274 return TelephonyConstants.CALL_STATE_PRE_DIAL_WAIT; 1275 case Call.STATE_CONNECTING: 1276 return TelephonyConstants.CALL_STATE_CONNECTING; 1277 case Call.STATE_DISCONNECTING: 1278 return TelephonyConstants.CALL_STATE_DISCONNECTING; 1279 case STATE_INVALID: 1280 return TelephonyConstants.CALL_STATE_INVALID; 1281 default: 1282 return TelephonyConstants.CALL_STATE_UNKNOWN; 1283 } 1284 } 1285 getAudioRoute(String audioRoute)1286 private static int getAudioRoute(String audioRoute) { 1287 switch (audioRoute.toUpperCase()) { 1288 case TelephonyConstants.AUDIO_ROUTE_BLUETOOTH: 1289 return CallAudioState.ROUTE_BLUETOOTH; 1290 case TelephonyConstants.AUDIO_ROUTE_EARPIECE: 1291 return CallAudioState.ROUTE_EARPIECE; 1292 case TelephonyConstants.AUDIO_ROUTE_SPEAKER: 1293 return CallAudioState.ROUTE_SPEAKER; 1294 case TelephonyConstants.AUDIO_ROUTE_WIRED_HEADSET: 1295 return CallAudioState.ROUTE_WIRED_HEADSET; 1296 case TelephonyConstants.AUDIO_ROUTE_WIRED_OR_EARPIECE: 1297 return CallAudioState.ROUTE_WIRED_OR_EARPIECE; 1298 default: 1299 return INVALID_AUDIO_ROUTE; 1300 } 1301 } 1302 getAudioRouteString(int audioRoute)1303 public static String getAudioRouteString(int audioRoute) { 1304 return CallAudioState.audioRouteToString(audioRoute); 1305 } 1306 getVideoCallSessionEventString(int event)1307 public static String getVideoCallSessionEventString(int event) { 1308 1309 switch (event) { 1310 case Connection.VideoProvider.SESSION_EVENT_RX_PAUSE: 1311 return TelephonyConstants.SESSION_EVENT_RX_PAUSE; 1312 case Connection.VideoProvider.SESSION_EVENT_RX_RESUME: 1313 return TelephonyConstants.SESSION_EVENT_RX_RESUME; 1314 case Connection.VideoProvider.SESSION_EVENT_TX_START: 1315 return TelephonyConstants.SESSION_EVENT_TX_START; 1316 case Connection.VideoProvider.SESSION_EVENT_TX_STOP: 1317 return TelephonyConstants.SESSION_EVENT_TX_STOP; 1318 case Connection.VideoProvider.SESSION_EVENT_CAMERA_FAILURE: 1319 return TelephonyConstants.SESSION_EVENT_CAMERA_FAILURE; 1320 case Connection.VideoProvider.SESSION_EVENT_CAMERA_READY: 1321 return TelephonyConstants.SESSION_EVENT_CAMERA_READY; 1322 default: 1323 return TelephonyConstants.SESSION_EVENT_UNKNOWN; 1324 } 1325 } 1326 getCallCapabilityString(int capability)1327 public static String getCallCapabilityString(int capability) { 1328 switch (capability) { 1329 case Call.Details.CAPABILITY_HOLD: 1330 return TelephonyConstants.CALL_CAPABILITY_HOLD; 1331 case Call.Details.CAPABILITY_SUPPORT_HOLD: 1332 return TelephonyConstants.CALL_CAPABILITY_SUPPORT_HOLD; 1333 case Call.Details.CAPABILITY_MERGE_CONFERENCE: 1334 return TelephonyConstants.CALL_CAPABILITY_MERGE_CONFERENCE; 1335 case Call.Details.CAPABILITY_SWAP_CONFERENCE: 1336 return TelephonyConstants.CALL_CAPABILITY_SWAP_CONFERENCE; 1337 case Call.Details.CAPABILITY_UNUSED_1: 1338 return TelephonyConstants.CALL_CAPABILITY_UNUSED_1; 1339 case Call.Details.CAPABILITY_RESPOND_VIA_TEXT: 1340 return TelephonyConstants.CALL_CAPABILITY_RESPOND_VIA_TEXT; 1341 case Call.Details.CAPABILITY_MUTE: 1342 return TelephonyConstants.CALL_CAPABILITY_MUTE; 1343 case Call.Details.CAPABILITY_MANAGE_CONFERENCE: 1344 return TelephonyConstants.CALL_CAPABILITY_MANAGE_CONFERENCE; 1345 case Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_RX: 1346 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_LOCAL_RX; 1347 case Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX: 1348 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_LOCAL_TX; 1349 case Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL: 1350 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL; 1351 case Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX: 1352 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_REMOTE_RX; 1353 case Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_TX: 1354 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_REMOTE_TX; 1355 case Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL: 1356 return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL; 1357 case Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE: 1358 return TelephonyConstants.CALL_CAPABILITY_SEPARATE_FROM_CONFERENCE; 1359 case Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE: 1360 return TelephonyConstants.CALL_CAPABILITY_DISCONNECT_FROM_CONFERENCE; 1361 case Call.Details.CAPABILITY_SPEED_UP_MT_AUDIO: 1362 return TelephonyConstants.CALL_CAPABILITY_SPEED_UP_MT_AUDIO; 1363 case Call.Details.CAPABILITY_CAN_UPGRADE_TO_VIDEO: 1364 return TelephonyConstants.CALL_CAPABILITY_CAN_UPGRADE_TO_VIDEO; 1365 case Call.Details.CAPABILITY_CAN_PAUSE_VIDEO: 1366 return TelephonyConstants.CALL_CAPABILITY_CAN_PAUSE_VIDEO; 1367 } 1368 return TelephonyConstants.CALL_CAPABILITY_UNKOWN; 1369 } 1370 getCallCapabilitiesString(int capabilities)1371 public static List<String> getCallCapabilitiesString(int capabilities) { 1372 final int[] capabilityConstants = new int[] { 1373 Call.Details.CAPABILITY_HOLD, 1374 Call.Details.CAPABILITY_SUPPORT_HOLD, 1375 Call.Details.CAPABILITY_MERGE_CONFERENCE, 1376 Call.Details.CAPABILITY_SWAP_CONFERENCE, 1377 Call.Details.CAPABILITY_UNUSED_1, 1378 Call.Details.CAPABILITY_RESPOND_VIA_TEXT, 1379 Call.Details.CAPABILITY_MUTE, 1380 Call.Details.CAPABILITY_MANAGE_CONFERENCE, 1381 Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_RX, 1382 Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX, 1383 Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL, 1384 Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX, 1385 Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_TX, 1386 Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL, 1387 Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE, 1388 Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE, 1389 Call.Details.CAPABILITY_SPEED_UP_MT_AUDIO, 1390 Call.Details.CAPABILITY_CAN_UPGRADE_TO_VIDEO, 1391 Call.Details.CAPABILITY_CAN_PAUSE_VIDEO 1392 }; 1393 1394 List<String> capabilityList = new ArrayList<String>(); 1395 1396 for (int capability : capabilityConstants) { 1397 if ((capabilities & capability) == capability) { 1398 capabilityList.add(getCallCapabilityString(capability)); 1399 } 1400 } 1401 return capabilityList; 1402 } 1403 getCallPropertyString(int property)1404 public static String getCallPropertyString(int property) { 1405 1406 switch (property) { 1407 case Call.Details.PROPERTY_CONFERENCE: 1408 return TelephonyConstants.CALL_PROPERTY_CONFERENCE; 1409 case Call.Details.PROPERTY_GENERIC_CONFERENCE: 1410 return TelephonyConstants.CALL_PROPERTY_GENERIC_CONFERENCE; 1411 case Call.Details.PROPERTY_EMERGENCY_CALLBACK_MODE: 1412 return TelephonyConstants.CALL_PROPERTY_EMERGENCY_CALLBACK_MODE; 1413 case Call.Details.PROPERTY_WIFI: 1414 return TelephonyConstants.CALL_PROPERTY_WIFI; 1415 case Call.Details.PROPERTY_HIGH_DEF_AUDIO: 1416 return TelephonyConstants.CALL_PROPERTY_HIGH_DEF_AUDIO; 1417 default: 1418 return TelephonyConstants.CALL_PROPERTY_UNKNOWN; 1419 } 1420 } 1421 getCallPropertiesString(int properties)1422 public static List<String> getCallPropertiesString(int properties) { 1423 final int[] propertyConstants = new int[] { 1424 Call.Details.PROPERTY_CONFERENCE, 1425 Call.Details.PROPERTY_GENERIC_CONFERENCE, 1426 Call.Details.PROPERTY_EMERGENCY_CALLBACK_MODE, 1427 Call.Details.PROPERTY_WIFI, 1428 Call.Details.PROPERTY_HIGH_DEF_AUDIO 1429 }; 1430 1431 List<String> propertyList = new ArrayList<String>(); 1432 1433 for (int property : propertyConstants) { 1434 if ((properties & property) == property) { 1435 propertyList.add(getCallPropertyString(property)); 1436 } 1437 } 1438 1439 return propertyList; 1440 } 1441 getCallPresentationInfoString(int presentation)1442 public static String getCallPresentationInfoString(int presentation) { 1443 switch (presentation) { 1444 case TelecomManager.PRESENTATION_ALLOWED: 1445 return TelephonyConstants.CALL_PRESENTATION_ALLOWED; 1446 case TelecomManager.PRESENTATION_RESTRICTED: 1447 return TelephonyConstants.CALL_PRESENTATION_RESTRICTED; 1448 case TelecomManager.PRESENTATION_PAYPHONE: 1449 return TelephonyConstants.CALL_PRESENTATION_PAYPHONE; 1450 default: 1451 return TelephonyConstants.CALL_PRESENTATION_UNKNOWN; 1452 } 1453 } 1454 } 1455