Merge "Fixing Google Voice to work with new incallui" into klp-dev
diff --git a/common/src/com/android/services/telephony/common/Call.java b/common/src/com/android/services/telephony/common/Call.java
index 994d9d2..4c68913 100644
--- a/common/src/com/android/services/telephony/common/Call.java
+++ b/common/src/com/android/services/telephony/common/Call.java
@@ -57,6 +57,20 @@
public static final int ONHOLD = 6; /* An active phone call placed on hold */
public static final int DISCONNECTED = 7; /* State after a call disconnects */
public static final int CONFERENCED = 8; /* Call part of a conference call */
+
+ public static boolean isConnected(int state) {
+ switch(state) {
+ case ACTIVE:
+ case INCOMING:
+ case CALL_WAITING:
+ case DIALING:
+ case ONHOLD:
+ case CONFERENCED:
+ return true;
+ default:
+ }
+ return false;
+ }
}
/**
@@ -174,6 +188,12 @@
// List of call Ids for for this call. (Used for managing conference calls).
private SortedSet<Integer> mChildCallIds = Sets.newSortedSet();
+ // Gateway number used to dial this call
+ private String mGatewayNumber;
+
+ // Gateway service package name
+ private String mGatewayPackage;
+
public Call(int callId) {
mCallId = callId;
}
@@ -278,6 +298,22 @@
return mChildCallIds.size() >= 2;
}
+ public String getGatewayNumber() {
+ return mGatewayNumber;
+ }
+
+ public void setGatewayNumber(String number) {
+ mGatewayNumber = number;
+ }
+
+ public String getGatewayPackage() {
+ return mGatewayPackage;
+ }
+
+ public void setGatewayPackage(String packageName) {
+ mGatewayPackage = packageName;
+ }
+
/**
* Parcelable implementation
*/
@@ -294,6 +330,8 @@
dest.writeInt(getCapabilities());
dest.writeLong(getConnectTime());
dest.writeIntArray(Ints.toArray(mChildCallIds));
+ dest.writeString(getGatewayNumber());
+ dest.writeString(getGatewayPackage());
}
/**
@@ -310,6 +348,8 @@
mCapabilities = in.readInt();
mConnectTime = in.readLong();
mChildCallIds.addAll(Ints.asList(in.createIntArray()));
+ mGatewayNumber = in.readString();
+ mGatewayPackage = in.readString();
}
@Override
@@ -336,9 +376,19 @@
@Override
public String toString() {
+ return toString(true);
+ }
+
+ public String toString(boolean safe) {
StringBuffer buffer = new StringBuffer();
buffer.append("callId: ");
buffer.append(mCallId);
+ if (!safe) {
+ buffer.append(", number: ");
+ buffer.append(mNumber);
+ buffer.append(", name: ");
+ buffer.append(mCnapName);
+ }
buffer.append(", state: ");
buffer.append(STATE_MAP.get(mState));
buffer.append(", disconnect_cause: ");
@@ -349,8 +399,14 @@
final long duration = System.currentTimeMillis() - getConnectTime();
buffer.append(", elapsedTime: ");
buffer.append(DateUtils.formatElapsedTime(duration / 1000));
+
buffer.append(", childCalls: ");
buffer.append(mChildCallIds.toString());
+ buffer.append(", gateway: ");
+ if (!safe) {
+ buffer.append(mGatewayNumber);
+ }
+ buffer.append(" [").append(mGatewayPackage).append("]");
return buffer.toString();
}
diff --git a/common/src/com/android/services/telephony/common/ICallHandlerService.aidl b/common/src/com/android/services/telephony/common/ICallHandlerService.aidl
index 4b6f913..df2e2de 100644
--- a/common/src/com/android/services/telephony/common/ICallHandlerService.aidl
+++ b/common/src/com/android/services/telephony/common/ICallHandlerService.aidl
@@ -31,7 +31,7 @@
oneway interface ICallHandlerService {
/**
- * Hands a command interface to the CallMonitorService through which
+ * Hands a command interface to the CallHandlerService through which
* the call monitor can control the phone calls.
*/
void setCallCommandService(ICallCommandService callCommandService);
diff --git a/src/com/android/phone/CallCard.java b/src/com/android/phone/CallCard.java
index fcef7f3..22215c0 100644
--- a/src/com/android/phone/CallCard.java
+++ b/src/com/android/phone/CallCard.java
@@ -101,14 +101,6 @@
/** Secondary "call info" block (the background "on hold" call) */
private ViewStub mSecondaryCallInfo;
- /**
- * Container for both provider info and call state. This will take care of showing/hiding
- * animation for those views.
- */
- private ViewGroup mSecondaryInfoContainer;
- private ViewGroup mProviderInfo;
- private TextView mProviderLabel;
- private TextView mProviderAddress;
// "Call state" widgets
private TextView mCallStateLabel;
@@ -217,10 +209,6 @@
mPrimaryCallInfo = (ViewGroup) findViewById(R.id.primary_call_info);
mPrimaryCallBanner = (ViewGroup) findViewById(R.id.primary_call_banner);
- mSecondaryInfoContainer = (ViewGroup) findViewById(R.id.secondary_info_container);
- mProviderInfo = (ViewGroup) findViewById(R.id.providerInfo);
- mProviderLabel = (TextView) findViewById(R.id.providerLabel);
- mProviderAddress = (TextView) findViewById(R.id.providerAddress);
mCallStateLabel = (TextView) findViewById(R.id.callStateLabel);
mElapsedTime = (TextView) findViewById(R.id.elapsedTime);
@@ -418,8 +406,6 @@
private void updateAlreadyDisconnected(CallManager cm) {
// For the foreground call, we manually set up every component based on previous state.
mPrimaryCallInfo.setVisibility(View.VISIBLE);
- mSecondaryInfoContainer.setLayoutTransition(null);
- mProviderInfo.setVisibility(View.GONE);
mCallStateLabel.setVisibility(View.VISIBLE);
mCallStateLabel.setText(mContext.getString(R.string.card_title_call_ended));
mElapsedTime.setVisibility(View.VISIBLE);
@@ -829,8 +815,7 @@
final InCallUiState inCallUiState = mApplication.inCallUiState;
if (DBG) {
log("==> callStateLabel: '" + callStateLabel
- + "', bluetoothIconId = " + bluetoothIconId
- + ", providerInfoVisible = " + inCallUiState.providerInfoVisible);
+ + "', bluetoothIconId = " + bluetoothIconId);
}
// Animation will be done by mCallerDetail's LayoutTransition, but in some cases, we don't
@@ -841,22 +826,6 @@
|| state == Call.State.DISCONNECTING
|| state == Call.State.DISCONNECTED);
LayoutTransition layoutTransition = null;
- if (skipAnimation) {
- // Evict LayoutTransition object to skip animation.
- layoutTransition = mSecondaryInfoContainer.getLayoutTransition();
- mSecondaryInfoContainer.setLayoutTransition(null);
- }
-
- if (inCallUiState.providerInfoVisible) {
- mProviderInfo.setVisibility(View.VISIBLE);
- mProviderLabel.setText(context.getString(R.string.calling_via_template,
- inCallUiState.providerLabel));
- mProviderAddress.setText(inCallUiState.providerAddress);
-
- mInCallScreen.requestRemoveProviderInfoWithDelay();
- } else {
- mProviderInfo.setVisibility(View.GONE);
- }
if (!TextUtils.isEmpty(callStateLabel)) {
mCallStateLabel.setVisibility(View.VISIBLE);
@@ -881,10 +850,6 @@
mCallStateLabel.setGravity(Gravity.END);
}
}
- if (skipAnimation) {
- // Restore LayoutTransition object to recover animation.
- mSecondaryInfoContainer.setLayoutTransition(layoutTransition);
- }
// ...and update the elapsed time widget too.
switch (state) {
diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
index 7b889de..1b19d9a 100644
--- a/src/com/android/phone/CallController.java
+++ b/src/com/android/phone/CallController.java
@@ -20,6 +20,7 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.phone.CallGatewayManager.RawGatewayInfo;
import com.android.phone.Constants.CallStatusCode;
import com.android.phone.InCallUiState.InCallScreenMode;
import com.android.phone.OtaUtils.CdmaOtaScreenState;
@@ -69,9 +70,10 @@
/** The singleton CallController instance. */
private static CallController sInstance;
- private PhoneGlobals mApp;
- private CallManager mCM;
- private CallLogger mCallLogger;
+ final private PhoneGlobals mApp;
+ final private CallManager mCM;
+ final private CallLogger mCallLogger;
+ final private CallGatewayManager mCallGatewayManager;
/** Helper object for emergency calls in some rare use cases. Created lazily. */
private EmergencyCallHelper mEmergencyCallHelper;
@@ -102,10 +104,11 @@
* PhoneApp's public "callController" field, which is why there's no
* getInstance() method here.
*/
- /* package */ static CallController init(PhoneGlobals app, CallLogger callLogger) {
+ /* package */ static CallController init(PhoneGlobals app, CallLogger callLogger,
+ CallGatewayManager callGatewayManager) {
synchronized (CallController.class) {
if (sInstance == null) {
- sInstance = new CallController(app, callLogger);
+ sInstance = new CallController(app, callLogger, callGatewayManager);
} else {
Log.wtf(TAG, "init() called multiple times! sInstance = " + sInstance);
}
@@ -117,11 +120,13 @@
* Private constructor (this is a singleton).
* @see init()
*/
- private CallController(PhoneGlobals app, CallLogger callLogger) {
+ private CallController(PhoneGlobals app, CallLogger callLogger,
+ CallGatewayManager callGatewayManager) {
if (DBG) log("CallController constructor: app = " + app);
mApp = app;
mCM = app.mCM;
mCallLogger = callLogger;
+ mCallGatewayManager = callGatewayManager;
}
@Override
@@ -243,15 +248,6 @@
// by the PhoneUtils phone state change handler.)
mApp.setRestoreMuteOnInCallResume(false);
- // If a provider is used, extract the info to build the
- // overlay and route the call. The overlay will be
- // displayed when the InCallScreen becomes visible.
- if (PhoneUtils.hasPhoneProviderExtras(intent)) {
- inCallUiState.setProviderInfo(intent);
- } else {
- inCallUiState.clearProviderInfo();
- }
-
CallStatusCode status = placeCallInternal(intent);
switch (status) {
@@ -477,6 +473,9 @@
// phone number to use for the outgoing call.
Uri contactUri = intent.getData();
+ // If a gateway is used, extract the data here and pass that into placeCall.
+ final RawGatewayInfo rawGatewayInfo = mCallGatewayManager.getRawGatewayInfo(intent, number);
+
// Watch out: PhoneUtils.placeCall() returns one of the
// CALL_STATUS_* constants, not a CallStatusCode enum value.
int callStatus = PhoneUtils.placeCall(mApp,
@@ -484,7 +483,8 @@
number,
contactUri,
(isEmergencyNumber || isEmergencyIntent),
- inCallUiState.providerGatewayUri);
+ rawGatewayInfo,
+ mCallGatewayManager);
switch (callStatus) {
case PhoneUtils.CALL_STATUS_DIALED:
diff --git a/src/com/android/phone/CallGatewayManager.java b/src/com/android/phone/CallGatewayManager.java
new file mode 100644
index 0000000..6fe2444
--- /dev/null
+++ b/src/com/android/phone/CallGatewayManager.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.telephony.Connection;
+import com.google.android.collect.Maps;
+
+import java.util.HashMap;
+
+/**
+ * This class manages gateway information for outgoing calls. When calls are made, they may contain
+ * gateway information for services which route phone calls through their own service/numbers.
+ * The data consists of a number to call and the package name of the service. This data is used in
+ * two ways:<br/>
+ * 1. Call the appropriate routing number<br/>
+ * 2. Display information about the routing to the user<br/>
+ *
+ * <p>When an outgoing call is finally placed in PhoneUtils.placeCall, it uses this class to get the
+ * proper number to dial. It also saves an association between the connection object and the gateway
+ * data into this class. This association is later used in CallModeler when building Call objects
+ * to send to the UI which require the gateway data to show an alert to users.
+ */
+public class CallGatewayManager {
+ private static final String LOG_TAG = CallGatewayManager.class.getSimpleName();
+
+ /**
+ * Intent extra to specify the package name of the gateway
+ * provider. Used to get the name displayed in the in-call screen
+ * during the call setup. The value is a string.
+ */
+ // TODO: This extra is currently set by the gateway application as
+ // a temporary measure. Ultimately, the framework will securely
+ // set it.
+ /* package */ static final String EXTRA_GATEWAY_PROVIDER_PACKAGE =
+ "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE";
+
+ /**
+ * Intent extra to specify the URI of the provider to place the
+ * call. The value is a string. It holds the gateway address
+ * (phone gateway URL should start with the 'tel:' scheme) that
+ * will actually be contacted to call the number passed in the
+ * intent URL or in the EXTRA_PHONE_NUMBER extra.
+ */
+ // TODO: Should the value be a Uri (Parcelable)? Need to make sure
+ // MMI code '#' don't get confused as URI fragments.
+ /* package */ static final String EXTRA_GATEWAY_URI =
+ "com.android.phone.extra.GATEWAY_URI";
+
+ public static final RawGatewayInfo EMPTY_INFO = new RawGatewayInfo(null, null, null);
+
+ private final HashMap<Connection, RawGatewayInfo> mMap = Maps.newHashMap();
+
+ public CallGatewayManager() {
+ }
+
+ /**
+ * Static method returns an object containing the gateway data stored in the extras of the
+ * Intent parameter. If no such data exists, returns a Null-Object RawGatewayInfo.
+ * @param intent The intent from which to read gateway data.
+ * @return A populated or empty RawGatewayInfo object.
+ */
+ public static RawGatewayInfo getRawGatewayInfo(Intent intent, String number) {
+ if (hasPhoneProviderExtras(intent)) {
+ return new RawGatewayInfo(intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE),
+ getProviderGatewayUri(intent), number);
+ }
+ return EMPTY_INFO;
+ }
+
+ /**
+ * This function sets the current mapping from connection to gatewayInfo so that CallModeler
+ * can request this data when creating Call objects.
+ * @param connection The connection object for the placed outgoing call.
+ * @param gatewayInfo Gateway info gathered using getRawGatewayInfo.
+ */
+ public void setGatewayInfoForConnection(Connection connection, RawGatewayInfo gatewayInfo) {
+ if (!gatewayInfo.isEmpty()) {
+ mMap.put(connection, gatewayInfo);
+ } else {
+ mMap.remove(connection);
+ }
+ }
+
+ /**
+ * Clears the gateway information previously stored via setGatewayInfoForConnection.
+ */
+ public void clearGatewayData(Connection connection) {
+ setGatewayInfoForConnection(connection, EMPTY_INFO);
+ }
+
+ /**
+ * If the parameter matches the connection object we previously saved through
+ * setGatewayInfoForConnection, return the associated raw gateway info data. If not, then
+ * return an empty raw gateway info.
+ */
+ public RawGatewayInfo getGatewayInfo(Connection connection) {
+ final RawGatewayInfo info = mMap.get(connection);
+ if (info != null) {
+ return info;
+ }
+
+ return EMPTY_INFO;
+ }
+
+ /**
+ * Check if all the provider's info is present in the intent.
+ * @param intent Expected to have the provider's extra.
+ * @return true if the intent has all the extras to build the
+ * in-call screen's provider info overlay.
+ */
+ public static boolean hasPhoneProviderExtras(Intent intent) {
+ if (null == intent) {
+ return false;
+ }
+ final String name = intent.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE);
+ final String gatewayUri = intent.getStringExtra(EXTRA_GATEWAY_URI);
+
+ return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(gatewayUri);
+ }
+
+ /**
+ * Copy all the expected extras set when a 3rd party provider is
+ * used from the source intent to the destination one. Checks all
+ * the required extras are present, if any is missing, none will
+ * be copied.
+ * @param src Intent which may contain the provider's extras.
+ * @param dst Intent where a copy of the extras will be added if applicable.
+ */
+ public static void checkAndCopyPhoneProviderExtras(Intent src, Intent dst) {
+ if (!hasPhoneProviderExtras(src)) {
+ Log.d(LOG_TAG, "checkAndCopyPhoneProviderExtras: some or all extras are missing.");
+ return;
+ }
+
+ dst.putExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE,
+ src.getStringExtra(EXTRA_GATEWAY_PROVIDER_PACKAGE));
+ dst.putExtra(EXTRA_GATEWAY_URI,
+ src.getStringExtra(EXTRA_GATEWAY_URI));
+ }
+
+ /**
+ * Return the gateway uri from the intent.
+ * @param intent With the gateway uri extra.
+ * @return The gateway URI or null if not found.
+ */
+ public static Uri getProviderGatewayUri(Intent intent) {
+ final String uri = intent.getStringExtra(EXTRA_GATEWAY_URI);
+ return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
+ }
+
+ /**
+ * Return a formatted version of the uri's scheme specific
+ * part. E.g for 'tel:12345678', return '1-234-5678'.
+ * @param uri A 'tel:' URI with the gateway phone number.
+ * @return the provider's address (from the gateway uri) formatted
+ * for user display. null if uri was null or its scheme was not 'tel:'.
+ */
+ public static String formatProviderUri(Uri uri) {
+ if (uri != null) {
+ if (Constants.SCHEME_TEL.equals(uri.getScheme())) {
+ return PhoneNumberUtils.formatNumber(uri.getSchemeSpecificPart());
+ } else {
+ return uri.toString();
+ }
+ }
+ return null;
+ }
+
+ public static class RawGatewayInfo {
+ public String packageName;
+ public Uri gatewayUri;
+ public String trueNumber;
+
+ public RawGatewayInfo(String packageName, Uri gatewayUri,
+ String trueNumber) {
+ this.packageName = packageName;
+ this.gatewayUri = gatewayUri;
+ this.trueNumber = trueNumber;
+ }
+
+ public String getFormattedGatewayNumber() {
+ return formatProviderUri(gatewayUri);
+ }
+
+ public boolean isEmpty() {
+ return TextUtils.isEmpty(packageName) || gatewayUri == null;
+ }
+ }
+}
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
index 89dcb21..a5e2044 100644
--- a/src/com/android/phone/CallModeler.java
+++ b/src/com/android/phone/CallModeler.java
@@ -35,6 +35,7 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.phone.CallGatewayManager.RawGatewayInfo;
import com.android.services.telephony.common.Call;
import com.android.services.telephony.common.Call.Capabilities;
import com.android.services.telephony.common.Call.State;
@@ -84,6 +85,7 @@
private final CallStateMonitor mCallStateMonitor;
private final CallManager mCallManager;
+ private final CallGatewayManager mCallGatewayManager;
private final HashMap<Connection, Call> mCallMap = Maps.newHashMap();
private final HashMap<Connection, Call> mConfCallMap = Maps.newHashMap();
private final AtomicInteger mNextCallId = new AtomicInteger(CALL_ID_START_VALUE);
@@ -91,10 +93,12 @@
private RejectWithTextMessageManager mRejectWithTextMessageManager;
public CallModeler(CallStateMonitor callStateMonitor, CallManager callManager,
- RejectWithTextMessageManager rejectWithTextMessageManager) {
+ RejectWithTextMessageManager rejectWithTextMessageManager,
+ CallGatewayManager callGatewayManager) {
mCallStateMonitor = callStateMonitor;
mCallManager = callManager;
mRejectWithTextMessageManager = rejectWithTextMessageManager;
+ mCallGatewayManager = callGatewayManager;
mCallStateMonitor.addListener(this);
}
@@ -330,6 +334,29 @@
}
/**
+ * Sets the new call state onto the call and performs some additional logic
+ * associated with setting the state.
+ */
+ private void setNewState(Call call, int newState, Connection connection) {
+ Preconditions.checkState(call.getState() != newState);
+
+ // When starting an outgoing call, we need to grab gateway information
+ // for the call, if available, and set it.
+ final RawGatewayInfo info = mCallGatewayManager.getGatewayInfo(connection);
+
+ if (newState == Call.State.DIALING) {
+ if (!info.isEmpty()) {
+ call.setGatewayNumber(info.getFormattedGatewayNumber());
+ call.setGatewayPackage(info.packageName);
+ }
+ } else if (!Call.State.isConnected(newState)) {
+ mCallGatewayManager.clearGatewayData(connection);
+ }
+
+ call.setState(newState);
+ }
+
+ /**
* Updates the Call properties to match the state of the connection object
* that it represents.
* @param call The call object to update.
@@ -344,7 +371,7 @@
final int newState = translateStateFromTelephony(connection, isForConference);
if (call.getState() != newState) {
- call.setState(newState);
+ setNewState(call, newState, connection);
changed = true;
}
@@ -362,29 +389,38 @@
}
if (!isForConference) {
+ // Number
final String oldNumber = call.getNumber();
- if (TextUtils.isEmpty(oldNumber) || !oldNumber.equals(connection.getAddress())) {
- call.setNumber(connection.getAddress());
+ String newNumber = connection.getAddress();
+ RawGatewayInfo info = mCallGatewayManager.getGatewayInfo(connection);
+ if (!info.isEmpty()) {
+ newNumber = info.trueNumber;
+ }
+ if (TextUtils.isEmpty(oldNumber) || !oldNumber.equals(newNumber)) {
+ call.setNumber(newNumber);
changed = true;
}
+ // Number presentation
final int newNumberPresentation = connection.getNumberPresentation();
if (call.getNumberPresentation() != newNumberPresentation) {
call.setNumberPresentation(newNumberPresentation);
changed = true;
}
- final int newCnapNamePresentation = connection.getCnapNamePresentation();
- if (call.getCnapNamePresentation() != newCnapNamePresentation) {
- call.setCnapNamePresentation(newCnapNamePresentation);
- changed = true;
- }
-
+ // Name
final String oldCnapName = call.getCnapName();
if (TextUtils.isEmpty(oldCnapName) || !oldCnapName.equals(connection.getCnapName())) {
call.setCnapName(connection.getCnapName());
changed = true;
}
+
+ // Name Presentation
+ final int newCnapNamePresentation = connection.getCnapNamePresentation();
+ if (call.getCnapNamePresentation() != newCnapNamePresentation) {
+ call.setCnapNamePresentation(newCnapNamePresentation);
+ changed = true;
+ }
} else {
// update the list of children by:
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 31b0c66..de5052f 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -1165,7 +1165,7 @@
if (autoretrySetting == InCallScreen.AUTO_RETRY_ON) {
// TODO: (Moto): The contact reference data may need to be stored and use
// here when redialing a call. For now, pass in NULL as the URI parameter.
- PhoneUtils.placeCall(mApplication, phone, number, null, false, null);
+ PhoneUtils.placeCall(mApplication, phone, number, null, false);
mIsCdmaRedialCall = true;
} else {
mIsCdmaRedialCall = false;
diff --git a/src/com/android/phone/EmergencyCallHelper.java b/src/com/android/phone/EmergencyCallHelper.java
index 7f5b0d2..a23e3e0 100644
--- a/src/com/android/phone/EmergencyCallHelper.java
+++ b/src/com/android/phone/EmergencyCallHelper.java
@@ -392,8 +392,7 @@
mPhone,
mNumber,
null, // contactUri
- true, // isEmergencyCall
- null); // gatewayUri
+ true); // isEmergencyCall
if (DBG) log("- PhoneUtils.placeCall() returned status = " + callStatus);
boolean success;
diff --git a/src/com/android/phone/InCallScreen.java b/src/com/android/phone/InCallScreen.java
index 31f680b..57006bb 100644
--- a/src/com/android/phone/InCallScreen.java
+++ b/src/com/android/phone/InCallScreen.java
@@ -97,29 +97,6 @@
// TODO: Should be EXTRA_SHOW_DIALPAD for consistency.
static final String SHOW_DIALPAD_EXTRA = "com.android.phone.ShowDialpad";
- /**
- * Intent extra to specify the package name of the gateway
- * provider. Used to get the name displayed in the in-call screen
- * during the call setup. The value is a string.
- */
- // TODO: This extra is currently set by the gateway application as
- // a temporary measure. Ultimately, the framework will securely
- // set it.
- /* package */ static final String EXTRA_GATEWAY_PROVIDER_PACKAGE =
- "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE";
-
- /**
- * Intent extra to specify the URI of the provider to place the
- * call. The value is a string. It holds the gateway address
- * (phone gateway URL should start with the 'tel:' scheme) that
- * will actually be contacted to call the number passed in the
- * intent URL or in the EXTRA_PHONE_NUMBER extra.
- */
- // TODO: Should the value be a Uri (Parcelable)? Need to make sure
- // MMI code '#' don't get confused as URI fragments.
- /* package */ static final String EXTRA_GATEWAY_URI =
- "com.android.phone.extra.GATEWAY_URI";
-
// Amount of time (in msec) that we display the "Call ended" state.
// The "short" value is for calls ended by the local user, and the
// "long" value is for calls ended by the remote caller.
@@ -371,7 +348,6 @@
break;
case EVENT_HIDE_PROVIDER_INFO:
- mApp.inCallUiState.providerInfoVisible = false;
if (mCallCard != null) {
mCallCard.updateState(mCM);
}
@@ -731,11 +707,6 @@
mIsForegroundActivity = false;
- // Force a clear of the provider info frame. Since the
- // frame is removed using a timed message, it is
- // possible we missed it if the prev call was interrupted.
- mApp.inCallUiState.providerInfoVisible = false;
-
// "show-already-disconnected-state" should be effective just during the first wake-up.
// We should never allow it to stay true after that.
mApp.inCallUiState.showAlreadyDisconnectedState = false;
diff --git a/src/com/android/phone/InCallUiState.java b/src/com/android/phone/InCallUiState.java
index 3b700d7..126ef63 100644
--- a/src/com/android/phone/InCallUiState.java
+++ b/src/com/android/phone/InCallUiState.java
@@ -340,52 +340,6 @@
return (progressIndication != ProgressIndicationType.NONE);
}
-
- //
- // (4) Optional info when a 3rd party "provider" is used.
- // @see InCallScreen#requestRemoveProviderInfoWithDelay()
- // @see CallCard#updateCallStateWidgets()
- //
-
- // TODO: maybe isolate all the provider-related stuff out to a
- // separate inner class?
- boolean providerInfoVisible;
- CharSequence providerLabel;
- Drawable providerIcon;
- Uri providerGatewayUri;
- // The formatted address extracted from mProviderGatewayUri. User visible.
- String providerAddress;
-
- /**
- * Set the fields related to the provider support
- * based on the specified intent.
- */
- public void setProviderInfo(Intent intent) {
- providerLabel = PhoneUtils.getProviderLabel(mContext, intent);
- providerIcon = PhoneUtils.getProviderIcon(mContext, intent);
- providerGatewayUri = PhoneUtils.getProviderGatewayUri(intent);
- providerAddress = PhoneUtils.formatProviderUri(providerGatewayUri);
- providerInfoVisible = true;
-
- // ...but if any of the "required" fields are missing, completely
- // disable the overlay.
- if (TextUtils.isEmpty(providerLabel) || providerIcon == null ||
- providerGatewayUri == null || TextUtils.isEmpty(providerAddress)) {
- clearProviderInfo();
- }
- }
-
- /**
- * Clear all the fields related to the provider support.
- */
- public void clearProviderInfo() {
- providerInfoVisible = false;
- providerLabel = null;
- providerIcon = null;
- providerGatewayUri = null;
- providerAddress = null;
- }
-
/**
* "Call origin" of the most recent phone call.
*
@@ -435,15 +389,6 @@
log(" - pending call status code: none");
}
log(" - progressIndication: " + progressIndication);
- if (providerInfoVisible) {
- log(" - provider info VISIBLE: "
- + providerLabel + " / "
- + providerIcon + " / "
- + providerGatewayUri + " / "
- + providerAddress);
- } else {
- log(" - provider info: none");
- }
log(" - latestActiveCallOrigin: " + latestActiveCallOrigin);
}
diff --git a/src/com/android/phone/OtaUtils.java b/src/com/android/phone/OtaUtils.java
index a59c2e6..e713df9 100644
--- a/src/com/android/phone/OtaUtils.java
+++ b/src/com/android/phone/OtaUtils.java
@@ -459,9 +459,8 @@
int callStatus = PhoneUtils.placeCall(context,
phone,
number,
- null, // contactRef
- false, //isEmergencyCall
- null); // gatewayUri
+ null, // contactRef
+ false); //isEmergencyCall
if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
if (DBG) log(" ==> successful return from placeCall(): callStatus = " + callStatus);
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index b9aea52..c5e8953 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -300,7 +300,7 @@
Intent newIntent = new Intent(Intent.ACTION_CALL, uri);
newIntent.putExtra(EXTRA_ACTUAL_NUMBER_TO_DIAL, number);
- PhoneUtils.checkAndCopyPhoneProviderExtras(intent, newIntent);
+ CallGatewayManager.checkAndCopyPhoneProviderExtras(intent, newIntent);
// Finally, launch the SipCallOptionHandler, with the copy of the
// original CALL intent stashed away in the EXTRA_NEW_CALL_INTENT
@@ -638,7 +638,7 @@
if (number != null) {
broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
}
- PhoneUtils.checkAndCopyPhoneProviderExtras(intent, broadcastIntent);
+ CallGatewayManager.checkAndCopyPhoneProviderExtras(intent, broadcastIntent);
broadcastIntent.putExtra(EXTRA_ALREADY_CALLED, callNow);
broadcastIntent.putExtra(EXTRA_ORIGINAL_URI, uri.toString());
// Need to raise foreground in-call UI as soon as possible while allowing 3rd party app
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 9ed0470..165ae67 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -171,6 +171,7 @@
private AudioRouter audioRouter;
private BluetoothManager bluetoothManager;
private CallCommandService callCommandService;
+ private CallGatewayManager callGatewayManager;
private CallHandlerServiceProxy callHandlerServiceProxy;
private CallModeler callModeler;
private CallStateMonitor callStateMonitor;
@@ -474,10 +475,13 @@
CallLogger callLogger = new CallLogger(this, new CallLogAsync());
+ callGatewayManager = new CallGatewayManager();
+
// Create the CallController singleton, which is the interface
// to the telephony layer for user-initiated telephony functionality
// (like making outgoing calls.)
- callController = CallController.init(this, callLogger);
+ callController = CallController.init(this, callLogger, callGatewayManager);
+
// ...and also the InCallUiState instance, used by the CallController to
// keep track of some "persistent state" of the in-call UI.
inCallUiState = InCallUiState.init(this);
@@ -495,7 +499,8 @@
rejectWithTextMessageManager = new RejectWithTextMessageManager();
// Creates call models for use with CallHandlerService.
- callModeler = new CallModeler(callStateMonitor, mCM, rejectWithTextMessageManager);
+ callModeler = new CallModeler(callStateMonitor, mCM, rejectWithTextMessageManager,
+ callGatewayManager);
// Plays DTMF Tones
dtmfTonePlayer = new DTMFTonePlayer(mCM, callModeler);
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 9671c17..6b96737 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -59,6 +59,7 @@
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.cdma.CdmaConnection;
import com.android.internal.telephony.sip.SipPhone;
+import com.android.phone.CallGatewayManager.RawGatewayInfo;
import java.util.ArrayList;
import java.util.Arrays;
@@ -561,6 +562,15 @@
}
/**
+ * @see placeCall below
+ */
+ public static int placeCall(Context context, Phone phone, String number, Uri contactRef,
+ boolean isEmergencyCall) {
+ return placeCall(context, phone, number, contactRef, isEmergencyCall,
+ CallGatewayManager.EMPTY_INFO, null);
+ }
+
+ /**
* Dial the number using the phone passed in.
*
* If the connection is establised, this method issues a sync call
@@ -578,12 +588,14 @@
* emergency call
* @param gatewayUri Is the address used to setup the connection, null
* if not using a gateway
+ * @param callGateway Class for setting gateway data on a successful call.
*
* @return either CALL_STATUS_DIALED or CALL_STATUS_FAILED
*/
- public static int placeCall(Context context, Phone phone,
- String number, Uri contactRef, boolean isEmergencyCall,
- Uri gatewayUri) {
+ public static int placeCall(Context context, Phone phone, String number, Uri contactRef,
+ boolean isEmergencyCall, RawGatewayInfo gatewayInfo, CallGatewayManager callGateway) {
+ final Uri gatewayUri = gatewayInfo.gatewayUri;
+
if (VDBG) {
log("placeCall()... number: '" + number + "'"
+ ", GW:'" + gatewayUri + "'"
@@ -642,6 +654,11 @@
// we dialed an MMI (see below).
}
+ // Now that the call is successful, we can save the gateway info for the call
+ if (callGateway != null) {
+ callGateway.setGatewayInfoForConnection(connection, gatewayInfo);
+ }
+
int phoneType = phone.getPhoneType();
// On GSM phones, null is returned for MMI codes
@@ -2321,107 +2338,6 @@
//
/**
- * Check if all the provider's info is present in the intent.
- * @param intent Expected to have the provider's extra.
- * @return true if the intent has all the extras to build the
- * in-call screen's provider info overlay.
- */
- /* package */ static boolean hasPhoneProviderExtras(Intent intent) {
- if (null == intent) {
- return false;
- }
- final String name = intent.getStringExtra(InCallScreen.EXTRA_GATEWAY_PROVIDER_PACKAGE);
- final String gatewayUri = intent.getStringExtra(InCallScreen.EXTRA_GATEWAY_URI);
-
- return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(gatewayUri);
- }
-
- /**
- * Copy all the expected extras set when a 3rd party provider is
- * used from the source intent to the destination one. Checks all
- * the required extras are present, if any is missing, none will
- * be copied.
- * @param src Intent which may contain the provider's extras.
- * @param dst Intent where a copy of the extras will be added if applicable.
- */
- /* package */ static void checkAndCopyPhoneProviderExtras(Intent src, Intent dst) {
- if (!hasPhoneProviderExtras(src)) {
- Log.d(LOG_TAG, "checkAndCopyPhoneProviderExtras: some or all extras are missing.");
- return;
- }
-
- dst.putExtra(InCallScreen.EXTRA_GATEWAY_PROVIDER_PACKAGE,
- src.getStringExtra(InCallScreen.EXTRA_GATEWAY_PROVIDER_PACKAGE));
- dst.putExtra(InCallScreen.EXTRA_GATEWAY_URI,
- src.getStringExtra(InCallScreen.EXTRA_GATEWAY_URI));
- }
-
- /**
- * Get the provider's label from the intent.
- * @param context to lookup the provider's package name.
- * @param intent with an extra set to the provider's package name.
- * @return The provider's application label. null if an error
- * occurred during the lookup of the package name or the label.
- */
- /* package */ static CharSequence getProviderLabel(Context context, Intent intent) {
- String packageName = intent.getStringExtra(InCallScreen.EXTRA_GATEWAY_PROVIDER_PACKAGE);
- PackageManager pm = context.getPackageManager();
-
- try {
- ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
-
- return pm.getApplicationLabel(info);
- } catch (PackageManager.NameNotFoundException e) {
- return null;
- }
- }
-
- /**
- * Get the provider's icon.
- * @param context to lookup the provider's icon.
- * @param intent with an extra set to the provider's package name.
- * @return The provider's application icon. null if an error occured during the icon lookup.
- */
- /* package */ static Drawable getProviderIcon(Context context, Intent intent) {
- String packageName = intent.getStringExtra(InCallScreen.EXTRA_GATEWAY_PROVIDER_PACKAGE);
- PackageManager pm = context.getPackageManager();
-
- try {
- return pm.getApplicationIcon(packageName);
- } catch (PackageManager.NameNotFoundException e) {
- return null;
- }
- }
-
- /**
- * Return the gateway uri from the intent.
- * @param intent With the gateway uri extra.
- * @return The gateway URI or null if not found.
- */
- /* package */ static Uri getProviderGatewayUri(Intent intent) {
- String uri = intent.getStringExtra(InCallScreen.EXTRA_GATEWAY_URI);
- return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
- }
-
- /**
- * Return a formatted version of the uri's scheme specific
- * part. E.g for 'tel:12345678', return '1-234-5678'.
- * @param uri A 'tel:' URI with the gateway phone number.
- * @return the provider's address (from the gateway uri) formatted
- * for user display. null if uri was null or its scheme was not 'tel:'.
- */
- /* package */ static String formatProviderUri(Uri uri) {
- if (null != uri) {
- if (Constants.SCHEME_TEL.equals(uri.getScheme())) {
- return PhoneNumberUtils.formatNumber(uri.getSchemeSpecificPart());
- } else {
- return uri.toString();
- }
- }
- return null;
- }
-
- /**
* Check if a phone number can be route through a 3rd party
* gateway. The number must be a global phone number in numerical
* form (1-800-666-SEXY won't work).
@@ -2432,7 +2348,7 @@
* @param number To be dialed via a 3rd party gateway.
* @return true If the number can be routed through the 3rd party network.
*/
- /* package */ static boolean isRoutableViaGateway(String number) {
+ private static boolean isRoutableViaGateway(String number) {
if (TextUtils.isEmpty(number)) {
return false;
}
diff --git a/src/com/android/phone/SipCallOptionHandler.java b/src/com/android/phone/SipCallOptionHandler.java
index 500f322..295e886 100644
--- a/src/com/android/phone/SipCallOptionHandler.java
+++ b/src/com/android/phone/SipCallOptionHandler.java
@@ -176,7 +176,7 @@
// call via the default pstn network. However, if one just alters
// the destination directly, then we still let it go through the
// Internet call option process.
- if (!PhoneUtils.hasPhoneProviderExtras(mIntent)) {
+ if (!CallGatewayManager.hasPhoneProviderExtras(mIntent)) {
if (!isNetworkConnected()) {
if (!isRegularCall) {
showDialog(DIALOG_NO_INTERNET_ERROR);