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