summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuchand Ghosh <suchan@codeaurora.org>2014-09-15 10:44:02 +0530
committerLinux Build Service Account <lnxbuild@localhost>2015-10-06 03:29:38 -0600
commit8ea43d354391cd7c75dd361a316e5936e1e1db96 (patch)
tree246e3dc1f0611f800e6b14256d5fc063f7a7d31d
parent7726e55795d0ea5493669f1f4d62cc51cd1e251d (diff)
downloadpackages_apps_Dialer-8ea43d354391cd7c75dd361a316e5936e1e1db96.tar.gz
packages_apps_Dialer-8ea43d354391cd7c75dd361a316e5936e1e1db96.tar.bz2
packages_apps_Dialer-8ea43d354391cd7c75dd361a316e5936e1e1db96.zip
Dialer app changes for IMS
IMS Conference URI UI changes 1. Add a new button for initiating conference URI call in the Dial screen. 2. Send a intent for the conference call with a extra to indicate the call type as conference. IMS: Allow dial Conference call without URI List Allow place conference call without URI List and don't show error toast in this case IMS: Clean up Conference URI system property Remove system property "persist.dbg.ims_volte_enable". Add platform configuration flag and user's enhanced 4G LTE setting to decide IMS capability. IMS: Add participant support Insert "add_participant" extra to dial intent IMS: Fix dialer app crash issue due to NPE FragmentActivity can be null if it's not yet attach. So it can be null in such case. Add null check to avoid NullPointerException. Change-Id: Ib35c394dd10dea7526601824f11e5ebd9db459ce
-rw-r--r--Android.mk4
-rw-r--r--res/drawable-hdpi/ic_add_group_holo_dark.pngbin0 -> 3181 bytes
-rw-r--r--res/layout/dialtacts_activity.xml21
-rw-r--r--src/com/android/dialer/DialtactsActivity.java89
-rw-r--r--src/com/android/dialer/dialpad/DialpadFragment.java186
5 files changed, 264 insertions, 36 deletions
diff --git a/Android.mk b/Android.mk
index 1440fcc3f..71df1e3c2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -29,7 +29,9 @@ LOCAL_AAPT_FLAGS := \
--extra-packages com.android.contacts.common \
--extra-packages com.android.phone.common
-LOCAL_JAVA_LIBRARIES := telephony-common
+LOCAL_JAVA_LIBRARIES := telephony-common \
+ ims-common
+
LOCAL_STATIC_JAVA_LIBRARIES := \
android-common \
android-support-v13 \
diff --git a/res/drawable-hdpi/ic_add_group_holo_dark.png b/res/drawable-hdpi/ic_add_group_holo_dark.png
new file mode 100644
index 000000000..85924aba4
--- /dev/null
+++ b/res/drawable-hdpi/ic_add_group_holo_dark.png
Binary files differ
diff --git a/res/layout/dialtacts_activity.xml b/res/layout/dialtacts_activity.xml
index 0f1f2bbdb..b1cfcee75 100644
--- a/res/layout/dialtacts_activity.xml
+++ b/res/layout/dialtacts_activity.xml
@@ -37,24 +37,33 @@
android:clipChildren="false" />
</FrameLayout>
- <FrameLayout
+ <LinearLayout
android:id="@+id/floating_action_button_container"
android:background="@drawable/fab_blue"
- android:layout_width="@dimen/floating_action_button_width"
+ android:layout_width="wrap_content"
android:layout_height="@dimen/floating_action_button_height"
android:layout_marginBottom="@dimen/floating_action_button_margin_bottom"
android:layout_gravity="center_horizontal|bottom">
<ImageButton
android:id="@+id/floating_action_button"
- android:background="@drawable/floating_action_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_gravity="bottom|left"
+ android:layout_weight="1"
+ android:background="@drawable/floating_action_button"
android:contentDescription="@string/action_menu_dialpad_button"
android:src="@drawable/fab_ic_dial"/>
-
- </FrameLayout>
-
+ <ImageButton
+ android:id="@+id/dialConferenceButton"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="bottom|right"
+ android:layout_weight="1"
+ android:background="@drawable/floating_action_button"
+ android:contentDescription="@string/action_menu_dialpad_button"
+ android:src="@drawable/ic_add_group_holo_dark"/>
+ </LinearLayout>
<!-- Host container for the contact tile drag shadow -->
<FrameLayout
android:id="@+id/activity_overlay"
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 69cc14673..f1a2a8803 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -89,6 +89,7 @@ import com.android.dialer.widget.SearchEditTextLayout;
import com.android.dialer.widget.SearchEditTextLayout.Callback;
import com.android.dialerbind.DatabaseHelperManager;
import com.android.phone.common.animation.AnimUtils;
+import com.android.ims.ImsManager;
import com.android.phone.common.animation.AnimationListenerAdapter;
import junit.framework.Assert;
@@ -160,6 +161,8 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
*/
private SmartDialSearchFragment mSmartDialSearchFragment;
+ private boolean mDialConferenceButtonPressed = false;
+
/**
* Animation that slides in.
*/
@@ -228,13 +231,16 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
private PopupMenu mOverflowMenu;
private EditText mSearchView;
private View mVoiceSearchButton;
+ private View mDialCallButton;
private String mSearchQuery;
private DialerDatabaseHelper mDialerDatabaseHelper;
private DragDropController mDragDropController;
private ActionBarController mActionBarController;
+ private ImageButton mFloatingActionButton;
+ private ImageButton mConferenceDialButton;
private FloatingActionButtonController mFloatingActionButtonController;
private int mActionBarHeight;
@@ -425,10 +431,13 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
final View floatingActionButtonContainer = findViewById(
R.id.floating_action_button_container);
- ImageButton floatingActionButton = (ImageButton) findViewById(R.id.floating_action_button);
- floatingActionButton.setOnClickListener(this);
+ mFloatingActionButton = (ImageButton) findViewById(R.id.floating_action_button);
+ mDialCallButton = findViewById(R.id.floating_action_button);
+ mFloatingActionButton.setOnClickListener(this);
+ mConferenceDialButton = (ImageButton) findViewById(R.id.dialConferenceButton);
+ mConferenceDialButton.setOnClickListener(this);
mFloatingActionButtonController = new FloatingActionButtonController(this,
- floatingActionButtonContainer, floatingActionButton);
+ floatingActionButtonContainer,mFloatingActionButton);
ImageButton optionsMenuButton =
(ImageButton) searchEditTextLayout.findViewById(R.id.dialtacts_options_menu_button);
@@ -441,6 +450,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.dialtacts_frame, new ListsFragment(), TAG_FAVORITES_FRAGMENT)
+ .add(R.id.dialtacts_container, new DialpadFragment(), TAG_DIALPAD_FRAGMENT)
.commit();
} else {
mSearchQuery = savedInstanceState.getString(KEY_SEARCH_QUERY);
@@ -535,6 +545,8 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
prepareVoiceSearchButton();
mDialerDatabaseHelper.startSmartDialUpdateThread();
mFloatingActionButtonController.align(getFabAlignment(), false /* animate */);
+ setConferenceDialButtonImage(false);
+ setConferenceDialButtonVisibility(true);
if (getIntent().hasExtra(EXTRA_SHOW_TAB)) {
int index = getIntent().getIntExtra(EXTRA_SHOW_TAB, ListsFragment.TAB_INDEX_SPEED_DIAL);
@@ -608,6 +620,10 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
public void onClick(View view) {
switch (view.getId()) {
case R.id.floating_action_button:
+ mDialConferenceButtonPressed = false;
+ if (mDialpadFragment != null) {
+ mDialpadFragment.showDialConference(false);
+ }
if (mListsFragment.getCurrentTabIndex()
== ListsFragment.TAB_INDEX_ALL_CONTACTS && !mInRegularSearch) {
DialerUtils.startActivityWithErrorToast(
@@ -617,8 +633,25 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
} else if (!mIsDialpadShown) {
mInCallDialpadUp = false;
showDialpadFragment(true);
+ mFloatingActionButton.setImageResource(R.drawable.fab_ic_call);
+ mFloatingActionButton.setVisibility(view.VISIBLE);
+ setConferenceDialButtonImage(false);
+ setConferenceDialButtonVisibility(true);
+ } else {
+ // Dial button was pressed; tell the Dialpad fragment
+ mDialpadFragment.dialButtonPressed();
}
break;
+ case R.id.dialConferenceButton:
+ mDialConferenceButtonPressed = true;
+ showDialpadFragment(true);
+ mIsDialpadShown = false;
+ mDialCallButton.setVisibility(view.VISIBLE);
+ mDialpadFragment.dialConferenceButtonPressed();
+ mFloatingActionButton.setImageResource(R.drawable.fab_ic_dial);
+ mFloatingActionButtonController.align(getFabAlignment(), true);
+ mFloatingActionButton.setVisibility(view.VISIBLE);
+ break;
case R.id.voice_search_button:
try {
startActivityForResult(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH),
@@ -722,6 +755,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
maybeEnterSearchUi();
}
mActionBarController.onDialpadUp();
+ setConferenceDialButtonVisibility(animate);
mListsFragment.getView().animate().alpha(0).withLayer();
}
@@ -731,6 +765,13 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
*/
public void onDialpadShown() {
Assert.assertNotNull(mDialpadFragment);
+ if (mDialConferenceButtonPressed) {
+ mFloatingActionButton.setImageResource(R.drawable.fab_ic_dial);
+ mDialConferenceButtonPressed = false;
+ } else {
+ mFloatingActionButton.setImageResource(R.drawable.fab_ic_call);
+ }
+ mFloatingActionButtonController.align(getFabAlignment(), mDialpadFragment.getAnimate());
if (mDialpadFragment.getAnimate()) {
mDialpadFragment.getView().startAnimation(mSlideIn);
} else {
@@ -752,7 +793,8 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
if (clearDialpad) {
mDialpadFragment.clearDialpad();
}
- if (!mIsDialpadShown) {
+ if (!mIsDialpadShown && !mDialpadFragment.isRecipientsShown()) {
+ mFloatingActionButtonController.align(getFabAlignment(), animate);
return;
}
mIsDialpadShown = false;
@@ -761,6 +803,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
mListsFragment.sendScreenViewForCurrentPosition();
updateSearchFragmentPosition();
+ mFloatingActionButton.setImageResource(R.drawable.fab_ic_dial);
mFloatingActionButtonController.align(getFabAlignment(), animate);
if (animate) {
@@ -781,7 +824,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
/**
* Finishes hiding the dialpad fragment after any animations are completed.
*/
- private void commitDialpadFragmentHide() {
+ public void commitDialpadFragmentHide() {
if (!mStateSaved && mDialpadFragment != null && !mDialpadFragment.isHidden()) {
final FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.hide(mDialpadFragment);
@@ -1060,7 +1103,14 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
if (mStateSaved) {
return;
}
- if (mIsDialpadShown) {
+ setConferenceDialButtonImage(false);
+ setConferenceDialButtonVisibility(true);
+ boolean mIsRecipientsShown = mDialpadFragment.isRecipientsShown();
+ if(mIsRecipientsShown) {
+ mDialpadFragment.hideAndClearDialConference();
+ }
+
+ if (mIsDialpadShown || mIsRecipientsShown) {
if (TextUtils.isEmpty(mSearchQuery) ||
(mSmartDialSearchFragment != null && mSmartDialSearchFragment.isVisible()
&& mSmartDialSearchFragment.getAdapter().getCount() == 0)) {
@@ -1161,6 +1211,33 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
// interactions with the ListsFragments.
}
+ @Override
+ public void setConferenceDialButtonVisibility(boolean enabled) {
+ boolean imsUseEnabled =
+ ImsManager.isVolteEnabledByPlatform(this) &&
+ ImsManager.isEnhanced4gLteModeSettingEnabledByUser(this);
+ if(mConferenceDialButton != null) {
+ mConferenceDialButton.setVisibility((enabled && imsUseEnabled) ?
+ View.VISIBLE : View.GONE);
+ }
+ }
+
+ @Override
+ public void setConferenceDialButtonImage(boolean setAddParticipantButton) {
+ if(mConferenceDialButton != null) {
+ /*
+ * If dial conference view is shown, button should show dialpad
+ * image. Pressing the button again will return to normal dialpad
+ * view. If normal dialpad view is shown, button should show dial
+ * conference image. Pressing the button again will show dial
+ * conference view
+ */
+ mConferenceDialButton
+ .setImageResource(setAddParticipantButton ? R.drawable.fab_ic_call
+ : R.drawable.ic_add_group_holo_dark);
+ }
+ }
+
private boolean phoneIsInUse() {
return getTelecomManager().isInCall();
}
diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index d35abd75b..629c830bc 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -67,6 +67,7 @@ import android.widget.PopupMenu;
import android.widget.RelativeLayout;
import android.widget.TextView;
+import com.android.contacts.common.CallUtil;
import com.android.contacts.common.GeoUtil;
import com.android.contacts.common.util.PermissionsUtil;
import com.android.contacts.common.util.PhoneNumberFormatter;
@@ -142,6 +143,20 @@ public class DialpadFragment extends Fragment
* be dismissed, unless there happens to be content showing.
*/
boolean onDialpadSpacerTouchWithEmptyQuery();
+
+ /**
+ * This interface allows the DialpadFragment to tell its hosting Activity when and when not
+ * to display the "dial" button. While this is logically part of the DialpadFragment, the
+ * need to have a particular kind of slick animation puts the "dial" button in the parent.
+ *
+ * The parent calls dialButtonPressed() and optionsMenuInvoked() on the dialpad fragment
+ * when appropriate.
+ *
+ * TODO: Refactor the app so this interchange is a bit cleaner.
+ */
+ void setConferenceDialButtonVisibility(boolean enabled);
+ void setConferenceDialButtonImage(boolean setAddParticipantButton);
+
}
private static final boolean DEBUG = DialtactsActivity.DEBUG;
@@ -168,6 +183,9 @@ public class DialpadFragment extends Fragment
private DialpadView mDialpadView;
private EditText mDigits;
+ private EditText mRecipients;
+ private View mDigitsContainer;
+ private View mDialpad;
private int mDialpadSlideInDuration;
/** Remembers if we need to clear digits field when the screen is completely gone. */
@@ -212,6 +230,13 @@ public class DialpadFragment extends Fragment
/** Identifier for the "Add Call" intent extra. */
private static final String ADD_CALL_MODE_KEY = "add_call_mode";
+ /** Identifier for the "Add Participant" intent extra. */
+ private static final String ADD_PARTICIPANT_KEY = "add_participant";
+
+ private static final String EXTRA_DIAL_CONFERENCE_URI = "org.codeaurora.extra.DIAL_CONFERENCE_URI";
+
+ private boolean mAddParticipant = false;
+
/**
* Identifier for intent extra for sending an empty Flash message for
* CDMA networks. This message is used by the network to simulate a
@@ -251,6 +276,12 @@ public class DialpadFragment extends Fragment
// onscreen, but useless...)
showDialpadChooser(false);
}
+ if (state == TelephonyManager.EXTRA_STATE_IDLE) {
+ final Activity activity = getActivity();
+ if (activity != null) {
+ ((HostInterface) activity).setConferenceDialButtonVisibility(true);
+ }
+ }
}
}
@@ -369,6 +400,13 @@ public class DialpadFragment extends Fragment
mDialpadView = (DialpadView) fragmentView.findViewById(R.id.dialpad_view);
mDialpadView.setCanDigitsBeEdited(true);
mDigits = mDialpadView.getDigits();
+ mRecipients = (EditText) fragmentView.findViewById(R.id.recipients);
+ mDigitsContainer = fragmentView.findViewById(R.id.digits_container);
+ mDialpad = fragmentView.findViewById(R.id.dialpad);
+ if (mRecipients != null) {
+ mRecipients.setVisibility(View.GONE);
+ mRecipients.addTextChangedListener(this);
+ }
mDigits.setKeyListener(UnicodeDialerKeyListener.INSTANCE);
mDigits.setOnClickListener(this);
mDigits.setOnKeyListener(this);
@@ -547,6 +585,9 @@ public class DialpadFragment extends Fragment
}
}
+ } else {
+ mAddParticipant = intent.getBooleanExtra(ADD_PARTICIPANT_KEY, false);
+ ((HostInterface) getActivity()).setConferenceDialButtonVisibility(true);
}
showDialpadChooser(needToShowDialpadChooser);
setStartedFromNewIntent(false);
@@ -663,6 +704,7 @@ public class DialpadFragment extends Fragment
if (!isPhoneInUse()) {
// A sanity-check: the "dialpad chooser" UI should not be visible if the phone is idle.
showDialpadChooser(false);
+ hideAndClearDialpad(true);
}
stopWatch.lap("hnt");
@@ -907,6 +949,79 @@ public class DialpadFragment extends Fragment
return popupMenu;
}
+ /**
+ * Called by the containing Activity to tell this Fragment that the dial button has been
+ * pressed.
+ */
+ public void dialButtonPressed() {
+ mHaptic.vibrate();
+ handleDialButtonPressed();
+ }
+
+ public void dialConferenceButtonPressed() {
+ // show dial conference screen if it is not shown
+ // If it is already shown, show normal dial screen
+ boolean show = (mRecipients != null) && !mRecipients.isShown();
+ Log.d(TAG, "dialConferenceButtonPressed show " + show);
+ if (show) {
+ showDialConference(show);
+ } else {
+ handleDialButtonPressed();
+ showDialConference(!show);
+ }
+ }
+
+ public void showDialConference(boolean enabled) {
+ // Check if onCreateView() is already called by checking one of View
+ // objects.
+ if (!isLayoutReady()) {
+ return;
+ }
+ Log.d(TAG, "showDialConference " + enabled);
+ /*
+ * if enabled is true then pick child views that should be
+ * visible/invisible when dialpad is choosen from conference dial button
+ * if enabled is false then pick child views that should be
+ * visible/invisible when dialpad is choosen from other buttons
+ */
+
+ // viewable when choosen through conference button
+ int conferenceButtonVisibility = (enabled ? View.VISIBLE : View.GONE);
+ // not viewable when choosen through conference button
+ int nonConferenceButtonVisibility = (enabled ? View.GONE : View.VISIBLE);
+
+ // change the image visibility of the button
+ if (mRecipients != null)
+ mRecipients.setVisibility(conferenceButtonVisibility);
+ if (mDigits != null)
+ mDigits.setVisibility(nonConferenceButtonVisibility);
+ if (mDelete != null)
+ mDelete.setVisibility(nonConferenceButtonVisibility);
+ if (mDialpad != null)
+ mDialpad.setVisibility(enabled ? View.INVISIBLE : View.VISIBLE);
+
+ if (enabled && (HostInterface)getActivity() != null) {
+ ((HostInterface)getActivity()).setConferenceDialButtonImage(enabled);
+ }
+ }
+
+ public void hideAndClearDialConference() {
+ // hide the image visibility of the button
+ if (mRecipients != null)
+ mRecipients.setVisibility(View.GONE);
+ if (mDigits != null)
+ mDigits.setVisibility(View.GONE);
+ if (mDelete != null)
+ mDelete.setVisibility(View.GONE);
+ if (mDialpad != null)
+ mDialpad.setVisibility(View.GONE);
+ ((DialtactsActivity) getActivity()).commitDialpadFragmentHide();
+ }
+
+ public boolean isRecipientsShown() {
+ return mRecipients != null && mRecipients.isShown();
+ }
+
@Override
public void onClick(View view) {
switch (view.getId()) {
@@ -1095,32 +1210,50 @@ public class DialpadFragment extends Fragment
* case described above).
*/
private void handleDialButtonPressed() {
- if (isDigitsEmpty()) { // No number entered.
+ if (isDigitsEmpty() && (mRecipients == null || !mRecipients.isShown())) {
+ // No number entered.
handleDialButtonClickWithEmptyDigits();
} else {
- final String number = mDigits.getText().toString();
-
- // "persist.radio.otaspdial" is a temporary hack needed for one carrier's automated
- // test equipment.
- // TODO: clean it up.
- if (number != null
- && !TextUtils.isEmpty(mProhibitedPhoneNumberRegexp)
- && number.matches(mProhibitedPhoneNumberRegexp)) {
- Log.i(TAG, "The phone number is prohibited explicitly by a rule.");
- if (getActivity() != null) {
- DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
- R.string.dialog_phone_call_prohibited_message);
- dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog");
- }
-
- // Clear the digits just in case.
- clearDialpad();
+ boolean isDigitsShown = mDigits.isShown();
+ final String number = isDigitsShown ? mDigits.getText().toString() :
+ mRecipients.getText().toString().trim();
+ if (isDigitsShown && isDigitsEmpty()) {
+ handleDialButtonClickWithEmptyDigits();
+ } else if (mAddParticipant && isDigitsEmpty() && mRecipients.isShown()
+ && isRecipientEmpty()) {
+ // mRecipients must be empty
+ // TODO add support for conference URI in last number dialed
+ // use ErrorDialogFragment instead? also see
+ // android.app.AlertDialog
+ android.widget.Toast.makeText(getActivity(),
+ "Error: Cannot dial. Please provide conference recipients.",
+ android.widget.Toast.LENGTH_SHORT).show();
} else {
- final Intent intent = IntentUtil.getCallIntent(number,
- (getActivity() instanceof DialtactsActivity ?
- ((DialtactsActivity) getActivity()).getCallOrigin() : null));
- DialerUtils.startActivityWithErrorToast(getActivity(), intent);
- hideAndClearDialpad(false);
+ // "persist.radio.otaspdial" is a temporary hack needed for one carrier's automated
+ // test equipment.
+ // TODO: clean it up.
+ if (number != null
+ && !TextUtils.isEmpty(mProhibitedPhoneNumberRegexp)
+ && number.matches(mProhibitedPhoneNumberRegexp)) {
+ Log.i(TAG, "The phone number is prohibited explicitly by a rule.");
+ if (getActivity() != null) {
+ DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
+ R.string.dialog_phone_call_prohibited_message);
+ dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog");
+ }
+
+ // Clear the digits just in case.
+ clearDialpad();
+ } else {
+ final Intent intent = CallUtil.getCallIntent(number);
+ if (!isDigitsShown) {
+ // must be dial conference add extra
+ intent.putExtra(EXTRA_DIAL_CONFERENCE_URI, true);
+ }
+ intent.putExtra(ADD_PARTICIPANT_KEY, mAddParticipant && isPhoneInUse());
+ DialerUtils.startActivityWithErrorToast(getActivity(), intent);
+ hideAndClearDialpad(false);
+ }
}
}
}
@@ -1608,6 +1741,13 @@ public class DialpadFragment extends Fragment
}
/**
+ * @return true if the widget with the mRecipients is empty.
+ */
+ private boolean isRecipientEmpty() {
+ return (mRecipients == null) || (mRecipients.length() == 0);
+ }
+
+ /**
* Starts the asyn query to get the last dialed/outgoing
* number. When the background query finishes, mLastNumberDialed
* is set to the last dialed number or an empty string if none