diff options
author | Nancy Chen <nancychen@google.com> | 2014-06-19 14:59:09 -0700 |
---|---|---|
committer | Nancy Chen <nancychen@google.com> | 2014-06-23 12:16:22 -0700 |
commit | bd93cb5444e886266b47e504138bcc65e6f09cbe (patch) | |
tree | 5eec091d6127dd9b9be7f9a5842e7a2662ad9fa9 | |
parent | 1887dab1ca8f5a1242f5e934620787ca587d1c73 (diff) |
InCallUI displaying Multi-SIM/Subscription/Wifi calling
Dynamic text and icon to represent information for the provider of the
call. This can be the name of the subscription, connection provider, or
wifi connection. This will show up at the banner above the name/number
of the call for incoming, outgoing, and active calls.
Change-Id: I065f12d41f5d62965d82c955aed9ee070628cadc
-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); |