Connection.java revision dc2b5d1c32cad5269106d00fd106bd64097238f4
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.telephony; 18 19import android.os.SystemClock; 20import android.telephony.Rlog; 21import android.util.Log; 22 23import java.lang.Override; 24import java.util.ArrayList; 25import java.util.List; 26import java.util.Set; 27import java.util.concurrent.CopyOnWriteArraySet; 28 29/** 30 * {@hide} 31 */ 32public abstract class Connection { 33 public interface PostDialListener { 34 void onPostDialWait(); 35 } 36 37 /** 38 * Listener interface for events related to the connection which should be reported to the 39 * {@link android.telecom.Connection}. 40 */ 41 public interface Listener { 42 public void onVideoStateChanged(int videoState); 43 public void onLocalVideoCapabilityChanged(boolean capable); 44 public void onRemoteVideoCapabilityChanged(boolean capable); 45 public void onVideoProviderChanged( 46 android.telecom.Connection.VideoProvider videoProvider); 47 public void onAudioQualityChanged(int audioQuality); 48 } 49 50 /** 51 * Base listener implementation. 52 */ 53 public abstract static class ListenerBase implements Listener { 54 @Override 55 public void onVideoStateChanged(int videoState) {} 56 @Override 57 public void onLocalVideoCapabilityChanged(boolean capable) {} 58 @Override 59 public void onRemoteVideoCapabilityChanged(boolean capable) {} 60 @Override 61 public void onVideoProviderChanged( 62 android.telecom.Connection.VideoProvider videoProvider) {} 63 @Override 64 public void onAudioQualityChanged(int audioQuality) {} 65 } 66 67 public static final int AUDIO_QUALITY_STANDARD = 1; 68 public static final int AUDIO_QUALITY_HIGH_DEFINITION = 2; 69 70 //Caller Name Display 71 protected String mCnapName; 72 protected int mCnapNamePresentation = PhoneConstants.PRESENTATION_ALLOWED; 73 protected String mAddress; // MAY BE NULL!!! 74 protected String mDialString; // outgoing calls only 75 protected int mNumberPresentation = PhoneConstants.PRESENTATION_ALLOWED; 76 protected boolean mIsIncoming; 77 /* 78 * These time/timespan values are based on System.currentTimeMillis(), 79 * i.e., "wall clock" time. 80 */ 81 protected long mCreateTime; 82 protected long mConnectTime; 83 /* 84 * These time/timespan values are based on SystemClock.elapsedRealTime(), 85 * i.e., time since boot. They are appropriate for comparison and 86 * calculating deltas. 87 */ 88 protected long mConnectTimeReal; 89 protected long mDuration; 90 protected long mHoldingStartTime; // The time when the Connection last transitioned 91 // into HOLDING 92 protected Connection mOrigConnection; 93 private List<PostDialListener> mPostDialListeners = new ArrayList<>(); 94 public Set<Listener> mListeners = new CopyOnWriteArraySet<>(); 95 96 private static String LOG_TAG = "Connection"; 97 98 Object mUserData; 99 private int mVideoState; 100 private boolean mLocalVideoCapable; 101 private boolean mRemoteVideoCapable; 102 private int mAudioQuality; 103 private android.telecom.Connection.VideoProvider mVideoProvider; 104 105 /* Instance Methods */ 106 107 /** 108 * Gets address (e.g. phone number) associated with connection. 109 * TODO: distinguish reasons for unavailability 110 * 111 * @return address or null if unavailable 112 */ 113 114 public String getAddress() { 115 return mAddress; 116 } 117 118 /** 119 * Gets CNAP name associated with connection. 120 * @return cnap name or null if unavailable 121 */ 122 public String getCnapName() { 123 return mCnapName; 124 } 125 126 /** 127 * Get original dial string. 128 * @return original dial string or null if unavailable 129 */ 130 public String getOrigDialString(){ 131 return null; 132 } 133 134 /** 135 * Gets CNAP presentation associated with connection. 136 * @return cnap name or null if unavailable 137 */ 138 139 public int getCnapNamePresentation() { 140 return mCnapNamePresentation; 141 } 142 143 /** 144 * @return Call that owns this Connection, or null if none 145 */ 146 public abstract Call getCall(); 147 148 /** 149 * Connection create time in currentTimeMillis() format 150 * Basically, set when object is created. 151 * Effectively, when an incoming call starts ringing or an 152 * outgoing call starts dialing 153 */ 154 public long getCreateTime() { 155 return mCreateTime; 156 } 157 158 /** 159 * Connection connect time in currentTimeMillis() format. 160 * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition. 161 * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition. 162 * Returns 0 before then. 163 */ 164 public long getConnectTime() { 165 return mConnectTime; 166 } 167 168 /** 169 * Connection connect time in elapsedRealtime() format. 170 * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition. 171 * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition. 172 * Returns 0 before then. 173 */ 174 public long getConnectTimeReal() { 175 return mConnectTimeReal; 176 } 177 178 /** 179 * Disconnect time in currentTimeMillis() format. 180 * The time when this Connection makes a transition into ENDED or FAIL. 181 * Returns 0 before then. 182 */ 183 public abstract long getDisconnectTime(); 184 185 /** 186 * Returns the number of milliseconds the call has been connected, 187 * or 0 if the call has never connected. 188 * If the call is still connected, then returns the elapsed 189 * time since connect. 190 */ 191 public long getDurationMillis() { 192 if (mConnectTimeReal == 0) { 193 return 0; 194 } else if (mDuration == 0) { 195 return SystemClock.elapsedRealtime() - mConnectTimeReal; 196 } else { 197 return mDuration; 198 } 199 } 200 201 /** 202 * The time when this Connection last transitioned into HOLDING 203 * in elapsedRealtime() format. 204 * Returns 0, if it has never made a transition into HOLDING. 205 */ 206 public long getHoldingStartTime() { 207 return mHoldingStartTime; 208 } 209 210 /** 211 * If this connection is HOLDING, return the number of milliseconds 212 * that it has been on hold for (approximately). 213 * If this connection is in any other state, return 0. 214 */ 215 216 public abstract long getHoldDurationMillis(); 217 218 /** 219 * Returns call disconnect cause. Values are defined in 220 * {@link android.telephony.DisconnectCause}. If the call is not yet 221 * disconnected, NOT_DISCONNECTED is returned. 222 */ 223 public abstract int getDisconnectCause(); 224 225 /** 226 * Returns true of this connection originated elsewhere 227 * ("MT" or mobile terminated; another party called this terminal) 228 * or false if this call originated here (MO or mobile originated). 229 */ 230 public boolean isIncoming() { 231 return mIsIncoming; 232 } 233 234 /** 235 * If this Connection is connected, then it is associated with 236 * a Call. 237 * 238 * Returns getCall().getState() or Call.State.IDLE if not 239 * connected 240 */ 241 public Call.State getState() { 242 Call c; 243 244 c = getCall(); 245 246 if (c == null) { 247 return Call.State.IDLE; 248 } else { 249 return c.getState(); 250 } 251 } 252 253 /** 254 * isAlive() 255 * 256 * @return true if the connection isn't disconnected 257 * (could be active, holding, ringing, dialing, etc) 258 */ 259 public boolean 260 isAlive() { 261 return getState().isAlive(); 262 } 263 264 /** 265 * Returns true if Connection is connected and is INCOMING or WAITING 266 */ 267 public boolean 268 isRinging() { 269 return getState().isRinging(); 270 } 271 272 /** 273 * 274 * @return the userdata set in setUserData() 275 */ 276 public Object getUserData() { 277 return mUserData; 278 } 279 280 /** 281 * 282 * @param userdata user can store an any userdata in the Connection object. 283 */ 284 public void setUserData(Object userdata) { 285 mUserData = userdata; 286 } 287 288 /** 289 * Hangup individual Connection 290 */ 291 public abstract void hangup() throws CallStateException; 292 293 /** 294 * Separate this call from its owner Call and assigns it to a new Call 295 * (eg if it is currently part of a Conference call 296 * TODO: Throw exception? Does GSM require error display on failure here? 297 */ 298 public abstract void separate() throws CallStateException; 299 300 public enum PostDialState { 301 NOT_STARTED, /* The post dial string playback hasn't 302 been started, or this call is not yet 303 connected, or this is an incoming call */ 304 STARTED, /* The post dial string playback has begun */ 305 WAIT, /* The post dial string playback is waiting for a 306 call to proceedAfterWaitChar() */ 307 WILD, /* The post dial string playback is waiting for a 308 call to proceedAfterWildChar() */ 309 COMPLETE, /* The post dial string playback is complete */ 310 CANCELLED, /* The post dial string playback was cancelled 311 with cancelPostDial() */ 312 PAUSE /* The post dial string playback is pausing for a 313 call to processNextPostDialChar*/ 314 } 315 316 public void clearUserData(){ 317 mUserData = null; 318 } 319 320 public final void addPostDialListener(PostDialListener listener) { 321 if (!mPostDialListeners.contains(listener)) { 322 mPostDialListeners.add(listener); 323 } 324 } 325 326 protected final void clearPostDialListeners() { 327 mPostDialListeners.clear(); 328 } 329 330 protected final void notifyPostDialListeners() { 331 if (getPostDialState() == PostDialState.WAIT) { 332 for (PostDialListener listener : new ArrayList<>(mPostDialListeners)) { 333 listener.onPostDialWait(); 334 } 335 } 336 } 337 338 public abstract PostDialState getPostDialState(); 339 340 /** 341 * Returns the portion of the post dial string that has not 342 * yet been dialed, or "" if none 343 */ 344 public abstract String getRemainingPostDialString(); 345 346 /** 347 * See Phone.setOnPostDialWaitCharacter() 348 */ 349 350 public abstract void proceedAfterWaitChar(); 351 352 /** 353 * See Phone.setOnPostDialWildCharacter() 354 */ 355 public abstract void proceedAfterWildChar(String str); 356 /** 357 * Cancel any post 358 */ 359 public abstract void cancelPostDial(); 360 361 /** 362 * Returns the caller id presentation type for incoming and waiting calls 363 * @return one of PRESENTATION_* 364 */ 365 public abstract int getNumberPresentation(); 366 367 /** 368 * Returns the User to User Signaling (UUS) information associated with 369 * incoming and waiting calls 370 * @return UUSInfo containing the UUS userdata. 371 */ 372 public abstract UUSInfo getUUSInfo(); 373 374 /** 375 * Returns the CallFail reason provided by the RIL with the result of 376 * RIL_REQUEST_LAST_CALL_FAIL_CAUSE 377 */ 378 public abstract int getPreciseDisconnectCause(); 379 380 /** 381 * Returns the original Connection instance associated with 382 * this Connection 383 */ 384 public Connection getOrigConnection() { 385 return mOrigConnection; 386 } 387 388 /** 389 * Returns whether the original ImsPhoneConnection was a member 390 * of a conference call 391 * @return valid only when getOrigConnection() is not null 392 */ 393 public abstract boolean isMultiparty(); 394 395 public void migrateFrom(Connection c) { 396 if (c == null) return; 397 mListeners = c.mListeners; 398 mAddress = c.getAddress(); 399 mNumberPresentation = c.getNumberPresentation(); 400 mDialString = c.getOrigDialString(); 401 mCnapName = c.getCnapName(); 402 mCnapNamePresentation = c.getCnapNamePresentation(); 403 mIsIncoming = c.isIncoming(); 404 mCreateTime = c.getCreateTime(); 405 mConnectTime = c.getConnectTime(); 406 mConnectTimeReal = c.getConnectTimeReal(); 407 mHoldingStartTime = c.getHoldingStartTime(); 408 mOrigConnection = c.getOrigConnection(); 409 } 410 411 /** 412 * Assign a listener to be notified of state changes. 413 * 414 * @param listener A listener. 415 */ 416 public final void addListener(Listener listener) { 417 mListeners.add(listener); 418 } 419 420 /** 421 * Removes a listener. 422 * 423 * @param listener A listener. 424 */ 425 public final void removeListener(Listener listener) { 426 mListeners.remove(listener); 427 } 428 429 /** 430 * Returns the current video state of the connection. 431 * 432 * @return The video state of the connection. 433 */ 434 public int getVideoState() { 435 return mVideoState; 436 } 437 438 /** 439 * Returns the local video capability state for the connection. 440 * 441 * @return {@code True} if the connection has local video capabilities. 442 */ 443 public boolean isLocalVideoCapable() { 444 return mLocalVideoCapable; 445 } 446 447 /** 448 * Returns the remote video capability state for the connection. 449 * 450 * @return {@code True} if the connection has remote video capabilities. 451 */ 452 public boolean isRemoteVideoCapable() { 453 return mRemoteVideoCapable; 454 } 455 456 /** 457 * Returns the {@link android.telecom.Connection.VideoProvider} for the connection. 458 * 459 * @return The {@link android.telecom.Connection.VideoProvider}. 460 */ 461 public android.telecom.Connection.VideoProvider getVideoProvider() { 462 return mVideoProvider; 463 } 464 465 /** 466 * Returns the audio-quality for the connection. 467 * 468 * @return The audio quality for the connection. 469 */ 470 public int getAudioQuality() { 471 return mAudioQuality; 472 } 473 474 /** 475 * Sets the videoState for the current connection and reports the changes to all listeners. 476 * Valid video states are defined in {@link android.telecom.VideoProfile}. 477 * 478 * @return The video state. 479 */ 480 public void setVideoState(int videoState) { 481 mVideoState = videoState; 482 for (Listener l : mListeners) { 483 l.onVideoStateChanged(mVideoState); 484 } 485 } 486 487 /** 488 * Sets whether video capability is present locally. 489 * 490 * @param capable {@code True} if video capable. 491 */ 492 public void setLocalVideoCapable(boolean capable) { 493 mLocalVideoCapable = capable; 494 for (Listener l : mListeners) { 495 l.onLocalVideoCapabilityChanged(mLocalVideoCapable); 496 } 497 } 498 499 /** 500 * Sets whether video capability is present remotely. 501 * 502 * @param capable {@code True} if video capable. 503 */ 504 public void setRemoteVideoCapable(boolean capable) { 505 mRemoteVideoCapable = capable; 506 for (Listener l : mListeners) { 507 l.onRemoteVideoCapabilityChanged(mRemoteVideoCapable); 508 } 509 } 510 511 /** 512 * Set the audio quality for the connection. 513 * 514 * @param audioQuality The audio quality. 515 */ 516 public void setAudioQuality(int audioQuality) { 517 mAudioQuality = audioQuality; 518 for (Listener l : mListeners) { 519 l.onAudioQualityChanged(mAudioQuality); 520 } 521 } 522 523 /** 524 * Sets the {@link android.telecom.Connection.VideoProvider} for the connection. 525 * 526 * @param videoProvider The video call provider. 527 */ 528 public void setVideoProvider(android.telecom.Connection.VideoProvider videoProvider) { 529 mVideoProvider = videoProvider; 530 for (Listener l : mListeners) { 531 l.onVideoProviderChanged(mVideoProvider); 532 } 533 } 534 535 /** 536 * Build a human representation of a connection instance, suitable for debugging. 537 * Don't log personal stuff unless in debug mode. 538 * @return a string representing the internal state of this connection. 539 */ 540 public String toString() { 541 StringBuilder str = new StringBuilder(128); 542 543 if (Rlog.isLoggable(LOG_TAG, Log.DEBUG)) { 544 str.append("addr: " + getAddress()) 545 .append(" pres.: " + getNumberPresentation()) 546 .append(" dial: " + getOrigDialString()) 547 .append(" postdial: " + getRemainingPostDialString()) 548 .append(" cnap name: " + getCnapName()) 549 .append("(" + getCnapNamePresentation() + ")"); 550 } 551 str.append(" incoming: " + isIncoming()) 552 .append(" state: " + getState()) 553 .append(" post dial state: " + getPostDialState()); 554 return str.toString(); 555 } 556} 557