diff options
-rw-r--r-- | InCallUI/res/layout/primary_call_info.xml | 33 | ||||
-rw-r--r-- | InCallUI/res/layout/secondary_call_info.xml | 39 | ||||
-rw-r--r-- | InCallUI/res/values/strings.xml | 8 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/Call.java | 10 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/CallCardFragment.java | 146 | ||||
-rw-r--r-- | InCallUI/src/com/android/incallui/CallCardPresenter.java | 74 |
6 files changed, 237 insertions, 73 deletions
diff --git a/InCallUI/res/layout/primary_call_info.xml b/InCallUI/res/layout/primary_call_info.xml index 369f70216..36c9813e2 100644 --- a/InCallUI/res/layout/primary_call_info.xml +++ b/InCallUI/res/layout/primary_call_info.xml @@ -33,15 +33,34 @@ android:animateLayoutChanges="true" android:gravity="center"> - <TextView android:id="@+id/callStateLabel" + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="?android:attr/textAppearanceLarge" - android:textColor="@color/incall_accent_color" - android:textSize="@dimen/call_status_text_size" - android:singleLine="true" - android:gravity="start" - android:ellipsize="end" /> + android:orientation="horizontal" + android:clipChildren="false" + android:clipToPadding="false"> + + <!-- Subscription provider or WiFi calling icon displayed to the left of the label --> + <ImageView android:id="@+id/callStateIcon" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_marginRight="4dp" + android:baselineAlignBottom="true" + android:tint="@color/incall_accent_color" + android:scaleType="centerInside" + android:visibility="gone" + android:src="@drawable/ic_in_call_wifi"/> + + <TextView android:id="@+id/callStateLabel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceLarge" + android:textColor="@color/incall_accent_color" + android:textSize="@dimen/call_status_text_size" + android:singleLine="true" + android:gravity="start" + android:ellipsize="end" /> + </LinearLayout> <!-- Name (or the phone number, if we don't have a name to display). --> <TextView android:id="@+id/name" diff --git a/InCallUI/res/layout/secondary_call_info.xml b/InCallUI/res/layout/secondary_call_info.xml index 4d8711d81..b926c9225 100644 --- a/InCallUI/res/layout/secondary_call_info.xml +++ b/InCallUI/res/layout/secondary_call_info.xml @@ -28,20 +28,47 @@ android:background="@color/incall_banner_secondary_background_color" android:elevation="@dimen/secondary_call_elevation" > - <!-- Name (or the phone number, if we don't have a name to display). --> - <TextView android:id="@+id/secondaryCallName" + <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" - android:textAppearance="?android:attr/textAppearanceMedium" - android:textColor="@color/incall_banner_secondary_text_color" - android:ellipsize="marquee" - android:singleLine="true"/> + android:orientation="vertical"> + <!-- Name (or the phone number, if we don't have a name to display). --> + <TextView android:id="@+id/secondaryCallName" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="@color/incall_banner_secondary_text_color" + android:ellipsize="marquee" + android:singleLine="true"/> + <!-- Provider, e.g. AT&T, that a call is associated with --> + <LinearLayout android:id="@+id/secondary_call_provider_info" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:visibility="gone" > + <ImageView android:id="@+id/secondaryCallProviderIcon" + android:layout_width="12dp" + android:layout_height="12dp" + android:layout_marginRight="2dp" + android:baselineAlignBottom="true" + android:scaleType="centerInside" + android:src="@drawable/ic_in_call_wifi"/> + <TextView android:id="@+id/secondaryCallProviderLabel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/onHold" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="@color/incall_banner_secondary_text_color" + android:singleLine="true"/> + </LinearLayout> + </LinearLayout> <!-- Call status of the background call, usually the string "On hold". --> <TextView android:id="@+id/secondaryCallStatus" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_gravity="center_vertical" android:paddingEnd="@dimen/call_banner_side_padding" android:text="@string/onHold" android:textAppearance="?android:attr/textAppearanceMedium" diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml index 4fef3f69b..4bcd5c09d 100644 --- a/InCallUI/res/values/strings.xml +++ b/InCallUI/res/values/strings.xml @@ -294,9 +294,12 @@ <!-- Title displayed above settings coming after voicemail in the call features screen --> <string name="other_settings">Other call settings</string> - <!-- Title displayed in the overlay when a call is placed using a 3rd party provider. + <!-- Title displayed in the overlay for outgoing calls which include the name of the provider. [CHAR LIMIT=40] --> <string name="calling_via_template">Calling via <xliff:g id="provider_name">%s</xliff:g></string> + <!-- Title displayed in the overlay for incoming calls which include the name of the provider. + [CHAR LIMIT=40] --> + <string name="incoming_via_template">Incoming via <xliff:g id="provider_name">%s</xliff:g></string> <!-- Use this as a default to describe the contact photo; currently for screen readers through accessibility. --> <string name="contactPhoto">contact photo</string> @@ -497,6 +500,9 @@ <string name="in_call_wifi_connected">Connected via <xliff:g id="wifi_ssid">%s</xliff:g></string> + <!-- Filler string to display as the provider in WiFi calling cases --> + <string name="wifi_constant">WiFi</string> + <!-- The digit to be displayed on the 0 key of the dialpad [CHAR LIMIT=1]--> <string name="dialpad_0_number">0</string> <!-- The digit to be displayed on the 1 key of the dialpad [CHAR LIMIT=1]--> diff --git a/InCallUI/src/com/android/incallui/Call.java b/InCallUI/src/com/android/incallui/Call.java index fccf608fa..71698d6a8 100644 --- a/InCallUI/src/com/android/incallui/Call.java +++ b/InCallUI/src/com/android/incallui/Call.java @@ -21,6 +21,7 @@ import android.telecomm.CallCapabilities; import android.telecomm.CallNumberPresentation; import android.telecomm.CallServiceDescriptor; import android.telecomm.GatewayInfo; +import android.telecomm.Subscription; import android.telephony.DisconnectCause; import com.google.common.collect.ImmutableSortedSet; @@ -106,6 +107,7 @@ public final class Call { private long mConnectTimeMillis = 0; private Uri mHandle; private GatewayInfo mGatewayInfo; + private Subscription mSubscription; private CallServiceDescriptor mCurrentCallServiceDescriptor; private CallServiceDescriptor mHandoffCallServiceDescriptor; private String mParentCallId; @@ -214,6 +216,14 @@ public final class Call { mGatewayInfo = gatewayInfo; } + public Subscription getSubscription() { + return mSubscription; + } + + public void setSubscription(Subscription subscription) { + mSubscription = subscription; + } + /** The descriptor for the call service currently routing this call. */ public CallServiceDescriptor getCurrentCallServiceDescriptor() { return mCurrentCallServiceDescriptor; diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java index 4509abc4a..933fbca30 100644 --- a/InCallUI/src/com/android/incallui/CallCardFragment.java +++ b/InCallUI/src/com/android/incallui/CallCardFragment.java @@ -63,6 +63,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr private TextView mPhoneNumber; private TextView mNumberLabel; private TextView mPrimaryName; + private ImageView mCallStateIcon; private TextView mCallStateLabel; private TextView mCallTypeLabel; private View mCallNumberAndLabel; @@ -78,6 +79,9 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr // Secondary caller info private View mSecondaryCallInfo; private TextView mSecondaryCallName; + private View mSecondaryCallProviderInfo; + private TextView mSecondaryCallProviderLabel; + private ImageView mSecondaryCallProviderIcon; private FloatingActionButtonController mFloatingActionButtonController; private View mFloatingActionButtonContainer; @@ -145,7 +149,9 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr mPrimaryName = (TextView) view.findViewById(R.id.name); mNumberLabel = (TextView) view.findViewById(R.id.label); mSecondaryCallInfo = (View) view.findViewById(R.id.secondary_call_info); + mSecondaryCallProviderInfo = (View) view.findViewById(R.id.secondary_call_provider_info); mPhoto = (ImageView) view.findViewById(R.id.photo); + mCallStateIcon = (ImageView) view.findViewById(R.id.callStateIcon); mCallStateLabel = (TextView) view.findViewById(R.id.callStateLabel); mCallNumberAndLabel = view.findViewById(R.id.labelAndNumber); mCallTypeLabel = (TextView) view.findViewById(R.id.callTypeLabel); @@ -292,7 +298,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr @Override public void setSecondary(boolean show, String name, boolean nameIsNumber, String label, - boolean isConference, boolean isGeneric) { + String providerLabel, Drawable providerIcon, boolean isConference, boolean isGeneric) { if (show) { if (isConference) { @@ -300,8 +306,14 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr nameIsNumber = false; } - showAndInitializeSecondaryCallInfo(); + boolean hasProvider = !TextUtils.isEmpty(providerLabel); + showAndInitializeSecondaryCallInfo(hasProvider); + mSecondaryCallName.setText(name); + if (hasProvider) { + mSecondaryCallProviderLabel.setText(providerLabel); + mSecondaryCallProviderIcon.setImageDrawable(providerIcon); + } int nameDirection = View.TEXT_DIRECTION_INHERIT; if (nameIsNumber) { @@ -314,31 +326,40 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr } @Override - public void setCallState(int state, int cause, boolean bluetoothOn, String gatewayLabel, - String gatewayNumber, boolean isWiFi, boolean isHandoffCapable, + public void setCallState(int state, int cause, boolean bluetoothOn, String connectionLabel, + Drawable connectionIcon, String gatewayNumber, boolean isWiFi, boolean isHandoffCapable, boolean isHandoffPending) { String callStateLabel = null; - if (Call.State.isDialing(state) && !TextUtils.isEmpty(gatewayLabel)) { - // Provider info: (e.g. "Calling via <gatewayLabel>") - callStateLabel = gatewayLabel; - } else { - callStateLabel = getCallStateLabelFromState(state, cause); - } + boolean isGatewayCall = !TextUtils.isEmpty(gatewayNumber); + callStateLabel = getCallStateLabelFromState(state, cause, connectionLabel, isWiFi, + isGatewayCall); Log.v(this, "setCallState " + callStateLabel); Log.v(this, "DisconnectCause " + DisconnectCause.toString(cause)); Log.v(this, "bluetooth on " + bluetoothOn); - Log.v(this, "gateway " + gatewayLabel + gatewayNumber); + Log.v(this, "gateway " + connectionLabel + gatewayNumber); Log.v(this, "isWiFi " + isWiFi); Log.v(this, "isHandoffCapable " + isHandoffCapable); Log.v(this, "isHandoffPending " + isHandoffPending); - // Update the call state label. + // Update the call state label and icon. if (!TextUtils.isEmpty(callStateLabel)) { mCallStateLabel.setText(callStateLabel); + mCallStateLabel.setAlpha(1); mCallStateLabel.setVisibility(View.VISIBLE); - if (state != Call.State.CONFERENCED) { + + if (connectionIcon == null) { + mCallStateIcon.setVisibility(View.GONE); + } else { + mCallStateIcon.setVisibility(View.VISIBLE); + mCallStateIcon.setImageDrawable(connectionIcon); + } + + if (state == Call.State.ACTIVE || state == Call.State.CONFERENCED) { + mCallStateLabel.clearAnimation(); + } else { + //TODO: add WiFi animation mCallStateLabel.startAnimation(mPulseAnimation); } } else { @@ -430,43 +451,68 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr /** * Gets the call state label based on the state of the call and * cause of disconnect + * + * Additional labels are applied as follows: + * 1. All outgoing calls with display "Calling via [Provider]" + * 2. Ongoing calls will display the name of the provider or wifi connection + * 2. Incoming calls will only display "Incoming via..." for subscriptions */ - private String getCallStateLabelFromState(int state, int cause) { + private String getCallStateLabelFromState(int state, int cause, String label, boolean isWiFi, + boolean isGatewayCall) { final Context context = getView().getContext(); String callStateLabel = null; // Label to display as part of the call banner - if (Call.State.IDLE == state) { - // "Call state" is meaningless in this state. - - } else if (Call.State.ACTIVE == state) { - // We normally don't show a "call state label" at all in - // this state (but see below for some special cases). - - } else if (Call.State.ONHOLD == state) { - callStateLabel = context.getString(R.string.card_title_on_hold); - } else if (Call.State.DIALING == state) { - callStateLabel = context.getString(R.string.card_title_dialing); - } else if (Call.State.REDIALING == state) { - callStateLabel = context.getString(R.string.card_title_redialing); - } else if (Call.State.INCOMING == state || Call.State.CALL_WAITING == state) { - callStateLabel = context.getString(R.string.card_title_incoming_call); - - } else if (Call.State.DISCONNECTING == state) { - // While in the DISCONNECTING state we display a "Hanging up" - // message in order to make the UI feel more responsive. (In - // GSM it's normal to see a delay of a couple of seconds while - // negotiating the disconnect with the network, so the "Hanging - // up" state at least lets the user know that we're doing - // something. This state is currently not used with CDMA.) - callStateLabel = context.getString(R.string.card_title_hanging_up); - - } else if (Call.State.DISCONNECTED == state) { - callStateLabel = getCallFailedString(cause); + boolean isSpecialCall = label != null; + boolean isSubscriptionOrWifi = isSpecialCall && !isGatewayCall; + boolean isSubscriptionOnly = isSubscriptionOrWifi && !isWiFi; - } else { - Log.wtf(this, "updateCallStateWidgets: unexpected call: " + state); + switch (state) { + case Call.State.IDLE: + // "Call state" is meaningless in this state. + break; + case Call.State.ACTIVE: + // We normally don't show a "call state label" at all in this state + // (but we can use the call state label to display the provider name). + if (isSubscriptionOrWifi) { + callStateLabel = label; + } + break; + case Call.State.ONHOLD: + callStateLabel = context.getString(R.string.card_title_on_hold); + break; + case Call.State.DIALING: + if (isSpecialCall) { + callStateLabel = context.getString(R.string.calling_via_template, label); + } else { + callStateLabel = context.getString(R.string.card_title_dialing); + } + break; + case Call.State.REDIALING: + callStateLabel = context.getString(R.string.card_title_redialing); + break; + case Call.State.INCOMING: + case Call.State.CALL_WAITING: + if (isSubscriptionOnly) { + callStateLabel = context.getString(R.string.incoming_via_template, label); + } else { + callStateLabel = context.getString(R.string.card_title_incoming_call); + } + break; + case Call.State.DISCONNECTING: + // While in the DISCONNECTING state we display a "Hanging up" + // message in order to make the UI feel more responsive. (In + // GSM it's normal to see a delay of a couple of seconds while + // negotiating the disconnect with the network, so the "Hanging + // up" state at least lets the user know that we're doing + // something. This state is currently not used with CDMA.) + callStateLabel = context.getString(R.string.card_title_hanging_up); + break; + case Call.State.DISCONNECTED: + callStateLabel = getCallFailedString(cause); + break; + default: + Log.wtf(this, "updateCallStateWidgets: unexpected call: " + state); } - return callStateLabel; } @@ -548,13 +594,20 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr return this.getView().getContext().getString(resID); } - private void showAndInitializeSecondaryCallInfo() { + private void showAndInitializeSecondaryCallInfo(boolean hasProvider) { mSecondaryCallInfo.setVisibility(View.VISIBLE); - // mSecondaryCallName is initialized here (vs. onViewCreated) because it is inaccesible + // mSecondaryCallName is initialized here (vs. onViewCreated) because it is inaccessible // until mSecondaryCallInfo is inflated in the call above. if (mSecondaryCallName == null) { mSecondaryCallName = (TextView) getView().findViewById(R.id.secondaryCallName); + if (hasProvider) { + mSecondaryCallProviderInfo.setVisibility(View.VISIBLE); + mSecondaryCallProviderLabel = (TextView) getView() + .findViewById(R.id.secondaryCallProviderLabel); + mSecondaryCallProviderIcon = (ImageView) getView() + .findViewById(R.id.secondaryCallProviderIcon); + } } mSecondaryCallInfo.setOnClickListener(new View.OnClickListener() { @Override @@ -575,6 +628,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr dispatchPopulateAccessibilityEvent(event, mPhoneNumber); dispatchPopulateAccessibilityEvent(event, mCallTypeLabel); dispatchPopulateAccessibilityEvent(event, mSecondaryCallName); + dispatchPopulateAccessibilityEvent(event, mSecondaryCallProviderLabel); return; } diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java index 576283211..e2dd14b3d 100644 --- a/InCallUI/src/com/android/incallui/CallCardPresenter.java +++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java @@ -16,15 +16,18 @@ package com.android.incallui; +import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.graphics.Bitmap; +import android.net.Uri; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.telecomm.CallCapabilities; import android.telecomm.CallServiceDescriptor; +import android.telecomm.Subscription; import android.telephony.DisconnectCause; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; @@ -37,6 +40,9 @@ import com.android.incallui.InCallPresenter.InCallState; import com.android.incallui.InCallPresenter.InCallStateListener; import com.android.incallui.InCallPresenter.IncomingCallListener; import com.android.services.telephony.common.AudioMode; + +import java.util.List; + import com.google.common.base.Preconditions; /** @@ -199,10 +205,10 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> mIsWiFiCachedValue = isWiFi; getUi().setCallState(callState, mPrimary.getDisconnectCause(), bluetoothOn, - getGatewayLabel(), getGatewayNumber(), isWiFi, isHandoffCapable, - isHandoffPending); + getConnectionLabel(), getConnectionIcon(), getGatewayNumber(), isWiFi, + isHandoffCapable, isHandoffPending); } else { - getUi().setCallState(callState, DisconnectCause.NOT_VALID, false, null, null, + getUi().setCallState(callState, DisconnectCause.NOT_VALID, false, null, null, null, mIsWiFiCachedValue, false, false); } @@ -217,7 +223,7 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> final boolean bluetoothOn = (AudioMode.BLUETOOTH == mode); getUi().setCallState(mPrimary.getState(), mPrimary.getDisconnectCause(), bluetoothOn, - getGatewayLabel(), getGatewayNumber(), isWifiCall(), + getConnectionLabel(), getConnectionIcon(), getGatewayNumber(), isWifiCall(), isHandoffCapable(), isHandoffPending()); } } @@ -417,10 +423,11 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> final boolean nameIsNumber = nameForCall != null && nameForCall.equals( mSecondaryContactInfo.number); ui.setSecondary(true /* show */, nameForCall, nameIsNumber, mSecondaryContactInfo.label, + getSecondaryCallProviderLabel(), getSecondaryCallProviderIcon(), isConference, isGenericConf); } else { // reset to nothing so that it starts off blank next time we use it. - ui.setSecondary(false, null, false, null, isConference, isGenericConf); + ui.setSecondary(false, null, false, null, null, null, isConference, isGenericConf); } } @@ -435,19 +442,59 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> } /** - * Returns the label for the gateway app for any existing outgoing call. + * Return the Drawable object of the icon to display to the left of the connection label. + */ + private Drawable getConnectionIcon() { + if (mIsWiFiCachedValue == true) { + return mContext.getResources().getDrawable(R.drawable.ic_in_call_wifi); + } + Subscription subscription = mPrimary.getSubscription(); + if (subscription != null) { + return subscription.getIcon(mContext); + } + return null; + } + + /** + * Returns the label (line of text above the number/name) for any given call. + * For example, "calling via [Subscription/Google Voice/Wifi]" for outgoing calls. */ - private String getGatewayLabel() { + private String getConnectionLabel() { if (hasOutgoingGatewayCall() && getUi() != null) { + // Return the label for the gateway app on outgoing calls. final PackageManager pm = mContext.getPackageManager(); try { ApplicationInfo info = pm.getApplicationInfo( mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0); - return mContext.getString(R.string.calling_via_template, - pm.getApplicationLabel(info).toString()); + return pm.getApplicationLabel(info).toString(); } catch (PackageManager.NameNotFoundException e) { + Log.e(this, "Gateway Application Not Found.", e); + return null; } } + Subscription subscription = mPrimary.getSubscription(); + if (mIsWiFiCachedValue == true || subscription != null) { + // Label will be either subscription name or WiFi connection + // TODO: get the name of the wifi connection + String wifiString = mContext.getString(R.string.wifi_constant); + return subscription == null? wifiString : subscription.getLabel(mContext); + } + return null; + } + + private String getSecondaryCallProviderLabel() { + Subscription subscription = mSecondary.getSubscription(); + if (subscription != null) { + return subscription.getLabel(mContext); + } + return null; + } + + private Drawable getSecondaryCallProviderIcon() { + Subscription subscription = mSecondary.getSubscription(); + if (subscription != null) { + return subscription.getIcon(mContext); + } return null; } @@ -510,10 +557,11 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> void setPrimary(String number, String name, boolean nameIsNumber, String label, Drawable photo, boolean isConference, boolean isGeneric, boolean isSipCall); void setSecondary(boolean show, String name, boolean nameIsNumber, String label, - boolean isConference, boolean isGeneric); - void setCallState(int state, int cause, boolean bluetoothOn, - String gatewayLabel, String gatewayNumber, boolean isWifi, boolean isHandoffCapable, - boolean isHandoffPending); + String providerLabel, Drawable providerIcon, boolean isConference, + boolean isGeneric); + void setCallState(int state, int cause, boolean bluetoothOn, String connectionLabel, + Drawable connectionIcon, String gatewayNumber, boolean isWifi, + boolean isHandoffCapable, boolean isHandoffPending); void setPrimaryCallElapsedTime(boolean show, String duration); void setPrimaryName(String name, boolean nameIsNumber); void setPrimaryImage(Drawable image); |