1 /* 2 * Copyright (C) 2019 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.android.car.telephony.common; 18 19 import android.net.Uri; 20 import android.os.Bundle; 21 import android.telecom.Call; 22 import android.telecom.DisconnectCause; 23 import android.telecom.GatewayInfo; 24 import android.telecom.PhoneAccountHandle; 25 26 import androidx.annotation.NonNull; 27 import androidx.annotation.Nullable; 28 29 /** 30 * Represents details of {@link Call.Details}. 31 */ 32 public class CallDetail { 33 private static final String EXTRA_SCO_STATE = "com.android.bluetooth.hfpclient.SCO_STATE"; 34 35 public static final int STATE_AUDIO_ERROR = -1; 36 public static final int STATE_AUDIO_DISCONNECTED = 0; 37 public static final int STATE_AUDIO_CONNECTING = 1; 38 public static final int STATE_AUDIO_CONNECTED = 2; 39 40 private final String mNumber; 41 private final CharSequence mDisconnectCause; 42 private final Uri mGatewayInfoOriginalAddress; 43 private final long mConnectTimeMillis; 44 private final boolean mIsConference; 45 private final PhoneAccountHandle mPhoneAccountHandle; 46 private final int mScoState; 47 CallDetail(String number, CharSequence disconnectCause, Uri gatewayInfoOriginalAddress, long connectTimeMillis, boolean isConference, PhoneAccountHandle phoneAccountHandle, int scoState)48 private CallDetail(String number, CharSequence disconnectCause, 49 Uri gatewayInfoOriginalAddress, long connectTimeMillis, 50 boolean isConference, PhoneAccountHandle phoneAccountHandle, int scoState) { 51 mNumber = number; 52 mDisconnectCause = disconnectCause; 53 mGatewayInfoOriginalAddress = gatewayInfoOriginalAddress; 54 mConnectTimeMillis = connectTimeMillis; 55 mIsConference = isConference; 56 mPhoneAccountHandle = phoneAccountHandle; 57 mScoState = scoState; 58 } 59 60 /** 61 * Creates an instance of {@link CallDetail} from a {@link Call.Details}. 62 */ fromTelecomCallDetail(@ullable Call.Details callDetail)63 public static CallDetail fromTelecomCallDetail(@Nullable Call.Details callDetail) { 64 return new CallDetail(getNumber(callDetail), getDisconnectCause(callDetail), 65 getGatewayInfoOriginalAddress(callDetail), getConnectTimeMillis(callDetail), 66 isConferenceCall(callDetail), getPhoneAccountHandle(callDetail), 67 getScoState(callDetail)); 68 } 69 70 /** 71 * Returns the phone number. Returns empty string if phone number is not available. 72 */ 73 @NonNull getNumber()74 public String getNumber() { 75 return mNumber; 76 } 77 78 /** 79 * Returns a descriptive reason of disconnect cause. 80 */ 81 @Nullable getDisconnectCause()82 public CharSequence getDisconnectCause() { 83 return mDisconnectCause; 84 } 85 86 /** 87 * Returns the address that the user is trying to connect to via the gateway. 88 */ 89 @Nullable getGatewayInfoOriginalAddress()90 public Uri getGatewayInfoOriginalAddress() { 91 return mGatewayInfoOriginalAddress; 92 } 93 94 /** 95 * Returns the timestamp when the call is connected. Returns 0 if detail is not available. 96 */ getConnectTimeMillis()97 public long getConnectTimeMillis() { 98 return mConnectTimeMillis; 99 } 100 101 /** 102 * Returns whether the call is a conference. 103 */ isConference()104 public boolean isConference() { 105 return mIsConference; 106 } 107 108 /** 109 * Returns the SCO state of the call. 110 */ getScoState()111 public int getScoState() { 112 return mScoState; 113 } 114 115 /** Returns the {@link PhoneAccountHandle} for this call. */ 116 @Nullable getPhoneAccountHandle()117 public PhoneAccountHandle getPhoneAccountHandle() { 118 return mPhoneAccountHandle; 119 } 120 getNumber(Call.Details callDetail)121 private static String getNumber(Call.Details callDetail) { 122 String number = ""; 123 if (callDetail == null) { 124 return number; 125 } 126 127 GatewayInfo gatewayInfo = callDetail.getGatewayInfo(); 128 if (gatewayInfo != null) { 129 number = gatewayInfo.getOriginalAddress().getSchemeSpecificPart(); 130 } else if (callDetail.getHandle() != null) { 131 number = callDetail.getHandle().getSchemeSpecificPart(); 132 } 133 return number; 134 } 135 136 @Nullable getDisconnectCause(Call.Details callDetail)137 private static CharSequence getDisconnectCause(Call.Details callDetail) { 138 DisconnectCause cause = callDetail == null ? null : callDetail.getDisconnectCause(); 139 return cause == null ? null : cause.getLabel(); 140 } 141 142 @Nullable getGatewayInfoOriginalAddress(Call.Details callDetail)143 private static Uri getGatewayInfoOriginalAddress(Call.Details callDetail) { 144 return callDetail != null && callDetail.getGatewayInfo() != null 145 ? callDetail.getGatewayInfo().getOriginalAddress() 146 : null; 147 } 148 getConnectTimeMillis(Call.Details callDetail)149 private static long getConnectTimeMillis(Call.Details callDetail) { 150 return callDetail == null ? 0 : callDetail.getConnectTimeMillis(); 151 } 152 isConferenceCall(Call.Details callDetail)153 private static boolean isConferenceCall(Call.Details callDetail) { 154 return callDetail != null && callDetail.hasProperty(Call.Details.PROPERTY_CONFERENCE); 155 } 156 157 @Nullable getPhoneAccountHandle(Call.Details callDetail)158 private static PhoneAccountHandle getPhoneAccountHandle(Call.Details callDetail) { 159 return callDetail == null ? null : callDetail.getAccountHandle(); 160 } 161 getScoState(Call.Details callDetail)162 private static int getScoState(Call.Details callDetail) { 163 int state = STATE_AUDIO_ERROR; 164 if (callDetail != null) { 165 Bundle extras = callDetail.getExtras(); 166 if (extras != null && extras.containsKey(EXTRA_SCO_STATE)) { 167 state = extras.getInt(EXTRA_SCO_STATE); 168 } 169 } 170 return state; 171 } 172 } 173